Backport 2010-03-27T00:45:32Z!cyd@stupidchicken.com from trunk
[emacs.git] / src / indent.c
bloba7f41f7e8e40f450697978fe335fc8040a717d2b
1 /* Indentation functions.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
23 #include <setjmp.h>
25 #include "lisp.h"
26 #include "buffer.h"
27 #include "character.h"
28 #include "category.h"
29 #include "composite.h"
30 #include "indent.h"
31 #include "keyboard.h"
32 #include "frame.h"
33 #include "window.h"
34 #include "termchar.h"
35 #include "termopts.h"
36 #include "disptab.h"
37 #include "intervals.h"
38 #include "dispextern.h"
39 #include "region-cache.h"
41 /* Indentation can insert tabs if this is non-zero;
42 otherwise always uses spaces. */
44 static int indent_tabs_mode;
46 #define CR 015
48 /* These three values memorize the current column to avoid recalculation. */
50 /* Last value returned by current_column.
51 Some things in set last_known_column_point to -1
52 to mark the memorized value as invalid. */
54 static double last_known_column;
56 /* Value of point when current_column was called. */
58 EMACS_INT last_known_column_point;
60 /* Value of MODIFF when current_column was called. */
62 static int last_known_column_modified;
64 static double current_column_1 P_ ((void));
65 static double position_indentation P_ ((int));
67 /* Cache of beginning of line found by the last call of
68 current_column. */
70 static EMACS_INT current_column_bol_cache;
72 /* Get the display table to use for the current buffer. */
74 struct Lisp_Char_Table *
75 buffer_display_table ()
77 Lisp_Object thisbuf;
79 thisbuf = current_buffer->display_table;
80 if (DISP_TABLE_P (thisbuf))
81 return XCHAR_TABLE (thisbuf);
82 if (DISP_TABLE_P (Vstandard_display_table))
83 return XCHAR_TABLE (Vstandard_display_table);
84 return 0;
87 /* Width run cache considerations. */
89 /* Return the width of character C under display table DP. */
91 static int
92 character_width (c, dp)
93 int c;
94 struct Lisp_Char_Table *dp;
96 Lisp_Object elt;
98 /* These width computations were determined by examining the cases
99 in display_text_line. */
101 /* Everything can be handled by the display table, if it's
102 present and the element is right. */
103 if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
104 return XVECTOR (elt)->size;
106 /* Some characters are special. */
107 if (c == '\n' || c == '\t' || c == '\015')
108 return 0;
110 /* Printing characters have width 1. */
111 else if (c >= 040 && c < 0177)
112 return 1;
114 /* Everybody else (control characters, metacharacters) has other
115 widths. We could return their actual widths here, but they
116 depend on things like ctl_arrow and crud like that, and they're
117 not very common at all. So we'll just claim we don't know their
118 widths. */
119 else
120 return 0;
123 /* Return true if the display table DISPTAB specifies the same widths
124 for characters as WIDTHTAB. We use this to decide when to
125 invalidate the buffer's width_run_cache. */
128 disptab_matches_widthtab (disptab, widthtab)
129 struct Lisp_Char_Table *disptab;
130 struct Lisp_Vector *widthtab;
132 int i;
134 if (widthtab->size != 256)
135 abort ();
137 for (i = 0; i < 256; i++)
138 if (character_width (i, disptab)
139 != XFASTINT (widthtab->contents[i]))
140 return 0;
142 return 1;
145 /* Recompute BUF's width table, using the display table DISPTAB. */
147 void
148 recompute_width_table (buf, disptab)
149 struct buffer *buf;
150 struct Lisp_Char_Table *disptab;
152 int i;
153 struct Lisp_Vector *widthtab;
155 if (!VECTORP (buf->width_table))
156 buf->width_table = Fmake_vector (make_number (256), make_number (0));
157 widthtab = XVECTOR (buf->width_table);
158 if (widthtab->size != 256)
159 abort ();
161 for (i = 0; i < 256; i++)
162 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
165 /* Allocate or free the width run cache, as requested by the current
166 state of current_buffer's cache_long_line_scans variable. */
168 static void
169 width_run_cache_on_off ()
171 if (NILP (current_buffer->cache_long_line_scans)
172 /* And, for the moment, this feature doesn't work on multibyte
173 characters. */
174 || !NILP (current_buffer->enable_multibyte_characters))
176 /* It should be off. */
177 if (current_buffer->width_run_cache)
179 free_region_cache (current_buffer->width_run_cache);
180 current_buffer->width_run_cache = 0;
181 current_buffer->width_table = Qnil;
184 else
186 /* It should be on. */
187 if (current_buffer->width_run_cache == 0)
189 current_buffer->width_run_cache = new_region_cache ();
190 recompute_width_table (current_buffer, buffer_display_table ());
196 /* Skip some invisible characters starting from POS.
197 This includes characters invisible because of text properties
198 and characters invisible because of overlays.
200 If position POS is followed by invisible characters,
201 skip some of them and return the position after them.
202 Otherwise return POS itself.
204 Set *NEXT_BOUNDARY_P to the next position at which
205 it will be necessary to call this function again.
207 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
208 to a value greater than TO.
210 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
211 take account of overlays that apply only in WINDOW.
213 We don't necessarily skip all the invisible characters after POS
214 because that could take a long time. We skip a reasonable number
215 which can be skipped quickly. If there might be more invisible
216 characters immediately following, then *NEXT_BOUNDARY_P
217 will equal the return value. */
219 EMACS_INT
220 skip_invisible (pos, next_boundary_p, to, window)
221 EMACS_INT pos;
222 EMACS_INT *next_boundary_p;
223 EMACS_INT to;
224 Lisp_Object window;
226 Lisp_Object prop, position, overlay_limit, proplimit;
227 Lisp_Object buffer, tmp;
228 EMACS_INT end;
229 int inv_p;
231 XSETFASTINT (position, pos);
232 XSETBUFFER (buffer, current_buffer);
234 /* Give faster response for overlay lookup near POS. */
235 recenter_overlay_lists (current_buffer, pos);
237 /* We must not advance farther than the next overlay change.
238 The overlay change might change the invisible property;
239 or there might be overlay strings to be displayed there. */
240 overlay_limit = Fnext_overlay_change (position);
241 /* As for text properties, this gives a lower bound
242 for where the invisible text property could change. */
243 proplimit = Fnext_property_change (position, buffer, Qt);
244 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
245 proplimit = overlay_limit;
246 /* PROPLIMIT is now a lower bound for the next change
247 in invisible status. If that is plenty far away,
248 use that lower bound. */
249 if (XFASTINT (proplimit) > pos + 100 || XFASTINT (proplimit) >= to)
250 *next_boundary_p = XFASTINT (proplimit);
251 /* Otherwise, scan for the next `invisible' property change. */
252 else
254 /* Don't scan terribly far. */
255 XSETFASTINT (proplimit, min (pos + 100, to));
256 /* No matter what, don't go past next overlay change. */
257 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
258 proplimit = overlay_limit;
259 tmp = Fnext_single_property_change (position, Qinvisible,
260 buffer, proplimit);
261 end = XFASTINT (tmp);
262 #if 0
263 /* Don't put the boundary in the middle of multibyte form if
264 there is no actual property change. */
265 if (end == pos + 100
266 && !NILP (current_buffer->enable_multibyte_characters)
267 && end < ZV)
268 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
269 end--;
270 #endif
271 *next_boundary_p = end;
273 /* if the `invisible' property is set, we can skip to
274 the next property change */
275 prop = Fget_char_property (position, Qinvisible,
276 (!NILP (window)
277 && EQ (XWINDOW (window)->buffer, buffer))
278 ? window : buffer);
279 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
280 /* When counting columns (window == nil), don't skip over ellipsis text. */
281 if (NILP (window) ? inv_p == 1 : inv_p)
282 return *next_boundary_p;
283 return pos;
286 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
288 DP is a display table or NULL.
290 This macro is used in current_column_1, Fmove_to_column, and
291 compute_motion. */
293 #define MULTIBYTE_BYTES_WIDTH(p, dp) \
294 do { \
295 int c; \
297 wide_column = 0; \
298 c = STRING_CHAR_AND_LENGTH (p, bytes); \
299 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
300 width = bytes * 4; \
301 else \
303 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) \
304 width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; \
305 else \
306 width = CHAR_WIDTH (c); \
307 if (width > 1) \
308 wide_column = width; \
310 } while (0)
313 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
314 doc: /* Return the horizontal position of point. Beginning of line is column 0.
315 This is calculated by adding together the widths of all the displayed
316 representations of the character between the start of the previous line
317 and point (eg. control characters will have a width of 2 or 4, tabs
318 will have a variable width).
319 Ignores finite width of frame, which means that this function may return
320 values greater than (frame-width).
321 Whether the line is visible (if `selective-display' is t) has no effect;
322 however, ^M is treated as end of line when `selective-display' is t.
323 Text that has an invisible property is considered as having width 0, unless
324 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
327 Lisp_Object temp;
328 XSETFASTINT (temp, (int) current_column ()); /* iftc */
329 return temp;
332 /* Cancel any recorded value of the horizontal position. */
334 void
335 invalidate_current_column ()
337 last_known_column_point = 0;
340 double
341 current_column ()
343 register int col;
344 register unsigned char *ptr, *stop;
345 register int tab_seen;
346 int post_tab;
347 register int c;
348 register int tab_width = XINT (current_buffer->tab_width);
349 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
350 register struct Lisp_Char_Table *dp = buffer_display_table ();
352 if (PT == last_known_column_point
353 && MODIFF == last_known_column_modified)
354 return last_known_column;
356 /* If the buffer has overlays, text properties,
357 or multibyte characters, use a more general algorithm. */
358 if (BUF_INTERVALS (current_buffer)
359 || current_buffer->overlays_before
360 || current_buffer->overlays_after
361 || Z != Z_BYTE)
362 return current_column_1 ();
364 /* Scan backwards from point to the previous newline,
365 counting width. Tab characters are the only complicated case. */
367 /* Make a pointer for decrementing through the chars before point. */
368 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
369 /* Make a pointer to where consecutive chars leave off,
370 going backwards from point. */
371 if (PT == BEGV)
372 stop = ptr;
373 else if (PT <= GPT || BEGV > GPT)
374 stop = BEGV_ADDR;
375 else
376 stop = GAP_END_ADDR;
378 if (tab_width <= 0 || tab_width > 1000)
379 tab_width = 8;
381 col = 0, tab_seen = 0, post_tab = 0;
383 while (1)
385 EMACS_INT i, n;
386 Lisp_Object charvec;
388 if (ptr == stop)
390 /* We stopped either for the beginning of the buffer
391 or for the gap. */
392 if (ptr == BEGV_ADDR)
393 break;
395 /* It was the gap. Jump back over it. */
396 stop = BEGV_ADDR;
397 ptr = GPT_ADDR;
399 /* Check whether that brings us to beginning of buffer. */
400 if (BEGV >= GPT)
401 break;
404 c = *--ptr;
406 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
408 charvec = DISP_CHAR_VECTOR (dp, c);
409 n = ASIZE (charvec);
411 else
413 charvec = Qnil;
414 n = 1;
417 for (i = n - 1; i >= 0; --i)
419 if (VECTORP (charvec))
421 /* This should be handled the same as
422 next_element_from_display_vector does it. */
423 Lisp_Object entry = AREF (charvec, i);
425 if (GLYPH_CODE_P (entry)
426 && GLYPH_CODE_CHAR_VALID_P (entry))
427 c = GLYPH_CODE_CHAR (entry);
428 else
429 c = ' ';
432 if (c >= 040 && c < 0177)
433 col++;
434 else if (c == '\n'
435 || (c == '\r'
436 && EQ (current_buffer->selective_display, Qt)))
438 ptr++;
439 goto start_of_line_found;
441 else if (c == '\t')
443 if (tab_seen)
444 col = ((col + tab_width) / tab_width) * tab_width;
446 post_tab += col;
447 col = 0;
448 tab_seen = 1;
450 else if (VECTORP (charvec))
451 /* With a display table entry, C is displayed as is, and
452 not displayed as \NNN or as ^N. If C is a single-byte
453 character, it takes one column. If C is multi-byte in
454 an unibyte buffer, it's translated to unibyte, so it
455 also takes one column. */
456 ++col;
457 else
458 col += (ctl_arrow && c < 0200) ? 2 : 4;
462 start_of_line_found:
464 if (tab_seen)
466 col = ((col + tab_width) / tab_width) * tab_width;
467 col += post_tab;
470 if (ptr == BEGV_ADDR)
471 current_column_bol_cache = BEGV;
472 else
473 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
475 last_known_column = col;
476 last_known_column_point = PT;
477 last_known_column_modified = MODIFF;
479 return col;
482 extern Lisp_Object Qspace, QCwidth, QCalign_to;
484 /* Check the presence of a display property and compute its width.
485 If a property was found and its width was found as well, return
486 its width (>= 0) and set the position of the end of the property
487 in ENDPOS.
488 Otherwise just return -1. */
489 static int
490 check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
492 Lisp_Object val, overlay;
494 if (CONSP (val = get_char_property_and_overlay
495 (make_number (pos), Qdisplay, Qnil, &overlay))
496 && EQ (Qspace, XCAR (val)))
497 { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */
498 Lisp_Object plist = XCDR (val), prop;
499 int width = -1;
501 if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop)))
502 width = XINT (prop);
503 else if (FLOATP (prop))
504 width = (int)(XFLOAT_DATA (prop) + 0.5);
505 else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop)))
506 width = XINT (prop) - col;
507 else if (FLOATP (prop))
508 width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
510 if (width >= 0)
512 EMACS_INT start;
513 if (OVERLAYP (overlay))
514 *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
515 else
516 get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
517 return width;
520 return -1;
523 /* Scanning from the beginning of the current line, stop at the buffer
524 position ENDPOS or at the column GOALCOL or at the end of line, whichever
525 comes first.
526 Return the resulting buffer position and column in ENDPOS and GOALCOL.
527 PREVCOL gets set to the column of the previous position (it's always
528 strictly smaller than the goal column). */
529 static void
530 scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
532 register EMACS_INT tab_width = XINT (current_buffer->tab_width);
533 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
534 register struct Lisp_Char_Table *dp = buffer_display_table ();
535 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
536 struct composition_it cmp_it;
537 Lisp_Object window;
538 struct window *w;
540 /* Start the scan at the beginning of this line with column number 0. */
541 register EMACS_INT col = 0, prev_col = 0;
542 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
543 EMACS_INT end = endpos ? *endpos : PT;
544 EMACS_INT scan, scan_byte;
545 EMACS_INT next_boundary;
547 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
548 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
549 current_column_bol_cache = PT;
550 scan = PT, scan_byte = PT_BYTE;
551 SET_PT_BOTH (opoint, opoint_byte);
552 next_boundary = scan;
555 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
556 w = ! NILP (window) ? XWINDOW (window) : NULL;
558 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
559 bzero (&cmp_it, sizeof cmp_it);
560 cmp_it.id = -1;
561 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
563 /* Scan forward to the target position. */
564 while (scan < end)
566 int c;
568 /* Occasionally we may need to skip invisible text. */
569 while (scan == next_boundary)
571 EMACS_INT old_scan = scan;
572 /* This updates NEXT_BOUNDARY to the next place
573 where we might need to skip more invisible text. */
574 scan = skip_invisible (scan, &next_boundary, end, Qnil);
575 if (scan != old_scan)
576 scan_byte = CHAR_TO_BYTE (scan);
577 if (scan >= end)
578 goto endloop;
581 /* Test reaching the goal column. We do this after skipping
582 invisible characters, so that we put point before the
583 character on which the cursor will appear. */
584 if (col >= goal)
585 break;
586 prev_col = col;
588 { /* Check display property. */
589 EMACS_INT end;
590 int width = check_display_width (scan, col, &end);
591 if (width >= 0)
593 col += width;
594 if (end > scan) /* Avoid infinite loops with 0-width overlays. */
596 scan = end; scan_byte = charpos_to_bytepos (scan);
597 continue;
602 /* Check composition sequence. */
603 if (cmp_it.id >= 0
604 || (scan == cmp_it.stop_pos
605 && composition_reseat_it (&cmp_it, scan, scan_byte, end,
606 w, NULL, Qnil)))
607 composition_update_it (&cmp_it, scan, scan_byte, Qnil);
608 if (cmp_it.id >= 0)
610 scan += cmp_it.nchars;
611 scan_byte += cmp_it.nbytes;
612 if (scan <= end)
613 col += cmp_it.width;
614 if (cmp_it.to == cmp_it.nglyphs)
616 cmp_it.id = -1;
617 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end,
618 Qnil);
620 else
621 cmp_it.from = cmp_it.to;
622 continue;
625 c = FETCH_BYTE (scan_byte);
627 /* See if there is a display table and it relates
628 to this character. */
630 if (dp != 0
631 && ! (multibyte && BASE_LEADING_CODE_P (c))
632 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
634 Lisp_Object charvec;
635 EMACS_INT i, n;
637 /* This character is displayed using a vector of glyphs.
638 Update the column/position based on those glyphs. */
640 charvec = DISP_CHAR_VECTOR (dp, c);
641 n = ASIZE (charvec);
643 for (i = 0; i < n; i++)
645 /* This should be handled the same as
646 next_element_from_display_vector does it. */
647 Lisp_Object entry = AREF (charvec, i);
649 if (GLYPH_CODE_P (entry)
650 && GLYPH_CODE_CHAR_VALID_P (entry))
651 c = GLYPH_CODE_CHAR (entry);
652 else
653 c = ' ';
655 if (c == '\n')
656 goto endloop;
657 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
658 goto endloop;
659 if (c == '\t')
661 col += tab_width;
662 col = col / tab_width * tab_width;
664 else
665 ++col;
668 else
670 /* The display table doesn't affect this character;
671 it displays as itself. */
673 if (c == '\n')
674 goto endloop;
675 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
676 goto endloop;
677 if (c == '\t')
679 col += tab_width;
680 col = col / tab_width * tab_width;
682 else if (multibyte && BASE_LEADING_CODE_P (c))
684 /* Start of multi-byte form. */
685 unsigned char *ptr;
686 int bytes, width, wide_column;
688 ptr = BYTE_POS_ADDR (scan_byte);
689 MULTIBYTE_BYTES_WIDTH (ptr, dp);
690 /* Subtract one to compensate for the increment
691 that is going to happen below. */
692 scan_byte += bytes - 1;
693 col += width;
695 else if (ctl_arrow && (c < 040 || c == 0177))
696 col += 2;
697 else if (c < 040 || c >= 0177)
698 col += 4;
699 else
700 col++;
702 scan++;
703 scan_byte++;
706 endloop:
708 last_known_column = col;
709 last_known_column_point = PT;
710 last_known_column_modified = MODIFF;
712 if (goalcol)
713 *goalcol = col;
714 if (endpos)
715 *endpos = scan;
716 if (prevcol)
717 *prevcol = prev_col;
720 /* Return the column number of position POS
721 by scanning forward from the beginning of the line.
722 This function handles characters that are invisible
723 due to text properties or overlays. */
725 static double
726 current_column_1 ()
728 EMACS_INT col = MOST_POSITIVE_FIXNUM;
729 EMACS_INT opoint = PT;
731 scan_for_column (&opoint, &col, NULL);
732 return col;
736 #if 0 /* Not used. */
738 /* Return the width in columns of the part of STRING from BEG to END.
739 If BEG is nil, that stands for the beginning of STRING.
740 If END is nil, that stands for the end of STRING. */
742 static double
743 string_display_width (string, beg, end)
744 Lisp_Object string, beg, end;
746 register int col;
747 register unsigned char *ptr, *stop;
748 register int tab_seen;
749 int post_tab;
750 register int c;
751 register int tab_width = XINT (current_buffer->tab_width);
752 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
753 register struct Lisp_Char_Table *dp = buffer_display_table ();
754 int b, e;
756 if (NILP (end))
757 e = SCHARS (string);
758 else
760 CHECK_NUMBER (end);
761 e = XINT (end);
764 if (NILP (beg))
765 b = 0;
766 else
768 CHECK_NUMBER (beg);
769 b = XINT (beg);
772 /* Make a pointer for decrementing through the chars before point. */
773 ptr = SDATA (string) + e;
774 /* Make a pointer to where consecutive chars leave off,
775 going backwards from point. */
776 stop = SDATA (string) + b;
778 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
780 col = 0, tab_seen = 0, post_tab = 0;
782 while (1)
784 if (ptr == stop)
785 break;
787 c = *--ptr;
788 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
789 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
790 else if (c >= 040 && c < 0177)
791 col++;
792 else if (c == '\n')
793 break;
794 else if (c == '\t')
796 if (tab_seen)
797 col = ((col + tab_width) / tab_width) * tab_width;
799 post_tab += col;
800 col = 0;
801 tab_seen = 1;
803 else
804 col += (ctl_arrow && c < 0200) ? 2 : 4;
807 if (tab_seen)
809 col = ((col + tab_width) / tab_width) * tab_width;
810 col += post_tab;
813 return col;
816 #endif /* 0 */
819 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
820 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
821 Optional second argument MINIMUM says always do at least MINIMUM spaces
822 even if that goes past COLUMN; by default, MINIMUM is zero.
824 The return value is COLUMN. */)
825 (column, minimum)
826 Lisp_Object column, minimum;
828 int mincol;
829 register int fromcol;
830 register int tab_width = XINT (current_buffer->tab_width);
832 CHECK_NUMBER (column);
833 if (NILP (minimum))
834 XSETFASTINT (minimum, 0);
835 CHECK_NUMBER (minimum);
837 fromcol = current_column ();
838 mincol = fromcol + XINT (minimum);
839 if (mincol < XINT (column)) mincol = XINT (column);
841 if (fromcol == mincol)
842 return make_number (mincol);
844 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
846 if (indent_tabs_mode)
848 Lisp_Object n;
849 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
850 if (XFASTINT (n) != 0)
852 Finsert_char (make_number ('\t'), n, Qt);
854 fromcol = (mincol / tab_width) * tab_width;
858 XSETFASTINT (column, mincol - fromcol);
859 Finsert_char (make_number (' '), column, Qt);
861 last_known_column = mincol;
862 last_known_column_point = PT;
863 last_known_column_modified = MODIFF;
865 XSETINT (column, mincol);
866 return column;
870 static double position_indentation P_ ((int));
872 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
873 0, 0, 0,
874 doc: /* Return the indentation of the current line.
875 This is the horizontal position of the character
876 following any initial whitespace. */)
879 Lisp_Object val;
880 int opoint = PT, opoint_byte = PT_BYTE;
882 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
884 XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */
885 SET_PT_BOTH (opoint, opoint_byte);
886 return val;
889 static double
890 position_indentation (pos_byte)
891 register int pos_byte;
893 register EMACS_INT column = 0;
894 register EMACS_INT tab_width = XINT (current_buffer->tab_width);
895 register unsigned char *p;
896 register unsigned char *stop;
897 unsigned char *start;
898 EMACS_INT next_boundary_byte = pos_byte;
899 EMACS_INT ceiling = next_boundary_byte;
901 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
903 p = BYTE_POS_ADDR (pos_byte);
904 /* STOP records the value of P at which we will need
905 to think about the gap, or about invisible text,
906 or about the end of the buffer. */
907 stop = p;
908 /* START records the starting value of P. */
909 start = p;
910 while (1)
912 while (p == stop)
914 EMACS_INT stop_pos_byte;
916 /* If we have updated P, set POS_BYTE to match.
917 The first time we enter the loop, POS_BYTE is already right. */
918 if (p != start)
919 pos_byte = PTR_BYTE_POS (p);
920 /* Consider the various reasons STOP might have been set here. */
921 if (pos_byte == ZV_BYTE)
922 return column;
923 if (pos_byte == next_boundary_byte)
925 EMACS_INT next_boundary;
926 EMACS_INT pos = BYTE_TO_CHAR (pos_byte);
927 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
928 pos_byte = CHAR_TO_BYTE (pos);
929 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
931 if (pos_byte >= ceiling)
932 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
933 /* Compute the next place we need to stop and think,
934 and set STOP accordingly. */
935 stop_pos_byte = min (ceiling, next_boundary_byte);
936 /* The -1 and +1 arrange to point at the first byte of gap
937 (if STOP_POS_BYTE is the position of the gap)
938 rather than at the data after the gap. */
940 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
941 p = BYTE_POS_ADDR (pos_byte);
943 switch (*p++)
945 case 0240:
946 if (! NILP (current_buffer->enable_multibyte_characters))
947 return column;
948 case ' ':
949 column++;
950 break;
951 case '\t':
952 column += tab_width - column % tab_width;
953 break;
954 default:
955 if (ASCII_BYTE_P (p[-1])
956 || NILP (current_buffer->enable_multibyte_characters))
957 return column;
959 int c;
960 pos_byte = PTR_BYTE_POS (p - 1);
961 c = FETCH_MULTIBYTE_CHAR (pos_byte);
962 if (CHAR_HAS_CATEGORY (c, ' '))
964 column++;
965 INC_POS (pos_byte);
966 p = BYTE_POS_ADDR (pos_byte);
968 else
969 return column;
975 /* Test whether the line beginning at POS is indented beyond COLUMN.
976 Blank lines are treated as if they had the same indentation as the
977 preceding line. */
980 indented_beyond_p (pos, pos_byte, column)
981 int pos, pos_byte;
982 double column;
984 double val;
985 int opoint = PT, opoint_byte = PT_BYTE;
987 SET_PT_BOTH (pos, pos_byte);
988 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
989 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
991 val = position_indentation (PT_BYTE);
992 SET_PT_BOTH (opoint, opoint_byte);
993 return val >= column; /* hmm, float comparison */
996 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
997 doc: /* Move point to column COLUMN in the current line.
998 Interactively, COLUMN is the value of prefix numeric argument.
999 The column of a character is calculated by adding together the widths
1000 as displayed of the previous characters in the line.
1001 This function ignores line-continuation;
1002 there is no upper limit on the column number a character can have
1003 and horizontal scrolling has no effect.
1005 If specified column is within a character, point goes after that character.
1006 If it's past end of line, point goes to end of line.
1008 Optional second argument FORCE non-nil means if COLUMN is in the
1009 middle of a tab character, change it to spaces.
1010 In addition, if FORCE is t, and the line is too short to reach
1011 COLUMN, add spaces/tabs to get there.
1013 The return value is the current column. */)
1014 (column, force)
1015 Lisp_Object column, force;
1017 EMACS_INT pos;
1018 EMACS_INT col, prev_col;
1019 EMACS_INT goal;
1021 CHECK_NATNUM (column);
1022 goal = XINT (column);
1024 col = goal;
1025 pos = ZV;
1026 scan_for_column (&pos, &col, &prev_col);
1028 SET_PT (pos);
1030 /* If a tab char made us overshoot, change it to spaces
1031 and scan through it again. */
1032 if (!NILP (force) && col > goal)
1034 int c;
1035 EMACS_INT pos_byte = PT_BYTE;
1037 DEC_POS (pos_byte);
1038 c = FETCH_CHAR (pos_byte);
1039 if (c == '\t' && prev_col < goal)
1041 EMACS_INT goal_pt, goal_pt_byte;
1043 /* Insert spaces in front of the tab to reach GOAL. Do this
1044 first so that a marker at the end of the tab gets
1045 adjusted. */
1046 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1047 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1049 /* Now delete the tab, and indent to COL. */
1050 del_range (PT, PT + 1);
1051 goal_pt = PT;
1052 goal_pt_byte = PT_BYTE;
1053 Findent_to (make_number (col), Qnil);
1054 SET_PT_BOTH (goal_pt, goal_pt_byte);
1056 /* Set the last_known... vars consistently. */
1057 col = goal;
1061 /* If line ends prematurely, add space to the end. */
1062 if (col < goal && EQ (force, Qt))
1063 Findent_to (make_number (col = goal), Qnil);
1065 last_known_column = col;
1066 last_known_column_point = PT;
1067 last_known_column_modified = MODIFF;
1069 return make_number (col);
1072 /* compute_motion: compute buffer posn given screen posn and vice versa */
1074 struct position val_compute_motion;
1076 /* Scan the current buffer forward from offset FROM, pretending that
1077 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1078 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1079 and return the ending buffer position and screen location. If we
1080 can't hit the requested column exactly (because of a tab or other
1081 multi-column character), overshoot.
1083 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1084 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1085 earlier call to compute_motion. The other common case is that FROMHPOS
1086 is zero and FROM is a position that "belongs" at column zero, but might
1087 be shifted by overlay strings; in this case DID_MOTION should be 0.
1089 WIDTH is the number of columns available to display text;
1090 compute_motion uses this to handle continuation lines and such.
1091 If WIDTH is -1, use width of window's text area adjusted for
1092 continuation glyph when needed.
1094 HSCROLL is the number of columns not being displayed at the left
1095 margin; this is usually taken from a window's hscroll member.
1096 TAB_OFFSET is the number of columns of the first tab that aren't
1097 being displayed, perhaps because of a continuation line or
1098 something.
1100 compute_motion returns a pointer to a struct position. The bufpos
1101 member gives the buffer position at the end of the scan, and hpos
1102 and vpos give its cartesian location. prevhpos is the column at
1103 which the character before bufpos started, and contin is non-zero
1104 if we reached the current line by continuing the previous.
1106 Note that FROMHPOS and TOHPOS should be expressed in real screen
1107 columns, taking HSCROLL and the truncation glyph at the left margin
1108 into account. That is, beginning-of-line moves you to the hpos
1109 -HSCROLL + (HSCROLL > 0).
1111 For example, to find the buffer position of column COL of line LINE
1112 of a certain window, pass the window's starting location as FROM
1113 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1114 Pass the buffer's ZV as TO, to limit the scan to the end of the
1115 visible section of the buffer, and pass LINE and COL as TOVPOS and
1116 TOHPOS.
1118 When displaying in window w, a typical formula for WIDTH is:
1120 window_width - 1
1121 - (has_vertical_scroll_bars
1122 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1123 : (window_width + window_left != frame_cols))
1125 where
1126 window_width is XFASTINT (w->total_cols),
1127 window_left is XFASTINT (w->left_col),
1128 has_vertical_scroll_bars is
1129 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1130 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1132 Or you can let window_box_text_cols do this all for you, and write:
1133 window_box_text_cols (w) - 1
1135 The `-1' accounts for the continuation-line backslashes; the rest
1136 accounts for window borders if the window is split horizontally, and
1137 the scroll bars if they are turned on. */
1139 struct position *
1140 compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, hscroll, tab_offset, win)
1141 EMACS_INT from, fromvpos, fromhpos, to, tovpos, tohpos;
1142 int did_motion;
1143 EMACS_INT width;
1144 EMACS_INT hscroll, tab_offset;
1145 struct window *win;
1147 register EMACS_INT hpos = fromhpos;
1148 register EMACS_INT vpos = fromvpos;
1150 register EMACS_INT pos;
1151 EMACS_INT pos_byte;
1152 register int c = 0;
1153 register EMACS_INT tab_width = XFASTINT (current_buffer->tab_width);
1154 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
1155 register struct Lisp_Char_Table *dp = window_display_table (win);
1156 int selective
1157 = (INTEGERP (current_buffer->selective_display)
1158 ? XINT (current_buffer->selective_display)
1159 : !NILP (current_buffer->selective_display) ? -1 : 0);
1160 int selective_rlen
1161 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1162 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
1163 /* The next location where the `invisible' property changes, or an
1164 overlay starts or ends. */
1165 EMACS_INT next_boundary = from;
1167 /* For computing runs of characters with similar widths.
1168 Invariant: width_run_width is zero, or all the characters
1169 from width_run_start to width_run_end have a fixed width of
1170 width_run_width. */
1171 EMACS_INT width_run_start = from;
1172 EMACS_INT width_run_end = from;
1173 EMACS_INT width_run_width = 0;
1174 Lisp_Object *width_table;
1175 Lisp_Object buffer;
1177 /* The next buffer pos where we should consult the width run cache. */
1178 EMACS_INT next_width_run = from;
1179 Lisp_Object window;
1181 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
1182 /* If previous char scanned was a wide character,
1183 this is the column where it ended. Otherwise, this is 0. */
1184 EMACS_INT wide_column_end_hpos = 0;
1185 EMACS_INT prev_pos; /* Previous buffer position. */
1186 EMACS_INT prev_pos_byte; /* Previous buffer position. */
1187 EMACS_INT prev_hpos = 0;
1188 EMACS_INT prev_vpos = 0;
1189 EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
1190 EMACS_INT prev_tab_offset; /* Previous tab offset. */
1191 EMACS_INT continuation_glyph_width;
1193 struct composition_it cmp_it;
1195 XSETBUFFER (buffer, current_buffer);
1196 XSETWINDOW (window, win);
1198 width_run_cache_on_off ();
1199 if (dp == buffer_display_table ())
1200 width_table = (VECTORP (current_buffer->width_table)
1201 ? XVECTOR (current_buffer->width_table)->contents
1202 : 0);
1203 else
1204 /* If the window has its own display table, we can't use the width
1205 run cache, because that's based on the buffer's display table. */
1206 width_table = 0;
1208 if (tab_width <= 0 || tab_width > 1000)
1209 tab_width = 8;
1211 /* Negative width means use all available text columns. */
1212 if (width < 0)
1214 width = window_box_text_cols (win);
1215 /* We must make room for continuation marks if we don't have fringes. */
1216 #ifdef HAVE_WINDOW_SYSTEM
1217 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1218 #endif
1219 width -= 1;
1222 continuation_glyph_width = 1;
1223 #ifdef HAVE_WINDOW_SYSTEM
1224 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1225 continuation_glyph_width = 0; /* In the fringe. */
1226 #endif
1228 immediate_quit = 1;
1229 QUIT;
1231 pos = prev_pos = from;
1232 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1233 contin_hpos = 0;
1234 prev_tab_offset = tab_offset;
1235 bzero (&cmp_it, sizeof cmp_it);
1236 cmp_it.id = -1;
1237 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil);
1239 while (1)
1241 while (pos == next_boundary)
1243 EMACS_INT pos_here = pos;
1244 EMACS_INT newpos;
1246 /* Don't skip invisible if we are already at the margin. */
1247 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1249 if (contin_hpos && prev_hpos == 0
1250 && hpos > tohpos
1251 && (contin_hpos == width || wide_column_end_hpos > width))
1252 { /* Line breaks because we can't put the character at the
1253 previous line any more. It is not the multi-column
1254 character continued in middle. Go back to previous
1255 buffer position, screen position, and set tab offset
1256 to previous value. It's the beginning of the
1257 line. */
1258 pos = prev_pos;
1259 pos_byte = prev_pos_byte;
1260 hpos = prev_hpos;
1261 vpos = prev_vpos;
1262 tab_offset = prev_tab_offset;
1264 break;
1267 /* If the caller says that the screen position came from an earlier
1268 call to compute_motion, then we've already accounted for the
1269 overlay strings at point. This is only true the first time
1270 through, so clear the flag after testing it. */
1271 if (!did_motion)
1272 /* We need to skip past the overlay strings. Currently those
1273 strings must not contain TAB;
1274 if we want to relax that restriction, something will have
1275 to be changed here. */
1277 unsigned char *ovstr;
1278 int ovlen = overlay_strings (pos, win, &ovstr);
1279 hpos += ((multibyte && ovlen > 0)
1280 ? strwidth (ovstr, ovlen) : ovlen);
1282 did_motion = 0;
1284 if (pos >= to)
1285 break;
1287 /* Advance POS past invisible characters
1288 (but not necessarily all that there are here),
1289 and store in next_boundary the next position where
1290 we need to call skip_invisible. */
1291 newpos = skip_invisible (pos, &next_boundary, to, window);
1293 if (newpos >= to)
1295 pos = min (to, newpos);
1296 pos_byte = CHAR_TO_BYTE (pos);
1297 goto after_loop;
1300 if (newpos != pos_here)
1302 pos = newpos;
1303 pos_byte = CHAR_TO_BYTE (pos);
1307 /* Handle right margin. */
1308 /* Note on a wide-column character.
1310 Characters are classified into the following three categories
1311 according to the width (columns occupied on screen).
1313 (1) single-column character: ex. `a'
1314 (2) multi-column character: ex. `^A', TAB, `\033'
1315 (3) wide-column character: ex. Japanese character, Chinese character
1316 (In the following example, `W_' stands for them.)
1318 Multi-column characters can be divided around the right margin,
1319 but wide-column characters cannot.
1321 NOTE:
1323 (*) The cursor is placed on the next character after the point.
1325 ----------
1326 abcdefghi\
1327 j ^---- next after the point
1328 ^--- next char. after the point.
1329 ----------
1330 In case of sigle-column character
1332 ----------
1333 abcdefgh\\
1334 033 ^---- next after the point, next char. after the point.
1335 ----------
1336 In case of multi-column character
1338 ----------
1339 abcdefgh\\
1340 W_ ^---- next after the point
1341 ^---- next char. after the point.
1342 ----------
1343 In case of wide-column character
1345 The problem here is continuation at a wide-column character.
1346 In this case, the line may shorter less than WIDTH.
1347 And we find the continuation AFTER it occurs.
1351 if (hpos > width)
1353 int total_width = width + continuation_glyph_width;
1354 int truncate = 0;
1356 if (!NILP (Vtruncate_partial_width_windows)
1357 && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1359 if (INTEGERP (Vtruncate_partial_width_windows))
1360 truncate
1361 = total_width < XFASTINT (Vtruncate_partial_width_windows);
1362 else
1363 truncate = 1;
1366 if (hscroll || truncate
1367 || !NILP (current_buffer->truncate_lines))
1369 /* Truncating: skip to newline, unless we are already past
1370 TO (we need to go back below). */
1371 if (pos <= to)
1373 pos = find_before_next_newline (pos, to, 1);
1374 pos_byte = CHAR_TO_BYTE (pos);
1375 hpos = width;
1376 /* If we just skipped next_boundary,
1377 loop around in the main while
1378 and handle it. */
1379 if (pos >= next_boundary)
1380 next_boundary = pos + 1;
1381 prev_hpos = width;
1382 prev_vpos = vpos;
1383 prev_tab_offset = tab_offset;
1386 else
1388 /* Continuing. */
1389 /* Remember the previous value. */
1390 prev_tab_offset = tab_offset;
1392 if (wide_column_end_hpos > width)
1394 hpos -= prev_hpos;
1395 tab_offset += prev_hpos;
1397 else
1399 tab_offset += width;
1400 hpos -= width;
1402 vpos++;
1403 contin_hpos = prev_hpos;
1404 prev_hpos = 0;
1405 prev_vpos = vpos;
1409 /* Stop if past the target buffer position or screen position. */
1410 if (pos > to)
1412 /* Go back to the previous position. */
1413 pos = prev_pos;
1414 pos_byte = prev_pos_byte;
1415 hpos = prev_hpos;
1416 vpos = prev_vpos;
1417 tab_offset = prev_tab_offset;
1419 /* NOTE on contin_hpos, hpos, and prev_hpos.
1421 ----------
1422 abcdefgh\\
1423 W_ ^---- contin_hpos
1424 | ^----- hpos
1425 \---- prev_hpos
1426 ----------
1429 if (contin_hpos && prev_hpos == 0
1430 && contin_hpos < width && !wide_column_end_hpos)
1432 /* Line breaking occurs in the middle of multi-column
1433 character. Go back to previous line. */
1434 hpos = contin_hpos;
1435 vpos = vpos - 1;
1437 break;
1440 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1442 if (contin_hpos && prev_hpos == 0
1443 && hpos > tohpos
1444 && (contin_hpos == width || wide_column_end_hpos > width))
1445 { /* Line breaks because we can't put the character at the
1446 previous line any more. It is not the multi-column
1447 character continued in middle. Go back to previous
1448 buffer position, screen position, and set tab offset
1449 to previous value. It's the beginning of the
1450 line. */
1451 pos = prev_pos;
1452 pos_byte = prev_pos_byte;
1453 hpos = prev_hpos;
1454 vpos = prev_vpos;
1455 tab_offset = prev_tab_offset;
1457 break;
1459 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1460 break;
1462 prev_hpos = hpos;
1463 prev_vpos = vpos;
1464 prev_pos = pos;
1465 prev_pos_byte = pos_byte;
1466 wide_column_end_hpos = 0;
1468 /* Consult the width run cache to see if we can avoid inspecting
1469 the text character-by-character. */
1470 if (current_buffer->width_run_cache && pos >= next_width_run)
1472 int run_end;
1473 int common_width
1474 = region_cache_forward (current_buffer,
1475 current_buffer->width_run_cache,
1476 pos, &run_end);
1478 /* A width of zero means the character's width varies (like
1479 a tab), is meaningless (like a newline), or we just don't
1480 want to skip over it for some other reason. */
1481 if (common_width != 0)
1483 int run_end_hpos;
1485 /* Don't go past the final buffer posn the user
1486 requested. */
1487 if (run_end > to)
1488 run_end = to;
1490 run_end_hpos = hpos + (run_end - pos) * common_width;
1492 /* Don't go past the final horizontal position the user
1493 requested. */
1494 if (vpos == tovpos && run_end_hpos > tohpos)
1496 run_end = pos + (tohpos - hpos) / common_width;
1497 run_end_hpos = hpos + (run_end - pos) * common_width;
1500 /* Don't go past the margin. */
1501 if (run_end_hpos >= width)
1503 run_end = pos + (width - hpos) / common_width;
1504 run_end_hpos = hpos + (run_end - pos) * common_width;
1507 hpos = run_end_hpos;
1508 if (run_end > pos)
1509 prev_hpos = hpos - common_width;
1510 if (pos != run_end)
1512 pos = run_end;
1513 pos_byte = CHAR_TO_BYTE (pos);
1517 next_width_run = run_end + 1;
1520 /* We have to scan the text character-by-character. */
1521 else
1523 EMACS_INT i, n;
1524 Lisp_Object charvec;
1526 /* Check composition sequence. */
1527 if (cmp_it.id >= 0
1528 || (pos == cmp_it.stop_pos
1529 && composition_reseat_it (&cmp_it, pos, pos_byte, to, win,
1530 NULL, Qnil)))
1531 composition_update_it (&cmp_it, pos, pos_byte, Qnil);
1532 if (cmp_it.id >= 0)
1534 pos += cmp_it.nchars;
1535 pos_byte += cmp_it.nbytes;
1536 hpos += cmp_it.width;
1537 if (cmp_it.to == cmp_it.nglyphs)
1539 cmp_it.id = -1;
1540 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to,
1541 Qnil);
1543 else
1544 cmp_it.from = cmp_it.to;
1545 continue;
1548 c = FETCH_BYTE (pos_byte);
1549 pos++, pos_byte++;
1551 /* Perhaps add some info to the width_run_cache. */
1552 if (current_buffer->width_run_cache)
1554 /* Is this character part of the current run? If so, extend
1555 the run. */
1556 if (pos - 1 == width_run_end
1557 && XFASTINT (width_table[c]) == width_run_width)
1558 width_run_end = pos;
1560 /* The previous run is over, since this is a character at a
1561 different position, or a different width. */
1562 else
1564 /* Have we accumulated a run to put in the cache?
1565 (Currently, we only cache runs of width == 1). */
1566 if (width_run_start < width_run_end
1567 && width_run_width == 1)
1568 know_region_cache (current_buffer,
1569 current_buffer->width_run_cache,
1570 width_run_start, width_run_end);
1572 /* Start recording a new width run. */
1573 width_run_width = XFASTINT (width_table[c]);
1574 width_run_start = pos - 1;
1575 width_run_end = pos;
1579 if (dp != 0
1580 && ! (multibyte && BASE_LEADING_CODE_P (c))
1581 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1583 charvec = DISP_CHAR_VECTOR (dp, c);
1584 n = ASIZE (charvec);
1586 else
1588 charvec = Qnil;
1589 n = 1;
1592 for (i = n - 1; i >= 0; --i)
1594 if (VECTORP (charvec))
1596 /* This should be handled the same as
1597 next_element_from_display_vector does it. */
1598 Lisp_Object entry = AREF (charvec, i);
1600 if (GLYPH_CODE_P (entry)
1601 && GLYPH_CODE_CHAR_VALID_P (entry))
1602 c = GLYPH_CODE_CHAR (entry);
1603 else
1604 c = ' ';
1607 if (c >= 040 && c < 0177)
1608 hpos++;
1609 else if (c == '\t')
1611 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1612 % tab_width);
1613 if (tem < 0)
1614 tem += tab_width;
1615 hpos += tab_width - tem;
1617 else if (c == '\n')
1619 if (selective > 0
1620 && indented_beyond_p (pos, pos_byte,
1621 (double) selective)) /* iftc */
1623 /* If (pos == to), we don't have to take care of
1624 selective display. */
1625 if (pos < to)
1627 /* Skip any number of invisible lines all at once */
1630 pos = find_before_next_newline (pos, to, 1);
1631 if (pos < to)
1632 pos++;
1633 pos_byte = CHAR_TO_BYTE (pos);
1635 while (pos < to
1636 && indented_beyond_p (pos, pos_byte,
1637 (double) selective)); /* iftc */
1638 /* Allow for the " ..." that is displayed for them. */
1639 if (selective_rlen)
1641 hpos += selective_rlen;
1642 if (hpos >= width)
1643 hpos = width;
1645 DEC_BOTH (pos, pos_byte);
1646 /* We have skipped the invis text, but not the
1647 newline after. */
1650 else
1652 /* A visible line. */
1653 vpos++;
1654 hpos = 0;
1655 hpos -= hscroll;
1656 /* Count the truncation glyph on column 0 */
1657 if (hscroll > 0)
1658 hpos += continuation_glyph_width;
1659 tab_offset = 0;
1661 contin_hpos = 0;
1663 else if (c == CR && selective < 0)
1665 /* In selective display mode,
1666 everything from a ^M to the end of the line is invisible.
1667 Stop *before* the real newline. */
1668 if (pos < to)
1670 pos = find_before_next_newline (pos, to, 1);
1671 pos_byte = CHAR_TO_BYTE (pos);
1673 /* If we just skipped next_boundary,
1674 loop around in the main while
1675 and handle it. */
1676 if (pos > next_boundary)
1677 next_boundary = pos;
1678 /* Allow for the " ..." that is displayed for them. */
1679 if (selective_rlen)
1681 hpos += selective_rlen;
1682 if (hpos >= width)
1683 hpos = width;
1686 else if (multibyte && BASE_LEADING_CODE_P (c))
1688 /* Start of multi-byte form. */
1689 unsigned char *ptr;
1690 int bytes, width, wide_column;
1692 pos_byte--; /* rewind POS_BYTE */
1693 ptr = BYTE_POS_ADDR (pos_byte);
1694 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1695 pos_byte += bytes;
1696 if (wide_column)
1697 wide_column_end_hpos = hpos + wide_column;
1698 hpos += width;
1700 else if (VECTORP (charvec))
1701 ++hpos;
1702 else
1703 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1708 after_loop:
1710 /* Remember any final width run in the cache. */
1711 if (current_buffer->width_run_cache
1712 && width_run_width == 1
1713 && width_run_start < width_run_end)
1714 know_region_cache (current_buffer, current_buffer->width_run_cache,
1715 width_run_start, width_run_end);
1717 val_compute_motion.bufpos = pos;
1718 val_compute_motion.bytepos = pos_byte;
1719 val_compute_motion.hpos = hpos;
1720 val_compute_motion.vpos = vpos;
1721 if (contin_hpos && prev_hpos == 0)
1722 val_compute_motion.prevhpos = contin_hpos;
1723 else
1724 val_compute_motion.prevhpos = prev_hpos;
1725 /* We alalways handle all of them here; none of them remain to do. */
1726 val_compute_motion.ovstring_chars_done = 0;
1728 /* Nonzero if have just continued a line */
1729 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1731 immediate_quit = 0;
1732 return &val_compute_motion;
1736 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1737 doc: /* Scan through the current buffer, calculating screen position.
1738 Scan the current buffer forward from offset FROM,
1739 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1740 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1741 and return the ending buffer position and screen location.
1743 If TOPOS is nil, the actual width and height of the window's
1744 text area are used.
1746 There are three additional arguments:
1748 WIDTH is the number of columns available to display text;
1749 this affects handling of continuation lines. A value of nil
1750 corresponds to the actual number of available text columns.
1752 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1753 HSCROLL is the number of columns not being displayed at the left
1754 margin; this is usually taken from a window's hscroll member.
1755 TAB-OFFSET is the number of columns of the first tab that aren't
1756 being displayed, perhaps because the line was continued within it.
1757 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1759 WINDOW is the window to operate on. It is used to choose the display table;
1760 if it is showing the current buffer, it is used also for
1761 deciding which overlay properties apply.
1762 Note that `compute-motion' always operates on the current buffer.
1764 The value is a list of five elements:
1765 (POS HPOS VPOS PREVHPOS CONTIN)
1766 POS is the buffer position where the scan stopped.
1767 VPOS is the vertical position where the scan stopped.
1768 HPOS is the horizontal position where the scan stopped.
1770 PREVHPOS is the horizontal position one character back from POS.
1771 CONTIN is t if a line was continued after (or within) the previous character.
1773 For example, to find the buffer position of column COL of line LINE
1774 of a certain window, pass the window's starting location as FROM
1775 and the window's upper-left coordinates as FROMPOS.
1776 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1777 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1778 (from, frompos, to, topos, width, offsets, window)
1779 Lisp_Object from, frompos, to, topos;
1780 Lisp_Object width, offsets, window;
1782 struct window *w;
1783 Lisp_Object bufpos, hpos, vpos, prevhpos;
1784 struct position *pos;
1785 int hscroll, tab_offset;
1787 CHECK_NUMBER_COERCE_MARKER (from);
1788 CHECK_CONS (frompos);
1789 CHECK_NUMBER_CAR (frompos);
1790 CHECK_NUMBER_CDR (frompos);
1791 CHECK_NUMBER_COERCE_MARKER (to);
1792 if (!NILP (topos))
1794 CHECK_CONS (topos);
1795 CHECK_NUMBER_CAR (topos);
1796 CHECK_NUMBER_CDR (topos);
1798 if (!NILP (width))
1799 CHECK_NUMBER (width);
1801 if (!NILP (offsets))
1803 CHECK_CONS (offsets);
1804 CHECK_NUMBER_CAR (offsets);
1805 CHECK_NUMBER_CDR (offsets);
1806 hscroll = XINT (XCAR (offsets));
1807 tab_offset = XINT (XCDR (offsets));
1809 else
1810 hscroll = tab_offset = 0;
1812 if (NILP (window))
1813 window = Fselected_window ();
1814 else
1815 CHECK_LIVE_WINDOW (window);
1816 w = XWINDOW (window);
1818 if (XINT (from) < BEGV || XINT (from) > ZV)
1819 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1820 if (XINT (to) < BEGV || XINT (to) > ZV)
1821 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1823 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1824 XINT (XCAR (frompos)), 0,
1825 XINT (to),
1826 (NILP (topos)
1827 ? window_internal_height (w)
1828 : XINT (XCDR (topos))),
1829 (NILP (topos)
1830 ? (window_box_text_cols (w)
1832 #ifdef HAVE_WINDOW_SYSTEM
1833 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1834 #endif
1836 : XINT (XCAR (topos))),
1837 (NILP (width) ? -1 : XINT (width)),
1838 hscroll, tab_offset,
1839 XWINDOW (window));
1841 XSETFASTINT (bufpos, pos->bufpos);
1842 XSETINT (hpos, pos->hpos);
1843 XSETINT (vpos, pos->vpos);
1844 XSETINT (prevhpos, pos->prevhpos);
1846 return Fcons (bufpos,
1847 Fcons (hpos,
1848 Fcons (vpos,
1849 Fcons (prevhpos,
1850 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1854 /* Fvertical_motion and vmotion */
1856 struct position val_vmotion;
1858 struct position *
1859 vmotion (from, vtarget, w)
1860 register EMACS_INT from, vtarget;
1861 struct window *w;
1863 EMACS_INT hscroll = XINT (w->hscroll);
1864 struct position pos;
1865 /* vpos is cumulative vertical position, changed as from is changed */
1866 register int vpos = 0;
1867 EMACS_INT prevline;
1868 register EMACS_INT first;
1869 EMACS_INT from_byte;
1870 EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0;
1871 int selective
1872 = (INTEGERP (current_buffer->selective_display)
1873 ? XINT (current_buffer->selective_display)
1874 : !NILP (current_buffer->selective_display) ? -1 : 0);
1875 Lisp_Object window;
1876 EMACS_INT start_hpos = 0;
1877 int did_motion;
1878 /* This is the object we use for fetching character properties. */
1879 Lisp_Object text_prop_object;
1881 XSETWINDOW (window, w);
1883 /* If the window contains this buffer, use it for getting text properties.
1884 Otherwise use the current buffer as arg for doing that. */
1885 if (EQ (w->buffer, Fcurrent_buffer ()))
1886 text_prop_object = window;
1887 else
1888 text_prop_object = Fcurrent_buffer ();
1890 if (vpos >= vtarget)
1892 /* To move upward, go a line at a time until
1893 we have gone at least far enough. */
1895 first = 1;
1897 while ((vpos > vtarget || first) && from > BEGV)
1899 Lisp_Object propval;
1901 prevline = find_next_newline_no_quit (from - 1, -1);
1902 while (prevline > BEGV
1903 && ((selective > 0
1904 && indented_beyond_p (prevline,
1905 CHAR_TO_BYTE (prevline),
1906 (double) selective)) /* iftc */
1907 /* Watch out for newlines with `invisible' property.
1908 When moving upward, check the newline before. */
1909 || (propval = Fget_char_property (make_number (prevline - 1),
1910 Qinvisible,
1911 text_prop_object),
1912 TEXT_PROP_MEANS_INVISIBLE (propval))))
1913 prevline = find_next_newline_no_quit (prevline - 1, -1);
1914 pos = *compute_motion (prevline, 0,
1915 lmargin + (prevline == BEG ? start_hpos : 0),
1917 from,
1918 /* Don't care for VPOS... */
1919 1 << (BITS_PER_SHORT - 1),
1920 /* ... nor HPOS. */
1921 1 << (BITS_PER_SHORT - 1),
1922 -1, hscroll,
1923 /* This compensates for start_hpos
1924 so that a tab as first character
1925 still occupies 8 columns. */
1926 (prevline == BEG ? -start_hpos : 0),
1928 vpos -= pos.vpos;
1929 first = 0;
1930 from = prevline;
1933 /* If we made exactly the desired vertical distance,
1934 or if we hit beginning of buffer,
1935 return point found */
1936 if (vpos >= vtarget)
1938 val_vmotion.bufpos = from;
1939 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1940 val_vmotion.vpos = vpos;
1941 val_vmotion.hpos = lmargin;
1942 val_vmotion.contin = 0;
1943 val_vmotion.prevhpos = 0;
1944 val_vmotion.ovstring_chars_done = 0;
1945 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1946 return &val_vmotion;
1949 /* Otherwise find the correct spot by moving down */
1951 /* Moving downward is simple, but must calculate from beg of line
1952 to determine hpos of starting point */
1953 from_byte = CHAR_TO_BYTE (from);
1954 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1956 Lisp_Object propval;
1958 prevline = find_next_newline_no_quit (from, -1);
1959 while (prevline > BEGV
1960 && ((selective > 0
1961 && indented_beyond_p (prevline,
1962 CHAR_TO_BYTE (prevline),
1963 (double) selective)) /* iftc */
1964 /* Watch out for newlines with `invisible' property.
1965 When moving downward, check the newline after. */
1966 || (propval = Fget_char_property (make_number (prevline),
1967 Qinvisible,
1968 text_prop_object),
1969 TEXT_PROP_MEANS_INVISIBLE (propval))))
1970 prevline = find_next_newline_no_quit (prevline - 1, -1);
1971 pos = *compute_motion (prevline, 0,
1972 lmargin + (prevline == BEG
1973 ? start_hpos : 0),
1975 from,
1976 /* Don't care for VPOS... */
1977 1 << (BITS_PER_SHORT - 1),
1978 /* ... nor HPOS. */
1979 1 << (BITS_PER_SHORT - 1),
1980 -1, hscroll,
1981 (prevline == BEG ? -start_hpos : 0),
1983 did_motion = 1;
1985 else
1987 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1988 pos.vpos = 0;
1989 pos.tab_offset = 0;
1990 did_motion = 0;
1992 return compute_motion (from, vpos, pos.hpos, did_motion,
1993 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1994 -1, hscroll,
1995 pos.tab_offset - (from == BEG ? start_hpos : 0),
1999 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
2000 doc: /* Move point to start of the screen line LINES lines down.
2001 If LINES is negative, this means moving up.
2003 This function is an ordinary cursor motion function
2004 which calculates the new position based on how text would be displayed.
2005 The new position may be the start of a line,
2006 or just the start of a continuation line.
2007 The function returns number of screen lines moved over;
2008 that usually equals LINES, but may be closer to zero
2009 if beginning or end of buffer was reached.
2011 The optional second argument WINDOW specifies the window to use for
2012 parameters such as width, horizontal scrolling, and so on.
2013 The default is to use the selected window's parameters.
2015 LINES can optionally take the form (COLS . LINES), in which case
2016 the motion will not stop at the start of a screen line but on
2017 its column COLS (if such exists on that line, that is).
2019 `vertical-motion' always uses the current buffer,
2020 regardless of which buffer is displayed in WINDOW.
2021 This is consistent with other cursor motion functions
2022 and makes it possible to use `vertical-motion' in any buffer,
2023 whether or not it is currently displayed in some window. */)
2024 (lines, window)
2025 Lisp_Object lines, window;
2027 struct it it;
2028 struct text_pos pt;
2029 struct window *w;
2030 Lisp_Object old_buffer;
2031 struct gcpro gcpro1;
2032 Lisp_Object lcols = Qnil;
2033 double cols;
2035 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
2036 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
2038 lcols = XCAR (lines);
2039 cols = INTEGERP (lcols) ? (double) XINT (lcols) : XFLOAT_DATA (lcols);
2040 lines = XCDR (lines);
2043 CHECK_NUMBER (lines);
2044 if (! NILP (window))
2045 CHECK_WINDOW (window);
2046 else
2047 window = selected_window;
2048 w = XWINDOW (window);
2050 old_buffer = Qnil;
2051 GCPRO1 (old_buffer);
2052 if (XBUFFER (w->buffer) != current_buffer)
2054 /* Set the window's buffer temporarily to the current buffer. */
2055 old_buffer = w->buffer;
2056 XSETBUFFER (w->buffer, current_buffer);
2059 if (noninteractive)
2061 struct position pos;
2062 pos = *vmotion (PT, XINT (lines), w);
2063 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2065 else
2067 int it_start, first_x, it_overshoot_expected;
2069 SET_TEXT_POS (pt, PT, PT_BYTE);
2070 start_display (&it, w, pt);
2071 first_x = it.first_visible_x;
2072 it_start = IT_CHARPOS (it);
2074 /* See comments below for why we calculate this. */
2075 if (XINT (lines) > 0)
2077 if (it.cmp_it.id >= 0)
2078 it_overshoot_expected = 1;
2079 else if (it.method == GET_FROM_STRING)
2081 const char *s = SDATA (it.string);
2082 const char *e = s + SBYTES (it.string);
2083 while (s < e && *s != '\n')
2084 ++s;
2085 it_overshoot_expected = (s == e) ? -1 : 0;
2087 else
2088 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2089 || it.method == GET_FROM_STRETCH);
2092 /* Scan from the start of the line containing PT. If we don't
2093 do this, we start moving with IT->current_x == 0, while PT is
2094 really at some x > 0. */
2095 reseat_at_previous_visible_line_start (&it);
2096 it.current_x = it.hpos = 0;
2097 if (IT_CHARPOS (it) != PT)
2098 /* We used to temporarily disable selective display here; the
2099 comment said this is "so we don't move too far" (2005-01-19
2100 checkin by kfs). But this does nothing useful that I can
2101 tell, and it causes Bug#2694 . -- cyd */
2102 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2104 if (XINT (lines) <= 0)
2106 it.vpos = 0;
2107 /* Do this even if LINES is 0, so that we move back to the
2108 beginning of the current line as we ought. */
2109 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2110 move_it_by_lines (&it, XINT (lines), 0);
2112 else
2114 if (IT_CHARPOS (it) > it_start)
2116 /* IT may move too far if truncate-lines is on and PT
2117 lies beyond the right margin. In that case,
2118 backtrack unless the starting point is on an image,
2119 stretch glyph, composition, or Lisp string. */
2120 if (!it_overshoot_expected
2121 /* Also, backtrack if the Lisp string contains no
2122 newline, but there is a newline right after it.
2123 In this case, IT overshoots if there is an
2124 after-string just before the newline. */
2125 || (it_overshoot_expected < 0
2126 && it.method == GET_FROM_BUFFER
2127 && it.c == '\n'))
2128 move_it_by_lines (&it, -1, 0);
2129 it.vpos = 0;
2130 move_it_by_lines (&it, XINT (lines), 0);
2132 else
2134 /* Otherwise, we are at the first row occupied by PT,
2135 which might span multiple screen lines (e.g., if it's
2136 on a multi-line display string). We want to start
2137 from the last line that it occupies. */
2138 if (it_start < ZV)
2140 while (IT_CHARPOS (it) <= it_start)
2142 it.vpos = 0;
2143 move_it_by_lines (&it, 1, 0);
2145 if (XINT (lines) > 1)
2146 move_it_by_lines (&it, XINT (lines) - 1, 0);
2148 else
2150 it.vpos = 0;
2151 move_it_by_lines (&it, XINT (lines), 0);
2156 /* Move to the goal column, if one was specified. */
2157 if (!NILP (lcols))
2159 /* If the window was originally hscrolled, move forward by
2160 the hscrolled amount first. */
2161 if (first_x > 0)
2163 move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X);
2164 it.current_x = 0;
2166 move_it_in_display_line
2167 (&it, ZV,
2168 (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
2169 MOVE_TO_X);
2172 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2175 if (BUFFERP (old_buffer))
2176 w->buffer = old_buffer;
2178 RETURN_UNGCPRO (make_number (it.vpos));
2183 /* File's initialization. */
2185 void
2186 syms_of_indent ()
2188 DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
2189 doc: /* *Indentation can insert tabs if this is non-nil. */);
2190 indent_tabs_mode = 1;
2192 defsubr (&Scurrent_indentation);
2193 defsubr (&Sindent_to);
2194 defsubr (&Scurrent_column);
2195 defsubr (&Smove_to_column);
2196 defsubr (&Svertical_motion);
2197 defsubr (&Scompute_motion);
2200 /* arch-tag: 9adfea44-71f7-4988-8ee3-96da15c502cc
2201 (do not change this comment) */