X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/2d809ffafd3e1bde360c08f3be4b7d9a43ff5f0e..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/indent.c diff --git a/src/indent.c b/src/indent.c index 47358e17db..5b95bcf8b6 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1,5 +1,5 @@ /* Indentation functions. - Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2013 Free Software + Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -141,33 +141,54 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); } -/* Allocate or free the width run cache, as requested by the current - state of current_buffer's cache_long_line_scans variable. */ +/* Allocate or free the width run cache, as requested by the + current state of current_buffer's cache_long_scans variable. */ -static void +static struct region_cache * width_run_cache_on_off (void) { - if (NILP (BVAR (current_buffer, cache_long_line_scans)) + struct buffer *cache_buffer = current_buffer; + bool indirect_p = false; + + if (cache_buffer->base_buffer) + { + cache_buffer = cache_buffer->base_buffer; + indirect_p = true; + } + + if (NILP (BVAR (current_buffer, cache_long_scans)) /* And, for the moment, this feature doesn't work on multibyte characters. */ || !NILP (BVAR (current_buffer, enable_multibyte_characters))) { - /* It should be off. */ - if (current_buffer->width_run_cache) - { - free_region_cache (current_buffer->width_run_cache); - current_buffer->width_run_cache = 0; - bset_width_table (current_buffer, Qnil); + if (!indirect_p + || NILP (BVAR (cache_buffer, cache_long_scans)) + || !NILP (BVAR (cache_buffer, enable_multibyte_characters))) + { + /* It should be off. */ + if (cache_buffer->width_run_cache) + { + free_region_cache (cache_buffer->width_run_cache); + cache_buffer->width_run_cache = 0; + bset_width_table (current_buffer, Qnil); + } } + return NULL; } else { - /* It should be on. */ - if (current_buffer->width_run_cache == 0) - { - current_buffer->width_run_cache = new_region_cache (); - recompute_width_table (current_buffer, buffer_display_table ()); - } + if (!indirect_p + || (!NILP (BVAR (cache_buffer, cache_long_scans)) + && NILP (BVAR (cache_buffer, enable_multibyte_characters)))) + { + /* It should be on. */ + if (cache_buffer->width_run_cache == 0) + { + cache_buffer->width_run_cache = new_region_cache (); + recompute_width_table (current_buffer, buffer_display_table ()); + } + } + return cache_buffer->width_run_cache; } } @@ -510,15 +531,10 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) register ptrdiff_t col = 0, prev_col = 0; EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM; ptrdiff_t end = endpos ? *endpos : PT; - ptrdiff_t scan, scan_byte; - ptrdiff_t next_boundary; - { - ptrdiff_t 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); + ptrdiff_t scan, scan_byte, next_boundary; + + scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); next_boundary = scan; - } window = Fget_buffer_window (Fcurrent_buffer (), Qnil); w = ! NILP (window) ? XWINDOW (window) : NULL; @@ -684,7 +700,7 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol) *prevcol = prev_col; } -/* Return the column number of position POS +/* Return the column number of point by scanning forward from the beginning of the line. This function handles characters that are invisible due to text properties or overlays. */ @@ -835,14 +851,10 @@ This is the horizontal position of the character following any initial whitespace. */) (void) { - Lisp_Object val; - ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - - scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); + ptrdiff_t posbyte; - XSETFASTINT (val, position_indentation (PT_BYTE)); - SET_PT_BOTH (opoint, opoint_byte); - return val; + find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &posbyte, 1); + return make_number (position_indentation (posbyte)); } static ptrdiff_t @@ -908,7 +920,7 @@ position_indentation (ptrdiff_t pos_byte) column += tab_width - column % tab_width; break; default: - if (ASCII_BYTE_P (p[-1]) + if (ASCII_CHAR_P (p[-1]) || NILP (BVAR (current_buffer, enable_multibyte_characters))) return column; { @@ -935,16 +947,13 @@ position_indentation (ptrdiff_t pos_byte) bool indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column) { - 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') - scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0); - - val = position_indentation (PT_BYTE); - SET_PT_BOTH (opoint, opoint_byte); - return val >= column; + while (pos > BEGV && FETCH_BYTE (pos_byte) == '\n') + { + DEC_BOTH (pos, pos_byte); + pos = find_newline (pos, pos_byte, BEGV, BEGV_BYTE, + -1, NULL, &pos_byte, 0); + } + return position_indentation (pos_byte) >= column; } DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, @@ -1140,12 +1149,16 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, EMACS_INT contin_hpos; /* HPOS of last column of continued line. */ int prev_tab_offset; /* Previous tab offset. */ int continuation_glyph_width; + struct buffer *cache_buffer = current_buffer; + struct region_cache *width_cache; struct composition_it cmp_it; XSETWINDOW (window, win); - width_run_cache_on_off (); + if (cache_buffer->base_buffer) + cache_buffer = cache_buffer->base_buffer; + width_cache = width_run_cache_on_off (); if (dp == buffer_display_table ()) width_table = (VECTORP (BVAR (current_buffer, width_table)) ? XVECTOR (BVAR (current_buffer, width_table))->contents @@ -1158,7 +1171,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, /* Negative width means use all available text columns. */ if (width < 0) { - width = window_body_cols (win); + width = window_body_width (win, 0); /* We must make room for continuation marks if we don't have fringes. */ #ifdef HAVE_WINDOW_SYSTEM if (!FRAME_WINDOW_P (XFRAME (win->frame))) @@ -1416,13 +1429,11 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, /* Consult the width run cache to see if we can avoid inspecting the text character-by-character. */ - if (current_buffer->width_run_cache && pos >= next_width_run) + if (width_cache && pos >= next_width_run) { ptrdiff_t run_end; int common_width - = region_cache_forward (current_buffer, - current_buffer->width_run_cache, - pos, &run_end); + = region_cache_forward (cache_buffer, width_cache, pos, &run_end); /* A width of zero means the character's width varies (like a tab), is meaningless (like a newline), or we just don't @@ -1498,7 +1509,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, pos++, pos_byte++; /* Perhaps add some info to the width_run_cache. */ - if (current_buffer->width_run_cache) + if (width_cache) { /* Is this character part of the current run? If so, extend the run. */ @@ -1514,8 +1525,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, (Currently, we only cache runs of width == 1). */ if (width_run_start < width_run_end && width_run_width == 1) - know_region_cache (current_buffer, - current_buffer->width_run_cache, + know_region_cache (cache_buffer, width_cache, width_run_start, width_run_end); /* Start recording a new width run. */ @@ -1651,10 +1661,10 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, after_loop: /* Remember any final width run in the cache. */ - if (current_buffer->width_run_cache + if (width_cache && width_run_width == 1 && width_run_start < width_run_end) - know_region_cache (current_buffer, current_buffer->width_run_cache, + know_region_cache (cache_buffer, width_cache, width_run_start, width_run_end); val_compute_motion.bufpos = pos; @@ -1768,7 +1778,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS. */) ? window_internal_height (w) : XINT (XCDR (topos))), (NILP (topos) - ? (window_body_cols (w) + ? (window_body_width (w, 0) - ( #ifdef HAVE_WINDOW_SYSTEM FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 : @@ -1934,9 +1944,12 @@ 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. -LINES can optionally take the form (COLS . LINES), in which case -the motion will not stop at the start of a screen line but on -its column COLS (if such exists on that line, that is). +LINES can optionally take the form (COLS . LINES), in which case the +motion will not stop at the start of a screen line but COLS column +from the visual start of the line (if such exists on that line, that +is). If the line is scrolled horizontally, COLS is interpreted +visually, i.e., as addition to the columns of text beyond the left +edge of the window. `vertical-motion' always uses the current buffer, regardless of which buffer is displayed in WINDOW. @@ -2041,8 +2054,15 @@ whether or not it is currently displayed in some window. */) string, move_it_to will overshoot it, while vertical-motion wants to put the cursor _before_ the display string. So in that case, we move to buffer position before the display - string, and avoid overshooting. */ - move_it_to (&it, disp_string_at_start_p ? PT - 1 : PT, + string, and avoid overshooting. But if the position before + the display string is a newline, we don't do this, because + otherwise we will end up in a screen line that is one too + far back. */ + move_it_to (&it, + (!disp_string_at_start_p + || FETCH_BYTE (IT_BYTEPOS (it)) == '\n') + ? PT + : PT - 1, -1, -1, -1, MOVE_TO_POS); /* IT may move too far if truncate-lines is on and PT lies @@ -2109,20 +2129,14 @@ whether or not it is currently displayed in some window. */) } } - /* Move to the goal column, if one was specified. */ + /* Move to the goal column, if one was specified. If the window + was originally hscrolled, the goal column is interpreted as + an addition to the hscroll amount. */ if (!NILP (lcols)) { - /* If the window was originally hscrolled, move forward by - the hscrolled amount first. */ - if (first_x > 0) - { - move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X); - it.current_x = 0; - } - move_it_in_display_line - (&it, ZV, - (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5), - MOVE_TO_X); + int to_x = (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5); + + move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X); } SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); @@ -2136,7 +2150,7 @@ whether or not it is currently displayed in some window. */) old_charpos, old_bytepos); } - RETURN_UNGCPRO (make_number (it.vpos)); + return make_number (it.vpos); } @@ -2146,14 +2160,9 @@ whether or not it is currently displayed in some window. */) void syms_of_indent (void) { +#include "indent.x" + DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode, doc: /* Indentation can insert tabs if this is non-nil. */); indent_tabs_mode = 1; - - defsubr (&Scurrent_indentation); - defsubr (&Sindent_to); - defsubr (&Scurrent_column); - defsubr (&Smove_to_column); - defsubr (&Svertical_motion); - defsubr (&Scompute_motion); }