X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/0d6459dfb52188481bfd6bb53f1b2f653ecd6a5d..d8c2fa787973fc6d0d8c3693b97ddbba622ca41f:/src/indent.c diff --git a/src/indent.c b/src/indent.c index 37ce647556..aaeaaf591e 100644 --- a/src/indent.c +++ b/src/indent.c @@ -93,7 +93,7 @@ character_width (int c, struct Lisp_Char_Table *dp) /* 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') @@ -121,7 +121,7 @@ disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *w { int i; - if (widthtab->size != 256) + if (widthtab->header.size != 256) abort (); for (i = 0; i < 256; i++) @@ -143,7 +143,7 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) 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++) @@ -271,25 +271,22 @@ skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Ob 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) @@ -321,6 +318,15 @@ invalidate_current_column (void) 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) { @@ -329,7 +335,7 @@ 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 (); @@ -359,9 +365,6 @@ current_column (void) 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) @@ -512,7 +515,7 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) 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)); @@ -538,7 +541,6 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) 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); @@ -569,14 +571,14 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) 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; } } @@ -666,10 +668,10 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) { /* 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; @@ -723,15 +725,14 @@ current_column_1 (void) 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; @@ -758,8 +759,6 @@ string_display_width (string, beg, end) 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) @@ -769,7 +768,7 @@ string_display_width (string, beg, end) 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') @@ -809,7 +808,7 @@ The return value is COLUMN. */) { 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)) @@ -823,8 +822,6 @@ The return value is COLUMN. */) if (fromcol == mincol) return make_number (mincol); - if (tab_width <= 0 || tab_width > 1000) tab_width = 8; - if (indent_tabs_mode) { Lisp_Object n; @@ -870,15 +867,13 @@ static EMACS_INT 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, @@ -1047,7 +1042,7 @@ The return value is the current column. */) /* 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 @@ -1105,8 +1100,8 @@ struct position val_compute_motion; 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 @@ -1121,7 +1116,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ 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 @@ -1130,7 +1125,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ : !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; @@ -1176,13 +1171,10 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ 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))) @@ -1657,15 +1649,15 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ { /* 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; @@ -1750,7 +1742,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) 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); @@ -1795,7 +1787,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) ? 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 : @@ -1821,7 +1813,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) /* 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) @@ -1993,9 +1985,11 @@ whether or not it is currently displayed in some window. */) struct text_pos pt; struct window *w; Lisp_Object old_buffer; - struct gcpro gcpro1; + EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); + struct gcpro gcpro1, gcpro2, gcpro3; Lisp_Object lcols = Qnil; - double cols; + double cols IF_LINT (= 0); + void *itdata = NULL; /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ if (CONSP (lines) && (NUMBERP (XCAR (lines)))) @@ -2013,12 +2007,16 @@ whether or not it is currently displayed in some window. */) 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) @@ -2029,8 +2027,10 @@ whether or not it is currently displayed in some window. */) } else { - int it_start, first_x, it_overshoot_expected; + EMACS_INT it_start; + int first_x, it_overshoot_expected IF_LINT (= 0); + itdata = bidi_shelve_cache (); SET_TEXT_POS (pt, PT, PT_BYTE); start_display (&it, w, pt); first_x = it.first_visible_x; @@ -2072,7 +2072,7 @@ 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, XINT (lines), 0); + move_it_by_lines (&it, XINT (lines)); } else { @@ -2090,9 +2090,9 @@ whether or not it is currently displayed in some window. */) || (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 { @@ -2105,15 +2105,15 @@ whether or not it is currently displayed in some window. */) 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)); } } } @@ -2135,10 +2135,14 @@ whether or not it is currently displayed in some window. */) } SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); + bidi_unshelve_cache (itdata); } 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)); }