Fix bug #9221 with memory leak in bidi display.
[emacs.git] / src / indent.c
blob70689311dd5c01605702e29fcde4ebdaae110696
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 (Lisp_Object string, Lisp_Object beg, Lisp_Object end)
730 register int col;
731 register unsigned char *ptr, *stop;
732 register int tab_seen;
733 int post_tab;
734 register int c;
735 int tab_width = sane_tab_width ();
736 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
737 register struct Lisp_Char_Table *dp = buffer_display_table ();
738 int b, e;
740 if (NILP (end))
741 e = SCHARS (string);
742 else
744 CHECK_NUMBER (end);
745 e = XINT (end);
748 if (NILP (beg))
749 b = 0;
750 else
752 CHECK_NUMBER (beg);
753 b = XINT (beg);
756 /* Make a pointer for decrementing through the chars before point. */
757 ptr = SDATA (string) + e;
758 /* Make a pointer to where consecutive chars leave off,
759 going backwards from point. */
760 stop = SDATA (string) + b;
762 col = 0, tab_seen = 0, post_tab = 0;
764 while (1)
766 if (ptr == stop)
767 break;
769 c = *--ptr;
770 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
771 col += ASIZE (DISP_CHAR_VECTOR (dp, c));
772 else if (c >= 040 && c < 0177)
773 col++;
774 else if (c == '\n')
775 break;
776 else if (c == '\t')
778 if (tab_seen)
779 col = ((col + tab_width) / tab_width) * tab_width;
781 post_tab += col;
782 col = 0;
783 tab_seen = 1;
785 else
786 col += (ctl_arrow && c < 0200) ? 2 : 4;
789 if (tab_seen)
791 col = ((col + tab_width) / tab_width) * tab_width;
792 col += post_tab;
795 return col;
798 #endif /* 0 */
801 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
802 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
803 Optional second argument MINIMUM says always do at least MINIMUM spaces
804 even if that goes past COLUMN; by default, MINIMUM is zero.
806 The return value is COLUMN. */)
807 (Lisp_Object column, Lisp_Object minimum)
809 EMACS_INT mincol;
810 register EMACS_INT fromcol;
811 int tab_width = sane_tab_width ();
813 CHECK_NUMBER (column);
814 if (NILP (minimum))
815 XSETFASTINT (minimum, 0);
816 CHECK_NUMBER (minimum);
818 fromcol = current_column ();
819 mincol = fromcol + XINT (minimum);
820 if (mincol < XINT (column)) mincol = XINT (column);
822 if (fromcol == mincol)
823 return make_number (mincol);
825 if (indent_tabs_mode)
827 Lisp_Object n;
828 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
829 if (XFASTINT (n) != 0)
831 Finsert_char (make_number ('\t'), n, Qt);
833 fromcol = (mincol / tab_width) * tab_width;
837 XSETFASTINT (column, mincol - fromcol);
838 Finsert_char (make_number (' '), column, Qt);
840 last_known_column = mincol;
841 last_known_column_point = PT;
842 last_known_column_modified = MODIFF;
844 XSETINT (column, mincol);
845 return column;
849 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
850 0, 0, 0,
851 doc: /* Return the indentation of the current line.
852 This is the horizontal position of the character
853 following any initial whitespace. */)
854 (void)
856 Lisp_Object val;
857 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
859 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
861 XSETFASTINT (val, position_indentation (PT_BYTE));
862 SET_PT_BOTH (opoint, opoint_byte);
863 return val;
866 static EMACS_INT
867 position_indentation (register int pos_byte)
869 register EMACS_INT column = 0;
870 int tab_width = sane_tab_width ();
871 register unsigned char *p;
872 register unsigned char *stop;
873 unsigned char *start;
874 EMACS_INT next_boundary_byte = pos_byte;
875 EMACS_INT ceiling = next_boundary_byte;
877 p = BYTE_POS_ADDR (pos_byte);
878 /* STOP records the value of P at which we will need
879 to think about the gap, or about invisible text,
880 or about the end of the buffer. */
881 stop = p;
882 /* START records the starting value of P. */
883 start = p;
884 while (1)
886 while (p == stop)
888 EMACS_INT stop_pos_byte;
890 /* If we have updated P, set POS_BYTE to match.
891 The first time we enter the loop, POS_BYTE is already right. */
892 if (p != start)
893 pos_byte = PTR_BYTE_POS (p);
894 /* Consider the various reasons STOP might have been set here. */
895 if (pos_byte == ZV_BYTE)
896 return column;
897 if (pos_byte == next_boundary_byte)
899 EMACS_INT next_boundary;
900 EMACS_INT pos = BYTE_TO_CHAR (pos_byte);
901 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
902 pos_byte = CHAR_TO_BYTE (pos);
903 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
905 if (pos_byte >= ceiling)
906 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
907 /* Compute the next place we need to stop and think,
908 and set STOP accordingly. */
909 stop_pos_byte = min (ceiling, next_boundary_byte);
910 /* The -1 and +1 arrange to point at the first byte of gap
911 (if STOP_POS_BYTE is the position of the gap)
912 rather than at the data after the gap. */
914 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
915 p = BYTE_POS_ADDR (pos_byte);
917 switch (*p++)
919 case 0240:
920 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
921 return column;
922 case ' ':
923 column++;
924 break;
925 case '\t':
926 column += tab_width - column % tab_width;
927 break;
928 default:
929 if (ASCII_BYTE_P (p[-1])
930 || NILP (BVAR (current_buffer, enable_multibyte_characters)))
931 return column;
933 int c;
934 pos_byte = PTR_BYTE_POS (p - 1);
935 c = FETCH_MULTIBYTE_CHAR (pos_byte);
936 if (CHAR_HAS_CATEGORY (c, ' '))
938 column++;
939 INC_POS (pos_byte);
940 p = BYTE_POS_ADDR (pos_byte);
942 else
943 return column;
949 /* Test whether the line beginning at POS is indented beyond COLUMN.
950 Blank lines are treated as if they had the same indentation as the
951 preceding line. */
954 indented_beyond_p (EMACS_INT pos, EMACS_INT pos_byte, EMACS_INT column)
956 EMACS_INT val;
957 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
959 SET_PT_BOTH (pos, pos_byte);
960 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
961 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
963 val = position_indentation (PT_BYTE);
964 SET_PT_BOTH (opoint, opoint_byte);
965 return val >= column;
968 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
969 doc: /* Move point to column COLUMN in the current line.
970 Interactively, COLUMN is the value of prefix numeric argument.
971 The column of a character is calculated by adding together the widths
972 as displayed of the previous characters in the line.
973 This function ignores line-continuation;
974 there is no upper limit on the column number a character can have
975 and horizontal scrolling has no effect.
977 If specified column is within a character, point goes after that character.
978 If it's past end of line, point goes to end of line.
980 Optional second argument FORCE non-nil means if COLUMN is in the
981 middle of a tab character, change it to spaces.
982 In addition, if FORCE is t, and the line is too short to reach
983 COLUMN, add spaces/tabs to get there.
985 The return value is the current column. */)
986 (Lisp_Object column, Lisp_Object force)
988 EMACS_INT pos;
989 EMACS_INT col, prev_col;
990 EMACS_INT goal;
992 CHECK_NATNUM (column);
993 goal = XINT (column);
995 col = goal;
996 pos = ZV;
997 scan_for_column (&pos, &col, &prev_col);
999 SET_PT (pos);
1001 /* If a tab char made us overshoot, change it to spaces
1002 and scan through it again. */
1003 if (!NILP (force) && col > goal)
1005 int c;
1006 EMACS_INT pos_byte = PT_BYTE;
1008 DEC_POS (pos_byte);
1009 c = FETCH_CHAR (pos_byte);
1010 if (c == '\t' && prev_col < goal)
1012 EMACS_INT goal_pt, goal_pt_byte;
1014 /* Insert spaces in front of the tab to reach GOAL. Do this
1015 first so that a marker at the end of the tab gets
1016 adjusted. */
1017 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1018 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1020 /* Now delete the tab, and indent to COL. */
1021 del_range (PT, PT + 1);
1022 goal_pt = PT;
1023 goal_pt_byte = PT_BYTE;
1024 Findent_to (make_number (col), Qnil);
1025 SET_PT_BOTH (goal_pt, goal_pt_byte);
1027 /* Set the last_known... vars consistently. */
1028 col = goal;
1032 /* If line ends prematurely, add space to the end. */
1033 if (col < goal && EQ (force, Qt))
1034 Findent_to (make_number (col = goal), Qnil);
1036 last_known_column = col;
1037 last_known_column_point = PT;
1038 last_known_column_modified = MODIFF;
1040 return make_number (col);
1043 /* compute_motion: compute buffer posn given screen posn and vice versa */
1045 static struct position val_compute_motion;
1047 /* Scan the current buffer forward from offset FROM, pretending that
1048 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1049 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1050 and return the ending buffer position and screen location. If we
1051 can't hit the requested column exactly (because of a tab or other
1052 multi-column character), overshoot.
1054 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1055 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1056 earlier call to compute_motion. The other common case is that FROMHPOS
1057 is zero and FROM is a position that "belongs" at column zero, but might
1058 be shifted by overlay strings; in this case DID_MOTION should be 0.
1060 WIDTH is the number of columns available to display text;
1061 compute_motion uses this to handle continuation lines and such.
1062 If WIDTH is -1, use width of window's text area adjusted for
1063 continuation glyph when needed.
1065 HSCROLL is the number of columns not being displayed at the left
1066 margin; this is usually taken from a window's hscroll member.
1067 TAB_OFFSET is the number of columns of the first tab that aren't
1068 being displayed, perhaps because of a continuation line or
1069 something.
1071 compute_motion returns a pointer to a struct position. The bufpos
1072 member gives the buffer position at the end of the scan, and hpos
1073 and vpos give its cartesian location. prevhpos is the column at
1074 which the character before bufpos started, and contin is non-zero
1075 if we reached the current line by continuing the previous.
1077 Note that FROMHPOS and TOHPOS should be expressed in real screen
1078 columns, taking HSCROLL and the truncation glyph at the left margin
1079 into account. That is, beginning-of-line moves you to the hpos
1080 -HSCROLL + (HSCROLL > 0).
1082 For example, to find the buffer position of column COL of line LINE
1083 of a certain window, pass the window's starting location as FROM
1084 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1085 Pass the buffer's ZV as TO, to limit the scan to the end of the
1086 visible section of the buffer, and pass LINE and COL as TOVPOS and
1087 TOHPOS.
1089 When displaying in window w, a typical formula for WIDTH is:
1091 window_width - 1
1092 - (has_vertical_scroll_bars
1093 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1094 : (window_width + window_left != frame_cols))
1096 where
1097 window_width is XFASTINT (w->total_cols),
1098 window_left is XFASTINT (w->left_col),
1099 has_vertical_scroll_bars is
1100 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1101 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1103 Or you can let window_body_cols do this all for you, and write:
1104 window_body_cols (w) - 1
1106 The `-1' accounts for the continuation-line backslashes; the rest
1107 accounts for window borders if the window is split horizontally, and
1108 the scroll bars if they are turned on. */
1110 struct position *
1111 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)
1113 register EMACS_INT hpos = fromhpos;
1114 register EMACS_INT vpos = fromvpos;
1116 register EMACS_INT pos;
1117 EMACS_INT pos_byte;
1118 register int c = 0;
1119 int tab_width = sane_tab_width ();
1120 register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow));
1121 register struct Lisp_Char_Table *dp = window_display_table (win);
1122 EMACS_INT selective
1123 = (INTEGERP (BVAR (current_buffer, selective_display))
1124 ? XINT (BVAR (current_buffer, selective_display))
1125 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1126 int selective_rlen
1127 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1128 ? ASIZE (DISP_INVIS_VECTOR (dp)) : 0);
1129 /* The next location where the `invisible' property changes, or an
1130 overlay starts or ends. */
1131 EMACS_INT next_boundary = from;
1133 /* For computing runs of characters with similar widths.
1134 Invariant: width_run_width is zero, or all the characters
1135 from width_run_start to width_run_end have a fixed width of
1136 width_run_width. */
1137 EMACS_INT width_run_start = from;
1138 EMACS_INT width_run_end = from;
1139 EMACS_INT width_run_width = 0;
1140 Lisp_Object *width_table;
1141 Lisp_Object buffer;
1143 /* The next buffer pos where we should consult the width run cache. */
1144 EMACS_INT next_width_run = from;
1145 Lisp_Object window;
1147 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
1148 /* If previous char scanned was a wide character,
1149 this is the column where it ended. Otherwise, this is 0. */
1150 EMACS_INT wide_column_end_hpos = 0;
1151 EMACS_INT prev_pos; /* Previous buffer position. */
1152 EMACS_INT prev_pos_byte; /* Previous buffer position. */
1153 EMACS_INT prev_hpos = 0;
1154 EMACS_INT prev_vpos = 0;
1155 EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
1156 EMACS_INT prev_tab_offset; /* Previous tab offset. */
1157 EMACS_INT continuation_glyph_width;
1159 struct composition_it cmp_it;
1161 XSETBUFFER (buffer, current_buffer);
1162 XSETWINDOW (window, win);
1164 width_run_cache_on_off ();
1165 if (dp == buffer_display_table ())
1166 width_table = (VECTORP (BVAR (current_buffer, width_table))
1167 ? XVECTOR (BVAR (current_buffer, width_table))->contents
1168 : 0);
1169 else
1170 /* If the window has its own display table, we can't use the width
1171 run cache, because that's based on the buffer's display table. */
1172 width_table = 0;
1174 /* Negative width means use all available text columns. */
1175 if (width < 0)
1177 width = window_body_cols (win);
1178 /* We must make room for continuation marks if we don't have fringes. */
1179 #ifdef HAVE_WINDOW_SYSTEM
1180 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1181 #endif
1182 width -= 1;
1185 continuation_glyph_width = 1;
1186 #ifdef HAVE_WINDOW_SYSTEM
1187 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1188 continuation_glyph_width = 0; /* In the fringe. */
1189 #endif
1191 immediate_quit = 1;
1192 QUIT;
1194 pos = prev_pos = from;
1195 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1196 contin_hpos = 0;
1197 prev_tab_offset = tab_offset;
1198 memset (&cmp_it, 0, sizeof cmp_it);
1199 cmp_it.id = -1;
1200 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil);
1202 while (1)
1204 while (pos == next_boundary)
1206 EMACS_INT pos_here = pos;
1207 EMACS_INT newpos;
1209 /* Don't skip invisible if we are already at the margin. */
1210 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1212 if (contin_hpos && prev_hpos == 0
1213 && hpos > tohpos
1214 && (contin_hpos == width || wide_column_end_hpos > width))
1215 { /* Line breaks because we can't put the character at the
1216 previous line any more. It is not the multi-column
1217 character continued in middle. Go back to previous
1218 buffer position, screen position, and set tab offset
1219 to previous value. It's the beginning of the
1220 line. */
1221 pos = prev_pos;
1222 pos_byte = prev_pos_byte;
1223 hpos = prev_hpos;
1224 vpos = prev_vpos;
1225 tab_offset = prev_tab_offset;
1227 break;
1230 /* If the caller says that the screen position came from an earlier
1231 call to compute_motion, then we've already accounted for the
1232 overlay strings at point. This is only true the first time
1233 through, so clear the flag after testing it. */
1234 if (!did_motion)
1235 /* We need to skip past the overlay strings. Currently those
1236 strings must not contain TAB;
1237 if we want to relax that restriction, something will have
1238 to be changed here. */
1240 unsigned char *ovstr;
1241 EMACS_INT ovlen = overlay_strings (pos, win, &ovstr);
1242 hpos += ((multibyte && ovlen > 0)
1243 ? strwidth ((char *) ovstr, ovlen) : ovlen);
1245 did_motion = 0;
1247 if (pos >= to)
1248 break;
1250 /* Advance POS past invisible characters
1251 (but not necessarily all that there are here),
1252 and store in next_boundary the next position where
1253 we need to call skip_invisible. */
1254 newpos = skip_invisible (pos, &next_boundary, to, window);
1256 if (newpos >= to)
1258 pos = min (to, newpos);
1259 pos_byte = CHAR_TO_BYTE (pos);
1260 goto after_loop;
1263 if (newpos != pos_here)
1265 pos = newpos;
1266 pos_byte = CHAR_TO_BYTE (pos);
1270 /* Handle right margin. */
1271 /* Note on a wide-column character.
1273 Characters are classified into the following three categories
1274 according to the width (columns occupied on screen).
1276 (1) single-column character: ex. `a'
1277 (2) multi-column character: ex. `^A', TAB, `\033'
1278 (3) wide-column character: ex. Japanese character, Chinese character
1279 (In the following example, `W_' stands for them.)
1281 Multi-column characters can be divided around the right margin,
1282 but wide-column characters cannot.
1284 NOTE:
1286 (*) The cursor is placed on the next character after the point.
1288 ----------
1289 abcdefghi\
1290 j ^---- next after the point
1291 ^--- next char. after the point.
1292 ----------
1293 In case of sigle-column character
1295 ----------
1296 abcdefgh\\
1297 033 ^---- next after the point, next char. after the point.
1298 ----------
1299 In case of multi-column character
1301 ----------
1302 abcdefgh\\
1303 W_ ^---- next after the point
1304 ^---- next char. after the point.
1305 ----------
1306 In case of wide-column character
1308 The problem here is continuation at a wide-column character.
1309 In this case, the line may shorter less than WIDTH.
1310 And we find the continuation AFTER it occurs.
1314 if (hpos > width)
1316 int total_width = width + continuation_glyph_width;
1317 int truncate = 0;
1319 if (!NILP (Vtruncate_partial_width_windows)
1320 && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1322 if (INTEGERP (Vtruncate_partial_width_windows))
1323 truncate
1324 = total_width < XFASTINT (Vtruncate_partial_width_windows);
1325 else
1326 truncate = 1;
1329 if (hscroll || truncate
1330 || !NILP (BVAR (current_buffer, truncate_lines)))
1332 /* Truncating: skip to newline, unless we are already past
1333 TO (we need to go back below). */
1334 if (pos <= to)
1336 pos = find_before_next_newline (pos, to, 1);
1337 pos_byte = CHAR_TO_BYTE (pos);
1338 hpos = width;
1339 /* If we just skipped next_boundary,
1340 loop around in the main while
1341 and handle it. */
1342 if (pos >= next_boundary)
1343 next_boundary = pos + 1;
1344 prev_hpos = width;
1345 prev_vpos = vpos;
1346 prev_tab_offset = tab_offset;
1349 else
1351 /* Continuing. */
1352 /* Remember the previous value. */
1353 prev_tab_offset = tab_offset;
1355 if (wide_column_end_hpos > width)
1357 hpos -= prev_hpos;
1358 tab_offset += prev_hpos;
1360 else
1362 tab_offset += width;
1363 hpos -= width;
1365 vpos++;
1366 contin_hpos = prev_hpos;
1367 prev_hpos = 0;
1368 prev_vpos = vpos;
1372 /* Stop if past the target buffer position or screen position. */
1373 if (pos > to)
1375 /* Go back to the previous position. */
1376 pos = prev_pos;
1377 pos_byte = prev_pos_byte;
1378 hpos = prev_hpos;
1379 vpos = prev_vpos;
1380 tab_offset = prev_tab_offset;
1382 /* NOTE on contin_hpos, hpos, and prev_hpos.
1384 ----------
1385 abcdefgh\\
1386 W_ ^---- contin_hpos
1387 | ^----- hpos
1388 \---- prev_hpos
1389 ----------
1392 if (contin_hpos && prev_hpos == 0
1393 && contin_hpos < width && !wide_column_end_hpos)
1395 /* Line breaking occurs in the middle of multi-column
1396 character. Go back to previous line. */
1397 hpos = contin_hpos;
1398 vpos = vpos - 1;
1400 break;
1403 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1405 if (contin_hpos && prev_hpos == 0
1406 && hpos > tohpos
1407 && (contin_hpos == width || wide_column_end_hpos > width))
1408 { /* Line breaks because we can't put the character at the
1409 previous line any more. It is not the multi-column
1410 character continued in middle. Go back to previous
1411 buffer position, screen position, and set tab offset
1412 to previous value. It's the beginning of the
1413 line. */
1414 pos = prev_pos;
1415 pos_byte = prev_pos_byte;
1416 hpos = prev_hpos;
1417 vpos = prev_vpos;
1418 tab_offset = prev_tab_offset;
1420 break;
1422 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1423 break;
1425 prev_hpos = hpos;
1426 prev_vpos = vpos;
1427 prev_pos = pos;
1428 prev_pos_byte = pos_byte;
1429 wide_column_end_hpos = 0;
1431 /* Consult the width run cache to see if we can avoid inspecting
1432 the text character-by-character. */
1433 if (current_buffer->width_run_cache && pos >= next_width_run)
1435 EMACS_INT run_end;
1436 int common_width
1437 = region_cache_forward (current_buffer,
1438 current_buffer->width_run_cache,
1439 pos, &run_end);
1441 /* A width of zero means the character's width varies (like
1442 a tab), is meaningless (like a newline), or we just don't
1443 want to skip over it for some other reason. */
1444 if (common_width != 0)
1446 EMACS_INT run_end_hpos;
1448 /* Don't go past the final buffer posn the user
1449 requested. */
1450 if (run_end > to)
1451 run_end = to;
1453 run_end_hpos = hpos + (run_end - pos) * common_width;
1455 /* Don't go past the final horizontal position the user
1456 requested. */
1457 if (vpos == tovpos && run_end_hpos > tohpos)
1459 run_end = pos + (tohpos - hpos) / common_width;
1460 run_end_hpos = hpos + (run_end - pos) * common_width;
1463 /* Don't go past the margin. */
1464 if (run_end_hpos >= width)
1466 run_end = pos + (width - hpos) / common_width;
1467 run_end_hpos = hpos + (run_end - pos) * common_width;
1470 hpos = run_end_hpos;
1471 if (run_end > pos)
1472 prev_hpos = hpos - common_width;
1473 if (pos != run_end)
1475 pos = run_end;
1476 pos_byte = CHAR_TO_BYTE (pos);
1480 next_width_run = run_end + 1;
1483 /* We have to scan the text character-by-character. */
1484 else
1486 EMACS_INT i, n;
1487 Lisp_Object charvec;
1489 /* Check composition sequence. */
1490 if (cmp_it.id >= 0
1491 || (pos == cmp_it.stop_pos
1492 && composition_reseat_it (&cmp_it, pos, pos_byte, to, win,
1493 NULL, Qnil)))
1494 composition_update_it (&cmp_it, pos, pos_byte, Qnil);
1495 if (cmp_it.id >= 0)
1497 pos += cmp_it.nchars;
1498 pos_byte += cmp_it.nbytes;
1499 hpos += cmp_it.width;
1500 if (cmp_it.to == cmp_it.nglyphs)
1502 cmp_it.id = -1;
1503 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to,
1504 Qnil);
1506 else
1507 cmp_it.from = cmp_it.to;
1508 continue;
1511 c = FETCH_BYTE (pos_byte);
1512 pos++, pos_byte++;
1514 /* Perhaps add some info to the width_run_cache. */
1515 if (current_buffer->width_run_cache)
1517 /* Is this character part of the current run? If so, extend
1518 the run. */
1519 if (pos - 1 == width_run_end
1520 && XFASTINT (width_table[c]) == width_run_width)
1521 width_run_end = pos;
1523 /* The previous run is over, since this is a character at a
1524 different position, or a different width. */
1525 else
1527 /* Have we accumulated a run to put in the cache?
1528 (Currently, we only cache runs of width == 1). */
1529 if (width_run_start < width_run_end
1530 && width_run_width == 1)
1531 know_region_cache (current_buffer,
1532 current_buffer->width_run_cache,
1533 width_run_start, width_run_end);
1535 /* Start recording a new width run. */
1536 width_run_width = XFASTINT (width_table[c]);
1537 width_run_start = pos - 1;
1538 width_run_end = pos;
1542 if (dp != 0
1543 && ! (multibyte && LEADING_CODE_P (c))
1544 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1546 charvec = DISP_CHAR_VECTOR (dp, c);
1547 n = ASIZE (charvec);
1549 else
1551 charvec = Qnil;
1552 n = 1;
1555 for (i = n - 1; i >= 0; --i)
1557 if (VECTORP (charvec))
1559 /* This should be handled the same as
1560 next_element_from_display_vector does it. */
1561 Lisp_Object entry = AREF (charvec, i);
1563 if (GLYPH_CODE_P (entry)
1564 && GLYPH_CODE_CHAR_VALID_P (entry))
1565 c = GLYPH_CODE_CHAR (entry);
1566 else
1567 c = ' ';
1570 if (c >= 040 && c < 0177)
1571 hpos++;
1572 else if (c == '\t')
1574 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1575 % tab_width);
1576 if (tem < 0)
1577 tem += tab_width;
1578 hpos += tab_width - tem;
1580 else if (c == '\n')
1582 if (selective > 0
1583 && indented_beyond_p (pos, pos_byte, selective))
1585 /* If (pos == to), we don't have to take care of
1586 selective display. */
1587 if (pos < to)
1589 /* Skip any number of invisible lines all at once */
1592 pos = find_before_next_newline (pos, to, 1);
1593 if (pos < to)
1594 pos++;
1595 pos_byte = CHAR_TO_BYTE (pos);
1597 while (pos < to
1598 && indented_beyond_p (pos, pos_byte,
1599 selective));
1600 /* Allow for the " ..." that is displayed for them. */
1601 if (selective_rlen)
1603 hpos += selective_rlen;
1604 if (hpos >= width)
1605 hpos = width;
1607 DEC_BOTH (pos, pos_byte);
1608 /* We have skipped the invis text, but not the
1609 newline after. */
1612 else
1614 /* A visible line. */
1615 vpos++;
1616 hpos = 0;
1617 hpos -= hscroll;
1618 /* Count the truncation glyph on column 0 */
1619 if (hscroll > 0)
1620 hpos += continuation_glyph_width;
1621 tab_offset = 0;
1623 contin_hpos = 0;
1625 else if (c == CR && selective < 0)
1627 /* In selective display mode,
1628 everything from a ^M to the end of the line is invisible.
1629 Stop *before* the real newline. */
1630 if (pos < to)
1632 pos = find_before_next_newline (pos, to, 1);
1633 pos_byte = CHAR_TO_BYTE (pos);
1635 /* If we just skipped next_boundary,
1636 loop around in the main while
1637 and handle it. */
1638 if (pos > next_boundary)
1639 next_boundary = pos;
1640 /* Allow for the " ..." that is displayed for them. */
1641 if (selective_rlen)
1643 hpos += selective_rlen;
1644 if (hpos >= width)
1645 hpos = width;
1648 else if (multibyte && LEADING_CODE_P (c))
1650 /* Start of multi-byte form. */
1651 unsigned char *ptr;
1652 int mb_bytes, mb_width;
1654 pos_byte--; /* rewind POS_BYTE */
1655 ptr = BYTE_POS_ADDR (pos_byte);
1656 MULTIBYTE_BYTES_WIDTH (ptr, dp, mb_bytes, mb_width);
1657 pos_byte += mb_bytes;
1658 if (mb_width > 1 && BYTES_BY_CHAR_HEAD (*ptr) == mb_bytes)
1659 wide_column_end_hpos = hpos + mb_width;
1660 hpos += mb_width;
1662 else if (VECTORP (charvec))
1663 ++hpos;
1664 else
1665 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1670 after_loop:
1672 /* Remember any final width run in the cache. */
1673 if (current_buffer->width_run_cache
1674 && width_run_width == 1
1675 && width_run_start < width_run_end)
1676 know_region_cache (current_buffer, current_buffer->width_run_cache,
1677 width_run_start, width_run_end);
1679 val_compute_motion.bufpos = pos;
1680 val_compute_motion.bytepos = pos_byte;
1681 val_compute_motion.hpos = hpos;
1682 val_compute_motion.vpos = vpos;
1683 if (contin_hpos && prev_hpos == 0)
1684 val_compute_motion.prevhpos = contin_hpos;
1685 else
1686 val_compute_motion.prevhpos = prev_hpos;
1687 /* We alalways handle all of them here; none of them remain to do. */
1688 val_compute_motion.ovstring_chars_done = 0;
1690 /* Nonzero if have just continued a line */
1691 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1693 immediate_quit = 0;
1694 return &val_compute_motion;
1698 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1699 doc: /* Scan through the current buffer, calculating screen position.
1700 Scan the current buffer forward from offset FROM,
1701 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1702 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1703 and return the ending buffer position and screen location.
1705 If TOPOS is nil, the actual width and height of the window's
1706 text area are used.
1708 There are three additional arguments:
1710 WIDTH is the number of columns available to display text;
1711 this affects handling of continuation lines. A value of nil
1712 corresponds to the actual number of available text columns.
1714 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1715 HSCROLL is the number of columns not being displayed at the left
1716 margin; this is usually taken from a window's hscroll member.
1717 TAB-OFFSET is the number of columns of the first tab that aren't
1718 being displayed, perhaps because the line was continued within it.
1719 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1721 WINDOW is the window to operate on. It is used to choose the display table;
1722 if it is showing the current buffer, it is used also for
1723 deciding which overlay properties apply.
1724 Note that `compute-motion' always operates on the current buffer.
1726 The value is a list of five elements:
1727 (POS HPOS VPOS PREVHPOS CONTIN)
1728 POS is the buffer position where the scan stopped.
1729 VPOS is the vertical position where the scan stopped.
1730 HPOS is the horizontal position where the scan stopped.
1732 PREVHPOS is the horizontal position one character back from POS.
1733 CONTIN is t if a line was continued after (or within) the previous character.
1735 For example, to find the buffer position of column COL of line LINE
1736 of a certain window, pass the window's starting location as FROM
1737 and the window's upper-left coordinates as FROMPOS.
1738 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1739 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1740 (Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos, Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
1742 struct window *w;
1743 Lisp_Object bufpos, hpos, vpos, prevhpos;
1744 struct position *pos;
1745 EMACS_INT hscroll, tab_offset;
1747 CHECK_NUMBER_COERCE_MARKER (from);
1748 CHECK_CONS (frompos);
1749 CHECK_NUMBER_CAR (frompos);
1750 CHECK_NUMBER_CDR (frompos);
1751 CHECK_NUMBER_COERCE_MARKER (to);
1752 if (!NILP (topos))
1754 CHECK_CONS (topos);
1755 CHECK_NUMBER_CAR (topos);
1756 CHECK_NUMBER_CDR (topos);
1758 if (!NILP (width))
1759 CHECK_NUMBER (width);
1761 if (!NILP (offsets))
1763 CHECK_CONS (offsets);
1764 CHECK_NUMBER_CAR (offsets);
1765 CHECK_NUMBER_CDR (offsets);
1766 hscroll = XINT (XCAR (offsets));
1767 tab_offset = XINT (XCDR (offsets));
1769 else
1770 hscroll = tab_offset = 0;
1772 if (NILP (window))
1773 window = Fselected_window ();
1774 else
1775 CHECK_LIVE_WINDOW (window);
1776 w = XWINDOW (window);
1778 if (XINT (from) < BEGV || XINT (from) > ZV)
1779 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1780 if (XINT (to) < BEGV || XINT (to) > ZV)
1781 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1783 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1784 XINT (XCAR (frompos)), 0,
1785 XINT (to),
1786 (NILP (topos)
1787 ? window_internal_height (w)
1788 : XINT (XCDR (topos))),
1789 (NILP (topos)
1790 ? (window_body_cols (w)
1792 #ifdef HAVE_WINDOW_SYSTEM
1793 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1794 #endif
1796 : XINT (XCAR (topos))),
1797 (NILP (width) ? -1 : XINT (width)),
1798 hscroll, tab_offset,
1799 XWINDOW (window));
1801 XSETFASTINT (bufpos, pos->bufpos);
1802 XSETINT (hpos, pos->hpos);
1803 XSETINT (vpos, pos->vpos);
1804 XSETINT (prevhpos, pos->prevhpos);
1806 return Fcons (bufpos,
1807 Fcons (hpos,
1808 Fcons (vpos,
1809 Fcons (prevhpos,
1810 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1814 /* Fvertical_motion and vmotion */
1816 static struct position val_vmotion;
1818 struct position *
1819 vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w)
1821 EMACS_INT hscroll = XINT (w->hscroll);
1822 struct position pos;
1823 /* vpos is cumulative vertical position, changed as from is changed */
1824 register int vpos = 0;
1825 EMACS_INT prevline;
1826 register EMACS_INT first;
1827 EMACS_INT from_byte;
1828 EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0;
1829 EMACS_INT selective
1830 = (INTEGERP (BVAR (current_buffer, selective_display))
1831 ? XINT (BVAR (current_buffer, selective_display))
1832 : !NILP (BVAR (current_buffer, selective_display)) ? -1 : 0);
1833 Lisp_Object window;
1834 EMACS_INT start_hpos = 0;
1835 int did_motion;
1836 /* This is the object we use for fetching character properties. */
1837 Lisp_Object text_prop_object;
1839 XSETWINDOW (window, w);
1841 /* If the window contains this buffer, use it for getting text properties.
1842 Otherwise use the current buffer as arg for doing that. */
1843 if (EQ (w->buffer, Fcurrent_buffer ()))
1844 text_prop_object = window;
1845 else
1846 text_prop_object = Fcurrent_buffer ();
1848 if (vpos >= vtarget)
1850 /* To move upward, go a line at a time until
1851 we have gone at least far enough. */
1853 first = 1;
1855 while ((vpos > vtarget || first) && from > BEGV)
1857 Lisp_Object propval;
1859 prevline = find_next_newline_no_quit (from - 1, -1);
1860 while (prevline > BEGV
1861 && ((selective > 0
1862 && indented_beyond_p (prevline,
1863 CHAR_TO_BYTE (prevline),
1864 selective))
1865 /* Watch out for newlines with `invisible' property.
1866 When moving upward, check the newline before. */
1867 || (propval = Fget_char_property (make_number (prevline - 1),
1868 Qinvisible,
1869 text_prop_object),
1870 TEXT_PROP_MEANS_INVISIBLE (propval))))
1871 prevline = find_next_newline_no_quit (prevline - 1, -1);
1872 pos = *compute_motion (prevline, 0,
1873 lmargin + (prevline == BEG ? start_hpos : 0),
1875 from,
1876 /* Don't care for VPOS... */
1877 1 << (BITS_PER_SHORT - 1),
1878 /* ... nor HPOS. */
1879 1 << (BITS_PER_SHORT - 1),
1880 -1, hscroll,
1881 /* This compensates for start_hpos
1882 so that a tab as first character
1883 still occupies 8 columns. */
1884 (prevline == BEG ? -start_hpos : 0),
1886 vpos -= pos.vpos;
1887 first = 0;
1888 from = prevline;
1891 /* If we made exactly the desired vertical distance,
1892 or if we hit beginning of buffer,
1893 return point found */
1894 if (vpos >= vtarget)
1896 val_vmotion.bufpos = from;
1897 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1898 val_vmotion.vpos = vpos;
1899 val_vmotion.hpos = lmargin;
1900 val_vmotion.contin = 0;
1901 val_vmotion.prevhpos = 0;
1902 val_vmotion.ovstring_chars_done = 0;
1903 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1904 return &val_vmotion;
1907 /* Otherwise find the correct spot by moving down */
1909 /* Moving downward is simple, but must calculate from beg of line
1910 to determine hpos of starting point */
1911 from_byte = CHAR_TO_BYTE (from);
1912 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1914 Lisp_Object propval;
1916 prevline = find_next_newline_no_quit (from, -1);
1917 while (prevline > BEGV
1918 && ((selective > 0
1919 && indented_beyond_p (prevline,
1920 CHAR_TO_BYTE (prevline),
1921 selective))
1922 /* Watch out for newlines with `invisible' property.
1923 When moving downward, check the newline after. */
1924 || (propval = Fget_char_property (make_number (prevline),
1925 Qinvisible,
1926 text_prop_object),
1927 TEXT_PROP_MEANS_INVISIBLE (propval))))
1928 prevline = find_next_newline_no_quit (prevline - 1, -1);
1929 pos = *compute_motion (prevline, 0,
1930 lmargin + (prevline == BEG
1931 ? start_hpos : 0),
1933 from,
1934 /* Don't care for VPOS... */
1935 1 << (BITS_PER_SHORT - 1),
1936 /* ... nor HPOS. */
1937 1 << (BITS_PER_SHORT - 1),
1938 -1, hscroll,
1939 (prevline == BEG ? -start_hpos : 0),
1941 did_motion = 1;
1943 else
1945 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1946 pos.vpos = 0;
1947 pos.tab_offset = 0;
1948 did_motion = 0;
1950 return compute_motion (from, vpos, pos.hpos, did_motion,
1951 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1952 -1, hscroll,
1953 pos.tab_offset - (from == BEG ? start_hpos : 0),
1957 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
1958 doc: /* Move point to start of the screen line LINES lines down.
1959 If LINES is negative, this means moving up.
1961 This function is an ordinary cursor motion function
1962 which calculates the new position based on how text would be displayed.
1963 The new position may be the start of a line,
1964 or just the start of a continuation line.
1965 The function returns number of screen lines moved over;
1966 that usually equals LINES, but may be closer to zero
1967 if beginning or end of buffer was reached.
1969 The optional second argument WINDOW specifies the window to use for
1970 parameters such as width, horizontal scrolling, and so on.
1971 The default is to use the selected window's parameters.
1973 LINES can optionally take the form (COLS . LINES), in which case
1974 the motion will not stop at the start of a screen line but on
1975 its column COLS (if such exists on that line, that is).
1977 `vertical-motion' always uses the current buffer,
1978 regardless of which buffer is displayed in WINDOW.
1979 This is consistent with other cursor motion functions
1980 and makes it possible to use `vertical-motion' in any buffer,
1981 whether or not it is currently displayed in some window. */)
1982 (Lisp_Object lines, Lisp_Object window)
1984 struct it it;
1985 struct text_pos pt;
1986 struct window *w;
1987 Lisp_Object old_buffer;
1988 EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0);
1989 struct gcpro gcpro1, gcpro2, gcpro3;
1990 Lisp_Object lcols = Qnil;
1991 double cols IF_LINT (= 0);
1992 void *itdata = NULL;
1994 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
1995 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
1997 lcols = XCAR (lines);
1998 cols = INTEGERP (lcols) ? (double) XINT (lcols) : XFLOAT_DATA (lcols);
1999 lines = XCDR (lines);
2002 CHECK_NUMBER (lines);
2003 if (! NILP (window))
2004 CHECK_WINDOW (window);
2005 else
2006 window = selected_window;
2007 w = XWINDOW (window);
2009 old_buffer = Qnil;
2010 GCPRO3 (old_buffer, old_charpos, old_bytepos);
2011 if (XBUFFER (w->buffer) != current_buffer)
2013 /* Set the window's buffer temporarily to the current buffer. */
2014 old_buffer = w->buffer;
2015 old_charpos = XMARKER (w->pointm)->charpos;
2016 old_bytepos = XMARKER (w->pointm)->bytepos;
2017 XSETBUFFER (w->buffer, current_buffer);
2018 set_marker_both
2019 (w->pointm, w->buffer, BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
2022 if (noninteractive)
2024 struct position pos;
2025 pos = *vmotion (PT, XINT (lines), w);
2026 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2028 else
2030 EMACS_INT it_start;
2031 int first_x, it_overshoot_expected IF_LINT (= 0);
2033 itdata = bidi_shelve_cache ();
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));
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);
2094 it.vpos = 0;
2095 move_it_by_lines (&it, XINT (lines));
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);
2110 if (XINT (lines) > 1)
2111 move_it_by_lines (&it, XINT (lines) - 1);
2113 else
2115 it.vpos = 0;
2116 move_it_by_lines (&it, XINT (lines));
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));
2138 bidi_unshelve_cache (itdata, 0);
2141 if (BUFFERP (old_buffer))
2143 w->buffer = old_buffer;
2144 set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos);
2147 RETURN_UNGCPRO (make_number (it.vpos));
2152 /* File's initialization. */
2154 void
2155 syms_of_indent (void)
2157 DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode,
2158 doc: /* *Indentation can insert tabs if this is non-nil. */);
2159 indent_tabs_mode = 1;
2161 defsubr (&Scurrent_indentation);
2162 defsubr (&Sindent_to);
2163 defsubr (&Scurrent_column);
2164 defsubr (&Smove_to_column);
2165 defsubr (&Svertical_motion);
2166 defsubr (&Scompute_motion);