X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/699c782b7668c44d0fa4446331b0590a6d5dac82..fb39b937b0628f4592b07d0aa61a41cf696abd30:/src/indent.c diff --git a/src/indent.c b/src/indent.c index a1fcd2b101..b368a7aeb0 100644 --- a/src/indent.c +++ b/src/indent.c @@ -19,11 +19,10 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include "lisp.h" -#include "buffer.h" #include "character.h" +#include "buffer.h" #include "category.h" #include "composite.h" #include "indent.h" @@ -45,23 +44,23 @@ along with GNU Emacs. If not, see . */ Some things in set last_known_column_point to -1 to mark the memorized value as invalid. */ -static EMACS_INT last_known_column; +static ptrdiff_t last_known_column; /* Value of point when current_column was called. */ -EMACS_INT last_known_column_point; +ptrdiff_t last_known_column_point; /* Value of MODIFF when current_column was called. */ -static int last_known_column_modified; +static EMACS_INT last_known_column_modified; -static EMACS_INT current_column_1 (void); -static EMACS_INT position_indentation (ptrdiff_t); +static ptrdiff_t current_column_1 (void); +static ptrdiff_t position_indentation (ptrdiff_t); /* Cache of beginning of line found by the last call of current_column. */ -static EMACS_INT current_column_bol_cache; +static ptrdiff_t current_column_bol_cache; /* Get the display table to use for the current buffer. */ @@ -116,13 +115,13 @@ character_width (int c, struct Lisp_Char_Table *dp) for characters as WIDTHTAB. We use this to decide when to invalidate the buffer's width_run_cache. */ -int +bool disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *widthtab) { int i; if (widthtab->header.size != 256) - abort (); + emacs_abort (); for (i = 0; i < 256; i++) if (character_width (i, disptab) @@ -141,10 +140,10 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) struct Lisp_Vector *widthtab; if (!VECTORP (BVAR (buf, width_table))) - BVAR (buf, width_table) = Fmake_vector (make_number (256), make_number (0)); + bset_width_table (buf, Fmake_vector (make_number (256), make_number (0))); widthtab = XVECTOR (BVAR (buf, width_table)); if (widthtab->header.size != 256) - abort (); + emacs_abort (); for (i = 0; i < 256; i++) XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); @@ -166,7 +165,7 @@ width_run_cache_on_off (void) { free_region_cache (current_buffer->width_run_cache); current_buffer->width_run_cache = 0; - BVAR (current_buffer, width_table) = Qnil; + bset_width_table (current_buffer, Qnil); } } else @@ -204,12 +203,12 @@ width_run_cache_on_off (void) characters immediately following, then *NEXT_BOUNDARY_P will equal the return value. */ -EMACS_INT -skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Object window) +ptrdiff_t +skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, ptrdiff_t to, Lisp_Object window) { Lisp_Object prop, position, overlay_limit, proplimit; Lisp_Object buffer, tmp; - EMACS_INT end; + ptrdiff_t end; int inv_p; XSETFASTINT (position, pos); @@ -318,17 +317,17 @@ invalidate_current_column (void) last_known_column_point = 0; } -EMACS_INT +ptrdiff_t current_column (void) { - register EMACS_INT col; - register unsigned char *ptr, *stop; - register int tab_seen; - EMACS_INT post_tab; - register int c; + ptrdiff_t col; + unsigned char *ptr, *stop; + bool tab_seen; + ptrdiff_t post_tab; + int c; int tab_width = SANE_TAB_WIDTH (current_buffer); - int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); - register struct Lisp_Char_Table *dp = buffer_display_table (); + bool ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); + struct Lisp_Char_Table *dp = buffer_display_table (); if (PT == last_known_column_point && MODIFF == last_known_column_modified) @@ -336,9 +335,8 @@ current_column (void) /* If the buffer has overlays, text properties, or multibyte characters, use a more general algorithm. */ - if (BUF_INTERVALS (current_buffer) - || current_buffer->overlays_before - || current_buffer->overlays_after + if (buffer_intervals (current_buffer) + || buffer_has_overlays () || Z != Z_BYTE) return current_column_1 (); @@ -360,7 +358,7 @@ current_column (void) while (1) { - EMACS_INT i, n; + ptrdiff_t i, n; Lisp_Object charvec; if (ptr == stop) @@ -400,8 +398,7 @@ current_column (void) next_element_from_display_vector does it. */ Lisp_Object entry = AREF (charvec, i); - if (GLYPH_CODE_P (entry) - && GLYPH_CODE_CHAR_VALID_P (entry)) + if (GLYPH_CODE_P (entry)) c = GLYPH_CODE_CHAR (entry); else c = ' '; @@ -464,7 +461,7 @@ current_column (void) in ENDPOS. Otherwise just return -1. */ static int -check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) +check_display_width (ptrdiff_t pos, ptrdiff_t col, ptrdiff_t *endpos) { Lisp_Object val, overlay; @@ -474,19 +471,27 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) { /* FIXME: Use calc_pixel_width_or_height. */ Lisp_Object plist = XCDR (val), prop; int width = -1; + EMACS_INT align_to_max = + (col < MOST_POSITIVE_FIXNUM - INT_MAX + ? (EMACS_INT) INT_MAX + col + : MOST_POSITIVE_FIXNUM); - if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop))) + if ((prop = Fplist_get (plist, QCwidth), + RANGED_INTEGERP (0, prop, INT_MAX))) width = XINT (prop); - else if (FLOATP (prop)) + else if (FLOATP (prop) && 0 <= XFLOAT_DATA (prop) + && XFLOAT_DATA (prop) <= INT_MAX) width = (int)(XFLOAT_DATA (prop) + 0.5); - else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop))) + else if ((prop = Fplist_get (plist, QCalign_to), + RANGED_INTEGERP (col, prop, align_to_max))) width = XINT (prop) - col; - else if (FLOATP (prop)) + else if (FLOATP (prop) && col <= XFLOAT_DATA (prop) + && (XFLOAT_DATA (prop) <= align_to_max)) width = (int)(XFLOAT_DATA (prop) + 0.5) - col; if (width >= 0) { - EMACS_INT start; + ptrdiff_t start; if (OVERLAYP (overlay)) *endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); else @@ -504,24 +509,24 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) PREVCOL gets set to the column of the previous position (it's always strictly smaller than the goal column). */ static void -scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) +scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) { int tab_width = SANE_TAB_WIDTH (current_buffer); - 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)); + bool ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); + struct Lisp_Char_Table *dp = buffer_display_table (); + bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); struct composition_it cmp_it; Lisp_Object window; struct window *w; /* Start the scan at the beginning of this line with column number 0. */ - register EMACS_INT col = 0, prev_col = 0; + register ptrdiff_t col = 0, prev_col = 0; EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; - EMACS_INT end = endpos ? *endpos : PT; - EMACS_INT scan, scan_byte; - EMACS_INT next_boundary; + ptrdiff_t end = endpos ? *endpos : PT; + ptrdiff_t scan, scan_byte; + ptrdiff_t next_boundary; { - EMACS_INT opoint = PT, opoint_byte = PT_BYTE; + ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); current_column_bol_cache = PT; scan = PT, scan_byte = PT_BYTE; @@ -544,7 +549,7 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) /* Occasionally we may need to skip invisible text. */ while (scan == next_boundary) { - EMACS_INT old_scan = scan; + ptrdiff_t old_scan = scan; /* This updates NEXT_BOUNDARY to the next place where we might need to skip more invisible text. */ scan = skip_invisible (scan, &next_boundary, end, Qnil); @@ -562,7 +567,7 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) prev_col = col; { /* Check display property. */ - EMACS_INT endp; + ptrdiff_t endp; int width = check_display_width (scan, col, &endp); if (width >= 0) { @@ -608,7 +613,7 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) && VECTORP (DISP_CHAR_VECTOR (dp, c))) { Lisp_Object charvec; - EMACS_INT i, n; + ptrdiff_t i, n; /* This character is displayed using a vector of glyphs. Update the column/position based on those glyphs. */ @@ -622,8 +627,7 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) next_element_from_display_vector does it. */ Lisp_Object entry = AREF (charvec, i); - if (GLYPH_CODE_P (entry) - && GLYPH_CODE_CHAR_VALID_P (entry)) + if (GLYPH_CODE_P (entry)) c = GLYPH_CODE_CHAR (entry); else c = ' '; @@ -698,11 +702,11 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) This function handles characters that are invisible due to text properties or overlays. */ -static EMACS_INT +static ptrdiff_t current_column_1 (void) { EMACS_INT col = MOST_POSITIVE_FIXNUM; - EMACS_INT opoint = PT; + ptrdiff_t opoint = PT; scan_for_column (&opoint, &col, NULL); return col; @@ -718,14 +722,14 @@ current_column_1 (void) static double 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 col; + unsigned char *ptr, *stop; + bool tab_seen; int post_tab; - register int c; + int c; int tab_width = SANE_TAB_WIDTH (current_buffer); - int ctl_arrow = !NILP (current_buffer->ctl_arrow); - register struct Lisp_Char_Table *dp = buffer_display_table (); + bool ctl_arrow = !NILP (current_buffer->ctl_arrow); + struct Lisp_Char_Table *dp = buffer_display_table (); int b, e; if (NILP (end)) @@ -798,7 +802,7 @@ The return value is COLUMN. */) (Lisp_Object column, Lisp_Object minimum) { EMACS_INT mincol; - register EMACS_INT fromcol; + register ptrdiff_t fromcol; int tab_width = SANE_TAB_WIDTH (current_buffer); CHECK_NUMBER (column); @@ -845,7 +849,7 @@ following any initial whitespace. */) (void) { Lisp_Object val; - EMACS_INT opoint = PT, opoint_byte = PT_BYTE; + ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); @@ -854,16 +858,16 @@ following any initial whitespace. */) return val; } -static EMACS_INT +static ptrdiff_t position_indentation (ptrdiff_t pos_byte) { - register EMACS_INT column = 0; + register ptrdiff_t column = 0; int tab_width = SANE_TAB_WIDTH (current_buffer); register unsigned char *p; register unsigned char *stop; unsigned char *start; - EMACS_INT next_boundary_byte = pos_byte; - EMACS_INT ceiling = next_boundary_byte; + ptrdiff_t next_boundary_byte = pos_byte; + ptrdiff_t ceiling = next_boundary_byte; p = BYTE_POS_ADDR (pos_byte); /* STOP records the value of P at which we will need @@ -876,7 +880,7 @@ position_indentation (ptrdiff_t pos_byte) { while (p == stop) { - EMACS_INT stop_pos_byte; + ptrdiff_t stop_pos_byte; /* If we have updated P, set POS_BYTE to match. The first time we enter the loop, POS_BYTE is already right. */ @@ -887,8 +891,8 @@ position_indentation (ptrdiff_t pos_byte) return column; if (pos_byte == next_boundary_byte) { - EMACS_INT next_boundary; - EMACS_INT pos = BYTE_TO_CHAR (pos_byte); + ptrdiff_t next_boundary; + ptrdiff_t pos = BYTE_TO_CHAR (pos_byte); pos = skip_invisible (pos, &next_boundary, ZV, Qnil); pos_byte = CHAR_TO_BYTE (pos); next_boundary_byte = CHAR_TO_BYTE (next_boundary); @@ -941,11 +945,11 @@ position_indentation (ptrdiff_t pos_byte) Blank lines are treated as if they had the same indentation as the preceding line. */ -int -indented_beyond_p (EMACS_INT pos, EMACS_INT pos_byte, EMACS_INT column) +bool +indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) { - EMACS_INT val; - EMACS_INT opoint = PT, opoint_byte = PT_BYTE; + ptrdiff_t val; + ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; SET_PT_BOTH (pos, pos_byte); while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n') @@ -956,7 +960,8 @@ indented_beyond_p (EMACS_INT pos, EMACS_INT pos_byte, EMACS_INT column) return val >= column; } -DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p", +DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, + "NMove to column: ", doc: /* Move point to column COLUMN in the current line. Interactively, COLUMN is the value of prefix numeric argument. The column of a character is calculated by adding together the widths @@ -976,8 +981,8 @@ COLUMN, add spaces/tabs to get there. The return value is the current column. */) (Lisp_Object column, Lisp_Object force) { - EMACS_INT pos; - EMACS_INT col, prev_col; + ptrdiff_t pos, prev_col; + EMACS_INT col; EMACS_INT goal; CHECK_NATNUM (column); @@ -994,13 +999,13 @@ The return value is the current column. */) if (!NILP (force) && col > goal) { int c; - EMACS_INT pos_byte = PT_BYTE; + ptrdiff_t pos_byte = PT_BYTE; DEC_POS (pos_byte); c = FETCH_CHAR (pos_byte); if (c == '\t' && prev_col < goal) { - EMACS_INT goal_pt, goal_pt_byte; + ptrdiff_t goal_pt, goal_pt_byte; /* Insert spaces in front of the tab to reach GOAL. Do this first so that a marker at the end of the tab gets @@ -1042,11 +1047,11 @@ static struct position val_compute_motion; can't hit the requested column exactly (because of a tab or other multi-column character), overshoot. - DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings + DID_MOTION is true if FROMHPOS has already accounted for overlay strings at FROM. This is the case if FROMVPOS and FROMVPOS came from an earlier call to compute_motion. The other common case is that FROMHPOS is zero and FROM is a position that "belongs" at column zero, but might - be shifted by overlay strings; in this case DID_MOTION should be 0. + be shifted by overlay strings; in this case DID_MOTION should be false. WIDTH is the number of columns available to display text; compute_motion uses this to handle continuation lines and such. @@ -1099,57 +1104,58 @@ static struct position val_compute_motion; the scroll bars if they are turned on. */ struct position * -compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_motion, EMACS_INT to, EMACS_INT tovpos, EMACS_INT tohpos, EMACS_INT width, EMACS_INT hscroll, EMACS_INT tab_offset, struct window *win) +compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos, + bool did_motion, ptrdiff_t to, + EMACS_INT tovpos, EMACS_INT tohpos, EMACS_INT width, + ptrdiff_t hscroll, int tab_offset, struct window *win) { - register EMACS_INT hpos = fromhpos; - register EMACS_INT vpos = fromvpos; + EMACS_INT hpos = fromhpos; + EMACS_INT vpos = fromvpos; - register EMACS_INT pos; - EMACS_INT pos_byte; - register int c = 0; + ptrdiff_t pos; + ptrdiff_t pos_byte; + int c = 0; int tab_width = SANE_TAB_WIDTH (current_buffer); - register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); - register struct Lisp_Char_Table *dp = window_display_table (win); + bool ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); + struct Lisp_Char_Table *dp = window_display_table (win); EMACS_INT selective = (INTEGERP (BVAR (current_buffer, selective_display)) ? XINT (BVAR (current_buffer, selective_display)) : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0); - int selective_rlen + ptrdiff_t selective_rlen = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp)) ? 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; + ptrdiff_t next_boundary = from; /* For computing runs of characters with similar widths. Invariant: width_run_width is zero, or all the characters from width_run_start to width_run_end have a fixed width of width_run_width. */ - EMACS_INT width_run_start = from; - EMACS_INT width_run_end = from; - EMACS_INT width_run_width = 0; + ptrdiff_t width_run_start = from; + ptrdiff_t width_run_end = from; + ptrdiff_t width_run_width = 0; Lisp_Object *width_table; - Lisp_Object buffer; /* The next buffer pos where we should consult the width run cache. */ - EMACS_INT next_width_run = from; + ptrdiff_t next_width_run = from; Lisp_Object window; - int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); + bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); /* If previous char scanned was a wide character, this is the column where it ended. Otherwise, this is 0. */ EMACS_INT wide_column_end_hpos = 0; - EMACS_INT prev_pos; /* Previous buffer position. */ - EMACS_INT prev_pos_byte; /* Previous buffer position. */ + ptrdiff_t prev_pos; /* Previous buffer position. */ + ptrdiff_t prev_pos_byte; /* Previous buffer position. */ EMACS_INT prev_hpos = 0; EMACS_INT prev_vpos = 0; EMACS_INT contin_hpos; /* HPOS of last column of continued line. */ - EMACS_INT prev_tab_offset; /* Previous tab offset. */ - EMACS_INT continuation_glyph_width; + int prev_tab_offset; /* Previous tab offset. */ + int continuation_glyph_width; struct composition_it cmp_it; - XSETBUFFER (buffer, current_buffer); XSETWINDOW (window, win); width_run_cache_on_off (); @@ -1194,8 +1200,8 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ { while (pos == next_boundary) { - EMACS_INT pos_here = pos; - EMACS_INT newpos; + ptrdiff_t pos_here = pos; + ptrdiff_t newpos; /* Don't skip invisible if we are already at the margin. */ if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos)) @@ -1229,7 +1235,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ to be changed here. */ { unsigned char *ovstr; - EMACS_INT ovlen = overlay_strings (pos, win, &ovstr); + ptrdiff_t ovlen = overlay_strings (pos, win, &ovstr); hpos += ((multibyte && ovlen > 0) ? strwidth ((char *) ovstr, ovlen) : ovlen); } @@ -1304,8 +1310,8 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ if (hpos > width) { - int total_width = width + continuation_glyph_width; - int truncate = 0; + EMACS_INT total_width = width + continuation_glyph_width; + bool truncate = 0; if (!NILP (Vtruncate_partial_width_windows) && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win))))) @@ -1434,7 +1440,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ want to skip over it for some other reason. */ if (common_width != 0) { - EMACS_INT run_end_hpos; + ptrdiff_t run_end_hpos; /* Don't go past the final buffer posn the user requested. */ @@ -1474,7 +1480,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ /* We have to scan the text character-by-character. */ else { - EMACS_INT i, n; + ptrdiff_t i, n; Lisp_Object charvec; /* Check composition sequence. */ @@ -1551,8 +1557,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ next_element_from_display_vector does it. */ Lisp_Object entry = AREF (charvec, i); - if (GLYPH_CODE_P (entry) - && GLYPH_CODE_CHAR_VALID_P (entry)) + if (GLYPH_CODE_P (entry)) c = GLYPH_CODE_CHAR (entry); else c = ' '; @@ -1675,8 +1680,6 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ val_compute_motion.prevhpos = contin_hpos; else val_compute_motion.prevhpos = prev_hpos; - /* We always handle all of them here; none of them remain to do. */ - val_compute_motion.ovstring_chars_done = 0; /* Nonzero if have just continued a line */ val_compute_motion.contin = (contin_hpos && prev_hpos == 0); @@ -1733,7 +1736,8 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) struct window *w; Lisp_Object bufpos, hpos, vpos, prevhpos; struct position *pos; - EMACS_INT hscroll, tab_offset; + ptrdiff_t hscroll; + int tab_offset; CHECK_NUMBER_COERCE_MARKER (from); CHECK_CONS (frompos); @@ -1754,6 +1758,9 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) CHECK_CONS (offsets); CHECK_NUMBER_CAR (offsets); CHECK_NUMBER_CDR (offsets); + if (! (0 <= XINT (XCAR (offsets)) && XINT (XCAR (offsets)) <= PTRDIFF_MAX + && 0 <= XINT (XCDR (offsets)) && XINT (XCDR (offsets)) <= INT_MAX)) + args_out_of_range (XCAR (offsets), XCDR (offsets)); hscroll = XINT (XCAR (offsets)); tab_offset = XINT (XCDR (offsets)); } @@ -1807,23 +1814,23 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) static struct position val_vmotion; struct position * -vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) +vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w) { - EMACS_INT hscroll = XINT (w->hscroll); + ptrdiff_t hscroll = w->hscroll; struct position pos; /* vpos is cumulative vertical position, changed as from is changed */ - register int vpos = 0; - EMACS_INT prevline; - register EMACS_INT first; - EMACS_INT from_byte; - EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0; - EMACS_INT selective + register EMACS_INT vpos = 0; + ptrdiff_t prevline; + register ptrdiff_t first; + ptrdiff_t from_byte; + ptrdiff_t lmargin = hscroll > 0 ? 1 - hscroll : 0; + ptrdiff_t selective = (INTEGERP (BVAR (current_buffer, selective_display)) - ? XINT (BVAR (current_buffer, selective_display)) + ? clip_to_bounds (-1, XINT (BVAR (current_buffer, selective_display)), + PTRDIFF_MAX) : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0); Lisp_Object window; - EMACS_INT start_hpos = 0; - int did_motion; + bool did_motion; /* This is the object we use for fetching character properties. */ Lisp_Object text_prop_object; @@ -1861,7 +1868,7 @@ vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) TEXT_PROP_MEANS_INVISIBLE (propval)))) prevline = find_next_newline_no_quit (prevline - 1, -1); pos = *compute_motion (prevline, 0, - lmargin + (prevline == BEG ? start_hpos : 0), + lmargin, 0, from, /* Don't care for VPOS... */ @@ -1869,10 +1876,7 @@ vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) /* ... nor HPOS. */ 1 << (BITS_PER_SHORT - 1), -1, hscroll, - /* This compensates for start_hpos - so that a tab as first character - still occupies 8 columns. */ - (prevline == BEG ? -start_hpos : 0), + 0, w); vpos -= pos.vpos; first = 0; @@ -1890,8 +1894,6 @@ vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) val_vmotion.hpos = lmargin; val_vmotion.contin = 0; val_vmotion.prevhpos = 0; - val_vmotion.ovstring_chars_done = 0; - val_vmotion.tab_offset = 0; /* For accumulating tab offset. */ return &val_vmotion; } @@ -1918,8 +1920,7 @@ vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) TEXT_PROP_MEANS_INVISIBLE (propval)))) prevline = find_next_newline_no_quit (prevline - 1, -1); pos = *compute_motion (prevline, 0, - lmargin + (prevline == BEG - ? start_hpos : 0), + lmargin, 0, from, /* Don't care for VPOS... */ @@ -1927,21 +1928,20 @@ vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w) /* ... nor HPOS. */ 1 << (BITS_PER_SHORT - 1), -1, hscroll, - (prevline == BEG ? -start_hpos : 0), + 0, w); did_motion = 1; } else { - pos.hpos = lmargin + (from == BEG ? start_hpos : 0); + pos.hpos = lmargin; pos.vpos = 0; - pos.tab_offset = 0; did_motion = 0; } return compute_motion (from, vpos, pos.hpos, did_motion, ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)), -1, hscroll, - pos.tab_offset - (from == BEG ? start_hpos : 0), + 0, w); } @@ -2005,9 +2005,9 @@ whether or not it is currently displayed in some window. */) 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)); + wset_buffer (w, Fcurrent_buffer ()); + set_marker_both (w->pointm, w->buffer, + BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); } if (noninteractive) @@ -2018,9 +2018,10 @@ whether or not it is currently displayed in some window. */) } else { - EMACS_INT it_start; - int first_x, it_overshoot_count = 0; - int overshoot_handled = 0; + ptrdiff_t it_start, it_overshoot_count = 0; + int first_x; + bool overshoot_handled = 0; + bool disp_string_at_start_p = 0; itdata = bidi_shelve_cache (); SET_TEXT_POS (pt, PT, PT_BYTE); @@ -2035,6 +2036,8 @@ whether or not it is currently displayed in some window. */) { const char *s = SSDATA (it.string); const char *e = s + SBYTES (it.string); + + disp_string_at_start_p = it.string_from_display_prop_p; while (s < e) { if (*s++ == '\n') @@ -2062,7 +2065,8 @@ whether or not it is currently displayed in some window. */) /* IT may move too far if truncate-lines is on and PT lies beyond the right margin. IT may also move too far if the starting point is on a Lisp string that has embedded - newlines. In these cases, backtrack. */ + newlines, or spans several screen lines. In these cases, + backtrack. */ if (IT_CHARPOS (it) > it_start) { /* We need to backtrack also if the Lisp string contains no @@ -2073,6 +2077,14 @@ whether or not it is currently displayed in some window. */) && it.method == GET_FROM_BUFFER && it.c == '\n') it_overshoot_count = 1; + else if (disp_string_at_start_p && it.vpos > 0) + { + /* This is the case of a display string that spans + several screen lines. In that case, we end up at the + end of the string, and it.vpos tells us how many + screen lines we need to backtrack. */ + it_overshoot_count = it.vpos; + } if (it_overshoot_count > 0) move_it_by_lines (&it, -it_overshoot_count); @@ -2084,12 +2096,12 @@ whether or not it is currently displayed in some window. */) /* 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, max (INT_MIN, XINT (lines))); + move_it_by_lines (&it, max (PTRDIFF_MIN, XINT (lines))); } else if (overshoot_handled) { it.vpos = 0; - move_it_by_lines (&it, min (INT_MAX, XINT (lines))); + move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines))); } else { @@ -2105,12 +2117,12 @@ whether or not it is currently displayed in some window. */) move_it_by_lines (&it, 1); } if (XINT (lines) > 1) - move_it_by_lines (&it, min (INT_MAX, XINT (lines) - 1)); + move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines) - 1)); } else { it.vpos = 0; - move_it_by_lines (&it, min (INT_MAX, XINT (lines))); + move_it_by_lines (&it, min (PTRDIFF_MAX, XINT (lines))); } } @@ -2136,8 +2148,9 @@ whether or not it is currently displayed in some window. */) if (BUFFERP (old_buffer)) { - w->buffer = old_buffer; - set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos); + wset_buffer (w, old_buffer); + set_marker_both (w->pointm, w->buffer, + old_charpos, old_bytepos); } RETURN_UNGCPRO (make_number (it.vpos)); @@ -2151,7 +2164,7 @@ void syms_of_indent (void) { DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode, - doc: /* *Indentation can insert tabs if this is non-nil. */); + doc: /* Indentation can insert tabs if this is non-nil. */); indent_tabs_mode = 1; defsubr (&Scurrent_indentation);