X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/48cdfb4b1778db5f05ae7894f6cd22ac09b04b18..986fb647cc1df1edeeaa2c0e7cb34c100eb9efb9:/src/indent.c diff --git a/src/indent.c b/src/indent.c index d08d4b3c7c..a7f41f7e8e 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1,6 +1,6 @@ /* Indentation functions. Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -20,11 +20,13 @@ along with GNU Emacs. If not, see . */ #include #include +#include #include "lisp.h" #include "buffer.h" #include "character.h" #include "category.h" +#include "composite.h" #include "indent.h" #include "keyboard.h" #include "frame.h" @@ -33,6 +35,7 @@ along with GNU Emacs. If not, see . */ #include "termopts.h" #include "disptab.h" #include "intervals.h" +#include "dispextern.h" #include "region-cache.h" /* Indentation can insert tabs if this is non-zero; @@ -250,7 +253,7 @@ skip_invisible (pos, next_boundary_p, to, window) { /* Don't scan terribly far. */ XSETFASTINT (proplimit, min (pos + 100, to)); - /* No matter what. don't go past next overlay change. */ + /* No matter what, don't go past next overlay change. */ if (XFASTINT (overlay_limit) < XFASTINT (proplimit)) proplimit = overlay_limit; tmp = Fnext_single_property_change (position, Qinvisible, @@ -280,32 +283,6 @@ skip_invisible (pos, next_boundary_p, to, window) return pos; } -/* If a composition starts at POS/POS_BYTE and it doesn't stride over - POINT, set *LEN / *LEN_BYTE to the character and byte lengths, *WIDTH - to the width, and return 1. Otherwise, return 0. */ - -static int -check_composition (pos, pos_byte, point, len, len_byte, width) - int pos, pos_byte, point; - int *len, *len_byte, *width; -{ - Lisp_Object prop; - EMACS_INT start, end; - int id; - - if (! find_composition (pos, -1, &start, &end, &prop, Qnil) - || pos != start || point < end - || !COMPOSITION_VALID_P (start, end, prop)) - return 0; - if ((id = get_composition_id (pos, pos_byte, end - pos, prop, Qnil)) < 0) - return 0; - - *len = COMPOSITION_LENGTH (prop); - *len_byte = CHAR_TO_BYTE (end) - pos_byte; - *width = composition_table[id]->width; - return 1; -} - /* Set variables WIDTH and BYTES for a multibyte sequence starting at P. DP is a display table or NULL. @@ -318,7 +295,7 @@ check_composition (pos, pos_byte, point, len, len_byte, width) int c; \ \ wide_column = 0; \ - c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, bytes); \ + c = STRING_CHAR_AND_LENGTH (p, bytes); \ if (BYTES_BY_CHAR_HEAD (*p) != bytes) \ width = bytes * 4; \ else \ @@ -556,6 +533,9 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) register int ctl_arrow = !NILP (current_buffer->ctl_arrow); register struct Lisp_Char_Table *dp = buffer_display_table (); int multibyte = !NILP (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; @@ -572,7 +552,13 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) next_boundary = scan; } + window = Fget_buffer_window (Fcurrent_buffer (), Qnil); + w = ! NILP (window) ? XWINDOW (window) : NULL; + if (tab_width <= 0 || tab_width > 1000) tab_width = 8; + bzero (&cmp_it, sizeof cmp_it); + cmp_it.id = -1; + composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); /* Scan forward to the target position. */ while (scan < end) @@ -599,20 +585,6 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) break; prev_col = col; - { /* Check composition sequence. */ - int len, len_byte, width; - - if (check_composition (scan, scan_byte, end, - &len, &len_byte, &width)) - { - scan += len; - scan_byte += len_byte; - if (scan <= end) - col += width; - continue; - } - } - { /* Check display property. */ EMACS_INT end; int width = check_display_width (scan, col, &end); @@ -627,6 +599,29 @@ scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) } } + /* Check composition sequence. */ + if (cmp_it.id >= 0 + || (scan == cmp_it.stop_pos + && composition_reseat_it (&cmp_it, scan, scan_byte, end, + w, NULL, Qnil))) + composition_update_it (&cmp_it, scan, scan_byte, Qnil); + if (cmp_it.id >= 0) + { + scan += cmp_it.nchars; + scan_byte += cmp_it.nbytes; + if (scan <= end) + col += cmp_it.width; + if (cmp_it.to == cmp_it.nglyphs) + { + cmp_it.id = -1; + composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, + Qnil); + } + else + cmp_it.from = cmp_it.to; + continue; + } + c = FETCH_BYTE (scan_byte); /* See if there is a display table and it relates @@ -1195,6 +1190,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, EMACS_INT prev_tab_offset; /* Previous tab offset. */ EMACS_INT continuation_glyph_width; + struct composition_it cmp_it; + XSETBUFFER (buffer, current_buffer); XSETWINDOW (window, win); @@ -1235,6 +1232,10 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, pos_byte = prev_pos_byte = CHAR_TO_BYTE (from); contin_hpos = 0; prev_tab_offset = tab_offset; + bzero (&cmp_it, sizeof cmp_it); + cmp_it.id = -1; + composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil); + while (1) { while (pos == next_boundary) @@ -1522,21 +1523,29 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, EMACS_INT i, n; Lisp_Object charvec; - c = FETCH_BYTE (pos_byte); - /* Check composition sequence. */ - { - int len, len_byte, width; - - if (check_composition (pos, pos_byte, to, &len, &len_byte, &width)) - { - pos += len; - pos_byte += len_byte; - hpos += width; - continue; - } - } + if (cmp_it.id >= 0 + || (pos == cmp_it.stop_pos + && composition_reseat_it (&cmp_it, pos, pos_byte, to, win, + NULL, Qnil))) + composition_update_it (&cmp_it, pos, pos_byte, Qnil); + if (cmp_it.id >= 0) + { + pos += cmp_it.nchars; + pos_byte += cmp_it.nbytes; + hpos += cmp_it.width; + if (cmp_it.to == cmp_it.nglyphs) + { + cmp_it.id = -1; + composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, + Qnil); + } + else + cmp_it.from = cmp_it.to; + continue; + } + c = FETCH_BYTE (pos_byte); pos++, pos_byte++; /* Perhaps add some info to the width_run_cache. */ @@ -2055,7 +2064,7 @@ whether or not it is currently displayed in some window. */) } else { - int it_start, oselective, first_x, it_overshoot_expected; + int it_start, first_x, it_overshoot_expected; SET_TEXT_POS (pt, PT, PT_BYTE); start_display (&it, w, pt); @@ -2065,7 +2074,9 @@ whether or not it is currently displayed in some window. */) /* See comments below for why we calculate this. */ if (XINT (lines) > 0) { - if (it.method == GET_FROM_STRING) + if (it.cmp_it.id >= 0) + it_overshoot_expected = 1; + else if (it.method == GET_FROM_STRING) { const char *s = SDATA (it.string); const char *e = s + SBYTES (it.string); @@ -2075,8 +2086,7 @@ whether or not it is currently displayed in some window. */) } else it_overshoot_expected = (it.method == GET_FROM_IMAGE - || it.method == GET_FROM_STRETCH - || it.method == GET_FROM_COMPOSITION); + || it.method == GET_FROM_STRETCH); } /* Scan from the start of the line containing PT. If we don't @@ -2084,11 +2094,12 @@ whether or not it is currently displayed in some window. */) really at some x > 0. */ reseat_at_previous_visible_line_start (&it); it.current_x = it.hpos = 0; - /* Temporarily disable selective display so we don't move too far */ - oselective = it.selective; - it.selective = 0; - move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); - it.selective = oselective; + if (IT_CHARPOS (it) != PT) + /* We used to temporarily disable selective display here; the + comment said this is "so we don't move too far" (2005-01-19 + checkin by kfs). But this does nothing useful that I can + tell, and it causes Bug#2694 . -- cyd */ + move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); if (XINT (lines) <= 0) { @@ -2100,7 +2111,7 @@ whether or not it is currently displayed in some window. */) } else { - if (IT_CHARPOS (it) > PT) + if (IT_CHARPOS (it) > it_start) { /* IT may move too far if truncate-lines is on and PT lies beyond the right margin. In that case, @@ -2124,15 +2135,21 @@ whether or not it is currently displayed in some window. */) which might span multiple screen lines (e.g., if it's on a multi-line display string). We want to start from the last line that it occupies. */ - it.vpos = 0; - if (PT < ZV) + if (it_start < ZV) { - while (IT_CHARPOS (it) <= PT) - move_it_by_lines (&it, 1, 0); - move_it_by_lines (&it, XINT (lines) - 1, 0); + while (IT_CHARPOS (it) <= it_start) + { + it.vpos = 0; + move_it_by_lines (&it, 1, 0); + } + if (XINT (lines) > 1) + move_it_by_lines (&it, XINT (lines) - 1, 0); } else - move_it_by_lines (&it, XINT (lines), 0); + { + it.vpos = 0; + move_it_by_lines (&it, XINT (lines), 0); + } } }