* keyboard.c (parse_modifiers_uncached, parse_modifiers):
[emacs.git] / src / indent.c
blobbaea06419487615cc86bf997f9c8968b49daee52
1 /* Indentation functions.
2 Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2011
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
21 #include <stdio.h>
22 #include <setjmp.h>
24 #include "lisp.h"
25 #include "buffer.h"
26 #include "character.h"
27 #include "category.h"
28 #include "composite.h"
29 #include "indent.h"
30 #include "keyboard.h"
31 #include "frame.h"
32 #include "window.h"
33 #include "termchar.h"
34 #include "termopts.h"
35 #include "disptab.h"
36 #include "intervals.h"
37 #include "dispextern.h"
38 #include "region-cache.h"
40 #define CR 015
42 /* These three values memorize the current column to avoid recalculation. */
44 /* Last value returned by current_column.
45 Some things in set last_known_column_point to -1
46 to mark the memorized value as invalid. */
48 static EMACS_INT last_known_column;
50 /* Value of point when current_column was called. */
52 EMACS_INT last_known_column_point;
54 /* Value of MODIFF when current_column was called. */
56 static int last_known_column_modified;
58 static EMACS_INT current_column_1 (void);
59 static EMACS_INT position_indentation (int);
61 /* Cache of beginning of line found by the last call of
62 current_column. */
64 static EMACS_INT current_column_bol_cache;
66 /* Get the display table to use for the current buffer. */
68 struct Lisp_Char_Table *
69 buffer_display_table (void)
71 Lisp_Object thisbuf;
73 thisbuf = BVAR (current_buffer, display_table);
74 if (DISP_TABLE_P (thisbuf))
75 return XCHAR_TABLE (thisbuf);
76 if (DISP_TABLE_P (Vstandard_display_table))
77 return XCHAR_TABLE (Vstandard_display_table);
78 return 0;
81 /* Width run cache considerations. */
83 /* Return the width of character C under display table DP. */
85 static int
86 character_width (int c, struct Lisp_Char_Table *dp)
88 Lisp_Object elt;
90 /* These width computations were determined by examining the cases
91 in display_text_line. */
93 /* Everything can be handled by the display table, if it's
94 present and the element is right. */
95 if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
96 return XVECTOR (elt)->size;
98 /* Some characters are special. */
99 if (c == '\n' || c == '\t' || c == '\015')
100 return 0;
102 /* Printing characters have width 1. */
103 else if (c >= 040 && c < 0177)
104 return 1;
106 /* Everybody else (control characters, metacharacters) has other
107 widths. We could return their actual widths here, but they
108 depend on things like ctl_arrow and crud like that, and they're
109 not very common at all. So we'll just claim we don't know their
110 widths. */
111 else
112 return 0;
115 /* Return true if the display table DISPTAB specifies the same widths
116 for characters as WIDTHTAB. We use this to decide when to
117 invalidate the buffer's width_run_cache. */
120 disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *widthtab)
122 int i;
124 if (widthtab->size != 256)
125 abort ();
127 for (i = 0; i < 256; i++)
128 if (character_width (i, disptab)
129 != XFASTINT (widthtab->contents[i]))
130 return 0;
132 return 1;
135 /* Recompute BUF's width table, using the display table DISPTAB. */
137 void
138 recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
140 int i;
141 struct Lisp_Vector *widthtab;
143 if (!VECTORP (BVAR (buf, width_table)))
144 BVAR (buf, width_table) = Fmake_vector (make_number (256), make_number (0));
145 widthtab = XVECTOR (BVAR (buf, width_table));
146 if (widthtab->size != 256)
147 abort ();
149 for (i = 0; i < 256; i++)
150 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
153 /* Allocate or free the width run cache, as requested by the current
154 state of current_buffer's cache_long_line_scans variable. */
156 static void
157 width_run_cache_on_off (void)
159 if (NILP (BVAR (current_buffer, cache_long_line_scans))
160 /* And, for the moment, this feature doesn't work on multibyte
161 characters. */
162 || !NILP (BVAR (current_buffer, enable_multibyte_characters)))
164 /* It should be off. */
165 if (current_buffer->width_run_cache)
167 free_region_cache (current_buffer->width_run_cache);
168 current_buffer->width_run_cache = 0;
169 BVAR (current_buffer, width_table) = Qnil;
172 else
174 /* It should be on. */
175 if (current_buffer->width_run_cache == 0)
177 current_buffer->width_run_cache = new_region_cache ();
178 recompute_width_table (current_buffer, buffer_display_table ());
184 /* Skip some invisible characters starting from POS.
185 This includes characters invisible because of text properties
186 and characters invisible because of overlays.
188 If position POS is followed by invisible characters,
189 skip some of them and return the position after them.
190 Otherwise return POS itself.
192 Set *NEXT_BOUNDARY_P to the next position at which
193 it will be necessary to call this function again.
195 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
196 to a value greater than TO.
198 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
199 take account of overlays that apply only in WINDOW.
201 We don't necessarily skip all the invisible characters after POS
202 because that could take a long time. We skip a reasonable number
203 which can be skipped quickly. If there might be more invisible
204 characters immediately following, then *NEXT_BOUNDARY_P
205 will equal the return value. */
207 EMACS_INT
208 skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Object window)
210 Lisp_Object prop, position, overlay_limit, proplimit;
211 Lisp_Object buffer, tmp;
212 EMACS_INT end;
213 int inv_p;
215 XSETFASTINT (position, pos);
216 XSETBUFFER (buffer, current_buffer);
218 /* Give faster response for overlay lookup near POS. */
219 recenter_overlay_lists (current_buffer, pos);
221 /* We must not advance farther than the next overlay change.
222 The overlay change might change the invisible property;
223 or there might be overlay strings to be displayed there. */
224 overlay_limit = Fnext_overlay_change (position);
225 /* As for text properties, this gives a lower bound
226 for where the invisible text property could change. */
227 proplimit = Fnext_property_change (position, buffer, Qt);
228 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
229 proplimit = overlay_limit;
230 /* PROPLIMIT is now a lower bound for the next change
231 in invisible status. If that is plenty far away,
232 use that lower bound. */
233 if (XFASTINT (proplimit) > pos + 100 || XFASTINT (proplimit) >= to)
234 *next_boundary_p = XFASTINT (proplimit);
235 /* Otherwise, scan for the next `invisible' property change. */
236 else
238 /* Don't scan terribly far. */
239 XSETFASTINT (proplimit, min (pos + 100, to));
240 /* No matter what, don't go past next overlay change. */
241 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
242 proplimit = overlay_limit;
243 tmp = Fnext_single_property_change (position, Qinvisible,
244 buffer, proplimit);
245 end = XFASTINT (tmp);
246 #if 0
247 /* Don't put the boundary in the middle of multibyte form if
248 there is no actual property change. */
249 if (end == pos + 100
250 && !NILP (current_buffer->enable_multibyte_characters)
251 && end < ZV)
252 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
253 end--;
254 #endif
255 *next_boundary_p = end;
257 /* if the `invisible' property is set, we can skip to
258 the next property change */
259 prop = Fget_char_property (position, Qinvisible,
260 (!NILP (window)
261 && EQ (XWINDOW (window)->buffer, buffer))
262 ? window : buffer);
263 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
264 /* When counting columns (window == nil), don't skip over ellipsis text. */
265 if (NILP (window) ? inv_p == 1 : inv_p)
266 return *next_boundary_p;
267 return pos;
270 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
272 DP is a display table or NULL.
274 This macro is used in current_column_1, Fmove_to_column, and
275 compute_motion. */
277 #define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \
278 do { \
279 int ch; \
281 wide_column = 0; \
282 ch = STRING_CHAR_AND_LENGTH (p, bytes); \
283 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
284 width = bytes * 4; \
285 else \
287 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
288 width = XVECTOR (DISP_CHAR_VECTOR (dp, ch))->size; \
289 else \
290 width = CHAR_WIDTH (ch); \
291 if (width > 1) \
292 wide_column = width; \
294 } while (0)
297 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
298 doc: /* Return the horizontal position of point. Beginning of line is column 0.
299 This is calculated by adding together the widths of all the displayed
300 representations of the character between the start of the previous line
301 and point (eg. control characters will have a width of 2 or 4, tabs
302 will have a variable width).
303 Ignores finite width of frame, which means that this function may return
304 values greater than (frame-width).
305 Whether the line is visible (if `selective-display' is t) has no effect;
306 however, ^M is treated as end of line when `selective-display' is t.
307 Text that has an invisible property is considered as having width 0, unless
308 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
309 (void)
311 Lisp_Object temp;
312 XSETFASTINT (temp, current_column ());
313 return temp;
316 /* Cancel any recorded value of the horizontal position. */
318 void
319 invalidate_current_column (void)
321 last_known_column_point = 0;
324 EMACS_INT
325 current_column (void)
327 register EMACS_INT col;
328 register unsigned char *ptr, *stop;
329 register int tab_seen;
330 EMACS_INT post_tab;
331 register int c;
332 register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
333 int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
334 register struct Lisp_Char_Table *dp = buffer_display_table ();
336 if (PT == last_known_column_point
337 && MODIFF == last_known_column_modified)
338 return last_known_column;
340 /* If the buffer has overlays, text properties,
341 or multibyte characters, use a more general algorithm. */
342 if (BUF_INTERVALS (current_buffer)
343 || current_buffer->overlays_before
344 || current_buffer->overlays_after
345 || Z != Z_BYTE)
346 return current_column_1 ();
348 /* Scan backwards from point to the previous newline,
349 counting width. Tab characters are the only complicated case. */
351 /* Make a pointer for decrementing through the chars before point. */
352 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
353 /* Make a pointer to where consecutive chars leave off,
354 going backwards from point. */
355 if (PT == BEGV)
356 stop = ptr;
357 else if (PT <= GPT || BEGV > GPT)
358 stop = BEGV_ADDR;
359 else
360 stop = GAP_END_ADDR;
362 if (tab_width <= 0 || tab_width > 1000)
363 tab_width = 8;
365 col = 0, tab_seen = 0, post_tab = 0;
367 while (1)
369 EMACS_INT i, n;
370 Lisp_Object charvec;
372 if (ptr == stop)
374 /* We stopped either for the beginning of the buffer
375 or for the gap. */
376 if (ptr == BEGV_ADDR)
377 break;
379 /* It was the gap. Jump back over it. */
380 stop = BEGV_ADDR;
381 ptr = GPT_ADDR;
383 /* Check whether that brings us to beginning of buffer. */
384 if (BEGV >= GPT)
385 break;
388 c = *--ptr;
390 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
392 charvec = DISP_CHAR_VECTOR (dp, c);
393 n = ASIZE (charvec);
395 else
397 charvec = Qnil;
398 n = 1;
401 for (i = n - 1; i >= 0; --i)
403 if (VECTORP (charvec))
405 /* This should be handled the same as
406 next_element_from_display_vector does it. */
407 Lisp_Object entry = AREF (charvec, i);
409 if (GLYPH_CODE_P (entry)
410 && GLYPH_CODE_CHAR_VALID_P (entry))
411 c = GLYPH_CODE_CHAR (entry);
412 else
413 c = ' ';
416 if (c >= 040 && c < 0177)
417 col++;
418 else if (c == '\n'
419 || (c == '\r'
420 && EQ (BVAR (current_buffer, selective_display), Qt)))
422 ptr++;
423 goto start_of_line_found;
425 else if (c == '\t')
427 if (tab_seen)
428 col = ((col + tab_width) / tab_width) * tab_width;
430 post_tab += col;
431 col = 0;
432 tab_seen = 1;
434 else if (VECTORP (charvec))
435 /* With a display table entry, C is displayed as is, and
436 not displayed as \NNN or as ^N. If C is a single-byte
437 character, it takes one column. If C is multi-byte in
438 an unibyte buffer, it's translated to unibyte, so it
439 also takes one column. */
440 ++col;
441 else
442 col += (ctl_arrow && c < 0200) ? 2 : 4;
446 start_of_line_found:
448 if (tab_seen)
450 col = ((col + tab_width) / tab_width) * tab_width;
451 col += post_tab;
454 if (ptr == BEGV_ADDR)
455 current_column_bol_cache = BEGV;
456 else
457 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
459 last_known_column = col;
460 last_known_column_point = PT;
461 last_known_column_modified = MODIFF;
463 return col;
467 /* Check the presence of a display property and compute its width.
468 If a property was found and its width was found as well, return
469 its width (>= 0) and set the position of the end of the property
470 in ENDPOS.
471 Otherwise just return -1. */
472 static int
473 check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
475 Lisp_Object val, overlay;
477 if (CONSP (val = get_char_property_and_overlay
478 (make_number (pos), Qdisplay, Qnil, &overlay))
479 && EQ (Qspace, XCAR (val)))
480 { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */
481 Lisp_Object plist = XCDR (val), prop;
482 int width = -1;
484 if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop)))
485 width = XINT (prop);
486 else if (FLOATP (prop))
487 width = (int)(XFLOAT_DATA (prop) + 0.5);
488 else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop)))
489 width = XINT (prop) - col;
490 else if (FLOATP (prop))
491 width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
493 if (width >= 0)
495 EMACS_INT start;
496 if (OVERLAYP (overlay))
497 *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
498 else
499 get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
500 return width;
503 return -1;
506 /* Scanning from the beginning of the current line, stop at the buffer
507 position ENDPOS or at the column GOALCOL or at the end of line, whichever
508 comes first.
509 Return the resulting buffer position and column in ENDPOS and GOALCOL.
510 PREVCOL gets set to the column of the previous position (it's always
511 strictly smaller than the goal column). */
512 static void
513 scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
515 register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
516 register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
517 register struct Lisp_Char_Table *dp = buffer_display_table ();
518 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
519 struct composition_it cmp_it;
520 Lisp_Object window;
521 struct window *w;
523 /* Start the scan at the beginning of this line with column number 0. */
524 register EMACS_INT col = 0, prev_col = 0;
525 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
526 EMACS_INT end = endpos ? *endpos : PT;
527 EMACS_INT scan, scan_byte;
528 EMACS_INT next_boundary;
530 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
531 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
532 current_column_bol_cache = PT;
533 scan = PT, scan_byte = PT_BYTE;
534 SET_PT_BOTH (opoint, opoint_byte);
535 next_boundary = scan;
538 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
539 w = ! NILP (window) ? XWINDOW (window) : NULL;
541 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
542 memset (&cmp_it, 0, sizeof cmp_it);
543 cmp_it.id = -1;
544 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
546 /* Scan forward to the target position. */
547 while (scan < end)
549 int c;
551 /* Occasionally we may need to skip invisible text. */
552 while (scan == next_boundary)
554 EMACS_INT old_scan = scan;
555 /* This updates NEXT_BOUNDARY to the next place
556 where we might need to skip more invisible text. */
557 scan = skip_invisible (scan, &next_boundary, end, Qnil);
558 if (scan != old_scan)
559 scan_byte = CHAR_TO_BYTE (scan);
560 if (scan >= end)
561 goto endloop;
564 /* Test reaching the goal column. We do this after skipping
565 invisible characters, so that we put point before the
566 character on which the cursor will appear. */
567 if (col >= goal)
568 break;
569 prev_col = col;
571 { /* Check display property. */
572 EMACS_INT endp;
573 int width = check_display_width (scan, col, &endp);
574 if (width >= 0)
576 col += width;
577 if (endp > scan) /* Avoid infinite loops with 0-width overlays. */
579 scan = endp; scan_byte = charpos_to_bytepos (scan);
580 continue;
585 /* Check composition sequence. */
586 if (cmp_it.id >= 0
587 || (scan == cmp_it.stop_pos
588 && composition_reseat_it (&cmp_it, scan, scan_byte, end,
589 w, NULL, Qnil)))
590 composition_update_it (&cmp_it, scan, scan_byte, Qnil);
591 if (cmp_it.id >= 0)
593 scan += cmp_it.nchars;
594 scan_byte += cmp_it.nbytes;
595 if (scan <= end)
596 col += cmp_it.width;
597 if (cmp_it.to == cmp_it.nglyphs)
599 cmp_it.id = -1;
600 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end,
601 Qnil);
603 else
604 cmp_it.from = cmp_it.to;
605 continue;
608 c = FETCH_BYTE (scan_byte);
610 /* See if there is a display table and it relates
611 to this character. */
613 if (dp != 0
614 && ! (multibyte && LEADING_CODE_P (c))
615 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
617 Lisp_Object charvec;
618 EMACS_INT i, n;
620 /* This character is displayed using a vector of glyphs.
621 Update the column/position based on those glyphs. */
623 charvec = DISP_CHAR_VECTOR (dp, c);
624 n = ASIZE (charvec);
626 for (i = 0; i < n; i++)
628 /* This should be handled the same as
629 next_element_from_display_vector does it. */
630 Lisp_Object entry = AREF (charvec, i);
632 if (GLYPH_CODE_P (entry)
633 && GLYPH_CODE_CHAR_VALID_P (entry))
634 c = GLYPH_CODE_CHAR (entry);
635 else
636 c = ' ';
638 if (c == '\n')
639 goto endloop;
640 if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
641 goto endloop;
642 if (c == '\t')
644 col += tab_width;
645 col = col / tab_width * tab_width;
647 else
648 ++col;
651 else
653 /* The display table doesn't affect this character;
654 it displays as itself. */
656 if (c == '\n')
657 goto endloop;
658 if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
659 goto endloop;
660 if (c == '\t')
662 col += tab_width;
663 col = col / tab_width * tab_width;
665 else if (multibyte && LEADING_CODE_P (c))
667 /* Start of multi-byte form. */
668 unsigned char *ptr;
669 int bytes, width, wide_column;
671 ptr = BYTE_POS_ADDR (scan_byte);
672 MULTIBYTE_BYTES_WIDTH (ptr, dp, bytes, width);
673 /* Subtract one to compensate for the increment
674 that is going to happen below. */
675 scan_byte += bytes - 1;
676 col += width;
678 else if (ctl_arrow && (c < 040 || c == 0177))
679 col += 2;
680 else if (c < 040 || c >= 0177)
681 col += 4;
682 else
683 col++;
685 scan++;
686 scan_byte++;
689 endloop:
691 last_known_column = col;
692 last_known_column_point = PT;
693 last_known_column_modified = MODIFF;
695 if (goalcol)
696 *goalcol = col;
697 if (endpos)
698 *endpos = scan;
699 if (prevcol)
700 *prevcol = prev_col;
703 /* Return the column number of position POS
704 by scanning forward from the beginning of the line.
705 This function handles characters that are invisible
706 due to text properties or overlays. */
708 static EMACS_INT
709 current_column_1 (void)
711 EMACS_INT col = MOST_POSITIVE_FIXNUM;
712 EMACS_INT opoint = PT;
714 scan_for_column (&opoint, &col, NULL);
715 return col;
719 #if 0 /* Not used. */
721 /* Return the width in columns of the part of STRING from BEG to END.
722 If BEG is nil, that stands for the beginning of STRING.
723 If END is nil, that stands for the end of STRING. */
725 static double
726 string_display_width (string, beg, end)
727 Lisp_Object string, beg, end;
729 register int col;
730 register unsigned char *ptr, *stop;
731 register int tab_seen;
732 int post_tab;
733 register int c;
734 register int tab_width = XINT (current_buffer->tab_width);
735 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
736 register struct Lisp_Char_Table *dp = buffer_display_table ();
737 int b, e;
739 if (NILP (end))
740 e = SCHARS (string);
741 else
743 CHECK_NUMBER (end);
744 e = XINT (end);
747 if (NILP (beg))
748 b = 0;
749 else
751 CHECK_NUMBER (beg);
752 b = XINT (beg);
755 /* Make a pointer for decrementing through the chars before point. */
756 ptr = SDATA (string) + e;
757 /* Make a pointer to where consecutive chars leave off,
758 going backwards from point. */
759 stop = SDATA (string) + b;
761 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
763 col = 0, tab_seen = 0, post_tab = 0;
765 while (1)
767 if (ptr == stop)
768 break;
770 c = *--ptr;
771 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
772 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
773 else if (c >= 040 && c < 0177)
774 col++;
775 else if (c == '\n')
776 break;
777 else if (c == '\t')
779 if (tab_seen)
780 col = ((col + tab_width) / tab_width) * tab_width;
782 post_tab += col;
783 col = 0;
784 tab_seen = 1;
786 else
787 col += (ctl_arrow && c < 0200) ? 2 : 4;
790 if (tab_seen)
792 col = ((col + tab_width) / tab_width) * tab_width;
793 col += post_tab;
796 return col;
799 #endif /* 0 */
802 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
803 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
804 Optional second argument MINIMUM says always do at least MINIMUM spaces
805 even if that goes past COLUMN; by default, MINIMUM is zero.
807 The return value is COLUMN. */)
808 (Lisp_Object column, Lisp_Object minimum)
810 EMACS_INT mincol;
811 register EMACS_INT fromcol;
812 register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
814 CHECK_NUMBER (column);
815 if (NILP (minimum))
816 XSETFASTINT (minimum, 0);
817 CHECK_NUMBER (minimum);
819 fromcol = current_column ();
820 mincol = fromcol + XINT (minimum);
821 if (mincol < XINT (column)) mincol = XINT (column);
823 if (fromcol == mincol)
824 return make_number (mincol);
826 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
828 if (indent_tabs_mode)
830 Lisp_Object n;
831 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
832 if (XFASTINT (n) != 0)
834 Finsert_char (make_number ('\t'), n, Qt);
836 fromcol = (mincol / tab_width) * tab_width;
840 XSETFASTINT (column, mincol - fromcol);
841 Finsert_char (make_number (' '), column, Qt);
843 last_known_column = mincol;
844 last_known_column_point = PT;
845 last_known_column_modified = MODIFF;
847 XSETINT (column, mincol);
848 return column;
852 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
853 0, 0, 0,
854 doc: /* Return the indentation of the current line.
855 This is the horizontal position of the character
856 following any initial whitespace. */)
857 (void)
859 Lisp_Object val;
860 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
862 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
864 XSETFASTINT (val, position_indentation (PT_BYTE));
865 SET_PT_BOTH (opoint, opoint_byte);
866 return val;
869 static EMACS_INT
870 position_indentation (register int pos_byte)
872 register EMACS_INT column = 0;
873 register EMACS_INT tab_width = XINT (BVAR (current_buffer, tab_width));
874 register unsigned char *p;
875 register unsigned char *stop;
876 unsigned char *start;
877 EMACS_INT next_boundary_byte = pos_byte;
878 EMACS_INT ceiling = next_boundary_byte;
880 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
882 p = BYTE_POS_ADDR (pos_byte);
883 /* STOP records the value of P at which we will need
884 to think about the gap, or about invisible text,
885 or about the end of the buffer. */
886 stop = p;
887 /* START records the starting value of P. */
888 start = p;
889 while (1)
891 while (p == stop)
893 EMACS_INT stop_pos_byte;
895 /* If we have updated P, set POS_BYTE to match.
896 The first time we enter the loop, POS_BYTE is already right. */
897 if (p != start)
898 pos_byte = PTR_BYTE_POS (p);
899 /* Consider the various reasons STOP might have been set here. */
900 if (pos_byte == ZV_BYTE)
901 return column;
902 if (pos_byte == next_boundary_byte)
904 EMACS_INT next_boundary;
905 EMACS_INT pos = BYTE_TO_CHAR (pos_byte);
906 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
907 pos_byte = CHAR_TO_BYTE (pos);
908 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
910 if (pos_byte >= ceiling)
911 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
912 /* Compute the next place we need to stop and think,
913 and set STOP accordingly. */
914 stop_pos_byte = min (ceiling, next_boundary_byte);
915 /* The -1 and +1 arrange to point at the first byte of gap
916 (if STOP_POS_BYTE is the position of the gap)
917 rather than at the data after the gap. */
919 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
920 p = BYTE_POS_ADDR (pos_byte);
922 switch (*p++)
924 case 0240:
925 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
926 return column;
927 case ' ':
928 column++;
929 break;
930 case '\t':
931 column += tab_width - column % tab_width;
932 break;
933 default:
934 if (ASCII_BYTE_P (p[-1])
935 || NILP (BVAR (current_buffer, enable_multibyte_characters)))
936 return column;
938 int c;
939 pos_byte = PTR_BYTE_POS (p - 1);
940 c = FETCH_MULTIBYTE_CHAR (pos_byte);
941 if (CHAR_HAS_CATEGORY (c, ' '))
943 column++;
944 INC_POS (pos_byte);
945 p = BYTE_POS_ADDR (pos_byte);
947 else
948 return column;
954 /* Test whether the line beginning at POS is indented beyond COLUMN.
955 Blank lines are treated as if they had the same indentation as the
956 preceding line. */
959 indented_beyond_p (EMACS_INT pos, EMACS_INT pos_byte, EMACS_INT column)
961 EMACS_INT val;
962 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
964 SET_PT_BOTH (pos, pos_byte);
965 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
966 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
968 val = position_indentation (PT_BYTE);
969 SET_PT_BOTH (opoint, opoint_byte);
970 return val >= column;
973 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
974 doc: /* Move point to column COLUMN in the current line.
975 Interactively, COLUMN is the value of prefix numeric argument.
976 The column of a character is calculated by adding together the widths
977 as displayed of the previous characters in the line.
978 This function ignores line-continuation;
979 there is no upper limit on the column number a character can have
980 and horizontal scrolling has no effect.
982 If specified column is within a character, point goes after that character.
983 If it's past end of line, point goes to end of line.
985 Optional second argument FORCE non-nil means if COLUMN is in the
986 middle of a tab character, change it to spaces.
987 In addition, if FORCE is t, and the line is too short to reach
988 COLUMN, add spaces/tabs to get there.
990 The return value is the current column. */)
991 (Lisp_Object column, Lisp_Object force)
993 EMACS_INT pos;
994 EMACS_INT col, prev_col;
995 EMACS_INT goal;
997 CHECK_NATNUM (column);
998 goal = XINT (column);
1000 col = goal;
1001 pos = ZV;
1002 scan_for_column (&pos, &col, &prev_col);
1004 SET_PT (pos);
1006 /* If a tab char made us overshoot, change it to spaces
1007 and scan through it again. */
1008 if (!NILP (force) && col > goal)
1010 int c;
1011 EMACS_INT pos_byte = PT_BYTE;
1013 DEC_POS (pos_byte);
1014 c = FETCH_CHAR (pos_byte);
1015 if (c == '\t' && prev_col < goal)
1017 EMACS_INT goal_pt, goal_pt_byte;
1019 /* Insert spaces in front of the tab to reach GOAL. Do this
1020 first so that a marker at the end of the tab gets
1021 adjusted. */
1022 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1023 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1025 /* Now delete the tab, and indent to COL. */
1026 del_range (PT, PT + 1);
1027 goal_pt = PT;
1028 goal_pt_byte = PT_BYTE;
1029 Findent_to (make_number (col), Qnil);
1030 SET_PT_BOTH (goal_pt, goal_pt_byte);
1032 /* Set the last_known... vars consistently. */
1033 col = goal;
1037 /* If line ends prematurely, add space to the end. */
1038 if (col < goal && EQ (force, Qt))
1039 Findent_to (make_number (col = goal), Qnil);
1041 last_known_column = col;
1042 last_known_column_point = PT;
1043 last_known_column_modified = MODIFF;
1045 return make_number (col);
1048 /* compute_motion: compute buffer posn given screen posn and vice versa */
1050 struct position val_compute_motion;
1052 /* Scan the current buffer forward from offset FROM, pretending that
1053 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1054 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1055 and return the ending buffer position and screen location. If we
1056 can't hit the requested column exactly (because of a tab or other
1057 multi-column character), overshoot.
1059 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1060 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1061 earlier call to compute_motion. The other common case is that FROMHPOS
1062 is zero and FROM is a position that "belongs" at column zero, but might
1063 be shifted by overlay strings; in this case DID_MOTION should be 0.
1065 WIDTH is the number of columns available to display text;
1066 compute_motion uses this to handle continuation lines and such.
1067 If WIDTH is -1, use width of window's text area adjusted for
1068 continuation glyph when needed.
1070 HSCROLL is the number of columns not being displayed at the left
1071 margin; this is usually taken from a window's hscroll member.
1072 TAB_OFFSET is the number of columns of the first tab that aren't
1073 being displayed, perhaps because of a continuation line or
1074 something.
1076 compute_motion returns a pointer to a struct position. The bufpos
1077 member gives the buffer position at the end of the scan, and hpos
1078 and vpos give its cartesian location. prevhpos is the column at
1079 which the character before bufpos started, and contin is non-zero
1080 if we reached the current line by continuing the previous.
1082 Note that FROMHPOS and TOHPOS should be expressed in real screen
1083 columns, taking HSCROLL and the truncation glyph at the left margin
1084 into account. That is, beginning-of-line moves you to the hpos
1085 -HSCROLL + (HSCROLL > 0).
1087 For example, to find the buffer position of column COL of line LINE
1088 of a certain window, pass the window's starting location as FROM
1089 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1090 Pass the buffer's ZV as TO, to limit the scan to the end of the
1091 visible section of the buffer, and pass LINE and COL as TOVPOS and
1092 TOHPOS.
1094 When displaying in window w, a typical formula for WIDTH is:
1096 window_width - 1
1097 - (has_vertical_scroll_bars
1098 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1099 : (window_width + window_left != frame_cols))
1101 where
1102 window_width is XFASTINT (w->total_cols),
1103 window_left is XFASTINT (w->left_col),
1104 has_vertical_scroll_bars is
1105 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1106 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1108 Or you can let window_box_text_cols do this all for you, and write:
1109 window_box_text_cols (w) - 1
1111 The `-1' accounts for the continuation-line backslashes; the rest
1112 accounts for window borders if the window is split horizontally, and
1113 the scroll bars if they are turned on. */
1115 struct position *
1116 compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_motion, EMACS_INT to, EMACS_INT tovpos, EMACS_INT tohpos, EMACS_INT width, EMACS_INT hscroll, EMACS_INT tab_offset, struct window *win)
1118 register EMACS_INT hpos = fromhpos;
1119 register EMACS_INT vpos = fromvpos;
1121 register EMACS_INT pos;
1122 EMACS_INT pos_byte;
1123 register int c = 0;
1124 register EMACS_INT tab_width = XFASTINT (BVAR (current_buffer, tab_width));
1125 register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
1126 register struct Lisp_Char_Table *dp = window_display_table (win);
1127 EMACS_INT selective
1128 = (INTEGERP (BVAR (current_buffer, selective_display))
1129 ? XINT (BVAR (current_buffer, selective_display))
1130 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1131 int selective_rlen
1132 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1133 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
1134 /* The next location where the `invisible' property changes, or an
1135 overlay starts or ends. */
1136 EMACS_INT next_boundary = from;
1138 /* For computing runs of characters with similar widths.
1139 Invariant: width_run_width is zero, or all the characters
1140 from width_run_start to width_run_end have a fixed width of
1141 width_run_width. */
1142 EMACS_INT width_run_start = from;
1143 EMACS_INT width_run_end = from;
1144 EMACS_INT width_run_width = 0;
1145 Lisp_Object *width_table;
1146 Lisp_Object buffer;
1148 /* The next buffer pos where we should consult the width run cache. */
1149 EMACS_INT next_width_run = from;
1150 Lisp_Object window;
1152 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
1153 /* If previous char scanned was a wide character,
1154 this is the column where it ended. Otherwise, this is 0. */
1155 EMACS_INT wide_column_end_hpos = 0;
1156 EMACS_INT prev_pos; /* Previous buffer position. */
1157 EMACS_INT prev_pos_byte; /* Previous buffer position. */
1158 EMACS_INT prev_hpos = 0;
1159 EMACS_INT prev_vpos = 0;
1160 EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
1161 EMACS_INT prev_tab_offset; /* Previous tab offset. */
1162 EMACS_INT continuation_glyph_width;
1164 struct composition_it cmp_it;
1166 XSETBUFFER (buffer, current_buffer);
1167 XSETWINDOW (window, win);
1169 width_run_cache_on_off ();
1170 if (dp == buffer_display_table ())
1171 width_table = (VECTORP (BVAR (current_buffer, width_table))
1172 ? XVECTOR (BVAR (current_buffer, width_table))->contents
1173 : 0);
1174 else
1175 /* If the window has its own display table, we can't use the width
1176 run cache, because that's based on the buffer's display table. */
1177 width_table = 0;
1179 if (tab_width <= 0 || tab_width > 1000)
1180 tab_width = 8;
1182 /* Negative width means use all available text columns. */
1183 if (width < 0)
1185 width = window_box_text_cols (win);
1186 /* We must make room for continuation marks if we don't have fringes. */
1187 #ifdef HAVE_WINDOW_SYSTEM
1188 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1189 #endif
1190 width -= 1;
1193 continuation_glyph_width = 1;
1194 #ifdef HAVE_WINDOW_SYSTEM
1195 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1196 continuation_glyph_width = 0; /* In the fringe. */
1197 #endif
1199 immediate_quit = 1;
1200 QUIT;
1202 pos = prev_pos = from;
1203 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1204 contin_hpos = 0;
1205 prev_tab_offset = tab_offset;
1206 memset (&cmp_it, 0, sizeof cmp_it);
1207 cmp_it.id = -1;
1208 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil);
1210 while (1)
1212 while (pos == next_boundary)
1214 EMACS_INT pos_here = pos;
1215 EMACS_INT newpos;
1217 /* Don't skip invisible if we are already at the margin. */
1218 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1220 if (contin_hpos && prev_hpos == 0
1221 && hpos > tohpos
1222 && (contin_hpos == width || wide_column_end_hpos > width))
1223 { /* Line breaks because we can't put the character at the
1224 previous line any more. It is not the multi-column
1225 character continued in middle. Go back to previous
1226 buffer position, screen position, and set tab offset
1227 to previous value. It's the beginning of the
1228 line. */
1229 pos = prev_pos;
1230 pos_byte = prev_pos_byte;
1231 hpos = prev_hpos;
1232 vpos = prev_vpos;
1233 tab_offset = prev_tab_offset;
1235 break;
1238 /* If the caller says that the screen position came from an earlier
1239 call to compute_motion, then we've already accounted for the
1240 overlay strings at point. This is only true the first time
1241 through, so clear the flag after testing it. */
1242 if (!did_motion)
1243 /* We need to skip past the overlay strings. Currently those
1244 strings must not contain TAB;
1245 if we want to relax that restriction, something will have
1246 to be changed here. */
1248 unsigned char *ovstr;
1249 EMACS_INT ovlen = overlay_strings (pos, win, &ovstr);
1250 hpos += ((multibyte && ovlen > 0)
1251 ? strwidth ((char *) ovstr, ovlen) : ovlen);
1253 did_motion = 0;
1255 if (pos >= to)
1256 break;
1258 /* Advance POS past invisible characters
1259 (but not necessarily all that there are here),
1260 and store in next_boundary the next position where
1261 we need to call skip_invisible. */
1262 newpos = skip_invisible (pos, &next_boundary, to, window);
1264 if (newpos >= to)
1266 pos = min (to, newpos);
1267 pos_byte = CHAR_TO_BYTE (pos);
1268 goto after_loop;
1271 if (newpos != pos_here)
1273 pos = newpos;
1274 pos_byte = CHAR_TO_BYTE (pos);
1278 /* Handle right margin. */
1279 /* Note on a wide-column character.
1281 Characters are classified into the following three categories
1282 according to the width (columns occupied on screen).
1284 (1) single-column character: ex. `a'
1285 (2) multi-column character: ex. `^A', TAB, `\033'
1286 (3) wide-column character: ex. Japanese character, Chinese character
1287 (In the following example, `W_' stands for them.)
1289 Multi-column characters can be divided around the right margin,
1290 but wide-column characters cannot.
1292 NOTE:
1294 (*) The cursor is placed on the next character after the point.
1296 ----------
1297 abcdefghi\
1298 j ^---- next after the point
1299 ^--- next char. after the point.
1300 ----------
1301 In case of sigle-column character
1303 ----------
1304 abcdefgh\\
1305 033 ^---- next after the point, next char. after the point.
1306 ----------
1307 In case of multi-column character
1309 ----------
1310 abcdefgh\\
1311 W_ ^---- next after the point
1312 ^---- next char. after the point.
1313 ----------
1314 In case of wide-column character
1316 The problem here is continuation at a wide-column character.
1317 In this case, the line may shorter less than WIDTH.
1318 And we find the continuation AFTER it occurs.
1322 if (hpos > width)
1324 int total_width = width + continuation_glyph_width;
1325 int truncate = 0;
1327 if (!NILP (Vtruncate_partial_width_windows)
1328 && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1330 if (INTEGERP (Vtruncate_partial_width_windows))
1331 truncate
1332 = total_width < XFASTINT (Vtruncate_partial_width_windows);
1333 else
1334 truncate = 1;
1337 if (hscroll || truncate
1338 || !NILP (BVAR (current_buffer, truncate_lines)))
1340 /* Truncating: skip to newline, unless we are already past
1341 TO (we need to go back below). */
1342 if (pos <= to)
1344 pos = find_before_next_newline (pos, to, 1);
1345 pos_byte = CHAR_TO_BYTE (pos);
1346 hpos = width;
1347 /* If we just skipped next_boundary,
1348 loop around in the main while
1349 and handle it. */
1350 if (pos >= next_boundary)
1351 next_boundary = pos + 1;
1352 prev_hpos = width;
1353 prev_vpos = vpos;
1354 prev_tab_offset = tab_offset;
1357 else
1359 /* Continuing. */
1360 /* Remember the previous value. */
1361 prev_tab_offset = tab_offset;
1363 if (wide_column_end_hpos > width)
1365 hpos -= prev_hpos;
1366 tab_offset += prev_hpos;
1368 else
1370 tab_offset += width;
1371 hpos -= width;
1373 vpos++;
1374 contin_hpos = prev_hpos;
1375 prev_hpos = 0;
1376 prev_vpos = vpos;
1380 /* Stop if past the target buffer position or screen position. */
1381 if (pos > to)
1383 /* Go back to the previous position. */
1384 pos = prev_pos;
1385 pos_byte = prev_pos_byte;
1386 hpos = prev_hpos;
1387 vpos = prev_vpos;
1388 tab_offset = prev_tab_offset;
1390 /* NOTE on contin_hpos, hpos, and prev_hpos.
1392 ----------
1393 abcdefgh\\
1394 W_ ^---- contin_hpos
1395 | ^----- hpos
1396 \---- prev_hpos
1397 ----------
1400 if (contin_hpos && prev_hpos == 0
1401 && contin_hpos < width && !wide_column_end_hpos)
1403 /* Line breaking occurs in the middle of multi-column
1404 character. Go back to previous line. */
1405 hpos = contin_hpos;
1406 vpos = vpos - 1;
1408 break;
1411 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1413 if (contin_hpos && prev_hpos == 0
1414 && hpos > tohpos
1415 && (contin_hpos == width || wide_column_end_hpos > width))
1416 { /* Line breaks because we can't put the character at the
1417 previous line any more. It is not the multi-column
1418 character continued in middle. Go back to previous
1419 buffer position, screen position, and set tab offset
1420 to previous value. It's the beginning of the
1421 line. */
1422 pos = prev_pos;
1423 pos_byte = prev_pos_byte;
1424 hpos = prev_hpos;
1425 vpos = prev_vpos;
1426 tab_offset = prev_tab_offset;
1428 break;
1430 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1431 break;
1433 prev_hpos = hpos;
1434 prev_vpos = vpos;
1435 prev_pos = pos;
1436 prev_pos_byte = pos_byte;
1437 wide_column_end_hpos = 0;
1439 /* Consult the width run cache to see if we can avoid inspecting
1440 the text character-by-character. */
1441 if (current_buffer->width_run_cache && pos >= next_width_run)
1443 EMACS_INT run_end;
1444 int common_width
1445 = region_cache_forward (current_buffer,
1446 current_buffer->width_run_cache,
1447 pos, &run_end);
1449 /* A width of zero means the character's width varies (like
1450 a tab), is meaningless (like a newline), or we just don't
1451 want to skip over it for some other reason. */
1452 if (common_width != 0)
1454 EMACS_INT run_end_hpos;
1456 /* Don't go past the final buffer posn the user
1457 requested. */
1458 if (run_end > to)
1459 run_end = to;
1461 run_end_hpos = hpos + (run_end - pos) * common_width;
1463 /* Don't go past the final horizontal position the user
1464 requested. */
1465 if (vpos == tovpos && run_end_hpos > tohpos)
1467 run_end = pos + (tohpos - hpos) / common_width;
1468 run_end_hpos = hpos + (run_end - pos) * common_width;
1471 /* Don't go past the margin. */
1472 if (run_end_hpos >= width)
1474 run_end = pos + (width - hpos) / common_width;
1475 run_end_hpos = hpos + (run_end - pos) * common_width;
1478 hpos = run_end_hpos;
1479 if (run_end > pos)
1480 prev_hpos = hpos - common_width;
1481 if (pos != run_end)
1483 pos = run_end;
1484 pos_byte = CHAR_TO_BYTE (pos);
1488 next_width_run = run_end + 1;
1491 /* We have to scan the text character-by-character. */
1492 else
1494 EMACS_INT i, n;
1495 Lisp_Object charvec;
1497 /* Check composition sequence. */
1498 if (cmp_it.id >= 0
1499 || (pos == cmp_it.stop_pos
1500 && composition_reseat_it (&cmp_it, pos, pos_byte, to, win,
1501 NULL, Qnil)))
1502 composition_update_it (&cmp_it, pos, pos_byte, Qnil);
1503 if (cmp_it.id >= 0)
1505 pos += cmp_it.nchars;
1506 pos_byte += cmp_it.nbytes;
1507 hpos += cmp_it.width;
1508 if (cmp_it.to == cmp_it.nglyphs)
1510 cmp_it.id = -1;
1511 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to,
1512 Qnil);
1514 else
1515 cmp_it.from = cmp_it.to;
1516 continue;
1519 c = FETCH_BYTE (pos_byte);
1520 pos++, pos_byte++;
1522 /* Perhaps add some info to the width_run_cache. */
1523 if (current_buffer->width_run_cache)
1525 /* Is this character part of the current run? If so, extend
1526 the run. */
1527 if (pos - 1 == width_run_end
1528 && XFASTINT (width_table[c]) == width_run_width)
1529 width_run_end = pos;
1531 /* The previous run is over, since this is a character at a
1532 different position, or a different width. */
1533 else
1535 /* Have we accumulated a run to put in the cache?
1536 (Currently, we only cache runs of width == 1). */
1537 if (width_run_start < width_run_end
1538 && width_run_width == 1)
1539 know_region_cache (current_buffer,
1540 current_buffer->width_run_cache,
1541 width_run_start, width_run_end);
1543 /* Start recording a new width run. */
1544 width_run_width = XFASTINT (width_table[c]);
1545 width_run_start = pos - 1;
1546 width_run_end = pos;
1550 if (dp != 0
1551 && ! (multibyte && LEADING_CODE_P (c))
1552 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1554 charvec = DISP_CHAR_VECTOR (dp, c);
1555 n = ASIZE (charvec);
1557 else
1559 charvec = Qnil;
1560 n = 1;
1563 for (i = n - 1; i >= 0; --i)
1565 if (VECTORP (charvec))
1567 /* This should be handled the same as
1568 next_element_from_display_vector does it. */
1569 Lisp_Object entry = AREF (charvec, i);
1571 if (GLYPH_CODE_P (entry)
1572 && GLYPH_CODE_CHAR_VALID_P (entry))
1573 c = GLYPH_CODE_CHAR (entry);
1574 else
1575 c = ' ';
1578 if (c >= 040 && c < 0177)
1579 hpos++;
1580 else if (c == '\t')
1582 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1583 % tab_width);
1584 if (tem < 0)
1585 tem += tab_width;
1586 hpos += tab_width - tem;
1588 else if (c == '\n')
1590 if (selective > 0
1591 && indented_beyond_p (pos, pos_byte, selective))
1593 /* If (pos == to), we don't have to take care of
1594 selective display. */
1595 if (pos < to)
1597 /* Skip any number of invisible lines all at once */
1600 pos = find_before_next_newline (pos, to, 1);
1601 if (pos < to)
1602 pos++;
1603 pos_byte = CHAR_TO_BYTE (pos);
1605 while (pos < to
1606 && indented_beyond_p (pos, pos_byte,
1607 selective));
1608 /* Allow for the " ..." that is displayed for them. */
1609 if (selective_rlen)
1611 hpos += selective_rlen;
1612 if (hpos >= width)
1613 hpos = width;
1615 DEC_BOTH (pos, pos_byte);
1616 /* We have skipped the invis text, but not the
1617 newline after. */
1620 else
1622 /* A visible line. */
1623 vpos++;
1624 hpos = 0;
1625 hpos -= hscroll;
1626 /* Count the truncation glyph on column 0 */
1627 if (hscroll > 0)
1628 hpos += continuation_glyph_width;
1629 tab_offset = 0;
1631 contin_hpos = 0;
1633 else if (c == CR && selective < 0)
1635 /* In selective display mode,
1636 everything from a ^M to the end of the line is invisible.
1637 Stop *before* the real newline. */
1638 if (pos < to)
1640 pos = find_before_next_newline (pos, to, 1);
1641 pos_byte = CHAR_TO_BYTE (pos);
1643 /* If we just skipped next_boundary,
1644 loop around in the main while
1645 and handle it. */
1646 if (pos > next_boundary)
1647 next_boundary = pos;
1648 /* Allow for the " ..." that is displayed for them. */
1649 if (selective_rlen)
1651 hpos += selective_rlen;
1652 if (hpos >= width)
1653 hpos = width;
1656 else if (multibyte && LEADING_CODE_P (c))
1658 /* Start of multi-byte form. */
1659 unsigned char *ptr;
1660 int mb_bytes, mb_width, wide_column;
1662 pos_byte--; /* rewind POS_BYTE */
1663 ptr = BYTE_POS_ADDR (pos_byte);
1664 MULTIBYTE_BYTES_WIDTH (ptr, dp, mb_bytes, mb_width);
1665 pos_byte += mb_bytes;
1666 if (wide_column)
1667 wide_column_end_hpos = hpos + wide_column;
1668 hpos += mb_width;
1670 else if (VECTORP (charvec))
1671 ++hpos;
1672 else
1673 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1678 after_loop:
1680 /* Remember any final width run in the cache. */
1681 if (current_buffer->width_run_cache
1682 && width_run_width == 1
1683 && width_run_start < width_run_end)
1684 know_region_cache (current_buffer, current_buffer->width_run_cache,
1685 width_run_start, width_run_end);
1687 val_compute_motion.bufpos = pos;
1688 val_compute_motion.bytepos = pos_byte;
1689 val_compute_motion.hpos = hpos;
1690 val_compute_motion.vpos = vpos;
1691 if (contin_hpos && prev_hpos == 0)
1692 val_compute_motion.prevhpos = contin_hpos;
1693 else
1694 val_compute_motion.prevhpos = prev_hpos;
1695 /* We alalways handle all of them here; none of them remain to do. */
1696 val_compute_motion.ovstring_chars_done = 0;
1698 /* Nonzero if have just continued a line */
1699 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1701 immediate_quit = 0;
1702 return &val_compute_motion;
1706 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1707 doc: /* Scan through the current buffer, calculating screen position.
1708 Scan the current buffer forward from offset FROM,
1709 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1710 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1711 and return the ending buffer position and screen location.
1713 If TOPOS is nil, the actual width and height of the window's
1714 text area are used.
1716 There are three additional arguments:
1718 WIDTH is the number of columns available to display text;
1719 this affects handling of continuation lines. A value of nil
1720 corresponds to the actual number of available text columns.
1722 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1723 HSCROLL is the number of columns not being displayed at the left
1724 margin; this is usually taken from a window's hscroll member.
1725 TAB-OFFSET is the number of columns of the first tab that aren't
1726 being displayed, perhaps because the line was continued within it.
1727 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1729 WINDOW is the window to operate on. It is used to choose the display table;
1730 if it is showing the current buffer, it is used also for
1731 deciding which overlay properties apply.
1732 Note that `compute-motion' always operates on the current buffer.
1734 The value is a list of five elements:
1735 (POS HPOS VPOS PREVHPOS CONTIN)
1736 POS is the buffer position where the scan stopped.
1737 VPOS is the vertical position where the scan stopped.
1738 HPOS is the horizontal position where the scan stopped.
1740 PREVHPOS is the horizontal position one character back from POS.
1741 CONTIN is t if a line was continued after (or within) the previous character.
1743 For example, to find the buffer position of column COL of line LINE
1744 of a certain window, pass the window's starting location as FROM
1745 and the window's upper-left coordinates as FROMPOS.
1746 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1747 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1748 (Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos, Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
1750 struct window *w;
1751 Lisp_Object bufpos, hpos, vpos, prevhpos;
1752 struct position *pos;
1753 int hscroll, tab_offset;
1755 CHECK_NUMBER_COERCE_MARKER (from);
1756 CHECK_CONS (frompos);
1757 CHECK_NUMBER_CAR (frompos);
1758 CHECK_NUMBER_CDR (frompos);
1759 CHECK_NUMBER_COERCE_MARKER (to);
1760 if (!NILP (topos))
1762 CHECK_CONS (topos);
1763 CHECK_NUMBER_CAR (topos);
1764 CHECK_NUMBER_CDR (topos);
1766 if (!NILP (width))
1767 CHECK_NUMBER (width);
1769 if (!NILP (offsets))
1771 CHECK_CONS (offsets);
1772 CHECK_NUMBER_CAR (offsets);
1773 CHECK_NUMBER_CDR (offsets);
1774 hscroll = XINT (XCAR (offsets));
1775 tab_offset = XINT (XCDR (offsets));
1777 else
1778 hscroll = tab_offset = 0;
1780 if (NILP (window))
1781 window = Fselected_window ();
1782 else
1783 CHECK_LIVE_WINDOW (window);
1784 w = XWINDOW (window);
1786 if (XINT (from) < BEGV || XINT (from) > ZV)
1787 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1788 if (XINT (to) < BEGV || XINT (to) > ZV)
1789 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1791 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1792 XINT (XCAR (frompos)), 0,
1793 XINT (to),
1794 (NILP (topos)
1795 ? window_internal_height (w)
1796 : XINT (XCDR (topos))),
1797 (NILP (topos)
1798 ? (window_box_text_cols (w)
1800 #ifdef HAVE_WINDOW_SYSTEM
1801 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1802 #endif
1804 : XINT (XCAR (topos))),
1805 (NILP (width) ? -1 : XINT (width)),
1806 hscroll, tab_offset,
1807 XWINDOW (window));
1809 XSETFASTINT (bufpos, pos->bufpos);
1810 XSETINT (hpos, pos->hpos);
1811 XSETINT (vpos, pos->vpos);
1812 XSETINT (prevhpos, pos->prevhpos);
1814 return Fcons (bufpos,
1815 Fcons (hpos,
1816 Fcons (vpos,
1817 Fcons (prevhpos,
1818 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1822 /* Fvertical_motion and vmotion */
1824 struct position val_vmotion;
1826 struct position *
1827 vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w)
1829 EMACS_INT hscroll = XINT (w->hscroll);
1830 struct position pos;
1831 /* vpos is cumulative vertical position, changed as from is changed */
1832 register int vpos = 0;
1833 EMACS_INT prevline;
1834 register EMACS_INT first;
1835 EMACS_INT from_byte;
1836 EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0;
1837 EMACS_INT selective
1838 = (INTEGERP (BVAR (current_buffer, selective_display))
1839 ? XINT (BVAR (current_buffer, selective_display))
1840 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1841 Lisp_Object window;
1842 EMACS_INT start_hpos = 0;
1843 int did_motion;
1844 /* This is the object we use for fetching character properties. */
1845 Lisp_Object text_prop_object;
1847 XSETWINDOW (window, w);
1849 /* If the window contains this buffer, use it for getting text properties.
1850 Otherwise use the current buffer as arg for doing that. */
1851 if (EQ (w->buffer, Fcurrent_buffer ()))
1852 text_prop_object = window;
1853 else
1854 text_prop_object = Fcurrent_buffer ();
1856 if (vpos >= vtarget)
1858 /* To move upward, go a line at a time until
1859 we have gone at least far enough. */
1861 first = 1;
1863 while ((vpos > vtarget || first) && from > BEGV)
1865 Lisp_Object propval;
1867 prevline = find_next_newline_no_quit (from - 1, -1);
1868 while (prevline > BEGV
1869 && ((selective > 0
1870 && indented_beyond_p (prevline,
1871 CHAR_TO_BYTE (prevline),
1872 selective))
1873 /* Watch out for newlines with `invisible' property.
1874 When moving upward, check the newline before. */
1875 || (propval = Fget_char_property (make_number (prevline - 1),
1876 Qinvisible,
1877 text_prop_object),
1878 TEXT_PROP_MEANS_INVISIBLE (propval))))
1879 prevline = find_next_newline_no_quit (prevline - 1, -1);
1880 pos = *compute_motion (prevline, 0,
1881 lmargin + (prevline == BEG ? start_hpos : 0),
1883 from,
1884 /* Don't care for VPOS... */
1885 1 << (BITS_PER_SHORT - 1),
1886 /* ... nor HPOS. */
1887 1 << (BITS_PER_SHORT - 1),
1888 -1, hscroll,
1889 /* This compensates for start_hpos
1890 so that a tab as first character
1891 still occupies 8 columns. */
1892 (prevline == BEG ? -start_hpos : 0),
1894 vpos -= pos.vpos;
1895 first = 0;
1896 from = prevline;
1899 /* If we made exactly the desired vertical distance,
1900 or if we hit beginning of buffer,
1901 return point found */
1902 if (vpos >= vtarget)
1904 val_vmotion.bufpos = from;
1905 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1906 val_vmotion.vpos = vpos;
1907 val_vmotion.hpos = lmargin;
1908 val_vmotion.contin = 0;
1909 val_vmotion.prevhpos = 0;
1910 val_vmotion.ovstring_chars_done = 0;
1911 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1912 return &val_vmotion;
1915 /* Otherwise find the correct spot by moving down */
1917 /* Moving downward is simple, but must calculate from beg of line
1918 to determine hpos of starting point */
1919 from_byte = CHAR_TO_BYTE (from);
1920 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1922 Lisp_Object propval;
1924 prevline = find_next_newline_no_quit (from, -1);
1925 while (prevline > BEGV
1926 && ((selective > 0
1927 && indented_beyond_p (prevline,
1928 CHAR_TO_BYTE (prevline),
1929 selective))
1930 /* Watch out for newlines with `invisible' property.
1931 When moving downward, check the newline after. */
1932 || (propval = Fget_char_property (make_number (prevline),
1933 Qinvisible,
1934 text_prop_object),
1935 TEXT_PROP_MEANS_INVISIBLE (propval))))
1936 prevline = find_next_newline_no_quit (prevline - 1, -1);
1937 pos = *compute_motion (prevline, 0,
1938 lmargin + (prevline == BEG
1939 ? start_hpos : 0),
1941 from,
1942 /* Don't care for VPOS... */
1943 1 << (BITS_PER_SHORT - 1),
1944 /* ... nor HPOS. */
1945 1 << (BITS_PER_SHORT - 1),
1946 -1, hscroll,
1947 (prevline == BEG ? -start_hpos : 0),
1949 did_motion = 1;
1951 else
1953 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1954 pos.vpos = 0;
1955 pos.tab_offset = 0;
1956 did_motion = 0;
1958 return compute_motion (from, vpos, pos.hpos, did_motion,
1959 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1960 -1, hscroll,
1961 pos.tab_offset - (from == BEG ? start_hpos : 0),
1965 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
1966 doc: /* Move point to start of the screen line LINES lines down.
1967 If LINES is negative, this means moving up.
1969 This function is an ordinary cursor motion function
1970 which calculates the new position based on how text would be displayed.
1971 The new position may be the start of a line,
1972 or just the start of a continuation line.
1973 The function returns number of screen lines moved over;
1974 that usually equals LINES, but may be closer to zero
1975 if beginning or end of buffer was reached.
1977 The optional second argument WINDOW specifies the window to use for
1978 parameters such as width, horizontal scrolling, and so on.
1979 The default is to use the selected window's parameters.
1981 LINES can optionally take the form (COLS . LINES), in which case
1982 the motion will not stop at the start of a screen line but on
1983 its column COLS (if such exists on that line, that is).
1985 `vertical-motion' always uses the current buffer,
1986 regardless of which buffer is displayed in WINDOW.
1987 This is consistent with other cursor motion functions
1988 and makes it possible to use `vertical-motion' in any buffer,
1989 whether or not it is currently displayed in some window. */)
1990 (Lisp_Object lines, Lisp_Object window)
1992 struct it it;
1993 struct text_pos pt;
1994 struct window *w;
1995 Lisp_Object old_buffer;
1996 struct gcpro gcpro1;
1997 Lisp_Object lcols = Qnil;
1998 double cols IF_LINT (= 0);
2000 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
2001 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
2003 lcols = XCAR (lines);
2004 cols = INTEGERP (lcols) ? (double) XINT (lcols) : XFLOAT_DATA (lcols);
2005 lines = XCDR (lines);
2008 CHECK_NUMBER (lines);
2009 if (! NILP (window))
2010 CHECK_WINDOW (window);
2011 else
2012 window = selected_window;
2013 w = XWINDOW (window);
2015 old_buffer = Qnil;
2016 GCPRO1 (old_buffer);
2017 if (XBUFFER (w->buffer) != current_buffer)
2019 /* Set the window's buffer temporarily to the current buffer. */
2020 old_buffer = w->buffer;
2021 XSETBUFFER (w->buffer, current_buffer);
2024 if (noninteractive)
2026 struct position pos;
2027 pos = *vmotion (PT, XINT (lines), w);
2028 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2030 else
2032 int it_start, first_x, it_overshoot_expected IF_LINT (= 0);
2034 SET_TEXT_POS (pt, PT, PT_BYTE);
2035 start_display (&it, w, pt);
2036 first_x = it.first_visible_x;
2037 it_start = IT_CHARPOS (it);
2039 /* See comments below for why we calculate this. */
2040 if (XINT (lines) > 0)
2042 if (it.cmp_it.id >= 0)
2043 it_overshoot_expected = 1;
2044 else if (it.method == GET_FROM_STRING)
2046 const char *s = SSDATA (it.string);
2047 const char *e = s + SBYTES (it.string);
2048 while (s < e && *s != '\n')
2049 ++s;
2050 it_overshoot_expected = (s == e) ? -1 : 0;
2052 else
2053 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2054 || it.method == GET_FROM_STRETCH);
2057 /* Scan from the start of the line containing PT. If we don't
2058 do this, we start moving with IT->current_x == 0, while PT is
2059 really at some x > 0. */
2060 reseat_at_previous_visible_line_start (&it);
2061 it.current_x = it.hpos = 0;
2062 if (IT_CHARPOS (it) != PT)
2063 /* We used to temporarily disable selective display here; the
2064 comment said this is "so we don't move too far" (2005-01-19
2065 checkin by kfs). But this does nothing useful that I can
2066 tell, and it causes Bug#2694 . -- cyd */
2067 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2069 if (XINT (lines) <= 0)
2071 it.vpos = 0;
2072 /* Do this even if LINES is 0, so that we move back to the
2073 beginning of the current line as we ought. */
2074 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2075 move_it_by_lines (&it, XINT (lines), 0);
2077 else
2079 if (IT_CHARPOS (it) > it_start)
2081 /* IT may move too far if truncate-lines is on and PT
2082 lies beyond the right margin. In that case,
2083 backtrack unless the starting point is on an image,
2084 stretch glyph, composition, or Lisp string. */
2085 if (!it_overshoot_expected
2086 /* Also, backtrack if the Lisp string contains no
2087 newline, but there is a newline right after it.
2088 In this case, IT overshoots if there is an
2089 after-string just before the newline. */
2090 || (it_overshoot_expected < 0
2091 && it.method == GET_FROM_BUFFER
2092 && it.c == '\n'))
2093 move_it_by_lines (&it, -1, 0);
2094 it.vpos = 0;
2095 move_it_by_lines (&it, XINT (lines), 0);
2097 else
2099 /* Otherwise, we are at the first row occupied by PT,
2100 which might span multiple screen lines (e.g., if it's
2101 on a multi-line display string). We want to start
2102 from the last line that it occupies. */
2103 if (it_start < ZV)
2105 while (IT_CHARPOS (it) <= it_start)
2107 it.vpos = 0;
2108 move_it_by_lines (&it, 1, 0);
2110 if (XINT (lines) > 1)
2111 move_it_by_lines (&it, XINT (lines) - 1, 0);
2113 else
2115 it.vpos = 0;
2116 move_it_by_lines (&it, XINT (lines), 0);
2121 /* Move to the goal column, if one was specified. */
2122 if (!NILP (lcols))
2124 /* If the window was originally hscrolled, move forward by
2125 the hscrolled amount first. */
2126 if (first_x > 0)
2128 move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X);
2129 it.current_x = 0;
2131 move_it_in_display_line
2132 (&it, ZV,
2133 (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
2134 MOVE_TO_X);
2137 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2140 if (BUFFERP (old_buffer))
2141 w->buffer = old_buffer;
2143 RETURN_UNGCPRO (make_number (it.vpos));
2148 /* File's initialization. */
2150 void
2151 syms_of_indent (void)
2153 DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode,
2154 doc: /* *Indentation can insert tabs if this is non-nil. */);
2155 indent_tabs_mode = 1;
2157 defsubr (&Scurrent_indentation);
2158 defsubr (&Sindent_to);
2159 defsubr (&Scurrent_column);
2160 defsubr (&Smove_to_column);
2161 defsubr (&Svertical_motion);
2162 defsubr (&Scompute_motion);