/* Indentation functions.
- Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2012
- Free Software Foundation, Inc.
+ Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2013 Free Software
+ Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
-#include <setjmp.h>
#include "lisp.h"
#include "character.h"
#include "frame.h"
#include "window.h"
#include "termchar.h"
-#include "termopts.h"
#include "disptab.h"
#include "intervals.h"
#include "dispextern.h"
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 ();
+ eassert (widthtab->header.size == 256);
for (i = 0; i < 256; i++)
if (character_width (i, 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, make_uninit_vector (256));
widthtab = XVECTOR (BVAR (buf, width_table));
- if (widthtab->header.size != 256)
- abort ();
+ eassert (widthtab->header.size == 256);
for (i = 0; i < 256; i++)
XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
{
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
the next property change */
prop = Fget_char_property (position, Qinvisible,
(!NILP (window)
- && EQ (WGET (XWINDOW (window), buffer), buffer))
+ && EQ (XWINDOW (window)->buffer, buffer))
? window : buffer);
inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
/* When counting columns (window == nil), don't skip over ellipsis text. */
doc: /* Return the horizontal position of point. Beginning of line is column 0.
This is calculated by adding together the widths of all the displayed
representations of the character between the start of the previous line
-and point (eg. control characters will have a width of 2 or 4, tabs
+and point (e.g., control characters will have a width of 2 or 4, tabs
will have a variable width).
Ignores finite width of frame, which means that this function may return
values greater than (frame-width).
ptrdiff_t
current_column (void)
{
- register ptrdiff_t col;
- register unsigned char *ptr, *stop;
- register int tab_seen;
+ ptrdiff_t col;
+ unsigned char *ptr, *stop;
+ bool tab_seen;
ptrdiff_t post_tab;
- register int c;
+ 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)
/* 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 ();
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;
col += width;
if (endp > scan) /* Avoid infinite loops with 0-width overlays. */
{
- scan = endp; scan_byte = charpos_to_bytepos (scan);
+ scan = endp;
+ scan_byte = CHAR_TO_BYTE (scan);
continue;
}
}
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))
Blank lines are treated as if they had the same indentation as the
preceding line. */
-int
+bool
indented_beyond_p (ptrdiff_t pos, ptrdiff_t pos_byte, EMACS_INT column)
{
ptrdiff_t val;
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.
the scroll bars if they are turned on. */
struct position *
-compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_motion, ptrdiff_t to, EMACS_INT tovpos, EMACS_INT tohpos, EMACS_INT width, ptrdiff_t hscroll, 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 ptrdiff_t pos;
+ ptrdiff_t pos;
ptrdiff_t pos_byte;
- register int c = 0;
+ 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))
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;
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 (WGET (win, frame))))
+ if (!FRAME_WINDOW_P (XFRAME (win->frame)))
#endif
width -= 1;
}
continuation_glyph_width = 1;
#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (XFRAME (WGET (win, frame))))
+ if (FRAME_WINDOW_P (XFRAME (win->frame)))
continuation_glyph_width = 0; /* In the fringe. */
#endif
if (hpos > width)
{
EMACS_INT total_width = width + continuation_glyph_width;
- int truncate = 0;
+ bool truncate = 0;
if (!NILP (Vtruncate_partial_width_windows)
&& (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
TO (we need to go back below). */
if (pos <= to)
{
- pos = find_before_next_newline (pos, to, 1);
- pos_byte = CHAR_TO_BYTE (pos);
+ pos = find_before_next_newline (pos, to, 1, &pos_byte);
hpos = width;
/* If we just skipped next_boundary,
loop around in the main while
/* Skip any number of invisible lines all at once */
do
{
- pos = find_before_next_newline (pos, to, 1);
+ pos = find_before_next_newline (pos, to, 1, &pos_byte);
if (pos < to)
- pos++;
- pos_byte = CHAR_TO_BYTE (pos);
+ INC_BOTH (pos, pos_byte);
}
while (pos < to
&& indented_beyond_p (pos, pos_byte,
everything from a ^M to the end of the line is invisible.
Stop *before* the real newline. */
if (pos < to)
- {
- pos = find_before_next_newline (pos, to, 1);
- pos_byte = CHAR_TO_BYTE (pos);
- }
+ pos = find_before_next_newline (pos, to, 1, &pos_byte);
/* If we just skipped next_boundary,
loop around in the main while
and handle it. */
else
hscroll = tab_offset = 0;
- if (NILP (window))
- window = Fselected_window ();
- else
- CHECK_LIVE_WINDOW (window);
- w = XWINDOW (window);
+ w = decode_live_window (window);
if (XINT (from) < BEGV || XINT (from) > ZV)
args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
? (window_body_cols (w)
- (
#ifdef HAVE_WINDOW_SYSTEM
- FRAME_WINDOW_P (XFRAME (WGET (w, frame))) ? 0 :
+ FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
#endif
1))
: XINT (XCAR (topos))),
(NILP (width) ? -1 : XINT (width)),
- hscroll, tab_offset,
- XWINDOW (window));
+ hscroll, tab_offset, w);
XSETFASTINT (bufpos, pos->bufpos);
XSETINT (hpos, pos->hpos);
PTRDIFF_MAX)
: !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
Lisp_Object window;
- int did_motion;
+ bool did_motion;
/* This is the object we use for fetching character properties. */
Lisp_Object text_prop_object;
/* If the window contains this buffer, use it for getting text properties.
Otherwise use the current buffer as arg for doing that. */
- if (EQ (WGET (w, buffer), Fcurrent_buffer ()))
+ if (EQ (w->buffer, Fcurrent_buffer ()))
text_prop_object = window;
else
text_prop_object = Fcurrent_buffer ();
while ((vpos > vtarget || first) && from > BEGV)
{
+ ptrdiff_t bytepos;
Lisp_Object propval;
- prevline = find_next_newline_no_quit (from - 1, -1);
+ prevline = find_next_newline_no_quit (from - 1, -1, &bytepos);
while (prevline > BEGV
&& ((selective > 0
- && indented_beyond_p (prevline,
- CHAR_TO_BYTE (prevline),
- selective))
+ && indented_beyond_p (prevline, bytepos, selective))
/* Watch out for newlines with `invisible' property.
When moving upward, check the newline before. */
|| (propval = Fget_char_property (make_number (prevline - 1),
Qinvisible,
text_prop_object),
TEXT_PROP_MEANS_INVISIBLE (propval))))
- prevline = find_next_newline_no_quit (prevline - 1, -1);
+ prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos);
pos = *compute_motion (prevline, 0,
lmargin,
0,
from_byte = CHAR_TO_BYTE (from);
if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
{
+ ptrdiff_t bytepos;
Lisp_Object propval;
- prevline = find_next_newline_no_quit (from, -1);
+ prevline = find_next_newline_no_quit (from, -1, &bytepos);
while (prevline > BEGV
&& ((selective > 0
- && indented_beyond_p (prevline,
- CHAR_TO_BYTE (prevline),
- selective))
+ && indented_beyond_p (prevline, bytepos, selective))
/* Watch out for newlines with `invisible' property.
When moving downward, check the newline after. */
|| (propval = Fget_char_property (make_number (prevline),
Qinvisible,
text_prop_object),
TEXT_PROP_MEANS_INVISIBLE (propval))))
- prevline = find_next_newline_no_quit (prevline - 1, -1);
+ prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos);
pos = *compute_motion (prevline, 0,
lmargin,
0,
struct window *w;
Lisp_Object old_buffer;
EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0);
- struct gcpro gcpro1, gcpro2, gcpro3;
+ struct gcpro gcpro1;
Lisp_Object lcols = Qnil;
double cols IF_LINT (= 0);
void *itdata = NULL;
}
CHECK_NUMBER (lines);
- if (! NILP (window))
- CHECK_WINDOW (window);
- else
- window = selected_window;
- w = XWINDOW (window);
+ w = decode_live_window (window);
old_buffer = Qnil;
- GCPRO3 (old_buffer, old_charpos, old_bytepos);
- if (XBUFFER (WGET (w, buffer)) != current_buffer)
+ GCPRO1 (old_buffer);
+ if (XBUFFER (w->buffer) != current_buffer)
{
/* Set the window's buffer temporarily to the current buffer. */
- old_buffer = WGET (w, buffer);
- old_charpos = XMARKER (WGET (w, pointm))->charpos;
- old_bytepos = XMARKER (WGET (w, pointm))->bytepos;
- WSET (w, buffer, Fcurrent_buffer ());
- set_marker_both (WGET (w, pointm), WGET (w, buffer),
+ old_buffer = w->buffer;
+ old_charpos = marker_position (w->pointm);
+ old_bytepos = marker_byte_position (w->pointm);
+ wset_buffer (w, Fcurrent_buffer ());
+ set_marker_both (w->pointm, w->buffer,
BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
}
{
ptrdiff_t it_start, it_overshoot_count = 0;
int first_x;
- int overshoot_handled = 0;
- int disp_string_at_start_p = 0;
+ bool overshoot_handled = 0;
+ bool disp_string_at_start_p = 0;
itdata = bidi_shelve_cache ();
SET_TEXT_POS (pt, PT, PT_BYTE);
const char *s = SSDATA (it.string);
const char *e = s + SBYTES (it.string);
- disp_string_at_start_p = it.string_from_display_prop_p;
+ /* If it.area is anything but TEXT_AREA, we need not bother
+ about the display string, as it doesn't affect cursor
+ positioning. */
+ disp_string_at_start_p =
+ it.string_from_display_prop_p && it.area == TEXT_AREA;
while (s < e)
{
if (*s++ == '\n')
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);
+ /* When the position we started from is covered by a display
+ 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,
+ -1, -1, -1, MOVE_TO_POS);
/* 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
}
move_it_in_display_line
(&it, ZV,
- (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (WGET (w, frame))) + 0.5),
+ (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
MOVE_TO_X);
}
if (BUFFERP (old_buffer))
{
- WSET (w, buffer, old_buffer);
- set_marker_both (WGET (w, pointm), WGET (w, buffer),
+ wset_buffer (w, old_buffer);
+ set_marker_both (w->pointm, w->buffer,
old_charpos, old_bytepos);
}