/* Everything can be handled by the display table, if it's
present and the element is right. */
if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
- return XVECTOR (elt)->size;
+ return ASIZE (elt);
/* Some characters are special. */
if (c == '\n' || c == '\t' || c == '\015')
{
int i;
- if (widthtab->size != 256)
+ if (widthtab->header.size != 256)
abort ();
for (i = 0; i < 256; i++)
if (!VECTORP (BVAR (buf, width_table)))
BVAR (buf, width_table) = Fmake_vector (make_number (256), make_number (0));
widthtab = XVECTOR (BVAR (buf, width_table));
- if (widthtab->size != 256)
+ if (widthtab->header.size != 256)
abort ();
for (i = 0; i < 256; i++)
DP is a display table or NULL.
- This macro is used in current_column_1, Fmove_to_column, and
+ This macro is used in scan_for_column and in
compute_motion. */
-#define MULTIBYTE_BYTES_WIDTH(p, dp) \
+#define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \
do { \
- int c; \
+ int ch; \
\
- wide_column = 0; \
- c = STRING_CHAR_AND_LENGTH (p, bytes); \
+ ch = STRING_CHAR_AND_LENGTH (p, bytes); \
if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
width = bytes * 4; \
else \
{ \
- if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) \
- width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; \
+ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
+ width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \
else \
- width = CHAR_WIDTH (c); \
- if (width > 1) \
- wide_column = width; \
+ width = CHAR_WIDTH (ch); \
} \
} while (0)
last_known_column_point = 0;
}
+/* Return a non-outlandish value for the tab width. */
+
+static int
+sane_tab_width (void)
+{
+ EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width));
+ return 0 < n && n <= 1000 ? n : 8;
+}
+
EMACS_INT
current_column (void)
{
register int tab_seen;
EMACS_INT post_tab;
register int c;
- register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
+ int tab_width = sane_tab_width ();
int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = buffer_display_table ();
else
stop = GAP_END_ADDR;
- if (tab_width <= 0 || tab_width > 1000)
- tab_width = 8;
-
col = 0, tab_seen = 0, post_tab = 0;
while (1)
static void
scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
{
- register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
+ int tab_width = sane_tab_width ();
register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = buffer_display_table ();
int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
w = ! NILP (window) ? XWINDOW (window) : NULL;
- if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
memset (&cmp_it, 0, sizeof cmp_it);
cmp_it.id = -1;
composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
prev_col = col;
{ /* Check display property. */
- EMACS_INT end;
- int width = check_display_width (scan, col, &end);
+ EMACS_INT endp;
+ int width = check_display_width (scan, col, &endp);
if (width >= 0)
{
col += width;
- if (end > scan) /* Avoid infinite loops with 0-width overlays. */
+ if (endp > scan) /* Avoid infinite loops with 0-width overlays. */
{
- scan = end; scan_byte = charpos_to_bytepos (scan);
+ scan = endp; scan_byte = charpos_to_bytepos (scan);
continue;
}
}
{
/* Start of multi-byte form. */
unsigned char *ptr;
- int bytes, width, wide_column;
+ int bytes, width;
ptr = BYTE_POS_ADDR (scan_byte);
- MULTIBYTE_BYTES_WIDTH (ptr, dp);
+ MULTIBYTE_BYTES_WIDTH (ptr, dp, bytes, width);
/* Subtract one to compensate for the increment
that is going to happen below. */
scan_byte += bytes - 1;
If END is nil, that stands for the end of STRING. */
static double
-string_display_width (string, beg, end)
- Lisp_Object string, beg, end;
+string_display_width (Lisp_Object string, Lisp_Object beg, Lisp_Object end)
{
register int col;
register unsigned char *ptr, *stop;
register int tab_seen;
int post_tab;
register int c;
- register int tab_width = XINT (current_buffer->tab_width);
+ int tab_width = sane_tab_width ();
int ctl_arrow = !NILP (current_buffer->ctl_arrow);
register struct Lisp_Char_Table *dp = buffer_display_table ();
int b, e;
going backwards from point. */
stop = SDATA (string) + b;
- if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
-
col = 0, tab_seen = 0, post_tab = 0;
while (1)
c = *--ptr;
if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
- col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
+ col += ASIZE (DISP_CHAR_VECTOR (dp, c));
else if (c >= 040 && c < 0177)
col++;
else if (c == '\n')
{
EMACS_INT mincol;
register EMACS_INT fromcol;
- register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
+ int tab_width = sane_tab_width ();
CHECK_NUMBER (column);
if (NILP (minimum))
if (fromcol == mincol)
return make_number (mincol);
- if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
-
if (indent_tabs_mode)
{
Lisp_Object n;
position_indentation (register int pos_byte)
{
register EMACS_INT column = 0;
- register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
+ int tab_width = sane_tab_width ();
register unsigned char *p;
register unsigned char *stop;
unsigned char *start;
EMACS_INT next_boundary_byte = pos_byte;
EMACS_INT ceiling = next_boundary_byte;
- if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
-
p = BYTE_POS_ADDR (pos_byte);
/* STOP records the value of P at which we will need
to think about the gap, or about invisible text,
\f
/* compute_motion: compute buffer posn given screen posn and vice versa */
-struct position val_compute_motion;
+static struct position val_compute_motion;
/* Scan the current buffer forward from offset FROM, pretending that
this is at line FROMVPOS, column FROMHPOS, until reaching buffer
WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
and frame_cols = FRAME_COLS (XFRAME (window->frame))
- Or you can let window_box_text_cols do this all for you, and write:
- window_box_text_cols (w) - 1
+ Or you can let window_body_cols do this all for you, and write:
+ window_body_cols (w) - 1
The `-1' accounts for the continuation-line backslashes; the rest
accounts for window borders if the window is split horizontally, and
register EMACS_INT pos;
EMACS_INT pos_byte;
register int c = 0;
- register EMACS_INT tab_width = XFASTINT (BVAR (current_buffer, tab_width));
+ int tab_width = sane_tab_width ();
register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
register struct Lisp_Char_Table *dp = window_display_table (win);
EMACS_INT selective
: !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
int selective_rlen
= (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
- ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
+ ? ASIZE (DISP_INVIS_VECTOR (dp)) : 0);
/* The next location where the `invisible' property changes, or an
overlay starts or ends. */
EMACS_INT next_boundary = from;
run cache, because that's based on the buffer's display table. */
width_table = 0;
- if (tab_width <= 0 || tab_width > 1000)
- tab_width = 8;
-
/* Negative width means use all available text columns. */
if (width < 0)
{
- width = window_box_text_cols (win);
+ width = window_body_cols (win);
/* We must make room for continuation marks if we don't have fringes. */
#ifdef HAVE_WINDOW_SYSTEM
if (!FRAME_WINDOW_P (XFRAME (win->frame)))
{
/* Start of multi-byte form. */
unsigned char *ptr;
- int bytes, width, wide_column;
+ int mb_bytes, mb_width;
pos_byte--; /* rewind POS_BYTE */
ptr = BYTE_POS_ADDR (pos_byte);
- MULTIBYTE_BYTES_WIDTH (ptr, dp);
- pos_byte += bytes;
- if (wide_column)
- wide_column_end_hpos = hpos + wide_column;
- hpos += width;
+ MULTIBYTE_BYTES_WIDTH (ptr, dp, mb_bytes, mb_width);
+ pos_byte += mb_bytes;
+ if (mb_width > 1 && BYTES_BY_CHAR_HEAD (*ptr) == mb_bytes)
+ wide_column_end_hpos = hpos + mb_width;
+ hpos += mb_width;
}
else if (VECTORP (charvec))
++hpos;
struct window *w;
Lisp_Object bufpos, hpos, vpos, prevhpos;
struct position *pos;
- int hscroll, tab_offset;
+ EMACS_INT hscroll, tab_offset;
CHECK_NUMBER_COERCE_MARKER (from);
CHECK_CONS (frompos);
? window_internal_height (w)
: XINT (XCDR (topos))),
(NILP (topos)
- ? (window_box_text_cols (w)
+ ? (window_body_cols (w)
- (
#ifdef HAVE_WINDOW_SYSTEM
FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
\f
/* Fvertical_motion and vmotion */
-struct position val_vmotion;
+static struct position val_vmotion;
struct position *
vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w)
struct text_pos pt;
struct window *w;
Lisp_Object old_buffer;
- struct gcpro gcpro1;
+ EMACS_INT old_charpos, old_bytepos;
+ struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object lcols = Qnil;
- double cols;
+ double cols IF_LINT (= 0);
/* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
if (CONSP (lines) && (NUMBERP (XCAR (lines))))
w = XWINDOW (window);
old_buffer = Qnil;
- GCPRO1 (old_buffer);
+ GCPRO3 (old_buffer, old_charpos, old_bytepos);
if (XBUFFER (w->buffer) != current_buffer)
{
/* Set the window's buffer temporarily to the current buffer. */
old_buffer = w->buffer;
+ old_charpos = XMARKER (w->pointm)->charpos;
+ old_bytepos = XMARKER (w->pointm)->bytepos;
XSETBUFFER (w->buffer, current_buffer);
+ set_marker_both
+ (w->pointm, w->buffer, BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
}
if (noninteractive)
}
else
{
- int it_start, first_x, it_overshoot_expected;
+ EMACS_INT it_start;
+ int first_x, it_overshoot_expected IF_LINT (= 0);
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
/* Do this even if LINES is 0, so that we move back to the
beginning of the current line as we ought. */
if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
- move_it_by_lines (&it, XINT (lines), 0);
+ move_it_by_lines (&it, XINT (lines));
}
else
{
|| (it_overshoot_expected < 0
&& it.method == GET_FROM_BUFFER
&& it.c == '\n'))
- move_it_by_lines (&it, -1, 0);
+ move_it_by_lines (&it, -1);
it.vpos = 0;
- move_it_by_lines (&it, XINT (lines), 0);
+ move_it_by_lines (&it, XINT (lines));
}
else
{
while (IT_CHARPOS (it) <= it_start)
{
it.vpos = 0;
- move_it_by_lines (&it, 1, 0);
+ move_it_by_lines (&it, 1);
}
if (XINT (lines) > 1)
- move_it_by_lines (&it, XINT (lines) - 1, 0);
+ move_it_by_lines (&it, XINT (lines) - 1);
}
else
{
it.vpos = 0;
- move_it_by_lines (&it, XINT (lines), 0);
+ move_it_by_lines (&it, XINT (lines));
}
}
}
}
if (BUFFERP (old_buffer))
- w->buffer = old_buffer;
+ {
+ w->buffer = old_buffer;
+ set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos);
+ }
RETURN_UNGCPRO (make_number (it.vpos));
}