/* Indentation functions.
- Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001
+ Copyright (C) 1985,86,87,88,93,94,95,98,2000,01,02,03,2004
Free Software Foundation, Inc.
This file is part of GNU Emacs.
int indent_tabs_mode;
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#define max(a, b) ((a) > (b) ? (a) : (b))
-
#define CR 015
-/* These three values memoize the current column to avoid recalculation. */
+/* These three values memorize the current column to avoid recalculation. */
/* Last value returned by current_column.
Some things in set last_known_column_point to -1
- to mark the memoized value as invalid. */
+ to mark the memorized value as invalid. */
-int last_known_column;
+double last_known_column;
/* Value of point when current_column was called. */
int last_known_column_modified;
-static int current_column_1 P_ ((void));
-static int position_indentation P_ ((int));
+static double current_column_1 P_ ((void));
+static double position_indentation P_ ((int));
/* Cache of beginning of line found by the last call of
current_column. */
{
Lisp_Object prop, position, overlay_limit, proplimit;
Lisp_Object buffer;
- int end;
+ int end, inv_p;
XSETFASTINT (position, pos);
XSETBUFFER (buffer, current_buffer);
}
/* if the `invisible' property is set, we can skip to
the next property change */
- if (!NILP (window) && EQ (XWINDOW (window)->buffer, buffer))
- prop = Fget_char_property (position, Qinvisible, window);
- else
- prop = Fget_char_property (position, Qinvisible, buffer);
- if (TEXT_PROP_MEANS_INVISIBLE (prop))
+ prop = Fget_char_property (position, Qinvisible,
+ (!NILP (window)
+ && EQ (XWINDOW (window)->buffer, buffer))
+ ? window : buffer);
+ inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
+ /* When counting columns (window == nil), don't skip over ellipsis text. */
+ if (NILP (window) ? inv_p == 1 : inv_p)
return *next_boundary_p;
return pos;
}
} \
} while (0)
+
DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
- "Return the horizontal position of point. Beginning of line is column 0.\n\
-This is calculated by adding together the widths of all the displayed\n\
-representations of the character between the start of the previous line\n\
-and point. (eg control characters will have a width of 2 or 4, tabs\n\
-will have a variable width)\n\
-Ignores finite width of frame, which means that this function may return\n\
-values greater than (frame-width).\n\
-Whether the line is visible (if `selective-display' is t) has no effect;\n\
-however, ^M is treated as end of line when `selective-display' is t.")
- ()
+ doc: /* Return the horizontal position of point. Beginning of line is column 0.
+This is calculated by adding together the widths of all the displayed
+representations of the character between the start of the previous line
+and point. (eg control characters will have a width of 2 or 4, tabs
+will have a variable width)
+Ignores finite width of frame, which means that this function may return
+values greater than (frame-width).
+Whether the line is visible (if `selective-display' is t) has no effect;
+however, ^M is treated as end of line when `selective-display' is t. */)
+ ()
{
Lisp_Object temp;
- XSETFASTINT (temp, current_column ());
+ XSETFASTINT (temp, (int) current_column ()); /* iftc */
return temp;
}
last_known_column_point = 0;
}
-int
+double
current_column ()
{
register int col;
/* If the buffer has overlays, text properties,
or multibyte characters, use a more general algorithm. */
if (BUF_INTERVALS (current_buffer)
- || !NILP (current_buffer->overlays_before)
- || !NILP (current_buffer->overlays_after)
+ || current_buffer->overlays_before
+ || current_buffer->overlays_after
|| Z != Z_BYTE)
return current_column_1 ();
{
EMACS_INT i, n;
Lisp_Object charvec;
-
+
if (ptr == stop)
{
/* We stopped either for the beginning of the buffer
or for the gap. */
if (ptr == BEGV_ADDR)
break;
-
+
/* It was the gap. Jump back over it. */
stop = BEGV_ADDR;
ptr = GPT_ADDR;
-
+
/* Check whether that brings us to beginning of buffer. */
if (BEGV >= GPT)
break;
}
c = *--ptr;
-
+
if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
{
charvec = DISP_CHAR_VECTOR (dp, c);
charvec = Qnil;
n = 1;
}
-
+
for (i = n - 1; i >= 0; --i)
{
if (VECTORP (charvec))
/* This should be handled the same as
next_element_from_display_vector does it. */
Lisp_Object entry = AREF (charvec, i);
-
+
if (INTEGERP (entry)
&& GLYPH_CHAR_VALID_P (XFASTINT (entry)))
c = FAST_GLYPH_CHAR (XFASTINT (entry));
else
c = ' ';
}
-
+
if (c >= 040 && c < 0177)
col++;
else if (c == '\n'
{
if (tab_seen)
col = ((col + tab_width) / tab_width) * tab_width;
-
+
post_tab += col;
col = 0;
tab_seen = 1;
}
+ else if (VECTORP (charvec))
+ /* With a display table entry, C is displayed as is, and
+ not displayed as \NNN or as ^N. If C is a single-byte
+ character, it takes one column. If C is multi-byte in
+ an unibyte buffer, it's translated to unibyte, so it
+ also takes one column. */
+ ++col;
else
col += (ctl_arrow && c < 0200) ? 2 : 4;
}
This function handles characters that are invisible
due to text properties or overlays. */
-static int
+static double
current_column_1 ()
{
register int tab_width = XINT (current_buffer->tab_width);
/* Start the scan at the beginning of this line with column number 0. */
register int col = 0;
int scan, scan_byte;
- int next_boundary, next_boundary_byte;
+ int next_boundary;
int opoint = PT, opoint_byte = PT_BYTE;
scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
scan = PT, scan_byte = PT_BYTE;
SET_PT_BOTH (opoint, opoint_byte);
next_boundary = scan;
- next_boundary_byte = scan_byte;
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
while (scan < opoint)
{
int c;
- EMACS_INT i, n;
- Lisp_Object charvec;
/* Occasionally we may need to skip invisible text. */
while (scan == next_boundary)
goto endloop;
if (scan != old_scan)
scan_byte = CHAR_TO_BYTE (scan);
- next_boundary_byte = CHAR_TO_BYTE (next_boundary);
}
/* Check composition sequence. */
&& ! (multibyte && BASE_LEADING_CODE_P (c))
&& VECTORP (DISP_CHAR_VECTOR (dp, c)))
{
+ Lisp_Object charvec;
+ EMACS_INT i, n;
+
+ /* This character is displayed using a vector of glyphs.
+ Update the column based on those glyphs. */
+
charvec = DISP_CHAR_VECTOR (dp, c);
n = ASIZE (charvec);
- }
- else
- {
- charvec = Qnil;
- n = 1;
- }
- for (i = n - 1; i >= 0; --i)
- {
- if (VECTORP (charvec))
+ for (i = 0; i < n; i++)
{
/* This should be handled the same as
next_element_from_display_vector does it. */
- Lisp_Object entry = AREF (charvec, i);
-
+ Lisp_Object entry;
+ entry = AREF (charvec, i);
+
if (INTEGERP (entry)
&& GLYPH_CHAR_VALID_P (XFASTINT (entry)))
c = FAST_GLYPH_CHAR (XFASTINT (entry));
else
c = ' ';
+
+ if (c == '\n')
+ goto endloop;
+ if (c == '\r' && EQ (current_buffer->selective_display, Qt))
+ goto endloop;
+ if (c == '\t')
+ {
+ col += tab_width;
+ col = col / tab_width * tab_width;
+ }
+ else
+ ++col;
}
-
+ }
+ else
+ {
+ /* The display table says nothing for this character.
+ Display it as itself. */
+
if (c == '\n')
goto endloop;
if (c == '\r' && EQ (current_buffer->selective_display, Qt))
goto endloop;
- scan++;
- scan_byte++;
if (c == '\t')
{
- int prev_col = col;
col += tab_width;
col = col / tab_width * tab_width;
}
{
unsigned char *ptr;
int bytes, width, wide_column;
-
- scan_byte--;
+
ptr = BYTE_POS_ADDR (scan_byte);
MULTIBYTE_BYTES_WIDTH (ptr, dp);
scan_byte += bytes;
+ /* Subtract one to compensate for the increment
+ that is going to happen below. */
+ scan_byte--;
col += width;
}
else if (ctl_arrow && (c < 040 || c == 0177))
else
col++;
}
+ scan++;
+ scan_byte++;
+
}
endloop:
If BEG is nil, that stands for the beginning of STRING.
If END is nil, that stands for the end of STRING. */
-static int
+static double
string_display_width (string, beg, end)
Lisp_Object string, beg, end;
{
int b, e;
if (NILP (end))
- e = XSTRING (string)->size;
+ e = SCHARS (string);
else
{
- CHECK_NUMBER (end, 0);
+ CHECK_NUMBER (end);
e = XINT (end);
}
b = 0;
else
{
- CHECK_NUMBER (beg, 0);
+ CHECK_NUMBER (beg);
b = XINT (beg);
}
/* Make a pointer for decrementing through the chars before point. */
- ptr = XSTRING (string)->data + e;
+ ptr = SDATA (string) + e;
/* Make a pointer to where consecutive chars leave off,
going backwards from point. */
- stop = XSTRING (string)->data + b;
+ stop = SDATA (string) + b;
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
\f
DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
- "Indent from point with tabs and spaces until COLUMN is reached.\n\
-Optional second argument MININUM says always do at least MININUM spaces\n\
-even if that goes past COLUMN; by default, MININUM is zero.")
- (column, minimum)
+ doc: /* Indent from point with tabs and spaces until COLUMN is reached.
+Optional second argument MININUM says always do at least MININUM spaces
+even if that goes past COLUMN; by default, MININUM is zero. */)
+ (column, minimum)
Lisp_Object column, minimum;
{
int mincol;
register int fromcol;
register int tab_width = XINT (current_buffer->tab_width);
- CHECK_NUMBER (column, 0);
+ CHECK_NUMBER (column);
if (NILP (minimum))
XSETFASTINT (minimum, 0);
- CHECK_NUMBER (minimum, 1);
+ CHECK_NUMBER (minimum);
fromcol = current_column ();
mincol = fromcol + XINT (minimum);
}
\f
-static int position_indentation P_ ((int));
+static double position_indentation P_ ((int));
DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
- 0, 0, 0,
- "Return the indentation of the current line.\n\
-This is the horizontal position of the character\n\
-following any initial whitespace.")
- ()
+ 0, 0, 0,
+ doc: /* Return the indentation of the current line.
+This is the horizontal position of the character
+following any initial whitespace. */)
+ ()
{
Lisp_Object val;
int opoint = PT, opoint_byte = PT_BYTE;
scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
- XSETFASTINT (val, position_indentation (PT_BYTE));
+ XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */
SET_PT_BOTH (opoint, opoint_byte);
return val;
}
-static int
+static double
position_indentation (pos_byte)
register int pos_byte;
{
/* The -1 and +1 arrange to point at the first byte of gap
(if STOP_POS_BYTE is the position of the gap)
rather than at the data after the gap. */
-
+
stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
p = BYTE_POS_ADDR (pos_byte);
}
int
indented_beyond_p (pos, pos_byte, column)
- int pos, pos_byte, column;
+ int pos, pos_byte;
+ double column;
{
- int val;
+ double val;
int opoint = PT, opoint_byte = PT_BYTE;
SET_PT_BOTH (pos, pos_byte);
val = position_indentation (PT_BYTE);
SET_PT_BOTH (opoint, opoint_byte);
- return val >= column;
+ return val >= column; /* hmm, float comparison */
}
\f
DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
- "Move point to column COLUMN in the current line.\n\
-The column of a character is calculated by adding together the widths\n\
-as displayed of the previous characters in the line.\n\
-This function ignores line-continuation;\n\
-there is no upper limit on the column number a character can have\n\
-and horizontal scrolling has no effect.\n\
-\n\
-If specified column is within a character, point goes after that character.\n\
-If it's past end of line, point goes to end of line.\n\n\
-A non-nil second (optional) argument FORCE means,\n\
-if COLUMN is in the middle of a tab character, change it to spaces.\n\
-In addition, if FORCE is t, and the line is too short\n\
-to reach column COLUMN, add spaces/tabs to get there.\n\
-\n\
-The return value is the current column.")
- (column, force)
+ doc: /* Move point to column COLUMN in the current line.
+The column of a character is calculated by adding together the widths
+as displayed of the previous characters in the line.
+This function ignores line-continuation;
+there is no upper limit on the column number a character can have
+and horizontal scrolling has no effect.
+
+If specified column is within a character, point goes after that character.
+If it's past end of line, point goes to end of line.
+
+A non-nil second (optional) argument FORCE means,
+if COLUMN is in the middle of a tab character, change it to spaces.
+In addition, if FORCE is t, and the line is too short
+to reach column COLUMN, add spaces/tabs to get there.
+
+The return value is the current column. */)
+ (column, force)
Lisp_Object column, force;
{
register int pos;
Lisp_Object val;
int prev_col = 0;
int c = 0;
- int next_boundary;
-
- int pos_byte, end_byte, next_boundary_byte;
+ int next_boundary, pos_byte;
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
- CHECK_NATNUM (column, 0);
+ CHECK_NATNUM (column);
goal = XINT (column);
pos = PT;
pos_byte = PT_BYTE;
end = ZV;
- end_byte = ZV_BYTE;
next_boundary = pos;
- next_boundary_byte = PT_BYTE;
/* If we're starting past the desired column,
back up to beginning of line and scan from there. */
while (pos < end)
{
- Lisp_Object charvec;
- EMACS_INT i, n;
-
while (pos == next_boundary)
{
int prev = pos;
pos = skip_invisible (pos, &next_boundary, end, Qnil);
if (pos != prev)
pos_byte = CHAR_TO_BYTE (pos);
- next_boundary_byte = CHAR_TO_BYTE (next_boundary);
if (pos >= end)
goto endloop;
}
c = FETCH_BYTE (pos_byte);
+ /* See if there is a display table and it relates
+ to this character. */
+
if (dp != 0
&& ! (multibyte && BASE_LEADING_CODE_P (c))
&& VECTORP (DISP_CHAR_VECTOR (dp, c)))
{
+ Lisp_Object charvec;
+ EMACS_INT i, n;
+
+ /* This character is displayed using a vector of glyphs.
+ Update the position based on those glyphs. */
+
charvec = DISP_CHAR_VECTOR (dp, c);
n = ASIZE (charvec);
- }
- else
- {
- charvec = Qnil;
- n = 1;
- }
- for (i = n - 1; i >= 0; --i)
- {
- if (VECTORP (charvec))
+ for (i = 0; i < n; i++)
{
/* This should be handled the same as
next_element_from_display_vector does it. */
- Lisp_Object entry = AREF (charvec, i);
-
+
+ Lisp_Object entry;
+ entry = AREF (charvec, i);
+
if (INTEGERP (entry)
&& GLYPH_CHAR_VALID_P (XFASTINT (entry)))
c = FAST_GLYPH_CHAR (XFASTINT (entry));
else
c = ' ';
+
+ if (c == '\n')
+ goto endloop;
+ if (c == '\r' && EQ (current_buffer->selective_display, Qt))
+ goto endloop;
+ if (c == '\t')
+ {
+ prev_col = col;
+ col += tab_width;
+ col = col / tab_width * tab_width;
+ }
+ else
+ ++col;
}
+ }
+ else
+ {
+ /* The display table doesn't affect this character;
+ it displays as itself. */
-
if (c == '\n')
goto endloop;
if (c == '\r' && EQ (current_buffer->selective_display, Qt))
goto endloop;
- pos++;
- pos_byte++;
if (c == '\t')
{
prev_col = col;
unsigned char *ptr;
int bytes, width, wide_column;
- pos_byte--;
ptr = BYTE_POS_ADDR (pos_byte);
MULTIBYTE_BYTES_WIDTH (ptr, dp);
- pos_byte += bytes;
+ pos_byte += bytes - 1;
col += width;
}
else
col += 4;
}
+
+ pos++;
+ pos_byte++;
}
endloop:
goal_pt_byte = PT_BYTE;
Findent_to (make_number (col), Qnil);
SET_PT_BOTH (goal_pt, goal_pt_byte);
-
+
/* Set the last_known... vars consistently. */
col = goal;
}
window_width - 1
- (has_vertical_scroll_bars
- ? FRAME_SCROLL_BAR_COLS (XFRAME (window->frame))
- : (window_width + window_left != frame_width))
+ ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
+ : (window_width + window_left != frame_cols))
where
- window_width is XFASTINT (w->width),
- window_left is XFASTINT (w->left),
+ window_width is XFASTINT (w->total_cols),
+ window_left is XFASTINT (w->left_col),
has_vertical_scroll_bars is
- FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (WINDOW_FRAME (window)))
- and frame_width = FRAME_WIDTH (XFRAME (window->frame))
+ WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
+ and frame_cols = FRAME_COLS (XFRAME (window->frame))
- Or you can let window_internal_width do this all for you, and write:
- window_internal_width (w) - 1
+ Or you can let window_box_text_cols do this all for you, and write:
+ window_box_text_cols (w) - 1
The `-1' accounts for the continuation-line backslashes; the rest
accounts for window borders if the window is split horizontally, and
= (INTEGERP (current_buffer->selective_display)
? XINT (current_buffer->selective_display)
: !NILP (current_buffer->selective_display) ? -1 : 0);
- int prev_hpos = 0;
int selective_rlen
= (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
int wide_column_end_hpos = 0;
int prev_pos; /* Previous buffer position. */
int prev_pos_byte; /* Previous buffer position. */
+ int prev_hpos = 0;
+ int prev_vpos = 0;
int contin_hpos; /* HPOS of last column of continued line. */
int prev_tab_offset; /* Previous tab offset. */
int newpos;
/* Don't skip invisible if we are already at the margin. */
- if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
+ if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
{
if (contin_hpos && prev_hpos == 0
&& hpos > tohpos
pos = prev_pos;
pos_byte = prev_pos_byte;
hpos = prev_hpos;
+ vpos = prev_vpos;
tab_offset = prev_tab_offset;
}
break;
W_ ^---- next after the point
^---- next char. after the point.
----------
- In case of wide-column character
+ In case of wide-column character
The problem here is continuation at a wide-column character.
In this case, the line may shorter less than WIDTH.
{
if (hscroll
|| (truncate_partial_width_windows
- && width + 1 < FRAME_WIDTH (XFRAME (WINDOW_FRAME (win))))
+ && width + 1 < FRAME_COLS (XFRAME (WINDOW_FRAME (win))))
|| !NILP (current_buffer->truncate_lines))
{
/* Truncating: skip to newline, unless we are already past
if (pos >= next_boundary)
next_boundary = pos + 1;
prev_hpos = width;
+ prev_vpos = vpos;
prev_tab_offset = tab_offset;
}
}
vpos++;
contin_hpos = prev_hpos;
prev_hpos = 0;
+ prev_vpos = vpos;
}
}
pos = prev_pos;
pos_byte = prev_pos_byte;
hpos = prev_hpos;
+ vpos = prev_vpos;
tab_offset = prev_tab_offset;
/* NOTE on contin_hpos, hpos, and prev_hpos.
hpos = contin_hpos;
vpos = vpos - 1;
}
- else if (c == '\n')
- /* If previous character is NEWLINE,
- set VPOS back to previous line */
- vpos = vpos - 1;
break;
}
- if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
+ if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
{
if (contin_hpos && prev_hpos == 0
&& hpos > tohpos
pos = prev_pos;
pos_byte = prev_pos_byte;
hpos = prev_hpos;
+ vpos = prev_vpos;
tab_offset = prev_tab_offset;
}
break;
break;
prev_hpos = hpos;
+ prev_vpos = vpos;
prev_pos = pos;
prev_pos_byte = pos_byte;
wide_column_end_hpos = 0;
{
EMACS_INT i, n;
Lisp_Object charvec;
-
+
c = FETCH_BYTE (pos_byte);
/* Check composition sequence. */
/* This should be handled the same as
next_element_from_display_vector does it. */
Lisp_Object entry = AREF (charvec, i);
-
+
if (INTEGERP (entry)
&& GLYPH_CHAR_VALID_P (XFASTINT (entry)))
c = FAST_GLYPH_CHAR (XFASTINT (entry));
else
c = ' ';
}
-
+
if (c >= 040 && c < 0177)
hpos++;
else if (c == '\t')
else if (c == '\n')
{
if (selective > 0
- && indented_beyond_p (pos, pos_byte, selective))
+ && indented_beyond_p (pos, pos_byte,
+ (double) selective)) /* iftc */
{
/* If (pos == to), we don't have to take care of
selective display. */
pos_byte = CHAR_TO_BYTE (pos);
}
while (pos < to
- && indented_beyond_p (pos, pos_byte, selective));
+ && indented_beyond_p (pos, pos_byte,
+ (double) selective)); /* iftc */
/* Allow for the " ..." that is displayed for them. */
if (selective_rlen)
{
wide_column_end_hpos = hpos + wide_column;
hpos += width;
}
+ else if (VECTORP (charvec))
+ ++hpos;
else
hpos += (ctl_arrow && c < 0200) ? 2 : 4;
}
}
-#if 0 /* The doc string is too long for some compilers,
- but make-docfile can find it in this comment. */
-DEFUN ("compute-motion", Ffoo, Sfoo, 7, 7, 0,
- "Scan through the current buffer, calculating screen position.\n\
-Scan the current buffer forward from offset FROM,\n\
-assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--\n\
-to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--\n\
-and return the ending buffer position and screen location.\n\
-\n\
-There are three additional arguments:\n\
-\n\
-WIDTH is the number of columns available to display text;\n\
-this affects handling of continuation lines.\n\
-This is usually the value returned by `window-width', less one (to allow\n\
-for the continuation glyph).\n\
-\n\
-OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).\n\
-HSCROLL is the number of columns not being displayed at the left\n\
-margin; this is usually taken from a window's hscroll member.\n\
-TAB-OFFSET is the number of columns of the first tab that aren't\n\
-being displayed, perhaps because the line was continued within it.\n\
-If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.\n\
-\n\
-WINDOW is the window to operate on. It is used to choose the display table;\n\
-if it is showing the current buffer, it is used also for\n\
-deciding which overlay properties apply.\n\
-Note that `compute-motion' always operates on the current buffer.\n\
-\n\
-The value is a list of five elements:\n\
- (POS HPOS VPOS PREVHPOS CONTIN)\n\
-POS is the buffer position where the scan stopped.\n\
-VPOS is the vertical position where the scan stopped.\n\
-HPOS is the horizontal position where the scan stopped.\n\
-\n\
-PREVHPOS is the horizontal position one character back from POS.\n\
-CONTIN is t if a line was continued after (or within) the previous character.\n\
-\n\
-For example, to find the buffer position of column COL of line LINE\n\
-of a certain window, pass the window's starting location as FROM\n\
-and the window's upper-left coordinates as FROMPOS.\n\
-Pass the buffer's (point-max) as TO, to limit the scan to the end of the\n\
-visible section of the buffer, and pass LINE and COL as TOPOS.")
- (from, frompos, to, topos, width, offsets, window)
-#endif
-
DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
- 0)
- (from, frompos, to, topos, width, offsets, window)
+ doc: /* Scan through the current buffer, calculating screen position.
+Scan the current buffer forward from offset FROM,
+assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
+to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
+and return the ending buffer position and screen location.
+
+There are three additional arguments:
+
+WIDTH is the number of columns available to display text;
+this affects handling of continuation lines.
+This is usually the value returned by `window-width', less one (to allow
+for the continuation glyph).
+
+OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
+HSCROLL is the number of columns not being displayed at the left
+margin; this is usually taken from a window's hscroll member.
+TAB-OFFSET is the number of columns of the first tab that aren't
+being displayed, perhaps because the line was continued within it.
+If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
+
+WINDOW is the window to operate on. It is used to choose the display table;
+if it is showing the current buffer, it is used also for
+deciding which overlay properties apply.
+Note that `compute-motion' always operates on the current buffer.
+
+The value is a list of five elements:
+ (POS HPOS VPOS PREVHPOS CONTIN)
+POS is the buffer position where the scan stopped.
+VPOS is the vertical position where the scan stopped.
+HPOS is the horizontal position where the scan stopped.
+
+PREVHPOS is the horizontal position one character back from POS.
+CONTIN is t if a line was continued after (or within) the previous character.
+
+For example, to find the buffer position of column COL of line LINE
+of a certain window, pass the window's starting 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
+visible section of the buffer, and pass LINE and COL as TOPOS. */)
+ (from, frompos, to, topos, width, offsets, window)
Lisp_Object from, frompos, to, topos;
Lisp_Object width, offsets, window;
{
struct position *pos;
int hscroll, tab_offset;
- CHECK_NUMBER_COERCE_MARKER (from, 0);
- CHECK_CONS (frompos, 0);
- CHECK_NUMBER (XCAR (frompos), 0);
- CHECK_NUMBER (XCDR (frompos), 0);
- CHECK_NUMBER_COERCE_MARKER (to, 0);
- CHECK_CONS (topos, 0);
- CHECK_NUMBER (XCAR (topos), 0);
- CHECK_NUMBER (XCDR (topos), 0);
- CHECK_NUMBER (width, 0);
+ CHECK_NUMBER_COERCE_MARKER (from);
+ CHECK_CONS (frompos);
+ CHECK_NUMBER_CAR (frompos);
+ CHECK_NUMBER_CDR (frompos);
+ CHECK_NUMBER_COERCE_MARKER (to);
+ CHECK_CONS (topos);
+ CHECK_NUMBER_CAR (topos);
+ CHECK_NUMBER_CDR (topos);
+ CHECK_NUMBER (width);
if (!NILP (offsets))
{
- CHECK_CONS (offsets, 0);
- CHECK_NUMBER (XCAR (offsets), 0);
- CHECK_NUMBER (XCDR (offsets), 0);
+ CHECK_CONS (offsets);
+ CHECK_NUMBER_CAR (offsets);
+ CHECK_NUMBER_CDR (offsets);
hscroll = XINT (XCAR (offsets));
tab_offset = XINT (XCDR (offsets));
}
if (NILP (window))
window = Fselected_window ();
else
- CHECK_LIVE_WINDOW (window, 0);
+ CHECK_LIVE_WINDOW (window);
if (XINT (from) < BEGV || XINT (from) > ZV)
args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
register int from, vtarget;
struct window *w;
{
- int width = window_internal_width (w) - 1;
+ int width = window_box_text_cols (w);
int hscroll = XINT (w->hscroll);
struct position pos;
/* vpos is cumulative vertical position, changed as from is changed */
XSETWINDOW (window, w);
+ /* We must make room for continuation marks if we don't have fringes. */
+#ifdef HAVE_WINDOW_SYSTEM
+ if (!FRAME_WINDOW_P (XFRAME (w->frame)))
+#endif
+ width -= 1;
+
/* If the window contains this buffer, use it for getting text properties.
Otherwise use the current buffer as arg for doing that. */
if (EQ (w->buffer, Fcurrent_buffer ()))
&& ((selective > 0
&& indented_beyond_p (XFASTINT (prevline),
CHAR_TO_BYTE (XFASTINT (prevline)),
- selective))
+ (double) selective)) /* iftc */
/* watch out for newlines with `invisible' property */
|| (propval = Fget_char_property (prevline,
Qinvisible,
lmargin + (XFASTINT (prevline) == BEG
? start_hpos : 0),
0,
- from,
+ from,
/* Don't care for VPOS... */
1 << (BITS_PER_SHORT - 1),
/* ... nor HPOS. */
&& ((selective > 0
&& indented_beyond_p (XFASTINT (prevline),
CHAR_TO_BYTE (XFASTINT (prevline)),
- selective))
+ (double) selective)) /* iftc */
/* watch out for newlines with `invisible' property */
|| (propval = Fget_char_property (prevline, Qinvisible,
text_prop_object),
lmargin + (XFASTINT (prevline) == BEG
? start_hpos : 0),
0,
- from,
+ from,
/* Don't care for VPOS... */
1 << (BITS_PER_SHORT - 1),
/* ... nor HPOS. */
}
DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
- "Move point to start of the screen line LINES lines down.\n\
-If LINES is negative, this means moving up.\n\
-\n\
-This function is an ordinary cursor motion function\n\
-which calculates the new position based on how text would be displayed.\n\
-The new position may be the start of a line,\n\
-or just the start of a continuation line.\n\
-The function returns number of screen lines moved over;\n\
-that usually equals LINES, but may be closer to zero\n\
-if beginning or end of buffer was reached.\n\
-\n\
-The optional second argument WINDOW specifies the window to use for\n\
-parameters such as width, horizontal scrolling, and so on.\n\
-The default is to use the selected window's parameters.\n\
-\n\
-`vertical-motion' always uses the current buffer,\n\
-regardless of which buffer is displayed in WINDOW.\n\
-This is consistent with other cursor motion functions\n\
-and makes it possible to use `vertical-motion' in any buffer,\n\
-whether or not it is currently displayed in some window.")
- (lines, window)
+ doc: /* Move point to start of the screen line LINES lines down.
+If LINES is negative, this means moving up.
+
+This function is an ordinary cursor motion function
+which calculates the new position based on how text would be displayed.
+The new position may be the start of a line,
+or just the start of a continuation line.
+The function returns number of screen lines moved over;
+that usually equals LINES, but may be closer to zero
+if beginning or end of buffer was reached.
+
+The optional second argument WINDOW specifies the window to use for
+parameters such as width, horizontal scrolling, and so on.
+The default is to use the selected window's parameters.
+
+`vertical-motion' always uses the current buffer,
+regardless of which buffer is displayed in WINDOW.
+This is consistent with other cursor motion functions
+and makes it possible to use `vertical-motion' in any buffer,
+whether or not it is currently displayed in some window. */)
+ (lines, window)
Lisp_Object lines, window;
{
struct it it;
Lisp_Object old_buffer;
struct gcpro gcpro1;
- CHECK_NUMBER (lines, 0);
+ CHECK_NUMBER (lines);
if (! NILP (window))
- CHECK_WINDOW (window, 0);
+ CHECK_WINDOW (window);
else
window = selected_window;
w = XWINDOW (window);
old_buffer = w->buffer;
XSETBUFFER (w->buffer, current_buffer);
}
-
+
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
- move_it_by_lines (&it, XINT (lines), 0);
+
+ /* Move to the start of the display line containing PT. If we don't
+ do this, we start moving with IT->current_x == 0, while PT is
+ really at some x > 0. The effect is, in continuation lines, that
+ we end up with the iterator placed at where it thinks X is 0,
+ while the end position is really at some X > 0, the same X that
+ PT had. */
+ move_it_by_lines (&it, 0, 0);
+
+ if (XINT (lines) != 0)
+ move_it_by_lines (&it, XINT (lines), 0);
+
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
if (BUFFERP (old_buffer))
w->buffer = old_buffer;
-
+
RETURN_UNGCPRO (make_number (it.vpos));
}
syms_of_indent ()
{
DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
- "*Indentation can insert tabs if this is non-nil.\n\
-Setting this variable automatically makes it local to the current buffer.");
+ doc: /* *Indentation can insert tabs if this is non-nil.
+Setting this variable automatically makes it local to the current buffer. */);
indent_tabs_mode = 1;
defsubr (&Scurrent_indentation);
defsubr (&Svertical_motion);
defsubr (&Scompute_motion);
}
+
+/* arch-tag: 9adfea44-71f7-4988-8ee3-96da15c502cc
+ (do not change this comment) */