* font.c: Don't assume string length fits in int.
[emacs.git] / src / indent.c
blob02d99d14ded2263932244884245750fe5e10dd53
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 ASIZE (elt);
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->header.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->header.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 scan_for_column and in
275 compute_motion. */
277 #define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \
278 do { \
279 int ch; \
281 ch = STRING_CHAR_AND_LENGTH (p, bytes); \
282 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
283 width = bytes * 4; \
284 else \
286 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
287 width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \
288 else \
289 width = CHAR_WIDTH (ch); \
291 } while (0)
294 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
295 doc: /* Return the horizontal position of point. Beginning of line is column 0.
296 This is calculated by adding together the widths of all the displayed
297 representations of the character between the start of the previous line
298 and point (eg. control characters will have a width of 2 or 4, tabs
299 will have a variable width).
300 Ignores finite width of frame, which means that this function may return
301 values greater than (frame-width).
302 Whether the line is visible (if `selective-display' is t) has no effect;
303 however, ^M is treated as end of line when `selective-display' is t.
304 Text that has an invisible property is considered as having width 0, unless
305 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
306 (void)
308 Lisp_Object temp;
309 XSETFASTINT (temp, current_column ());
310 return temp;
313 /* Cancel any recorded value of the horizontal position. */
315 void
316 invalidate_current_column (void)
318 last_known_column_point = 0;
321 /* Return a non-outlandish value for the tab width. */
323 static int
324 sane_tab_width (void)
326 EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width));
327 return 0 < n && n <= 1000 ? n : 8;
330 EMACS_INT
331 current_column (void)
333 register EMACS_INT col;
334 register unsigned char *ptr, *stop;
335 register int tab_seen;
336 EMACS_INT post_tab;
337 register int c;
338 int tab_width = sane_tab_width ();
339 int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
340 register struct Lisp_Char_Table *dp = buffer_display_table ();
342 if (PT == last_known_column_point
343 && MODIFF == last_known_column_modified)
344 return last_known_column;
346 /* If the buffer has overlays, text properties,
347 or multibyte characters, use a more general algorithm. */
348 if (BUF_INTERVALS (current_buffer)
349 || current_buffer->overlays_before
350 || current_buffer->overlays_after
351 || Z != Z_BYTE)
352 return current_column_1 ();
354 /* Scan backwards from point to the previous newline,
355 counting width. Tab characters are the only complicated case. */
357 /* Make a pointer for decrementing through the chars before point. */
358 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
359 /* Make a pointer to where consecutive chars leave off,
360 going backwards from point. */
361 if (PT == BEGV)
362 stop = ptr;
363 else if (PT <= GPT || BEGV > GPT)
364 stop = BEGV_ADDR;
365 else
366 stop = GAP_END_ADDR;
368 col = 0, tab_seen = 0, post_tab = 0;
370 while (1)
372 EMACS_INT i, n;
373 Lisp_Object charvec;
375 if (ptr == stop)
377 /* We stopped either for the beginning of the buffer
378 or for the gap. */
379 if (ptr == BEGV_ADDR)
380 break;
382 /* It was the gap. Jump back over it. */
383 stop = BEGV_ADDR;
384 ptr = GPT_ADDR;
386 /* Check whether that brings us to beginning of buffer. */
387 if (BEGV >= GPT)
388 break;
391 c = *--ptr;
393 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
395 charvec = DISP_CHAR_VECTOR (dp, c);
396 n = ASIZE (charvec);
398 else
400 charvec = Qnil;
401 n = 1;
404 for (i = n - 1; i >= 0; --i)
406 if (VECTORP (charvec))
408 /* This should be handled the same as
409 next_element_from_display_vector does it. */
410 Lisp_Object entry = AREF (charvec, i);
412 if (GLYPH_CODE_P (entry)
413 && GLYPH_CODE_CHAR_VALID_P (entry))
414 c = GLYPH_CODE_CHAR (entry);
415 else
416 c = ' ';
419 if (c >= 040 && c < 0177)
420 col++;
421 else if (c == '\n'
422 || (c == '\r'
423 && EQ (BVAR (current_buffer, selective_display), Qt)))
425 ptr++;
426 goto start_of_line_found;
428 else if (c == '\t')
430 if (tab_seen)
431 col = ((col + tab_width) / tab_width) * tab_width;
433 post_tab += col;
434 col = 0;
435 tab_seen = 1;
437 else if (VECTORP (charvec))
438 /* With a display table entry, C is displayed as is, and
439 not displayed as \NNN or as ^N. If C is a single-byte
440 character, it takes one column. If C is multi-byte in
441 an unibyte buffer, it's translated to unibyte, so it
442 also takes one column. */
443 ++col;
444 else
445 col += (ctl_arrow && c < 0200) ? 2 : 4;
449 start_of_line_found:
451 if (tab_seen)
453 col = ((col + tab_width) / tab_width) * tab_width;
454 col += post_tab;
457 if (ptr == BEGV_ADDR)
458 current_column_bol_cache = BEGV;
459 else
460 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
462 last_known_column = col;
463 last_known_column_point = PT;
464 last_known_column_modified = MODIFF;
466 return col;
470 /* Check the presence of a display property and compute its width.
471 If a property was found and its width was found as well, return
472 its width (>= 0) and set the position of the end of the property
473 in ENDPOS.
474 Otherwise just return -1. */
475 static int
476 check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
478 Lisp_Object val, overlay;
480 if (CONSP (val = get_char_property_and_overlay
481 (make_number (pos), Qdisplay, Qnil, &overlay))
482 && EQ (Qspace, XCAR (val)))
483 { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */
484 Lisp_Object plist = XCDR (val), prop;
485 int width = -1;
487 if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop)))
488 width = XINT (prop);
489 else if (FLOATP (prop))
490 width = (int)(XFLOAT_DATA (prop) + 0.5);
491 else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop)))
492 width = XINT (prop) - col;
493 else if (FLOATP (prop))
494 width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
496 if (width >= 0)
498 EMACS_INT start;
499 if (OVERLAYP (overlay))
500 *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
501 else
502 get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
503 return width;
506 return -1;
509 /* Scanning from the beginning of the current line, stop at the buffer
510 position ENDPOS or at the column GOALCOL or at the end of line, whichever
511 comes first.
512 Return the resulting buffer position and column in ENDPOS and GOALCOL.
513 PREVCOL gets set to the column of the previous position (it's always
514 strictly smaller than the goal column). */
515 static void
516 scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
518 int tab_width = sane_tab_width ();
519 register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
520 register struct Lisp_Char_Table *dp = buffer_display_table ();
521 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
522 struct composition_it cmp_it;
523 Lisp_Object window;
524 struct window *w;
526 /* Start the scan at the beginning of this line with column number 0. */
527 register EMACS_INT col = 0, prev_col = 0;
528 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
529 EMACS_INT end = endpos ? *endpos : PT;
530 EMACS_INT scan, scan_byte;
531 EMACS_INT next_boundary;
533 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
534 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
535 current_column_bol_cache = PT;
536 scan = PT, scan_byte = PT_BYTE;
537 SET_PT_BOTH (opoint, opoint_byte);
538 next_boundary = scan;
541 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
542 w = ! NILP (window) ? XWINDOW (window) : NULL;
544 memset (&cmp_it, 0, sizeof cmp_it);
545 cmp_it.id = -1;
546 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
548 /* Scan forward to the target position. */
549 while (scan < end)
551 int c;
553 /* Occasionally we may need to skip invisible text. */
554 while (scan == next_boundary)
556 EMACS_INT old_scan = scan;
557 /* This updates NEXT_BOUNDARY to the next place
558 where we might need to skip more invisible text. */
559 scan = skip_invisible (scan, &next_boundary, end, Qnil);
560 if (scan != old_scan)
561 scan_byte = CHAR_TO_BYTE (scan);
562 if (scan >= end)
563 goto endloop;
566 /* Test reaching the goal column. We do this after skipping
567 invisible characters, so that we put point before the
568 character on which the cursor will appear. */
569 if (col >= goal)
570 break;
571 prev_col = col;
573 { /* Check display property. */
574 EMACS_INT endp;
575 int width = check_display_width (scan, col, &endp);
576 if (width >= 0)
578 col += width;
579 if (endp > scan) /* Avoid infinite loops with 0-width overlays. */
581 scan = endp; scan_byte = charpos_to_bytepos (scan);
582 continue;
587 /* Check composition sequence. */
588 if (cmp_it.id >= 0
589 || (scan == cmp_it.stop_pos
590 && composition_reseat_it (&cmp_it, scan, scan_byte, end,
591 w, NULL, Qnil)))
592 composition_update_it (&cmp_it, scan, scan_byte, Qnil);
593 if (cmp_it.id >= 0)
595 scan += cmp_it.nchars;
596 scan_byte += cmp_it.nbytes;
597 if (scan <= end)
598 col += cmp_it.width;
599 if (cmp_it.to == cmp_it.nglyphs)
601 cmp_it.id = -1;
602 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end,
603 Qnil);
605 else
606 cmp_it.from = cmp_it.to;
607 continue;
610 c = FETCH_BYTE (scan_byte);
612 /* See if there is a display table and it relates
613 to this character. */
615 if (dp != 0
616 && ! (multibyte && LEADING_CODE_P (c))
617 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
619 Lisp_Object charvec;
620 EMACS_INT i, n;
622 /* This character is displayed using a vector of glyphs.
623 Update the column/position based on those glyphs. */
625 charvec = DISP_CHAR_VECTOR (dp, c);
626 n = ASIZE (charvec);
628 for (i = 0; i < n; i++)
630 /* This should be handled the same as
631 next_element_from_display_vector does it. */
632 Lisp_Object entry = AREF (charvec, i);
634 if (GLYPH_CODE_P (entry)
635 && GLYPH_CODE_CHAR_VALID_P (entry))
636 c = GLYPH_CODE_CHAR (entry);
637 else
638 c = ' ';
640 if (c == '\n')
641 goto endloop;
642 if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
643 goto endloop;
644 if (c == '\t')
646 col += tab_width;
647 col = col / tab_width * tab_width;
649 else
650 ++col;
653 else
655 /* The display table doesn't affect this character;
656 it displays as itself. */
658 if (c == '\n')
659 goto endloop;
660 if (c == '\r' && EQ (BVAR (current_buffer, selective_display), Qt))
661 goto endloop;
662 if (c == '\t')
664 col += tab_width;
665 col = col / tab_width * tab_width;
667 else if (multibyte && LEADING_CODE_P (c))
669 /* Start of multi-byte form. */
670 unsigned char *ptr;
671 int bytes, width;
673 ptr = BYTE_POS_ADDR (scan_byte);
674 MULTIBYTE_BYTES_WIDTH (ptr, dp, bytes, width);
675 /* Subtract one to compensate for the increment
676 that is going to happen below. */
677 scan_byte += bytes - 1;
678 col += width;
680 else if (ctl_arrow && (c < 040 || c == 0177))
681 col += 2;
682 else if (c < 040 || c >= 0177)
683 col += 4;
684 else
685 col++;
687 scan++;
688 scan_byte++;
691 endloop:
693 last_known_column = col;
694 last_known_column_point = PT;
695 last_known_column_modified = MODIFF;
697 if (goalcol)
698 *goalcol = col;
699 if (endpos)
700 *endpos = scan;
701 if (prevcol)
702 *prevcol = prev_col;
705 /* Return the column number of position POS
706 by scanning forward from the beginning of the line.
707 This function handles characters that are invisible
708 due to text properties or overlays. */
710 static EMACS_INT
711 current_column_1 (void)
713 EMACS_INT col = MOST_POSITIVE_FIXNUM;
714 EMACS_INT opoint = PT;
716 scan_for_column (&opoint, &col, NULL);
717 return col;
721 #if 0 /* Not used. */
723 /* Return the width in columns of the part of STRING from BEG to END.
724 If BEG is nil, that stands for the beginning of STRING.
725 If END is nil, that stands for the end of STRING. */
727 static double
728 string_display_width (string, beg, end)
729 Lisp_Object string, beg, end;
731 register int col;
732 register unsigned char *ptr, *stop;
733 register int tab_seen;
734 int post_tab;
735 register int c;
736 int tab_width = sane_tab_width ();
737 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
738 register struct Lisp_Char_Table *dp = buffer_display_table ();
739 int b, e;
741 if (NILP (end))
742 e = SCHARS (string);
743 else
745 CHECK_NUMBER (end);
746 e = XINT (end);
749 if (NILP (beg))
750 b = 0;
751 else
753 CHECK_NUMBER (beg);
754 b = XINT (beg);
757 /* Make a pointer for decrementing through the chars before point. */
758 ptr = SDATA (string) + e;
759 /* Make a pointer to where consecutive chars leave off,
760 going backwards from point. */
761 stop = SDATA (string) + b;
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 += ASIZE (DISP_CHAR_VECTOR (dp, c));
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 int tab_width = sane_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 (indent_tabs_mode)
828 Lisp_Object n;
829 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
830 if (XFASTINT (n) != 0)
832 Finsert_char (make_number ('\t'), n, Qt);
834 fromcol = (mincol / tab_width) * tab_width;
838 XSETFASTINT (column, mincol - fromcol);
839 Finsert_char (make_number (' '), column, Qt);
841 last_known_column = mincol;
842 last_known_column_point = PT;
843 last_known_column_modified = MODIFF;
845 XSETINT (column, mincol);
846 return column;
850 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
851 0, 0, 0,
852 doc: /* Return the indentation of the current line.
853 This is the horizontal position of the character
854 following any initial whitespace. */)
855 (void)
857 Lisp_Object val;
858 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
860 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
862 XSETFASTINT (val, position_indentation (PT_BYTE));
863 SET_PT_BOTH (opoint, opoint_byte);
864 return val;
867 static EMACS_INT
868 position_indentation (register int pos_byte)
870 register EMACS_INT column = 0;
871 int tab_width = sane_tab_width ();
872 register unsigned char *p;
873 register unsigned char *stop;
874 unsigned char *start;
875 EMACS_INT next_boundary_byte = pos_byte;
876 EMACS_INT ceiling = next_boundary_byte;
878 p = BYTE_POS_ADDR (pos_byte);
879 /* STOP records the value of P at which we will need
880 to think about the gap, or about invisible text,
881 or about the end of the buffer. */
882 stop = p;
883 /* START records the starting value of P. */
884 start = p;
885 while (1)
887 while (p == stop)
889 EMACS_INT stop_pos_byte;
891 /* If we have updated P, set POS_BYTE to match.
892 The first time we enter the loop, POS_BYTE is already right. */
893 if (p != start)
894 pos_byte = PTR_BYTE_POS (p);
895 /* Consider the various reasons STOP might have been set here. */
896 if (pos_byte == ZV_BYTE)
897 return column;
898 if (pos_byte == next_boundary_byte)
900 EMACS_INT next_boundary;
901 EMACS_INT pos = BYTE_TO_CHAR (pos_byte);
902 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
903 pos_byte = CHAR_TO_BYTE (pos);
904 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
906 if (pos_byte >= ceiling)
907 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
908 /* Compute the next place we need to stop and think,
909 and set STOP accordingly. */
910 stop_pos_byte = min (ceiling, next_boundary_byte);
911 /* The -1 and +1 arrange to point at the first byte of gap
912 (if STOP_POS_BYTE is the position of the gap)
913 rather than at the data after the gap. */
915 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
916 p = BYTE_POS_ADDR (pos_byte);
918 switch (*p++)
920 case 0240:
921 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
922 return column;
923 case ' ':
924 column++;
925 break;
926 case '\t':
927 column += tab_width - column % tab_width;
928 break;
929 default:
930 if (ASCII_BYTE_P (p[-1])
931 || NILP (BVAR (current_buffer, enable_multibyte_characters)))
932 return column;
934 int c;
935 pos_byte = PTR_BYTE_POS (p - 1);
936 c = FETCH_MULTIBYTE_CHAR (pos_byte);
937 if (CHAR_HAS_CATEGORY (c, ' '))
939 column++;
940 INC_POS (pos_byte);
941 p = BYTE_POS_ADDR (pos_byte);
943 else
944 return column;
950 /* Test whether the line beginning at POS is indented beyond COLUMN.
951 Blank lines are treated as if they had the same indentation as the
952 preceding line. */
955 indented_beyond_p (EMACS_INT pos, EMACS_INT pos_byte, EMACS_INT column)
957 EMACS_INT val;
958 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
960 SET_PT_BOTH (pos, pos_byte);
961 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
962 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
964 val = position_indentation (PT_BYTE);
965 SET_PT_BOTH (opoint, opoint_byte);
966 return val >= column;
969 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
970 doc: /* Move point to column COLUMN in the current line.
971 Interactively, COLUMN is the value of prefix numeric argument.
972 The column of a character is calculated by adding together the widths
973 as displayed of the previous characters in the line.
974 This function ignores line-continuation;
975 there is no upper limit on the column number a character can have
976 and horizontal scrolling has no effect.
978 If specified column is within a character, point goes after that character.
979 If it's past end of line, point goes to end of line.
981 Optional second argument FORCE non-nil means if COLUMN is in the
982 middle of a tab character, change it to spaces.
983 In addition, if FORCE is t, and the line is too short to reach
984 COLUMN, add spaces/tabs to get there.
986 The return value is the current column. */)
987 (Lisp_Object column, Lisp_Object force)
989 EMACS_INT pos;
990 EMACS_INT col, prev_col;
991 EMACS_INT goal;
993 CHECK_NATNUM (column);
994 goal = XINT (column);
996 col = goal;
997 pos = ZV;
998 scan_for_column (&pos, &col, &prev_col);
1000 SET_PT (pos);
1002 /* If a tab char made us overshoot, change it to spaces
1003 and scan through it again. */
1004 if (!NILP (force) && col > goal)
1006 int c;
1007 EMACS_INT pos_byte = PT_BYTE;
1009 DEC_POS (pos_byte);
1010 c = FETCH_CHAR (pos_byte);
1011 if (c == '\t' && prev_col < goal)
1013 EMACS_INT goal_pt, goal_pt_byte;
1015 /* Insert spaces in front of the tab to reach GOAL. Do this
1016 first so that a marker at the end of the tab gets
1017 adjusted. */
1018 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1019 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1021 /* Now delete the tab, and indent to COL. */
1022 del_range (PT, PT + 1);
1023 goal_pt = PT;
1024 goal_pt_byte = PT_BYTE;
1025 Findent_to (make_number (col), Qnil);
1026 SET_PT_BOTH (goal_pt, goal_pt_byte);
1028 /* Set the last_known... vars consistently. */
1029 col = goal;
1033 /* If line ends prematurely, add space to the end. */
1034 if (col < goal && EQ (force, Qt))
1035 Findent_to (make_number (col = goal), Qnil);
1037 last_known_column = col;
1038 last_known_column_point = PT;
1039 last_known_column_modified = MODIFF;
1041 return make_number (col);
1044 /* compute_motion: compute buffer posn given screen posn and vice versa */
1046 static struct position val_compute_motion;
1048 /* Scan the current buffer forward from offset FROM, pretending that
1049 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1050 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1051 and return the ending buffer position and screen location. If we
1052 can't hit the requested column exactly (because of a tab or other
1053 multi-column character), overshoot.
1055 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1056 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1057 earlier call to compute_motion. The other common case is that FROMHPOS
1058 is zero and FROM is a position that "belongs" at column zero, but might
1059 be shifted by overlay strings; in this case DID_MOTION should be 0.
1061 WIDTH is the number of columns available to display text;
1062 compute_motion uses this to handle continuation lines and such.
1063 If WIDTH is -1, use width of window's text area adjusted for
1064 continuation glyph when needed.
1066 HSCROLL is the number of columns not being displayed at the left
1067 margin; this is usually taken from a window's hscroll member.
1068 TAB_OFFSET is the number of columns of the first tab that aren't
1069 being displayed, perhaps because of a continuation line or
1070 something.
1072 compute_motion returns a pointer to a struct position. The bufpos
1073 member gives the buffer position at the end of the scan, and hpos
1074 and vpos give its cartesian location. prevhpos is the column at
1075 which the character before bufpos started, and contin is non-zero
1076 if we reached the current line by continuing the previous.
1078 Note that FROMHPOS and TOHPOS should be expressed in real screen
1079 columns, taking HSCROLL and the truncation glyph at the left margin
1080 into account. That is, beginning-of-line moves you to the hpos
1081 -HSCROLL + (HSCROLL > 0).
1083 For example, to find the buffer position of column COL of line LINE
1084 of a certain window, pass the window's starting location as FROM
1085 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1086 Pass the buffer's ZV as TO, to limit the scan to the end of the
1087 visible section of the buffer, and pass LINE and COL as TOVPOS and
1088 TOHPOS.
1090 When displaying in window w, a typical formula for WIDTH is:
1092 window_width - 1
1093 - (has_vertical_scroll_bars
1094 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1095 : (window_width + window_left != frame_cols))
1097 where
1098 window_width is XFASTINT (w->total_cols),
1099 window_left is XFASTINT (w->left_col),
1100 has_vertical_scroll_bars is
1101 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1102 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1104 Or you can let window_body_cols do this all for you, and write:
1105 window_body_cols (w) - 1
1107 The `-1' accounts for the continuation-line backslashes; the rest
1108 accounts for window borders if the window is split horizontally, and
1109 the scroll bars if they are turned on. */
1111 struct position *
1112 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)
1114 register EMACS_INT hpos = fromhpos;
1115 register EMACS_INT vpos = fromvpos;
1117 register EMACS_INT pos;
1118 EMACS_INT pos_byte;
1119 register int c = 0;
1120 int tab_width = sane_tab_width ();
1121 register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
1122 register struct Lisp_Char_Table *dp = window_display_table (win);
1123 EMACS_INT selective
1124 = (INTEGERP (BVAR (current_buffer, selective_display))
1125 ? XINT (BVAR (current_buffer, selective_display))
1126 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1127 int selective_rlen
1128 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1129 ? ASIZE (DISP_INVIS_VECTOR (dp)) : 0);
1130 /* The next location where the `invisible' property changes, or an
1131 overlay starts or ends. */
1132 EMACS_INT next_boundary = from;
1134 /* For computing runs of characters with similar widths.
1135 Invariant: width_run_width is zero, or all the characters
1136 from width_run_start to width_run_end have a fixed width of
1137 width_run_width. */
1138 EMACS_INT width_run_start = from;
1139 EMACS_INT width_run_end = from;
1140 EMACS_INT width_run_width = 0;
1141 Lisp_Object *width_table;
1142 Lisp_Object buffer;
1144 /* The next buffer pos where we should consult the width run cache. */
1145 EMACS_INT next_width_run = from;
1146 Lisp_Object window;
1148 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
1149 /* If previous char scanned was a wide character,
1150 this is the column where it ended. Otherwise, this is 0. */
1151 EMACS_INT wide_column_end_hpos = 0;
1152 EMACS_INT prev_pos; /* Previous buffer position. */
1153 EMACS_INT prev_pos_byte; /* Previous buffer position. */
1154 EMACS_INT prev_hpos = 0;
1155 EMACS_INT prev_vpos = 0;
1156 EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
1157 EMACS_INT prev_tab_offset; /* Previous tab offset. */
1158 EMACS_INT continuation_glyph_width;
1160 struct composition_it cmp_it;
1162 XSETBUFFER (buffer, current_buffer);
1163 XSETWINDOW (window, win);
1165 width_run_cache_on_off ();
1166 if (dp == buffer_display_table ())
1167 width_table = (VECTORP (BVAR (current_buffer, width_table))
1168 ? XVECTOR (BVAR (current_buffer, width_table))->contents
1169 : 0);
1170 else
1171 /* If the window has its own display table, we can't use the width
1172 run cache, because that's based on the buffer's display table. */
1173 width_table = 0;
1175 /* Negative width means use all available text columns. */
1176 if (width < 0)
1178 width = window_body_cols (win);
1179 /* We must make room for continuation marks if we don't have fringes. */
1180 #ifdef HAVE_WINDOW_SYSTEM
1181 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1182 #endif
1183 width -= 1;
1186 continuation_glyph_width = 1;
1187 #ifdef HAVE_WINDOW_SYSTEM
1188 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1189 continuation_glyph_width = 0; /* In the fringe. */
1190 #endif
1192 immediate_quit = 1;
1193 QUIT;
1195 pos = prev_pos = from;
1196 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1197 contin_hpos = 0;
1198 prev_tab_offset = tab_offset;
1199 memset (&cmp_it, 0, sizeof cmp_it);
1200 cmp_it.id = -1;
1201 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil);
1203 while (1)
1205 while (pos == next_boundary)
1207 EMACS_INT pos_here = pos;
1208 EMACS_INT newpos;
1210 /* Don't skip invisible if we are already at the margin. */
1211 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1213 if (contin_hpos && prev_hpos == 0
1214 && hpos > tohpos
1215 && (contin_hpos == width || wide_column_end_hpos > width))
1216 { /* Line breaks because we can't put the character at the
1217 previous line any more. It is not the multi-column
1218 character continued in middle. Go back to previous
1219 buffer position, screen position, and set tab offset
1220 to previous value. It's the beginning of the
1221 line. */
1222 pos = prev_pos;
1223 pos_byte = prev_pos_byte;
1224 hpos = prev_hpos;
1225 vpos = prev_vpos;
1226 tab_offset = prev_tab_offset;
1228 break;
1231 /* If the caller says that the screen position came from an earlier
1232 call to compute_motion, then we've already accounted for the
1233 overlay strings at point. This is only true the first time
1234 through, so clear the flag after testing it. */
1235 if (!did_motion)
1236 /* We need to skip past the overlay strings. Currently those
1237 strings must not contain TAB;
1238 if we want to relax that restriction, something will have
1239 to be changed here. */
1241 unsigned char *ovstr;
1242 EMACS_INT ovlen = overlay_strings (pos, win, &ovstr);
1243 hpos += ((multibyte && ovlen > 0)
1244 ? strwidth ((char *) ovstr, ovlen) : ovlen);
1246 did_motion = 0;
1248 if (pos >= to)
1249 break;
1251 /* Advance POS past invisible characters
1252 (but not necessarily all that there are here),
1253 and store in next_boundary the next position where
1254 we need to call skip_invisible. */
1255 newpos = skip_invisible (pos, &next_boundary, to, window);
1257 if (newpos >= to)
1259 pos = min (to, newpos);
1260 pos_byte = CHAR_TO_BYTE (pos);
1261 goto after_loop;
1264 if (newpos != pos_here)
1266 pos = newpos;
1267 pos_byte = CHAR_TO_BYTE (pos);
1271 /* Handle right margin. */
1272 /* Note on a wide-column character.
1274 Characters are classified into the following three categories
1275 according to the width (columns occupied on screen).
1277 (1) single-column character: ex. `a'
1278 (2) multi-column character: ex. `^A', TAB, `\033'
1279 (3) wide-column character: ex. Japanese character, Chinese character
1280 (In the following example, `W_' stands for them.)
1282 Multi-column characters can be divided around the right margin,
1283 but wide-column characters cannot.
1285 NOTE:
1287 (*) The cursor is placed on the next character after the point.
1289 ----------
1290 abcdefghi\
1291 j ^---- next after the point
1292 ^--- next char. after the point.
1293 ----------
1294 In case of sigle-column character
1296 ----------
1297 abcdefgh\\
1298 033 ^---- next after the point, next char. after the point.
1299 ----------
1300 In case of multi-column character
1302 ----------
1303 abcdefgh\\
1304 W_ ^---- next after the point
1305 ^---- next char. after the point.
1306 ----------
1307 In case of wide-column character
1309 The problem here is continuation at a wide-column character.
1310 In this case, the line may shorter less than WIDTH.
1311 And we find the continuation AFTER it occurs.
1315 if (hpos > width)
1317 int total_width = width + continuation_glyph_width;
1318 int truncate = 0;
1320 if (!NILP (Vtruncate_partial_width_windows)
1321 && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1323 if (INTEGERP (Vtruncate_partial_width_windows))
1324 truncate
1325 = total_width < XFASTINT (Vtruncate_partial_width_windows);
1326 else
1327 truncate = 1;
1330 if (hscroll || truncate
1331 || !NILP (BVAR (current_buffer, truncate_lines)))
1333 /* Truncating: skip to newline, unless we are already past
1334 TO (we need to go back below). */
1335 if (pos <= to)
1337 pos = find_before_next_newline (pos, to, 1);
1338 pos_byte = CHAR_TO_BYTE (pos);
1339 hpos = width;
1340 /* If we just skipped next_boundary,
1341 loop around in the main while
1342 and handle it. */
1343 if (pos >= next_boundary)
1344 next_boundary = pos + 1;
1345 prev_hpos = width;
1346 prev_vpos = vpos;
1347 prev_tab_offset = tab_offset;
1350 else
1352 /* Continuing. */
1353 /* Remember the previous value. */
1354 prev_tab_offset = tab_offset;
1356 if (wide_column_end_hpos > width)
1358 hpos -= prev_hpos;
1359 tab_offset += prev_hpos;
1361 else
1363 tab_offset += width;
1364 hpos -= width;
1366 vpos++;
1367 contin_hpos = prev_hpos;
1368 prev_hpos = 0;
1369 prev_vpos = vpos;
1373 /* Stop if past the target buffer position or screen position. */
1374 if (pos > to)
1376 /* Go back to the previous position. */
1377 pos = prev_pos;
1378 pos_byte = prev_pos_byte;
1379 hpos = prev_hpos;
1380 vpos = prev_vpos;
1381 tab_offset = prev_tab_offset;
1383 /* NOTE on contin_hpos, hpos, and prev_hpos.
1385 ----------
1386 abcdefgh\\
1387 W_ ^---- contin_hpos
1388 | ^----- hpos
1389 \---- prev_hpos
1390 ----------
1393 if (contin_hpos && prev_hpos == 0
1394 && contin_hpos < width && !wide_column_end_hpos)
1396 /* Line breaking occurs in the middle of multi-column
1397 character. Go back to previous line. */
1398 hpos = contin_hpos;
1399 vpos = vpos - 1;
1401 break;
1404 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1406 if (contin_hpos && prev_hpos == 0
1407 && hpos > tohpos
1408 && (contin_hpos == width || wide_column_end_hpos > width))
1409 { /* Line breaks because we can't put the character at the
1410 previous line any more. It is not the multi-column
1411 character continued in middle. Go back to previous
1412 buffer position, screen position, and set tab offset
1413 to previous value. It's the beginning of the
1414 line. */
1415 pos = prev_pos;
1416 pos_byte = prev_pos_byte;
1417 hpos = prev_hpos;
1418 vpos = prev_vpos;
1419 tab_offset = prev_tab_offset;
1421 break;
1423 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1424 break;
1426 prev_hpos = hpos;
1427 prev_vpos = vpos;
1428 prev_pos = pos;
1429 prev_pos_byte = pos_byte;
1430 wide_column_end_hpos = 0;
1432 /* Consult the width run cache to see if we can avoid inspecting
1433 the text character-by-character. */
1434 if (current_buffer->width_run_cache && pos >= next_width_run)
1436 EMACS_INT run_end;
1437 int common_width
1438 = region_cache_forward (current_buffer,
1439 current_buffer->width_run_cache,
1440 pos, &run_end);
1442 /* A width of zero means the character's width varies (like
1443 a tab), is meaningless (like a newline), or we just don't
1444 want to skip over it for some other reason. */
1445 if (common_width != 0)
1447 EMACS_INT run_end_hpos;
1449 /* Don't go past the final buffer posn the user
1450 requested. */
1451 if (run_end > to)
1452 run_end = to;
1454 run_end_hpos = hpos + (run_end - pos) * common_width;
1456 /* Don't go past the final horizontal position the user
1457 requested. */
1458 if (vpos == tovpos && run_end_hpos > tohpos)
1460 run_end = pos + (tohpos - hpos) / common_width;
1461 run_end_hpos = hpos + (run_end - pos) * common_width;
1464 /* Don't go past the margin. */
1465 if (run_end_hpos >= width)
1467 run_end = pos + (width - hpos) / common_width;
1468 run_end_hpos = hpos + (run_end - pos) * common_width;
1471 hpos = run_end_hpos;
1472 if (run_end > pos)
1473 prev_hpos = hpos - common_width;
1474 if (pos != run_end)
1476 pos = run_end;
1477 pos_byte = CHAR_TO_BYTE (pos);
1481 next_width_run = run_end + 1;
1484 /* We have to scan the text character-by-character. */
1485 else
1487 EMACS_INT i, n;
1488 Lisp_Object charvec;
1490 /* Check composition sequence. */
1491 if (cmp_it.id >= 0
1492 || (pos == cmp_it.stop_pos
1493 && composition_reseat_it (&cmp_it, pos, pos_byte, to, win,
1494 NULL, Qnil)))
1495 composition_update_it (&cmp_it, pos, pos_byte, Qnil);
1496 if (cmp_it.id >= 0)
1498 pos += cmp_it.nchars;
1499 pos_byte += cmp_it.nbytes;
1500 hpos += cmp_it.width;
1501 if (cmp_it.to == cmp_it.nglyphs)
1503 cmp_it.id = -1;
1504 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to,
1505 Qnil);
1507 else
1508 cmp_it.from = cmp_it.to;
1509 continue;
1512 c = FETCH_BYTE (pos_byte);
1513 pos++, pos_byte++;
1515 /* Perhaps add some info to the width_run_cache. */
1516 if (current_buffer->width_run_cache)
1518 /* Is this character part of the current run? If so, extend
1519 the run. */
1520 if (pos - 1 == width_run_end
1521 && XFASTINT (width_table[c]) == width_run_width)
1522 width_run_end = pos;
1524 /* The previous run is over, since this is a character at a
1525 different position, or a different width. */
1526 else
1528 /* Have we accumulated a run to put in the cache?
1529 (Currently, we only cache runs of width == 1). */
1530 if (width_run_start < width_run_end
1531 && width_run_width == 1)
1532 know_region_cache (current_buffer,
1533 current_buffer->width_run_cache,
1534 width_run_start, width_run_end);
1536 /* Start recording a new width run. */
1537 width_run_width = XFASTINT (width_table[c]);
1538 width_run_start = pos - 1;
1539 width_run_end = pos;
1543 if (dp != 0
1544 && ! (multibyte && LEADING_CODE_P (c))
1545 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1547 charvec = DISP_CHAR_VECTOR (dp, c);
1548 n = ASIZE (charvec);
1550 else
1552 charvec = Qnil;
1553 n = 1;
1556 for (i = n - 1; i >= 0; --i)
1558 if (VECTORP (charvec))
1560 /* This should be handled the same as
1561 next_element_from_display_vector does it. */
1562 Lisp_Object entry = AREF (charvec, i);
1564 if (GLYPH_CODE_P (entry)
1565 && GLYPH_CODE_CHAR_VALID_P (entry))
1566 c = GLYPH_CODE_CHAR (entry);
1567 else
1568 c = ' ';
1571 if (c >= 040 && c < 0177)
1572 hpos++;
1573 else if (c == '\t')
1575 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1576 % tab_width);
1577 if (tem < 0)
1578 tem += tab_width;
1579 hpos += tab_width - tem;
1581 else if (c == '\n')
1583 if (selective > 0
1584 && indented_beyond_p (pos, pos_byte, selective))
1586 /* If (pos == to), we don't have to take care of
1587 selective display. */
1588 if (pos < to)
1590 /* Skip any number of invisible lines all at once */
1593 pos = find_before_next_newline (pos, to, 1);
1594 if (pos < to)
1595 pos++;
1596 pos_byte = CHAR_TO_BYTE (pos);
1598 while (pos < to
1599 && indented_beyond_p (pos, pos_byte,
1600 selective));
1601 /* Allow for the " ..." that is displayed for them. */
1602 if (selective_rlen)
1604 hpos += selective_rlen;
1605 if (hpos >= width)
1606 hpos = width;
1608 DEC_BOTH (pos, pos_byte);
1609 /* We have skipped the invis text, but not the
1610 newline after. */
1613 else
1615 /* A visible line. */
1616 vpos++;
1617 hpos = 0;
1618 hpos -= hscroll;
1619 /* Count the truncation glyph on column 0 */
1620 if (hscroll > 0)
1621 hpos += continuation_glyph_width;
1622 tab_offset = 0;
1624 contin_hpos = 0;
1626 else if (c == CR && selective < 0)
1628 /* In selective display mode,
1629 everything from a ^M to the end of the line is invisible.
1630 Stop *before* the real newline. */
1631 if (pos < to)
1633 pos = find_before_next_newline (pos, to, 1);
1634 pos_byte = CHAR_TO_BYTE (pos);
1636 /* If we just skipped next_boundary,
1637 loop around in the main while
1638 and handle it. */
1639 if (pos > next_boundary)
1640 next_boundary = pos;
1641 /* Allow for the " ..." that is displayed for them. */
1642 if (selective_rlen)
1644 hpos += selective_rlen;
1645 if (hpos >= width)
1646 hpos = width;
1649 else if (multibyte && LEADING_CODE_P (c))
1651 /* Start of multi-byte form. */
1652 unsigned char *ptr;
1653 int mb_bytes, mb_width;
1655 pos_byte--; /* rewind POS_BYTE */
1656 ptr = BYTE_POS_ADDR (pos_byte);
1657 MULTIBYTE_BYTES_WIDTH (ptr, dp, mb_bytes, mb_width);
1658 pos_byte += mb_bytes;
1659 if (mb_width > 1 && BYTES_BY_CHAR_HEAD (*ptr) == mb_bytes)
1660 wide_column_end_hpos = hpos + mb_width;
1661 hpos += mb_width;
1663 else if (VECTORP (charvec))
1664 ++hpos;
1665 else
1666 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1671 after_loop:
1673 /* Remember any final width run in the cache. */
1674 if (current_buffer->width_run_cache
1675 && width_run_width == 1
1676 && width_run_start < width_run_end)
1677 know_region_cache (current_buffer, current_buffer->width_run_cache,
1678 width_run_start, width_run_end);
1680 val_compute_motion.bufpos = pos;
1681 val_compute_motion.bytepos = pos_byte;
1682 val_compute_motion.hpos = hpos;
1683 val_compute_motion.vpos = vpos;
1684 if (contin_hpos && prev_hpos == 0)
1685 val_compute_motion.prevhpos = contin_hpos;
1686 else
1687 val_compute_motion.prevhpos = prev_hpos;
1688 /* We alalways handle all of them here; none of them remain to do. */
1689 val_compute_motion.ovstring_chars_done = 0;
1691 /* Nonzero if have just continued a line */
1692 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1694 immediate_quit = 0;
1695 return &val_compute_motion;
1699 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1700 doc: /* Scan through the current buffer, calculating screen position.
1701 Scan the current buffer forward from offset FROM,
1702 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1703 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1704 and return the ending buffer position and screen location.
1706 If TOPOS is nil, the actual width and height of the window's
1707 text area are used.
1709 There are three additional arguments:
1711 WIDTH is the number of columns available to display text;
1712 this affects handling of continuation lines. A value of nil
1713 corresponds to the actual number of available text columns.
1715 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1716 HSCROLL is the number of columns not being displayed at the left
1717 margin; this is usually taken from a window's hscroll member.
1718 TAB-OFFSET is the number of columns of the first tab that aren't
1719 being displayed, perhaps because the line was continued within it.
1720 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1722 WINDOW is the window to operate on. It is used to choose the display table;
1723 if it is showing the current buffer, it is used also for
1724 deciding which overlay properties apply.
1725 Note that `compute-motion' always operates on the current buffer.
1727 The value is a list of five elements:
1728 (POS HPOS VPOS PREVHPOS CONTIN)
1729 POS is the buffer position where the scan stopped.
1730 VPOS is the vertical position where the scan stopped.
1731 HPOS is the horizontal position where the scan stopped.
1733 PREVHPOS is the horizontal position one character back from POS.
1734 CONTIN is t if a line was continued after (or within) the previous character.
1736 For example, to find the buffer position of column COL of line LINE
1737 of a certain window, pass the window's starting location as FROM
1738 and the window's upper-left coordinates as FROMPOS.
1739 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1740 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1741 (Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos, Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
1743 struct window *w;
1744 Lisp_Object bufpos, hpos, vpos, prevhpos;
1745 struct position *pos;
1746 EMACS_INT hscroll, tab_offset;
1748 CHECK_NUMBER_COERCE_MARKER (from);
1749 CHECK_CONS (frompos);
1750 CHECK_NUMBER_CAR (frompos);
1751 CHECK_NUMBER_CDR (frompos);
1752 CHECK_NUMBER_COERCE_MARKER (to);
1753 if (!NILP (topos))
1755 CHECK_CONS (topos);
1756 CHECK_NUMBER_CAR (topos);
1757 CHECK_NUMBER_CDR (topos);
1759 if (!NILP (width))
1760 CHECK_NUMBER (width);
1762 if (!NILP (offsets))
1764 CHECK_CONS (offsets);
1765 CHECK_NUMBER_CAR (offsets);
1766 CHECK_NUMBER_CDR (offsets);
1767 hscroll = XINT (XCAR (offsets));
1768 tab_offset = XINT (XCDR (offsets));
1770 else
1771 hscroll = tab_offset = 0;
1773 if (NILP (window))
1774 window = Fselected_window ();
1775 else
1776 CHECK_LIVE_WINDOW (window);
1777 w = XWINDOW (window);
1779 if (XINT (from) < BEGV || XINT (from) > ZV)
1780 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1781 if (XINT (to) < BEGV || XINT (to) > ZV)
1782 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1784 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1785 XINT (XCAR (frompos)), 0,
1786 XINT (to),
1787 (NILP (topos)
1788 ? window_internal_height (w)
1789 : XINT (XCDR (topos))),
1790 (NILP (topos)
1791 ? (window_body_cols (w)
1793 #ifdef HAVE_WINDOW_SYSTEM
1794 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1795 #endif
1797 : XINT (XCAR (topos))),
1798 (NILP (width) ? -1 : XINT (width)),
1799 hscroll, tab_offset,
1800 XWINDOW (window));
1802 XSETFASTINT (bufpos, pos->bufpos);
1803 XSETINT (hpos, pos->hpos);
1804 XSETINT (vpos, pos->vpos);
1805 XSETINT (prevhpos, pos->prevhpos);
1807 return Fcons (bufpos,
1808 Fcons (hpos,
1809 Fcons (vpos,
1810 Fcons (prevhpos,
1811 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1815 /* Fvertical_motion and vmotion */
1817 static struct position val_vmotion;
1819 struct position *
1820 vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w)
1822 EMACS_INT hscroll = XINT (w->hscroll);
1823 struct position pos;
1824 /* vpos is cumulative vertical position, changed as from is changed */
1825 register int vpos = 0;
1826 EMACS_INT prevline;
1827 register EMACS_INT first;
1828 EMACS_INT from_byte;
1829 EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0;
1830 EMACS_INT selective
1831 = (INTEGERP (BVAR (current_buffer, selective_display))
1832 ? XINT (BVAR (current_buffer, selective_display))
1833 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1834 Lisp_Object window;
1835 EMACS_INT start_hpos = 0;
1836 int did_motion;
1837 /* This is the object we use for fetching character properties. */
1838 Lisp_Object text_prop_object;
1840 XSETWINDOW (window, w);
1842 /* If the window contains this buffer, use it for getting text properties.
1843 Otherwise use the current buffer as arg for doing that. */
1844 if (EQ (w->buffer, Fcurrent_buffer ()))
1845 text_prop_object = window;
1846 else
1847 text_prop_object = Fcurrent_buffer ();
1849 if (vpos >= vtarget)
1851 /* To move upward, go a line at a time until
1852 we have gone at least far enough. */
1854 first = 1;
1856 while ((vpos > vtarget || first) && from > BEGV)
1858 Lisp_Object propval;
1860 prevline = find_next_newline_no_quit (from - 1, -1);
1861 while (prevline > BEGV
1862 && ((selective > 0
1863 && indented_beyond_p (prevline,
1864 CHAR_TO_BYTE (prevline),
1865 selective))
1866 /* Watch out for newlines with `invisible' property.
1867 When moving upward, check the newline before. */
1868 || (propval = Fget_char_property (make_number (prevline - 1),
1869 Qinvisible,
1870 text_prop_object),
1871 TEXT_PROP_MEANS_INVISIBLE (propval))))
1872 prevline = find_next_newline_no_quit (prevline - 1, -1);
1873 pos = *compute_motion (prevline, 0,
1874 lmargin + (prevline == BEG ? start_hpos : 0),
1876 from,
1877 /* Don't care for VPOS... */
1878 1 << (BITS_PER_SHORT - 1),
1879 /* ... nor HPOS. */
1880 1 << (BITS_PER_SHORT - 1),
1881 -1, hscroll,
1882 /* This compensates for start_hpos
1883 so that a tab as first character
1884 still occupies 8 columns. */
1885 (prevline == BEG ? -start_hpos : 0),
1887 vpos -= pos.vpos;
1888 first = 0;
1889 from = prevline;
1892 /* If we made exactly the desired vertical distance,
1893 or if we hit beginning of buffer,
1894 return point found */
1895 if (vpos >= vtarget)
1897 val_vmotion.bufpos = from;
1898 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1899 val_vmotion.vpos = vpos;
1900 val_vmotion.hpos = lmargin;
1901 val_vmotion.contin = 0;
1902 val_vmotion.prevhpos = 0;
1903 val_vmotion.ovstring_chars_done = 0;
1904 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1905 return &val_vmotion;
1908 /* Otherwise find the correct spot by moving down */
1910 /* Moving downward is simple, but must calculate from beg of line
1911 to determine hpos of starting point */
1912 from_byte = CHAR_TO_BYTE (from);
1913 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1915 Lisp_Object propval;
1917 prevline = find_next_newline_no_quit (from, -1);
1918 while (prevline > BEGV
1919 && ((selective > 0
1920 && indented_beyond_p (prevline,
1921 CHAR_TO_BYTE (prevline),
1922 selective))
1923 /* Watch out for newlines with `invisible' property.
1924 When moving downward, check the newline after. */
1925 || (propval = Fget_char_property (make_number (prevline),
1926 Qinvisible,
1927 text_prop_object),
1928 TEXT_PROP_MEANS_INVISIBLE (propval))))
1929 prevline = find_next_newline_no_quit (prevline - 1, -1);
1930 pos = *compute_motion (prevline, 0,
1931 lmargin + (prevline == BEG
1932 ? start_hpos : 0),
1934 from,
1935 /* Don't care for VPOS... */
1936 1 << (BITS_PER_SHORT - 1),
1937 /* ... nor HPOS. */
1938 1 << (BITS_PER_SHORT - 1),
1939 -1, hscroll,
1940 (prevline == BEG ? -start_hpos : 0),
1942 did_motion = 1;
1944 else
1946 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1947 pos.vpos = 0;
1948 pos.tab_offset = 0;
1949 did_motion = 0;
1951 return compute_motion (from, vpos, pos.hpos, did_motion,
1952 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1953 -1, hscroll,
1954 pos.tab_offset - (from == BEG ? start_hpos : 0),
1958 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
1959 doc: /* Move point to start of the screen line LINES lines down.
1960 If LINES is negative, this means moving up.
1962 This function is an ordinary cursor motion function
1963 which calculates the new position based on how text would be displayed.
1964 The new position may be the start of a line,
1965 or just the start of a continuation line.
1966 The function returns number of screen lines moved over;
1967 that usually equals LINES, but may be closer to zero
1968 if beginning or end of buffer was reached.
1970 The optional second argument WINDOW specifies the window to use for
1971 parameters such as width, horizontal scrolling, and so on.
1972 The default is to use the selected window's parameters.
1974 LINES can optionally take the form (COLS . LINES), in which case
1975 the motion will not stop at the start of a screen line but on
1976 its column COLS (if such exists on that line, that is).
1978 `vertical-motion' always uses the current buffer,
1979 regardless of which buffer is displayed in WINDOW.
1980 This is consistent with other cursor motion functions
1981 and makes it possible to use `vertical-motion' in any buffer,
1982 whether or not it is currently displayed in some window. */)
1983 (Lisp_Object lines, Lisp_Object window)
1985 struct it it;
1986 struct text_pos pt;
1987 struct window *w;
1988 Lisp_Object old_buffer;
1989 struct gcpro gcpro1;
1990 Lisp_Object lcols = Qnil;
1991 double cols IF_LINT (= 0);
1993 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
1994 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
1996 lcols = XCAR (lines);
1997 cols = INTEGERP (lcols) ? (double) XINT (lcols) : XFLOAT_DATA (lcols);
1998 lines = XCDR (lines);
2001 CHECK_NUMBER (lines);
2002 if (! NILP (window))
2003 CHECK_WINDOW (window);
2004 else
2005 window = selected_window;
2006 w = XWINDOW (window);
2008 old_buffer = Qnil;
2009 GCPRO1 (old_buffer);
2010 if (XBUFFER (w->buffer) != current_buffer)
2012 /* Set the window's buffer temporarily to the current buffer. */
2013 old_buffer = w->buffer;
2014 XSETBUFFER (w->buffer, current_buffer);
2017 if (noninteractive)
2019 struct position pos;
2020 pos = *vmotion (PT, XINT (lines), w);
2021 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2023 else
2025 EMACS_INT it_start;
2026 int first_x, it_overshoot_expected IF_LINT (= 0);
2028 SET_TEXT_POS (pt, PT, PT_BYTE);
2029 start_display (&it, w, pt);
2030 first_x = it.first_visible_x;
2031 it_start = IT_CHARPOS (it);
2033 /* See comments below for why we calculate this. */
2034 if (XINT (lines) > 0)
2036 if (it.cmp_it.id >= 0)
2037 it_overshoot_expected = 1;
2038 else if (it.method == GET_FROM_STRING)
2040 const char *s = SSDATA (it.string);
2041 const char *e = s + SBYTES (it.string);
2042 while (s < e && *s != '\n')
2043 ++s;
2044 it_overshoot_expected = (s == e) ? -1 : 0;
2046 else
2047 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2048 || it.method == GET_FROM_STRETCH);
2051 /* Scan from the start of the line containing PT. If we don't
2052 do this, we start moving with IT->current_x == 0, while PT is
2053 really at some x > 0. */
2054 reseat_at_previous_visible_line_start (&it);
2055 it.current_x = it.hpos = 0;
2056 if (IT_CHARPOS (it) != PT)
2057 /* We used to temporarily disable selective display here; the
2058 comment said this is "so we don't move too far" (2005-01-19
2059 checkin by kfs). But this does nothing useful that I can
2060 tell, and it causes Bug#2694 . -- cyd */
2061 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2063 if (XINT (lines) <= 0)
2065 it.vpos = 0;
2066 /* Do this even if LINES is 0, so that we move back to the
2067 beginning of the current line as we ought. */
2068 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2069 move_it_by_lines (&it, XINT (lines));
2071 else
2073 if (IT_CHARPOS (it) > it_start)
2075 /* IT may move too far if truncate-lines is on and PT
2076 lies beyond the right margin. In that case,
2077 backtrack unless the starting point is on an image,
2078 stretch glyph, composition, or Lisp string. */
2079 if (!it_overshoot_expected
2080 /* Also, backtrack if the Lisp string contains no
2081 newline, but there is a newline right after it.
2082 In this case, IT overshoots if there is an
2083 after-string just before the newline. */
2084 || (it_overshoot_expected < 0
2085 && it.method == GET_FROM_BUFFER
2086 && it.c == '\n'))
2087 move_it_by_lines (&it, -1);
2088 it.vpos = 0;
2089 move_it_by_lines (&it, XINT (lines));
2091 else
2093 /* Otherwise, we are at the first row occupied by PT,
2094 which might span multiple screen lines (e.g., if it's
2095 on a multi-line display string). We want to start
2096 from the last line that it occupies. */
2097 if (it_start < ZV)
2099 while (IT_CHARPOS (it) <= it_start)
2101 it.vpos = 0;
2102 move_it_by_lines (&it, 1);
2104 if (XINT (lines) > 1)
2105 move_it_by_lines (&it, XINT (lines) - 1);
2107 else
2109 it.vpos = 0;
2110 move_it_by_lines (&it, XINT (lines));
2115 /* Move to the goal column, if one was specified. */
2116 if (!NILP (lcols))
2118 /* If the window was originally hscrolled, move forward by
2119 the hscrolled amount first. */
2120 if (first_x > 0)
2122 move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X);
2123 it.current_x = 0;
2125 move_it_in_display_line
2126 (&it, ZV,
2127 (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
2128 MOVE_TO_X);
2131 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2134 if (BUFFERP (old_buffer))
2135 w->buffer = old_buffer;
2137 RETURN_UNGCPRO (make_number (it.vpos));
2142 /* File's initialization. */
2144 void
2145 syms_of_indent (void)
2147 DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode,
2148 doc: /* *Indentation can insert tabs if this is non-nil. */);
2149 indent_tabs_mode = 1;
2151 defsubr (&Scurrent_indentation);
2152 defsubr (&Sindent_to);
2153 defsubr (&Scurrent_column);
2154 defsubr (&Smove_to_column);
2155 defsubr (&Svertical_motion);
2156 defsubr (&Scompute_motion);