#include "charset.h"
#include "category.h"
#include "indent.h"
+#include "keyboard.h"
#include "frame.h"
#include "window.h"
#include "termchar.h"
return pos;
}
\f
+/* 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;
+ int start, end;
+ int id;
+
+ if (! find_composition (pos, -1, &start, &end, &prop, Qnil)
+ || pos != start || point < end)
+ 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;
+}
+\f
/* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
DP is a display table or NULL.
This macro is used in current_column_1, Fmove_to_column, and
compute_motion. */
-#define MULTIBYTE_BYTES_WIDTH(p, dp) \
- do { \
- int c; \
- \
- wide_column = 0; \
- c = STRING_CHAR_AND_LENGTH (p, MAX_LENGTH_OF_MULTI_BYTE_FORM, 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; \
- else \
- width = WIDTH_BY_CHAR_HEAD (*p); \
- if (width > 1) \
- wide_column = width; \
- } \
+#define MULTIBYTE_BYTES_WIDTH(p, dp) \
+ do { \
+ int c; \
+ \
+ wide_column = 0; \
+ c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, 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; \
+ else \
+ width = WIDTH_BY_CHAR_HEAD (*p); \
+ if (width > 1) \
+ wide_column = width; \
+ } \
} while (0)
DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
register int tab_width = XINT (current_buffer->tab_width);
int ctl_arrow = !NILP (current_buffer->ctl_arrow);
register struct Lisp_Char_Table *dp = buffer_display_table ();
- int stopchar;
if (PT == last_known_column_point
&& MODIFF == last_known_column_modified)
next_boundary_byte = CHAR_TO_BYTE (next_boundary);
}
+ /* Check composition sequence. */
+ {
+ int len, len_byte, width;
+
+ if (check_composition (scan, scan_byte, opoint,
+ &len, &len_byte, &width))
+ {
+ scan += len;
+ scan_byte += len_byte;
+ if (scan <= opoint)
+ col += width;
+ continue;
+ }
+ }
+
c = FETCH_BYTE (scan_byte);
if (dp != 0
&& ! (multibyte && BASE_LEADING_CODE_P (c))
register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
Lisp_Object val;
- int prev_col;
- int c;
+ int prev_col = 0;
+ int c = 0;
int next_boundary;
int pos_byte, end_byte, next_boundary_byte;
if (col >= goal)
break;
+ /* Check composition sequence. */
+ {
+ int len, len_byte, width;
+
+ if (check_composition (pos, pos_byte, Z, &len, &len_byte, &width))
+ {
+ pos += len;
+ pos_byte += len_byte;
+ col += width;
+ continue;
+ }
+ }
+
c = FETCH_BYTE (pos_byte);
if (dp != 0
&& ! (multibyte && BASE_LEADING_CODE_P (c))
and scan through it again. */
if (!NILP (force) && col > goal && c == '\t' && prev_col < goal)
{
- int old_point, old_point_byte;
-
- del_range (PT - 1, PT);
- Findent_to (make_number (goal), Qnil);
- old_point = PT;
- old_point_byte = PT_BYTE;
+ int goal_pt, goal_pt_byte;
+
+ /* Insert spaces in front of the tab to reach GOAL. Do this
+ first so that a marker at the end of the tab gets
+ adjusted. */
+ SET_PT_BOTH (PT - 1, PT_BYTE - 1);
+ Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
+
+ /* Now delete the tab, and indent to COL. */
+ del_range (PT, PT + 1);
+ goal_pt = PT;
+ goal_pt_byte = PT_BYTE;
Findent_to (make_number (col), Qnil);
- SET_PT_BOTH (old_point, old_point_byte);
+ SET_PT_BOTH (goal_pt, goal_pt_byte);
+
/* Set the last_known... vars consistently. */
col = goal;
}
register int pos;
int pos_byte;
- register int c;
+ register int c = 0;
register int tab_width = XFASTINT (current_buffer->tab_width);
register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
register struct Lisp_Char_Table *dp = window_display_table (win);
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;
+ if (tab_width <= 0 || tab_width > 1000)
+ tab_width = 8;
+
+ immediate_quit = 1;
+ QUIT;
pos = prev_pos = from;
pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
if (newpos >= to)
{
pos = min (to, newpos);
+ pos_byte = CHAR_TO_BYTE (pos);
goto after_loop;
}
else
{
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;
+ }
+ }
+
pos++, pos_byte++;
/* Perhaps add some info to the width_run_cache. */
/* Nonzero if have just continued a line */
val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
+ immediate_quit = 0;
return &val_compute_motion;
}
Lisp_Object from, frompos, to, topos;
Lisp_Object width, offsets, window;
{
- Lisp_Object bufpos, hpos, vpos, prevhpos, contin;
+ Lisp_Object bufpos, hpos, vpos, prevhpos;
struct position *pos;
int hscroll, tab_offset;
CHECK_NUMBER_COERCE_MARKER (from, 0);
CHECK_CONS (frompos, 0);
- CHECK_NUMBER (XCONS (frompos)->car, 0);
- CHECK_NUMBER (XCONS (frompos)->cdr, 0);
+ CHECK_NUMBER (XCAR (frompos), 0);
+ CHECK_NUMBER (XCDR (frompos), 0);
CHECK_NUMBER_COERCE_MARKER (to, 0);
CHECK_CONS (topos, 0);
- CHECK_NUMBER (XCONS (topos)->car, 0);
- CHECK_NUMBER (XCONS (topos)->cdr, 0);
+ CHECK_NUMBER (XCAR (topos), 0);
+ CHECK_NUMBER (XCDR (topos), 0);
CHECK_NUMBER (width, 0);
if (!NILP (offsets))
{
CHECK_CONS (offsets, 0);
- CHECK_NUMBER (XCONS (offsets)->car, 0);
- CHECK_NUMBER (XCONS (offsets)->cdr, 0);
- hscroll = XINT (XCONS (offsets)->car);
- tab_offset = XINT (XCONS (offsets)->cdr);
+ CHECK_NUMBER (XCAR (offsets), 0);
+ CHECK_NUMBER (XCDR (offsets), 0);
+ hscroll = XINT (XCAR (offsets));
+ tab_offset = XINT (XCDR (offsets));
}
else
hscroll = tab_offset = 0;
if (XINT (to) < BEGV || XINT (to) > ZV)
args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
- pos = compute_motion (XINT (from), XINT (XCONS (frompos)->cdr),
- XINT (XCONS (frompos)->car), 0,
- XINT (to), XINT (XCONS (topos)->cdr),
- XINT (XCONS (topos)->car),
+ pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
+ XINT (XCAR (frompos)), 0,
+ XINT (to), XINT (XCDR (topos)),
+ XINT (XCAR (topos)),
XINT (width), hscroll, tab_offset,
XWINDOW (window));
&& indented_beyond_p (XFASTINT (prevline),
CHAR_TO_BYTE (XFASTINT (prevline)),
selective))
-#ifdef USE_TEXT_PROPERTIES
/* watch out for newlines with `invisible' property */
|| (propval = Fget_char_property (prevline,
Qinvisible,
text_prop_object),
- TEXT_PROP_MEANS_INVISIBLE (propval))
-#endif
- ))
+ TEXT_PROP_MEANS_INVISIBLE (propval))))
XSETFASTINT (prevline,
find_next_newline_no_quit (XFASTINT (prevline) - 1,
-1));
&& indented_beyond_p (XFASTINT (prevline),
CHAR_TO_BYTE (XFASTINT (prevline)),
selective))
-#ifdef USE_TEXT_PROPERTIES
/* watch out for newlines with `invisible' property */
|| (propval = Fget_char_property (prevline, Qinvisible,
text_prop_object),
- TEXT_PROP_MEANS_INVISIBLE (propval))
-#endif
- ))
+ TEXT_PROP_MEANS_INVISIBLE (propval))))
XSETFASTINT (prevline,
find_next_newline_no_quit (XFASTINT (prevline) - 1,
-1));
{
struct it it;
struct text_pos pt;
- struct buffer *old, *b;
struct window *w;
+ Lisp_Object old_buffer;
+ struct gcpro gcpro1;
CHECK_NUMBER (lines, 0);
if (! NILP (window))
CHECK_WINDOW (window, 0);
else
window = selected_window;
-
w = XWINDOW (window);
- b = XBUFFER (w->buffer);
- if (b != current_buffer)
+
+ old_buffer = Qnil;
+ GCPRO1 (old_buffer);
+ if (XBUFFER (w->buffer) != current_buffer)
{
- old = current_buffer;
- set_buffer_internal_1 (b);
+ /* Set the window's buffer temporarily to the current buffer. */
+ old_buffer = w->buffer;
+ XSETBUFFER (w->buffer, current_buffer);
}
- else
- old = NULL;
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
move_it_by_lines (&it, XINT (lines), 0);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
- if (old)
- set_buffer_internal_1 (old);
+ if (BUFFERP (old_buffer))
+ w->buffer = old_buffer;
- return make_number (it.vpos);
+ RETURN_UNGCPRO (make_number (it.vpos));
}