elisp: Screen Lines

 
 29.2.5 Motion by Screen Lines
 -----------------------------
 
 The line functions in the previous section count text lines, delimited
 only by newline characters.  By contrast, these functions count screen
 lines, which are defined by the way the text appears on the screen.  A
 text line is a single screen line if it is short enough to fit the width
 of the selected window, but otherwise it may occupy several screen
 lines.
 
    In some cases, text lines are truncated on the screen rather than
 continued onto additional screen lines.  In these cases,
 ‘vertical-motion’ moves point much like ‘forward-line’.  See
 Truncation.
 
    Because the width of a given string depends on the flags that control
 the appearance of certain characters, ‘vertical-motion’ behaves
 differently, for a given piece of text, depending on the buffer it is
 in, and even on the selected window (because the width, the truncation
 flag, and display table may vary between windows).  SeeUsual
 Display.
 
    These functions scan text to determine where screen lines break, and
 thus take time proportional to the distance scanned.
 
  -- Function: vertical-motion count &optional window cur-col
      This function moves point to the start of the screen line COUNT
      screen lines down from the screen line containing point.  If COUNT
      is negative, it moves up instead.
 
      The COUNT argument can be a cons cell, ‘(COLS . LINES)’, instead of
      an integer.  Then the function moves by LINES screen lines, and
      puts point COLS columns from the visual start of that screen line.
      Note that COLS are counted from the _visual_ start of the line; if
      the window is scrolled horizontally (SeeHorizontal Scrolling),
      the column on which point will end is in addition to the number of
      columns by which the text is scrolled.
 
      The return value is the number of screen lines over which point was
      moved.  The value may be less in absolute value than COUNT if the
      beginning or end of the buffer was reached.
 
      The window WINDOW is used for obtaining parameters such as the
      width, the horizontal scrolling, and the display table.  But
      ‘vertical-motion’ always operates on the current buffer, even if
      WINDOW currently displays some other buffer.
 
      The optional argument CUR-COL specifies the current column when the
      function is called.  This is the window-relative horizontal
      coordinate of point, measured in units of font width of the frame’s
      default face.  Providing it speeds up the function, especially in
      very long lines, because it doesn’t have to go back in the buffer
      in order to determine the current column.  Note that CUR-COL is
      also counted from the visual start of the line.
 
  -- Function: count-screen-lines &optional beg end count-final-newline
           window
      This function returns the number of screen lines in the text from
      BEG to END.  The number of screen lines may be different from the
      number of actual lines, due to line continuation, the display
      table, etc.  If BEG and END are ‘nil’ or omitted, they default to
      the beginning and end of the accessible portion of the buffer.
 
      If the region ends with a newline, that is ignored unless the
      optional third argument COUNT-FINAL-NEWLINE is non-‘nil’.
 
      The optional fourth argument WINDOW specifies the window for
      obtaining parameters such as width, horizontal scrolling, and so
      on.  The default is to use the selected window’s parameters.
 
      Like ‘vertical-motion’, ‘count-screen-lines’ always uses the
      current buffer, regardless of which buffer is displayed in WINDOW.
      This makes possible to use ‘count-screen-lines’ in any buffer,
      whether or not it is currently displayed in some window.
 
  -- Command: move-to-window-line count
      This function moves point with respect to the text currently
      displayed in the selected window.  It moves point to the beginning
      of the screen line COUNT screen lines from the top of the window.
      If COUNT is negative, that specifies a position −COUNT lines from
      the bottom (or the last line of the buffer, if the buffer ends
      above the specified screen position).
 
      If COUNT is ‘nil’, then point moves to the beginning of the line in
      the middle of the window.  If the absolute value of COUNT is
      greater than the size of the window, then point moves to the place
      that would appear on that screen line if the window were tall
      enough.  This will probably cause the next redisplay to scroll to
      bring that location onto the screen.
 
      In an interactive call, COUNT is the numeric prefix argument.
 
      The value returned is the window line number point has moved to,
      with the top line in the window numbered 0.
 
  -- Function: move-to-window-group-line count
      This function is like ‘move-to-window-line’, except that when the
      selected window is a part of a group of windows (SeeWindow
      Group), ‘move-to-window-group-line’ will move to a position with
      respect to the entire group, not just the single window.  This
      condition holds when the buffer local variable
      ‘move-to-window-group-line-function’ is set to a function.  In this
      case, ‘move-to-window-group-line’ calls the function with the
      argument COUNT, then returns its result.
 
  -- Function: compute-motion from frompos to topos width offsets window
      This function scans the current buffer, calculating screen
      positions.  It scans the buffer forward from position FROM,
      assuming that is at screen coordinates FROMPOS, to position TO or
      coordinates TOPOS, whichever comes first.  It returns the ending
      buffer position and screen coordinates.
 
      The coordinate arguments FROMPOS and TOPOS are cons cells of the
      form ‘(HPOS . VPOS)’.
 
      The argument WIDTH is the number of columns available to display
      text; this affects handling of continuation lines.  ‘nil’ means the
      actual number of usable text columns in the window, which is
      equivalent to the value returned by ‘(window-width window)’.
 
      The argument OFFSETS is either ‘nil’ or a cons cell of the form
      ‘(HSCROLL . TAB-OFFSET)’.  Here HSCROLL is the number of columns
      not being displayed at the left margin; most callers get this by
      calling ‘window-hscroll’.  Meanwhile, TAB-OFFSET is the offset
      between column numbers on the screen and column numbers in the
      buffer.  This can be nonzero in a continuation line, when the
      previous screen lines’ widths do not add up to a multiple of
      ‘tab-width’.  It is always zero in a non-continuation line.
 
      The window WINDOW serves only to specify which display table to
      use.  ‘compute-motion’ always operates on the current buffer,
      regardless of what buffer is displayed in WINDOW.
 
      The return value is a list of five elements:
 
           (POS HPOS VPOS PREVHPOS CONTIN)
 
      Here POS is the buffer position where the scan stopped, VPOS is the
      vertical screen position, and HPOS is the horizontal screen
      position.
 
      The result PREVHPOS is the horizontal position one character back
      from POS.  The result CONTIN is ‘t’ if the last line was continued
      after (or within) the previous character.
 
      For example, to find the buffer position of column COL of screen
      line LINE of a certain window, pass the window’s display start
      location as FROM and the window’s upper-left coordinates as
      FROMPOS.  Pass the buffer’s ‘(point-max)’ as TO, to limit the scan
      to the end of the accessible portion of the buffer, and pass LINE
      and COL as TOPOS.  Here’s a function that does this:
 
           (defun coordinates-of-position (col line)
             (car (compute-motion (window-start)
                                  '(0 . 0)
                                  (point-max)
                                  (cons col line)
                                  (window-width)
                                  (cons (window-hscroll) 0)
                                  (selected-window))))
 
      When you use ‘compute-motion’ for the minibuffer, you need to use
      ‘minibuffer-prompt-width’ to get the horizontal position of the
      beginning of the first screen line.  SeeMinibuffer Contents.