#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,
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;
}
{
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));
}