/* 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.
for (i = 0; i < 256; i++)
if (character_width (i, disptab)
- != XFASTINT (widthtab->u.contents[i]))
+ != XFASTINT (widthtab->contents[i]))
return 0;
return 1;
eassert (widthtab->header.size == 256);
for (i = 0; i < 256; i++)
- XSETFASTINT (widthtab->u.contents[i], character_width (i, 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_scans variable. */
-static void
+static struct region_cache *
width_run_cache_on_off (void)
{
+ 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;
}
}
*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. */
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;
{
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))->u.contents
+ ? XVECTOR (BVAR (current_buffer, width_table))->contents
: 0);
else
/* If the window has its own display table, we can't use the width
/* 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)))
/* 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
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. */
(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. */
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;
? 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 :
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.
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
}
}
- /* 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));
old_charpos, old_bytepos);
}
- RETURN_UNGCPRO (make_number (it.vpos));
+ return make_number (it.vpos);
}
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);
}