gnus-ems.el: Provide compatibility functions for gnus-set-process-plist by Katsumi...
[emacs.git] / src / indent.c
blob970904cba7b0961bb65cad828549a5de04b2fc8c
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 (void);
65 static double position_indentation (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 (void)
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 (int c, struct Lisp_Char_Table *dp)
94 Lisp_Object elt;
96 /* These width computations were determined by examining the cases
97 in display_text_line. */
99 /* Everything can be handled by the display table, if it's
100 present and the element is right. */
101 if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
102 return XVECTOR (elt)->size;
104 /* Some characters are special. */
105 if (c == '\n' || c == '\t' || c == '\015')
106 return 0;
108 /* Printing characters have width 1. */
109 else if (c >= 040 && c < 0177)
110 return 1;
112 /* Everybody else (control characters, metacharacters) has other
113 widths. We could return their actual widths here, but they
114 depend on things like ctl_arrow and crud like that, and they're
115 not very common at all. So we'll just claim we don't know their
116 widths. */
117 else
118 return 0;
121 /* Return true if the display table DISPTAB specifies the same widths
122 for characters as WIDTHTAB. We use this to decide when to
123 invalidate the buffer's width_run_cache. */
126 disptab_matches_widthtab (struct Lisp_Char_Table *disptab, struct Lisp_Vector *widthtab)
128 int i;
130 if (widthtab->size != 256)
131 abort ();
133 for (i = 0; i < 256; i++)
134 if (character_width (i, disptab)
135 != XFASTINT (widthtab->contents[i]))
136 return 0;
138 return 1;
141 /* Recompute BUF's width table, using the display table DISPTAB. */
143 void
144 recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
146 int i;
147 struct Lisp_Vector *widthtab;
149 if (!VECTORP (buf->width_table))
150 buf->width_table = Fmake_vector (make_number (256), make_number (0));
151 widthtab = XVECTOR (buf->width_table);
152 if (widthtab->size != 256)
153 abort ();
155 for (i = 0; i < 256; i++)
156 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
159 /* Allocate or free the width run cache, as requested by the current
160 state of current_buffer's cache_long_line_scans variable. */
162 static void
163 width_run_cache_on_off (void)
165 if (NILP (current_buffer->cache_long_line_scans)
166 /* And, for the moment, this feature doesn't work on multibyte
167 characters. */
168 || !NILP (current_buffer->enable_multibyte_characters))
170 /* It should be off. */
171 if (current_buffer->width_run_cache)
173 free_region_cache (current_buffer->width_run_cache);
174 current_buffer->width_run_cache = 0;
175 current_buffer->width_table = Qnil;
178 else
180 /* It should be on. */
181 if (current_buffer->width_run_cache == 0)
183 current_buffer->width_run_cache = new_region_cache ();
184 recompute_width_table (current_buffer, buffer_display_table ());
190 /* Skip some invisible characters starting from POS.
191 This includes characters invisible because of text properties
192 and characters invisible because of overlays.
194 If position POS is followed by invisible characters,
195 skip some of them and return the position after them.
196 Otherwise return POS itself.
198 Set *NEXT_BOUNDARY_P to the next position at which
199 it will be necessary to call this function again.
201 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
202 to a value greater than TO.
204 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
205 take account of overlays that apply only in WINDOW.
207 We don't necessarily skip all the invisible characters after POS
208 because that could take a long time. We skip a reasonable number
209 which can be skipped quickly. If there might be more invisible
210 characters immediately following, then *NEXT_BOUNDARY_P
211 will equal the return value. */
213 EMACS_INT
214 skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Object window)
216 Lisp_Object prop, position, overlay_limit, proplimit;
217 Lisp_Object buffer, tmp;
218 EMACS_INT end;
219 int inv_p;
221 XSETFASTINT (position, pos);
222 XSETBUFFER (buffer, current_buffer);
224 /* Give faster response for overlay lookup near POS. */
225 recenter_overlay_lists (current_buffer, pos);
227 /* We must not advance farther than the next overlay change.
228 The overlay change might change the invisible property;
229 or there might be overlay strings to be displayed there. */
230 overlay_limit = Fnext_overlay_change (position);
231 /* As for text properties, this gives a lower bound
232 for where the invisible text property could change. */
233 proplimit = Fnext_property_change (position, buffer, Qt);
234 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
235 proplimit = overlay_limit;
236 /* PROPLIMIT is now a lower bound for the next change
237 in invisible status. If that is plenty far away,
238 use that lower bound. */
239 if (XFASTINT (proplimit) > pos + 100 || XFASTINT (proplimit) >= to)
240 *next_boundary_p = XFASTINT (proplimit);
241 /* Otherwise, scan for the next `invisible' property change. */
242 else
244 /* Don't scan terribly far. */
245 XSETFASTINT (proplimit, min (pos + 100, to));
246 /* No matter what, don't go past next overlay change. */
247 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
248 proplimit = overlay_limit;
249 tmp = Fnext_single_property_change (position, Qinvisible,
250 buffer, proplimit);
251 end = XFASTINT (tmp);
252 #if 0
253 /* Don't put the boundary in the middle of multibyte form if
254 there is no actual property change. */
255 if (end == pos + 100
256 && !NILP (current_buffer->enable_multibyte_characters)
257 && end < ZV)
258 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
259 end--;
260 #endif
261 *next_boundary_p = end;
263 /* if the `invisible' property is set, we can skip to
264 the next property change */
265 prop = Fget_char_property (position, Qinvisible,
266 (!NILP (window)
267 && EQ (XWINDOW (window)->buffer, buffer))
268 ? window : buffer);
269 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
270 /* When counting columns (window == nil), don't skip over ellipsis text. */
271 if (NILP (window) ? inv_p == 1 : inv_p)
272 return *next_boundary_p;
273 return pos;
276 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
278 DP is a display table or NULL.
280 This macro is used in current_column_1, Fmove_to_column, and
281 compute_motion. */
283 #define MULTIBYTE_BYTES_WIDTH(p, dp) \
284 do { \
285 int c; \
287 wide_column = 0; \
288 c = STRING_CHAR_AND_LENGTH (p, bytes); \
289 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
290 width = bytes * 4; \
291 else \
293 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) \
294 width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; \
295 else \
296 width = CHAR_WIDTH (c); \
297 if (width > 1) \
298 wide_column = width; \
300 } while (0)
303 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
304 doc: /* Return the horizontal position of point. Beginning of line is column 0.
305 This is calculated by adding together the widths of all the displayed
306 representations of the character between the start of the previous line
307 and point (eg. control characters will have a width of 2 or 4, tabs
308 will have a variable width).
309 Ignores finite width of frame, which means that this function may return
310 values greater than (frame-width).
311 Whether the line is visible (if `selective-display' is t) has no effect;
312 however, ^M is treated as end of line when `selective-display' is t.
313 Text that has an invisible property is considered as having width 0, unless
314 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
315 (void)
317 Lisp_Object temp;
318 XSETFASTINT (temp, (int) current_column ()); /* iftc */
319 return temp;
322 /* Cancel any recorded value of the horizontal position. */
324 void
325 invalidate_current_column (void)
327 last_known_column_point = 0;
330 double
331 current_column (void)
333 register int col;
334 register unsigned char *ptr, *stop;
335 register int tab_seen;
336 int post_tab;
337 register int c;
338 register int tab_width = XINT (current_buffer->tab_width);
339 int ctl_arrow = !NILP (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 if (tab_width <= 0 || tab_width > 1000)
369 tab_width = 8;
371 col = 0, tab_seen = 0, post_tab = 0;
373 while (1)
375 EMACS_INT i, n;
376 Lisp_Object charvec;
378 if (ptr == stop)
380 /* We stopped either for the beginning of the buffer
381 or for the gap. */
382 if (ptr == BEGV_ADDR)
383 break;
385 /* It was the gap. Jump back over it. */
386 stop = BEGV_ADDR;
387 ptr = GPT_ADDR;
389 /* Check whether that brings us to beginning of buffer. */
390 if (BEGV >= GPT)
391 break;
394 c = *--ptr;
396 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
398 charvec = DISP_CHAR_VECTOR (dp, c);
399 n = ASIZE (charvec);
401 else
403 charvec = Qnil;
404 n = 1;
407 for (i = n - 1; i >= 0; --i)
409 if (VECTORP (charvec))
411 /* This should be handled the same as
412 next_element_from_display_vector does it. */
413 Lisp_Object entry = AREF (charvec, i);
415 if (GLYPH_CODE_P (entry)
416 && GLYPH_CODE_CHAR_VALID_P (entry))
417 c = GLYPH_CODE_CHAR (entry);
418 else
419 c = ' ';
422 if (c >= 040 && c < 0177)
423 col++;
424 else if (c == '\n'
425 || (c == '\r'
426 && EQ (current_buffer->selective_display, Qt)))
428 ptr++;
429 goto start_of_line_found;
431 else if (c == '\t')
433 if (tab_seen)
434 col = ((col + tab_width) / tab_width) * tab_width;
436 post_tab += col;
437 col = 0;
438 tab_seen = 1;
440 else if (VECTORP (charvec))
441 /* With a display table entry, C is displayed as is, and
442 not displayed as \NNN or as ^N. If C is a single-byte
443 character, it takes one column. If C is multi-byte in
444 an unibyte buffer, it's translated to unibyte, so it
445 also takes one column. */
446 ++col;
447 else
448 col += (ctl_arrow && c < 0200) ? 2 : 4;
452 start_of_line_found:
454 if (tab_seen)
456 col = ((col + tab_width) / tab_width) * tab_width;
457 col += post_tab;
460 if (ptr == BEGV_ADDR)
461 current_column_bol_cache = BEGV;
462 else
463 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
465 last_known_column = col;
466 last_known_column_point = PT;
467 last_known_column_modified = MODIFF;
469 return col;
473 /* Check the presence of a display property and compute its width.
474 If a property was found and its width was found as well, return
475 its width (>= 0) and set the position of the end of the property
476 in ENDPOS.
477 Otherwise just return -1. */
478 static int
479 check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos)
481 Lisp_Object val, overlay;
483 if (CONSP (val = get_char_property_and_overlay
484 (make_number (pos), Qdisplay, Qnil, &overlay))
485 && EQ (Qspace, XCAR (val)))
486 { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */
487 Lisp_Object plist = XCDR (val), prop;
488 int width = -1;
490 if ((prop = Fplist_get (plist, QCwidth), NATNUMP (prop)))
491 width = XINT (prop);
492 else if (FLOATP (prop))
493 width = (int)(XFLOAT_DATA (prop) + 0.5);
494 else if ((prop = Fplist_get (plist, QCalign_to), NATNUMP (prop)))
495 width = XINT (prop) - col;
496 else if (FLOATP (prop))
497 width = (int)(XFLOAT_DATA (prop) + 0.5) - col;
499 if (width >= 0)
501 EMACS_INT start;
502 if (OVERLAYP (overlay))
503 *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
504 else
505 get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
506 return width;
509 return -1;
512 /* Scanning from the beginning of the current line, stop at the buffer
513 position ENDPOS or at the column GOALCOL or at the end of line, whichever
514 comes first.
515 Return the resulting buffer position and column in ENDPOS and GOALCOL.
516 PREVCOL gets set to the column of the previous position (it's always
517 strictly smaller than the goal column). */
518 static void
519 scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol)
521 register EMACS_INT tab_width = XINT (current_buffer->tab_width);
522 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
523 register struct Lisp_Char_Table *dp = buffer_display_table ();
524 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
525 struct composition_it cmp_it;
526 Lisp_Object window;
527 struct window *w;
529 /* Start the scan at the beginning of this line with column number 0. */
530 register EMACS_INT col = 0, prev_col = 0;
531 EMACS_INT goal = goalcol ? *goalcol : MOST_POSITIVE_FIXNUM;
532 EMACS_INT end = endpos ? *endpos : PT;
533 EMACS_INT scan, scan_byte;
534 EMACS_INT next_boundary;
536 EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
537 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
538 current_column_bol_cache = PT;
539 scan = PT, scan_byte = PT_BYTE;
540 SET_PT_BOTH (opoint, opoint_byte);
541 next_boundary = scan;
544 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
545 w = ! NILP (window) ? XWINDOW (window) : NULL;
547 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
548 memset (&cmp_it, 0, sizeof cmp_it);
549 cmp_it.id = -1;
550 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
552 /* Scan forward to the target position. */
553 while (scan < end)
555 int c;
557 /* Occasionally we may need to skip invisible text. */
558 while (scan == next_boundary)
560 EMACS_INT old_scan = scan;
561 /* This updates NEXT_BOUNDARY to the next place
562 where we might need to skip more invisible text. */
563 scan = skip_invisible (scan, &next_boundary, end, Qnil);
564 if (scan != old_scan)
565 scan_byte = CHAR_TO_BYTE (scan);
566 if (scan >= end)
567 goto endloop;
570 /* Test reaching the goal column. We do this after skipping
571 invisible characters, so that we put point before the
572 character on which the cursor will appear. */
573 if (col >= goal)
574 break;
575 prev_col = col;
577 { /* Check display property. */
578 EMACS_INT end;
579 int width = check_display_width (scan, col, &end);
580 if (width >= 0)
582 col += width;
583 if (end > scan) /* Avoid infinite loops with 0-width overlays. */
585 scan = end; scan_byte = charpos_to_bytepos (scan);
586 continue;
591 /* Check composition sequence. */
592 if (cmp_it.id >= 0
593 || (scan == cmp_it.stop_pos
594 && composition_reseat_it (&cmp_it, scan, scan_byte, end,
595 w, NULL, Qnil)))
596 composition_update_it (&cmp_it, scan, scan_byte, Qnil);
597 if (cmp_it.id >= 0)
599 scan += cmp_it.nchars;
600 scan_byte += cmp_it.nbytes;
601 if (scan <= end)
602 col += cmp_it.width;
603 if (cmp_it.to == cmp_it.nglyphs)
605 cmp_it.id = -1;
606 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end,
607 Qnil);
609 else
610 cmp_it.from = cmp_it.to;
611 continue;
614 c = FETCH_BYTE (scan_byte);
616 /* See if there is a display table and it relates
617 to this character. */
619 if (dp != 0
620 && ! (multibyte && LEADING_CODE_P (c))
621 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
623 Lisp_Object charvec;
624 EMACS_INT i, n;
626 /* This character is displayed using a vector of glyphs.
627 Update the column/position based on those glyphs. */
629 charvec = DISP_CHAR_VECTOR (dp, c);
630 n = ASIZE (charvec);
632 for (i = 0; i < n; i++)
634 /* This should be handled the same as
635 next_element_from_display_vector does it. */
636 Lisp_Object entry = AREF (charvec, i);
638 if (GLYPH_CODE_P (entry)
639 && GLYPH_CODE_CHAR_VALID_P (entry))
640 c = GLYPH_CODE_CHAR (entry);
641 else
642 c = ' ';
644 if (c == '\n')
645 goto endloop;
646 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
647 goto endloop;
648 if (c == '\t')
650 col += tab_width;
651 col = col / tab_width * tab_width;
653 else
654 ++col;
657 else
659 /* The display table doesn't affect this character;
660 it displays as itself. */
662 if (c == '\n')
663 goto endloop;
664 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
665 goto endloop;
666 if (c == '\t')
668 col += tab_width;
669 col = col / tab_width * tab_width;
671 else if (multibyte && LEADING_CODE_P (c))
673 /* Start of multi-byte form. */
674 unsigned char *ptr;
675 int bytes, width, wide_column;
677 ptr = BYTE_POS_ADDR (scan_byte);
678 MULTIBYTE_BYTES_WIDTH (ptr, dp);
679 /* Subtract one to compensate for the increment
680 that is going to happen below. */
681 scan_byte += bytes - 1;
682 col += width;
684 else if (ctl_arrow && (c < 040 || c == 0177))
685 col += 2;
686 else if (c < 040 || c >= 0177)
687 col += 4;
688 else
689 col++;
691 scan++;
692 scan_byte++;
695 endloop:
697 last_known_column = col;
698 last_known_column_point = PT;
699 last_known_column_modified = MODIFF;
701 if (goalcol)
702 *goalcol = col;
703 if (endpos)
704 *endpos = scan;
705 if (prevcol)
706 *prevcol = prev_col;
709 /* Return the column number of position POS
710 by scanning forward from the beginning of the line.
711 This function handles characters that are invisible
712 due to text properties or overlays. */
714 static double
715 current_column_1 (void)
717 EMACS_INT col = MOST_POSITIVE_FIXNUM;
718 EMACS_INT opoint = PT;
720 scan_for_column (&opoint, &col, NULL);
721 return col;
725 #if 0 /* Not used. */
727 /* Return the width in columns of the part of STRING from BEG to END.
728 If BEG is nil, that stands for the beginning of STRING.
729 If END is nil, that stands for the end of STRING. */
731 static double
732 string_display_width (string, beg, end)
733 Lisp_Object string, beg, end;
735 register int col;
736 register unsigned char *ptr, *stop;
737 register int tab_seen;
738 int post_tab;
739 register int c;
740 register int tab_width = XINT (current_buffer->tab_width);
741 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
742 register struct Lisp_Char_Table *dp = buffer_display_table ();
743 int b, e;
745 if (NILP (end))
746 e = SCHARS (string);
747 else
749 CHECK_NUMBER (end);
750 e = XINT (end);
753 if (NILP (beg))
754 b = 0;
755 else
757 CHECK_NUMBER (beg);
758 b = XINT (beg);
761 /* Make a pointer for decrementing through the chars before point. */
762 ptr = SDATA (string) + e;
763 /* Make a pointer to where consecutive chars leave off,
764 going backwards from point. */
765 stop = SDATA (string) + b;
767 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
769 col = 0, tab_seen = 0, post_tab = 0;
771 while (1)
773 if (ptr == stop)
774 break;
776 c = *--ptr;
777 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
778 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
779 else if (c >= 040 && c < 0177)
780 col++;
781 else if (c == '\n')
782 break;
783 else if (c == '\t')
785 if (tab_seen)
786 col = ((col + tab_width) / tab_width) * tab_width;
788 post_tab += col;
789 col = 0;
790 tab_seen = 1;
792 else
793 col += (ctl_arrow && c < 0200) ? 2 : 4;
796 if (tab_seen)
798 col = ((col + tab_width) / tab_width) * tab_width;
799 col += post_tab;
802 return col;
805 #endif /* 0 */
808 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
809 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
810 Optional second argument MINIMUM says always do at least MINIMUM spaces
811 even if that goes past COLUMN; by default, MINIMUM is zero.
813 The return value is COLUMN. */)
814 (Lisp_Object column, Lisp_Object minimum)
816 int mincol;
817 register int fromcol;
818 register int tab_width = XINT (current_buffer->tab_width);
820 CHECK_NUMBER (column);
821 if (NILP (minimum))
822 XSETFASTINT (minimum, 0);
823 CHECK_NUMBER (minimum);
825 fromcol = current_column ();
826 mincol = fromcol + XINT (minimum);
827 if (mincol < XINT (column)) mincol = XINT (column);
829 if (fromcol == mincol)
830 return make_number (mincol);
832 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
834 if (indent_tabs_mode)
836 Lisp_Object n;
837 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
838 if (XFASTINT (n) != 0)
840 Finsert_char (make_number ('\t'), n, Qt);
842 fromcol = (mincol / tab_width) * tab_width;
846 XSETFASTINT (column, mincol - fromcol);
847 Finsert_char (make_number (' '), column, Qt);
849 last_known_column = mincol;
850 last_known_column_point = PT;
851 last_known_column_modified = MODIFF;
853 XSETINT (column, mincol);
854 return column;
858 static double position_indentation (int);
860 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
861 0, 0, 0,
862 doc: /* Return the indentation of the current line.
863 This is the horizontal position of the character
864 following any initial whitespace. */)
865 (void)
867 Lisp_Object val;
868 int opoint = PT, opoint_byte = PT_BYTE;
870 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
872 XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */
873 SET_PT_BOTH (opoint, opoint_byte);
874 return val;
877 static double
878 position_indentation (register int pos_byte)
880 register EMACS_INT column = 0;
881 register EMACS_INT tab_width = XINT (current_buffer->tab_width);
882 register unsigned char *p;
883 register unsigned char *stop;
884 unsigned char *start;
885 EMACS_INT next_boundary_byte = pos_byte;
886 EMACS_INT ceiling = next_boundary_byte;
888 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
890 p = BYTE_POS_ADDR (pos_byte);
891 /* STOP records the value of P at which we will need
892 to think about the gap, or about invisible text,
893 or about the end of the buffer. */
894 stop = p;
895 /* START records the starting value of P. */
896 start = p;
897 while (1)
899 while (p == stop)
901 EMACS_INT stop_pos_byte;
903 /* If we have updated P, set POS_BYTE to match.
904 The first time we enter the loop, POS_BYTE is already right. */
905 if (p != start)
906 pos_byte = PTR_BYTE_POS (p);
907 /* Consider the various reasons STOP might have been set here. */
908 if (pos_byte == ZV_BYTE)
909 return column;
910 if (pos_byte == next_boundary_byte)
912 EMACS_INT next_boundary;
913 EMACS_INT pos = BYTE_TO_CHAR (pos_byte);
914 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
915 pos_byte = CHAR_TO_BYTE (pos);
916 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
918 if (pos_byte >= ceiling)
919 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
920 /* Compute the next place we need to stop and think,
921 and set STOP accordingly. */
922 stop_pos_byte = min (ceiling, next_boundary_byte);
923 /* The -1 and +1 arrange to point at the first byte of gap
924 (if STOP_POS_BYTE is the position of the gap)
925 rather than at the data after the gap. */
927 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
928 p = BYTE_POS_ADDR (pos_byte);
930 switch (*p++)
932 case 0240:
933 if (! NILP (current_buffer->enable_multibyte_characters))
934 return column;
935 case ' ':
936 column++;
937 break;
938 case '\t':
939 column += tab_width - column % tab_width;
940 break;
941 default:
942 if (ASCII_BYTE_P (p[-1])
943 || NILP (current_buffer->enable_multibyte_characters))
944 return column;
946 int c;
947 pos_byte = PTR_BYTE_POS (p - 1);
948 c = FETCH_MULTIBYTE_CHAR (pos_byte);
949 if (CHAR_HAS_CATEGORY (c, ' '))
951 column++;
952 INC_POS (pos_byte);
953 p = BYTE_POS_ADDR (pos_byte);
955 else
956 return column;
962 /* Test whether the line beginning at POS is indented beyond COLUMN.
963 Blank lines are treated as if they had the same indentation as the
964 preceding line. */
967 indented_beyond_p (int pos, int pos_byte, double column)
969 double val;
970 int opoint = PT, opoint_byte = PT_BYTE;
972 SET_PT_BOTH (pos, pos_byte);
973 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
974 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
976 val = position_indentation (PT_BYTE);
977 SET_PT_BOTH (opoint, opoint_byte);
978 return val >= column; /* hmm, float comparison */
981 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
982 doc: /* Move point to column COLUMN in the current line.
983 Interactively, COLUMN is the value of prefix numeric argument.
984 The column of a character is calculated by adding together the widths
985 as displayed of the previous characters in the line.
986 This function ignores line-continuation;
987 there is no upper limit on the column number a character can have
988 and horizontal scrolling has no effect.
990 If specified column is within a character, point goes after that character.
991 If it's past end of line, point goes to end of line.
993 Optional second argument FORCE non-nil means if COLUMN is in the
994 middle of a tab character, change it to spaces.
995 In addition, if FORCE is t, and the line is too short to reach
996 COLUMN, add spaces/tabs to get there.
998 The return value is the current column. */)
999 (Lisp_Object column, Lisp_Object force)
1001 EMACS_INT pos;
1002 EMACS_INT col, prev_col;
1003 EMACS_INT goal;
1005 CHECK_NATNUM (column);
1006 goal = XINT (column);
1008 col = goal;
1009 pos = ZV;
1010 scan_for_column (&pos, &col, &prev_col);
1012 SET_PT (pos);
1014 /* If a tab char made us overshoot, change it to spaces
1015 and scan through it again. */
1016 if (!NILP (force) && col > goal)
1018 int c;
1019 EMACS_INT pos_byte = PT_BYTE;
1021 DEC_POS (pos_byte);
1022 c = FETCH_CHAR (pos_byte);
1023 if (c == '\t' && prev_col < goal)
1025 EMACS_INT goal_pt, goal_pt_byte;
1027 /* Insert spaces in front of the tab to reach GOAL. Do this
1028 first so that a marker at the end of the tab gets
1029 adjusted. */
1030 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1031 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1033 /* Now delete the tab, and indent to COL. */
1034 del_range (PT, PT + 1);
1035 goal_pt = PT;
1036 goal_pt_byte = PT_BYTE;
1037 Findent_to (make_number (col), Qnil);
1038 SET_PT_BOTH (goal_pt, goal_pt_byte);
1040 /* Set the last_known... vars consistently. */
1041 col = goal;
1045 /* If line ends prematurely, add space to the end. */
1046 if (col < goal && EQ (force, Qt))
1047 Findent_to (make_number (col = goal), Qnil);
1049 last_known_column = col;
1050 last_known_column_point = PT;
1051 last_known_column_modified = MODIFF;
1053 return make_number (col);
1056 /* compute_motion: compute buffer posn given screen posn and vice versa */
1058 struct position val_compute_motion;
1060 /* Scan the current buffer forward from offset FROM, pretending that
1061 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1062 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1063 and return the ending buffer position and screen location. If we
1064 can't hit the requested column exactly (because of a tab or other
1065 multi-column character), overshoot.
1067 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1068 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1069 earlier call to compute_motion. The other common case is that FROMHPOS
1070 is zero and FROM is a position that "belongs" at column zero, but might
1071 be shifted by overlay strings; in this case DID_MOTION should be 0.
1073 WIDTH is the number of columns available to display text;
1074 compute_motion uses this to handle continuation lines and such.
1075 If WIDTH is -1, use width of window's text area adjusted for
1076 continuation glyph when needed.
1078 HSCROLL is the number of columns not being displayed at the left
1079 margin; this is usually taken from a window's hscroll member.
1080 TAB_OFFSET is the number of columns of the first tab that aren't
1081 being displayed, perhaps because of a continuation line or
1082 something.
1084 compute_motion returns a pointer to a struct position. The bufpos
1085 member gives the buffer position at the end of the scan, and hpos
1086 and vpos give its cartesian location. prevhpos is the column at
1087 which the character before bufpos started, and contin is non-zero
1088 if we reached the current line by continuing the previous.
1090 Note that FROMHPOS and TOHPOS should be expressed in real screen
1091 columns, taking HSCROLL and the truncation glyph at the left margin
1092 into account. That is, beginning-of-line moves you to the hpos
1093 -HSCROLL + (HSCROLL > 0).
1095 For example, to find the buffer position of column COL of line LINE
1096 of a certain window, pass the window's starting location as FROM
1097 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1098 Pass the buffer's ZV as TO, to limit the scan to the end of the
1099 visible section of the buffer, and pass LINE and COL as TOVPOS and
1100 TOHPOS.
1102 When displaying in window w, a typical formula for WIDTH is:
1104 window_width - 1
1105 - (has_vertical_scroll_bars
1106 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1107 : (window_width + window_left != frame_cols))
1109 where
1110 window_width is XFASTINT (w->total_cols),
1111 window_left is XFASTINT (w->left_col),
1112 has_vertical_scroll_bars is
1113 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1114 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1116 Or you can let window_box_text_cols do this all for you, and write:
1117 window_box_text_cols (w) - 1
1119 The `-1' accounts for the continuation-line backslashes; the rest
1120 accounts for window borders if the window is split horizontally, and
1121 the scroll bars if they are turned on. */
1123 struct position *
1124 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)
1126 register EMACS_INT hpos = fromhpos;
1127 register EMACS_INT vpos = fromvpos;
1129 register EMACS_INT pos;
1130 EMACS_INT pos_byte;
1131 register int c = 0;
1132 register EMACS_INT tab_width = XFASTINT (current_buffer->tab_width);
1133 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
1134 register struct Lisp_Char_Table *dp = window_display_table (win);
1135 int selective
1136 = (INTEGERP (current_buffer->selective_display)
1137 ? XINT (current_buffer->selective_display)
1138 : !NILP (current_buffer->selective_display) ? -1 : 0);
1139 int selective_rlen
1140 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1141 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
1142 /* The next location where the `invisible' property changes, or an
1143 overlay starts or ends. */
1144 EMACS_INT next_boundary = from;
1146 /* For computing runs of characters with similar widths.
1147 Invariant: width_run_width is zero, or all the characters
1148 from width_run_start to width_run_end have a fixed width of
1149 width_run_width. */
1150 EMACS_INT width_run_start = from;
1151 EMACS_INT width_run_end = from;
1152 EMACS_INT width_run_width = 0;
1153 Lisp_Object *width_table;
1154 Lisp_Object buffer;
1156 /* The next buffer pos where we should consult the width run cache. */
1157 EMACS_INT next_width_run = from;
1158 Lisp_Object window;
1160 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
1161 /* If previous char scanned was a wide character,
1162 this is the column where it ended. Otherwise, this is 0. */
1163 EMACS_INT wide_column_end_hpos = 0;
1164 EMACS_INT prev_pos; /* Previous buffer position. */
1165 EMACS_INT prev_pos_byte; /* Previous buffer position. */
1166 EMACS_INT prev_hpos = 0;
1167 EMACS_INT prev_vpos = 0;
1168 EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
1169 EMACS_INT prev_tab_offset; /* Previous tab offset. */
1170 EMACS_INT continuation_glyph_width;
1172 struct composition_it cmp_it;
1174 XSETBUFFER (buffer, current_buffer);
1175 XSETWINDOW (window, win);
1177 width_run_cache_on_off ();
1178 if (dp == buffer_display_table ())
1179 width_table = (VECTORP (current_buffer->width_table)
1180 ? XVECTOR (current_buffer->width_table)->contents
1181 : 0);
1182 else
1183 /* If the window has its own display table, we can't use the width
1184 run cache, because that's based on the buffer's display table. */
1185 width_table = 0;
1187 if (tab_width <= 0 || tab_width > 1000)
1188 tab_width = 8;
1190 /* Negative width means use all available text columns. */
1191 if (width < 0)
1193 width = window_box_text_cols (win);
1194 /* We must make room for continuation marks if we don't have fringes. */
1195 #ifdef HAVE_WINDOW_SYSTEM
1196 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1197 #endif
1198 width -= 1;
1201 continuation_glyph_width = 1;
1202 #ifdef HAVE_WINDOW_SYSTEM
1203 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1204 continuation_glyph_width = 0; /* In the fringe. */
1205 #endif
1207 immediate_quit = 1;
1208 QUIT;
1210 pos = prev_pos = from;
1211 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1212 contin_hpos = 0;
1213 prev_tab_offset = tab_offset;
1214 memset (&cmp_it, 0, sizeof cmp_it);
1215 cmp_it.id = -1;
1216 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to, Qnil);
1218 while (1)
1220 while (pos == next_boundary)
1222 EMACS_INT pos_here = pos;
1223 EMACS_INT newpos;
1225 /* Don't skip invisible if we are already at the margin. */
1226 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1228 if (contin_hpos && prev_hpos == 0
1229 && hpos > tohpos
1230 && (contin_hpos == width || wide_column_end_hpos > width))
1231 { /* Line breaks because we can't put the character at the
1232 previous line any more. It is not the multi-column
1233 character continued in middle. Go back to previous
1234 buffer position, screen position, and set tab offset
1235 to previous value. It's the beginning of the
1236 line. */
1237 pos = prev_pos;
1238 pos_byte = prev_pos_byte;
1239 hpos = prev_hpos;
1240 vpos = prev_vpos;
1241 tab_offset = prev_tab_offset;
1243 break;
1246 /* If the caller says that the screen position came from an earlier
1247 call to compute_motion, then we've already accounted for the
1248 overlay strings at point. This is only true the first time
1249 through, so clear the flag after testing it. */
1250 if (!did_motion)
1251 /* We need to skip past the overlay strings. Currently those
1252 strings must not contain TAB;
1253 if we want to relax that restriction, something will have
1254 to be changed here. */
1256 unsigned char *ovstr;
1257 int ovlen = overlay_strings (pos, win, &ovstr);
1258 hpos += ((multibyte && ovlen > 0)
1259 ? strwidth (ovstr, ovlen) : ovlen);
1261 did_motion = 0;
1263 if (pos >= to)
1264 break;
1266 /* Advance POS past invisible characters
1267 (but not necessarily all that there are here),
1268 and store in next_boundary the next position where
1269 we need to call skip_invisible. */
1270 newpos = skip_invisible (pos, &next_boundary, to, window);
1272 if (newpos >= to)
1274 pos = min (to, newpos);
1275 pos_byte = CHAR_TO_BYTE (pos);
1276 goto after_loop;
1279 if (newpos != pos_here)
1281 pos = newpos;
1282 pos_byte = CHAR_TO_BYTE (pos);
1286 /* Handle right margin. */
1287 /* Note on a wide-column character.
1289 Characters are classified into the following three categories
1290 according to the width (columns occupied on screen).
1292 (1) single-column character: ex. `a'
1293 (2) multi-column character: ex. `^A', TAB, `\033'
1294 (3) wide-column character: ex. Japanese character, Chinese character
1295 (In the following example, `W_' stands for them.)
1297 Multi-column characters can be divided around the right margin,
1298 but wide-column characters cannot.
1300 NOTE:
1302 (*) The cursor is placed on the next character after the point.
1304 ----------
1305 abcdefghi\
1306 j ^---- next after the point
1307 ^--- next char. after the point.
1308 ----------
1309 In case of sigle-column character
1311 ----------
1312 abcdefgh\\
1313 033 ^---- next after the point, next char. after the point.
1314 ----------
1315 In case of multi-column character
1317 ----------
1318 abcdefgh\\
1319 W_ ^---- next after the point
1320 ^---- next char. after the point.
1321 ----------
1322 In case of wide-column character
1324 The problem here is continuation at a wide-column character.
1325 In this case, the line may shorter less than WIDTH.
1326 And we find the continuation AFTER it occurs.
1330 if (hpos > width)
1332 int total_width = width + continuation_glyph_width;
1333 int truncate = 0;
1335 if (!NILP (Vtruncate_partial_width_windows)
1336 && (total_width < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1338 if (INTEGERP (Vtruncate_partial_width_windows))
1339 truncate
1340 = total_width < XFASTINT (Vtruncate_partial_width_windows);
1341 else
1342 truncate = 1;
1345 if (hscroll || truncate
1346 || !NILP (current_buffer->truncate_lines))
1348 /* Truncating: skip to newline, unless we are already past
1349 TO (we need to go back below). */
1350 if (pos <= to)
1352 pos = find_before_next_newline (pos, to, 1);
1353 pos_byte = CHAR_TO_BYTE (pos);
1354 hpos = width;
1355 /* If we just skipped next_boundary,
1356 loop around in the main while
1357 and handle it. */
1358 if (pos >= next_boundary)
1359 next_boundary = pos + 1;
1360 prev_hpos = width;
1361 prev_vpos = vpos;
1362 prev_tab_offset = tab_offset;
1365 else
1367 /* Continuing. */
1368 /* Remember the previous value. */
1369 prev_tab_offset = tab_offset;
1371 if (wide_column_end_hpos > width)
1373 hpos -= prev_hpos;
1374 tab_offset += prev_hpos;
1376 else
1378 tab_offset += width;
1379 hpos -= width;
1381 vpos++;
1382 contin_hpos = prev_hpos;
1383 prev_hpos = 0;
1384 prev_vpos = vpos;
1388 /* Stop if past the target buffer position or screen position. */
1389 if (pos > to)
1391 /* Go back to the previous position. */
1392 pos = prev_pos;
1393 pos_byte = prev_pos_byte;
1394 hpos = prev_hpos;
1395 vpos = prev_vpos;
1396 tab_offset = prev_tab_offset;
1398 /* NOTE on contin_hpos, hpos, and prev_hpos.
1400 ----------
1401 abcdefgh\\
1402 W_ ^---- contin_hpos
1403 | ^----- hpos
1404 \---- prev_hpos
1405 ----------
1408 if (contin_hpos && prev_hpos == 0
1409 && contin_hpos < width && !wide_column_end_hpos)
1411 /* Line breaking occurs in the middle of multi-column
1412 character. Go back to previous line. */
1413 hpos = contin_hpos;
1414 vpos = vpos - 1;
1416 break;
1419 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1421 if (contin_hpos && prev_hpos == 0
1422 && hpos > tohpos
1423 && (contin_hpos == width || wide_column_end_hpos > width))
1424 { /* Line breaks because we can't put the character at the
1425 previous line any more. It is not the multi-column
1426 character continued in middle. Go back to previous
1427 buffer position, screen position, and set tab offset
1428 to previous value. It's the beginning of the
1429 line. */
1430 pos = prev_pos;
1431 pos_byte = prev_pos_byte;
1432 hpos = prev_hpos;
1433 vpos = prev_vpos;
1434 tab_offset = prev_tab_offset;
1436 break;
1438 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1439 break;
1441 prev_hpos = hpos;
1442 prev_vpos = vpos;
1443 prev_pos = pos;
1444 prev_pos_byte = pos_byte;
1445 wide_column_end_hpos = 0;
1447 /* Consult the width run cache to see if we can avoid inspecting
1448 the text character-by-character. */
1449 if (current_buffer->width_run_cache && pos >= next_width_run)
1451 int run_end;
1452 int common_width
1453 = region_cache_forward (current_buffer,
1454 current_buffer->width_run_cache,
1455 pos, &run_end);
1457 /* A width of zero means the character's width varies (like
1458 a tab), is meaningless (like a newline), or we just don't
1459 want to skip over it for some other reason. */
1460 if (common_width != 0)
1462 int run_end_hpos;
1464 /* Don't go past the final buffer posn the user
1465 requested. */
1466 if (run_end > to)
1467 run_end = to;
1469 run_end_hpos = hpos + (run_end - pos) * common_width;
1471 /* Don't go past the final horizontal position the user
1472 requested. */
1473 if (vpos == tovpos && run_end_hpos > tohpos)
1475 run_end = pos + (tohpos - hpos) / common_width;
1476 run_end_hpos = hpos + (run_end - pos) * common_width;
1479 /* Don't go past the margin. */
1480 if (run_end_hpos >= width)
1482 run_end = pos + (width - hpos) / common_width;
1483 run_end_hpos = hpos + (run_end - pos) * common_width;
1486 hpos = run_end_hpos;
1487 if (run_end > pos)
1488 prev_hpos = hpos - common_width;
1489 if (pos != run_end)
1491 pos = run_end;
1492 pos_byte = CHAR_TO_BYTE (pos);
1496 next_width_run = run_end + 1;
1499 /* We have to scan the text character-by-character. */
1500 else
1502 EMACS_INT i, n;
1503 Lisp_Object charvec;
1505 /* Check composition sequence. */
1506 if (cmp_it.id >= 0
1507 || (pos == cmp_it.stop_pos
1508 && composition_reseat_it (&cmp_it, pos, pos_byte, to, win,
1509 NULL, Qnil)))
1510 composition_update_it (&cmp_it, pos, pos_byte, Qnil);
1511 if (cmp_it.id >= 0)
1513 pos += cmp_it.nchars;
1514 pos_byte += cmp_it.nbytes;
1515 hpos += cmp_it.width;
1516 if (cmp_it.to == cmp_it.nglyphs)
1518 cmp_it.id = -1;
1519 composition_compute_stop_pos (&cmp_it, pos, pos_byte, to,
1520 Qnil);
1522 else
1523 cmp_it.from = cmp_it.to;
1524 continue;
1527 c = FETCH_BYTE (pos_byte);
1528 pos++, pos_byte++;
1530 /* Perhaps add some info to the width_run_cache. */
1531 if (current_buffer->width_run_cache)
1533 /* Is this character part of the current run? If so, extend
1534 the run. */
1535 if (pos - 1 == width_run_end
1536 && XFASTINT (width_table[c]) == width_run_width)
1537 width_run_end = pos;
1539 /* The previous run is over, since this is a character at a
1540 different position, or a different width. */
1541 else
1543 /* Have we accumulated a run to put in the cache?
1544 (Currently, we only cache runs of width == 1). */
1545 if (width_run_start < width_run_end
1546 && width_run_width == 1)
1547 know_region_cache (current_buffer,
1548 current_buffer->width_run_cache,
1549 width_run_start, width_run_end);
1551 /* Start recording a new width run. */
1552 width_run_width = XFASTINT (width_table[c]);
1553 width_run_start = pos - 1;
1554 width_run_end = pos;
1558 if (dp != 0
1559 && ! (multibyte && LEADING_CODE_P (c))
1560 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1562 charvec = DISP_CHAR_VECTOR (dp, c);
1563 n = ASIZE (charvec);
1565 else
1567 charvec = Qnil;
1568 n = 1;
1571 for (i = n - 1; i >= 0; --i)
1573 if (VECTORP (charvec))
1575 /* This should be handled the same as
1576 next_element_from_display_vector does it. */
1577 Lisp_Object entry = AREF (charvec, i);
1579 if (GLYPH_CODE_P (entry)
1580 && GLYPH_CODE_CHAR_VALID_P (entry))
1581 c = GLYPH_CODE_CHAR (entry);
1582 else
1583 c = ' ';
1586 if (c >= 040 && c < 0177)
1587 hpos++;
1588 else if (c == '\t')
1590 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1591 % tab_width);
1592 if (tem < 0)
1593 tem += tab_width;
1594 hpos += tab_width - tem;
1596 else if (c == '\n')
1598 if (selective > 0
1599 && indented_beyond_p (pos, pos_byte,
1600 (double) selective)) /* iftc */
1602 /* If (pos == to), we don't have to take care of
1603 selective display. */
1604 if (pos < to)
1606 /* Skip any number of invisible lines all at once */
1609 pos = find_before_next_newline (pos, to, 1);
1610 if (pos < to)
1611 pos++;
1612 pos_byte = CHAR_TO_BYTE (pos);
1614 while (pos < to
1615 && indented_beyond_p (pos, pos_byte,
1616 (double) selective)); /* iftc */
1617 /* Allow for the " ..." that is displayed for them. */
1618 if (selective_rlen)
1620 hpos += selective_rlen;
1621 if (hpos >= width)
1622 hpos = width;
1624 DEC_BOTH (pos, pos_byte);
1625 /* We have skipped the invis text, but not the
1626 newline after. */
1629 else
1631 /* A visible line. */
1632 vpos++;
1633 hpos = 0;
1634 hpos -= hscroll;
1635 /* Count the truncation glyph on column 0 */
1636 if (hscroll > 0)
1637 hpos += continuation_glyph_width;
1638 tab_offset = 0;
1640 contin_hpos = 0;
1642 else if (c == CR && selective < 0)
1644 /* In selective display mode,
1645 everything from a ^M to the end of the line is invisible.
1646 Stop *before* the real newline. */
1647 if (pos < to)
1649 pos = find_before_next_newline (pos, to, 1);
1650 pos_byte = CHAR_TO_BYTE (pos);
1652 /* If we just skipped next_boundary,
1653 loop around in the main while
1654 and handle it. */
1655 if (pos > next_boundary)
1656 next_boundary = pos;
1657 /* Allow for the " ..." that is displayed for them. */
1658 if (selective_rlen)
1660 hpos += selective_rlen;
1661 if (hpos >= width)
1662 hpos = width;
1665 else if (multibyte && LEADING_CODE_P (c))
1667 /* Start of multi-byte form. */
1668 unsigned char *ptr;
1669 int bytes, width, wide_column;
1671 pos_byte--; /* rewind POS_BYTE */
1672 ptr = BYTE_POS_ADDR (pos_byte);
1673 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1674 pos_byte += bytes;
1675 if (wide_column)
1676 wide_column_end_hpos = hpos + wide_column;
1677 hpos += width;
1679 else if (VECTORP (charvec))
1680 ++hpos;
1681 else
1682 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1687 after_loop:
1689 /* Remember any final width run in the cache. */
1690 if (current_buffer->width_run_cache
1691 && width_run_width == 1
1692 && width_run_start < width_run_end)
1693 know_region_cache (current_buffer, current_buffer->width_run_cache,
1694 width_run_start, width_run_end);
1696 val_compute_motion.bufpos = pos;
1697 val_compute_motion.bytepos = pos_byte;
1698 val_compute_motion.hpos = hpos;
1699 val_compute_motion.vpos = vpos;
1700 if (contin_hpos && prev_hpos == 0)
1701 val_compute_motion.prevhpos = contin_hpos;
1702 else
1703 val_compute_motion.prevhpos = prev_hpos;
1704 /* We alalways handle all of them here; none of them remain to do. */
1705 val_compute_motion.ovstring_chars_done = 0;
1707 /* Nonzero if have just continued a line */
1708 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1710 immediate_quit = 0;
1711 return &val_compute_motion;
1715 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1716 doc: /* Scan through the current buffer, calculating screen position.
1717 Scan the current buffer forward from offset FROM,
1718 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1719 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1720 and return the ending buffer position and screen location.
1722 If TOPOS is nil, the actual width and height of the window's
1723 text area are used.
1725 There are three additional arguments:
1727 WIDTH is the number of columns available to display text;
1728 this affects handling of continuation lines. A value of nil
1729 corresponds to the actual number of available text columns.
1731 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1732 HSCROLL is the number of columns not being displayed at the left
1733 margin; this is usually taken from a window's hscroll member.
1734 TAB-OFFSET is the number of columns of the first tab that aren't
1735 being displayed, perhaps because the line was continued within it.
1736 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1738 WINDOW is the window to operate on. It is used to choose the display table;
1739 if it is showing the current buffer, it is used also for
1740 deciding which overlay properties apply.
1741 Note that `compute-motion' always operates on the current buffer.
1743 The value is a list of five elements:
1744 (POS HPOS VPOS PREVHPOS CONTIN)
1745 POS is the buffer position where the scan stopped.
1746 VPOS is the vertical position where the scan stopped.
1747 HPOS is the horizontal position where the scan stopped.
1749 PREVHPOS is the horizontal position one character back from POS.
1750 CONTIN is t if a line was continued after (or within) the previous character.
1752 For example, to find the buffer position of column COL of line LINE
1753 of a certain window, pass the window's starting location as FROM
1754 and the window's upper-left coordinates as FROMPOS.
1755 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1756 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1757 (Lisp_Object from, Lisp_Object frompos, Lisp_Object to, Lisp_Object topos, Lisp_Object width, Lisp_Object offsets, Lisp_Object window)
1759 struct window *w;
1760 Lisp_Object bufpos, hpos, vpos, prevhpos;
1761 struct position *pos;
1762 int hscroll, tab_offset;
1764 CHECK_NUMBER_COERCE_MARKER (from);
1765 CHECK_CONS (frompos);
1766 CHECK_NUMBER_CAR (frompos);
1767 CHECK_NUMBER_CDR (frompos);
1768 CHECK_NUMBER_COERCE_MARKER (to);
1769 if (!NILP (topos))
1771 CHECK_CONS (topos);
1772 CHECK_NUMBER_CAR (topos);
1773 CHECK_NUMBER_CDR (topos);
1775 if (!NILP (width))
1776 CHECK_NUMBER (width);
1778 if (!NILP (offsets))
1780 CHECK_CONS (offsets);
1781 CHECK_NUMBER_CAR (offsets);
1782 CHECK_NUMBER_CDR (offsets);
1783 hscroll = XINT (XCAR (offsets));
1784 tab_offset = XINT (XCDR (offsets));
1786 else
1787 hscroll = tab_offset = 0;
1789 if (NILP (window))
1790 window = Fselected_window ();
1791 else
1792 CHECK_LIVE_WINDOW (window);
1793 w = XWINDOW (window);
1795 if (XINT (from) < BEGV || XINT (from) > ZV)
1796 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1797 if (XINT (to) < BEGV || XINT (to) > ZV)
1798 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1800 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1801 XINT (XCAR (frompos)), 0,
1802 XINT (to),
1803 (NILP (topos)
1804 ? window_internal_height (w)
1805 : XINT (XCDR (topos))),
1806 (NILP (topos)
1807 ? (window_box_text_cols (w)
1809 #ifdef HAVE_WINDOW_SYSTEM
1810 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1811 #endif
1813 : XINT (XCAR (topos))),
1814 (NILP (width) ? -1 : XINT (width)),
1815 hscroll, tab_offset,
1816 XWINDOW (window));
1818 XSETFASTINT (bufpos, pos->bufpos);
1819 XSETINT (hpos, pos->hpos);
1820 XSETINT (vpos, pos->vpos);
1821 XSETINT (prevhpos, pos->prevhpos);
1823 return Fcons (bufpos,
1824 Fcons (hpos,
1825 Fcons (vpos,
1826 Fcons (prevhpos,
1827 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1831 /* Fvertical_motion and vmotion */
1833 struct position val_vmotion;
1835 struct position *
1836 vmotion (register EMACS_INT from, register EMACS_INT vtarget, struct window *w)
1838 EMACS_INT hscroll = XINT (w->hscroll);
1839 struct position pos;
1840 /* vpos is cumulative vertical position, changed as from is changed */
1841 register int vpos = 0;
1842 EMACS_INT prevline;
1843 register EMACS_INT first;
1844 EMACS_INT from_byte;
1845 EMACS_INT lmargin = hscroll > 0 ? 1 - hscroll : 0;
1846 int selective
1847 = (INTEGERP (current_buffer->selective_display)
1848 ? XINT (current_buffer->selective_display)
1849 : !NILP (current_buffer->selective_display) ? -1 : 0);
1850 Lisp_Object window;
1851 EMACS_INT start_hpos = 0;
1852 int did_motion;
1853 /* This is the object we use for fetching character properties. */
1854 Lisp_Object text_prop_object;
1856 XSETWINDOW (window, w);
1858 /* If the window contains this buffer, use it for getting text properties.
1859 Otherwise use the current buffer as arg for doing that. */
1860 if (EQ (w->buffer, Fcurrent_buffer ()))
1861 text_prop_object = window;
1862 else
1863 text_prop_object = Fcurrent_buffer ();
1865 if (vpos >= vtarget)
1867 /* To move upward, go a line at a time until
1868 we have gone at least far enough. */
1870 first = 1;
1872 while ((vpos > vtarget || first) && from > BEGV)
1874 Lisp_Object propval;
1876 prevline = find_next_newline_no_quit (from - 1, -1);
1877 while (prevline > BEGV
1878 && ((selective > 0
1879 && indented_beyond_p (prevline,
1880 CHAR_TO_BYTE (prevline),
1881 (double) selective)) /* iftc */
1882 /* Watch out for newlines with `invisible' property.
1883 When moving upward, check the newline before. */
1884 || (propval = Fget_char_property (make_number (prevline - 1),
1885 Qinvisible,
1886 text_prop_object),
1887 TEXT_PROP_MEANS_INVISIBLE (propval))))
1888 prevline = find_next_newline_no_quit (prevline - 1, -1);
1889 pos = *compute_motion (prevline, 0,
1890 lmargin + (prevline == BEG ? start_hpos : 0),
1892 from,
1893 /* Don't care for VPOS... */
1894 1 << (BITS_PER_SHORT - 1),
1895 /* ... nor HPOS. */
1896 1 << (BITS_PER_SHORT - 1),
1897 -1, hscroll,
1898 /* This compensates for start_hpos
1899 so that a tab as first character
1900 still occupies 8 columns. */
1901 (prevline == BEG ? -start_hpos : 0),
1903 vpos -= pos.vpos;
1904 first = 0;
1905 from = prevline;
1908 /* If we made exactly the desired vertical distance,
1909 or if we hit beginning of buffer,
1910 return point found */
1911 if (vpos >= vtarget)
1913 val_vmotion.bufpos = from;
1914 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1915 val_vmotion.vpos = vpos;
1916 val_vmotion.hpos = lmargin;
1917 val_vmotion.contin = 0;
1918 val_vmotion.prevhpos = 0;
1919 val_vmotion.ovstring_chars_done = 0;
1920 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1921 return &val_vmotion;
1924 /* Otherwise find the correct spot by moving down */
1926 /* Moving downward is simple, but must calculate from beg of line
1927 to determine hpos of starting point */
1928 from_byte = CHAR_TO_BYTE (from);
1929 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1931 Lisp_Object propval;
1933 prevline = find_next_newline_no_quit (from, -1);
1934 while (prevline > BEGV
1935 && ((selective > 0
1936 && indented_beyond_p (prevline,
1937 CHAR_TO_BYTE (prevline),
1938 (double) selective)) /* iftc */
1939 /* Watch out for newlines with `invisible' property.
1940 When moving downward, check the newline after. */
1941 || (propval = Fget_char_property (make_number (prevline),
1942 Qinvisible,
1943 text_prop_object),
1944 TEXT_PROP_MEANS_INVISIBLE (propval))))
1945 prevline = find_next_newline_no_quit (prevline - 1, -1);
1946 pos = *compute_motion (prevline, 0,
1947 lmargin + (prevline == BEG
1948 ? start_hpos : 0),
1950 from,
1951 /* Don't care for VPOS... */
1952 1 << (BITS_PER_SHORT - 1),
1953 /* ... nor HPOS. */
1954 1 << (BITS_PER_SHORT - 1),
1955 -1, hscroll,
1956 (prevline == BEG ? -start_hpos : 0),
1958 did_motion = 1;
1960 else
1962 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1963 pos.vpos = 0;
1964 pos.tab_offset = 0;
1965 did_motion = 0;
1967 return compute_motion (from, vpos, pos.hpos, did_motion,
1968 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1969 -1, hscroll,
1970 pos.tab_offset - (from == BEG ? start_hpos : 0),
1974 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
1975 doc: /* Move point to start of the screen line LINES lines down.
1976 If LINES is negative, this means moving up.
1978 This function is an ordinary cursor motion function
1979 which calculates the new position based on how text would be displayed.
1980 The new position may be the start of a line,
1981 or just the start of a continuation line.
1982 The function returns number of screen lines moved over;
1983 that usually equals LINES, but may be closer to zero
1984 if beginning or end of buffer was reached.
1986 The optional second argument WINDOW specifies the window to use for
1987 parameters such as width, horizontal scrolling, and so on.
1988 The default is to use the selected window's parameters.
1990 LINES can optionally take the form (COLS . LINES), in which case
1991 the motion will not stop at the start of a screen line but on
1992 its column COLS (if such exists on that line, that is).
1994 `vertical-motion' always uses the current buffer,
1995 regardless of which buffer is displayed in WINDOW.
1996 This is consistent with other cursor motion functions
1997 and makes it possible to use `vertical-motion' in any buffer,
1998 whether or not it is currently displayed in some window. */)
1999 (Lisp_Object lines, Lisp_Object window)
2001 struct it it;
2002 struct text_pos pt;
2003 struct window *w;
2004 Lisp_Object old_buffer;
2005 struct gcpro gcpro1;
2006 Lisp_Object lcols = Qnil;
2007 double cols;
2009 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
2010 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
2012 lcols = XCAR (lines);
2013 cols = INTEGERP (lcols) ? (double) XINT (lcols) : XFLOAT_DATA (lcols);
2014 lines = XCDR (lines);
2017 CHECK_NUMBER (lines);
2018 if (! NILP (window))
2019 CHECK_WINDOW (window);
2020 else
2021 window = selected_window;
2022 w = XWINDOW (window);
2024 old_buffer = Qnil;
2025 GCPRO1 (old_buffer);
2026 if (XBUFFER (w->buffer) != current_buffer)
2028 /* Set the window's buffer temporarily to the current buffer. */
2029 old_buffer = w->buffer;
2030 XSETBUFFER (w->buffer, current_buffer);
2033 if (noninteractive)
2035 struct position pos;
2036 pos = *vmotion (PT, XINT (lines), w);
2037 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2039 else
2041 int it_start, first_x, it_overshoot_expected;
2043 SET_TEXT_POS (pt, PT, PT_BYTE);
2044 start_display (&it, w, pt);
2045 first_x = it.first_visible_x;
2046 it_start = IT_CHARPOS (it);
2048 /* See comments below for why we calculate this. */
2049 if (XINT (lines) > 0)
2051 if (it.cmp_it.id >= 0)
2052 it_overshoot_expected = 1;
2053 else if (it.method == GET_FROM_STRING)
2055 const char *s = SDATA (it.string);
2056 const char *e = s + SBYTES (it.string);
2057 while (s < e && *s != '\n')
2058 ++s;
2059 it_overshoot_expected = (s == e) ? -1 : 0;
2061 else
2062 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2063 || it.method == GET_FROM_STRETCH);
2066 /* Scan from the start of the line containing PT. If we don't
2067 do this, we start moving with IT->current_x == 0, while PT is
2068 really at some x > 0. */
2069 reseat_at_previous_visible_line_start (&it);
2070 it.current_x = it.hpos = 0;
2071 if (IT_CHARPOS (it) != PT)
2072 /* We used to temporarily disable selective display here; the
2073 comment said this is "so we don't move too far" (2005-01-19
2074 checkin by kfs). But this does nothing useful that I can
2075 tell, and it causes Bug#2694 . -- cyd */
2076 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2078 if (XINT (lines) <= 0)
2080 it.vpos = 0;
2081 /* Do this even if LINES is 0, so that we move back to the
2082 beginning of the current line as we ought. */
2083 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2084 move_it_by_lines (&it, XINT (lines), 0);
2086 else
2088 if (IT_CHARPOS (it) > it_start)
2090 /* IT may move too far if truncate-lines is on and PT
2091 lies beyond the right margin. In that case,
2092 backtrack unless the starting point is on an image,
2093 stretch glyph, composition, or Lisp string. */
2094 if (!it_overshoot_expected
2095 /* Also, backtrack if the Lisp string contains no
2096 newline, but there is a newline right after it.
2097 In this case, IT overshoots if there is an
2098 after-string just before the newline. */
2099 || (it_overshoot_expected < 0
2100 && it.method == GET_FROM_BUFFER
2101 && it.c == '\n'))
2102 move_it_by_lines (&it, -1, 0);
2103 it.vpos = 0;
2104 move_it_by_lines (&it, XINT (lines), 0);
2106 else
2108 /* Otherwise, we are at the first row occupied by PT,
2109 which might span multiple screen lines (e.g., if it's
2110 on a multi-line display string). We want to start
2111 from the last line that it occupies. */
2112 if (it_start < ZV)
2114 while (IT_CHARPOS (it) <= it_start)
2116 it.vpos = 0;
2117 move_it_by_lines (&it, 1, 0);
2119 if (XINT (lines) > 1)
2120 move_it_by_lines (&it, XINT (lines) - 1, 0);
2122 else
2124 it.vpos = 0;
2125 move_it_by_lines (&it, XINT (lines), 0);
2130 /* Move to the goal column, if one was specified. */
2131 if (!NILP (lcols))
2133 /* If the window was originally hscrolled, move forward by
2134 the hscrolled amount first. */
2135 if (first_x > 0)
2137 move_it_in_display_line (&it, ZV, first_x, MOVE_TO_X);
2138 it.current_x = 0;
2140 move_it_in_display_line
2141 (&it, ZV,
2142 (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5),
2143 MOVE_TO_X);
2146 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2149 if (BUFFERP (old_buffer))
2150 w->buffer = old_buffer;
2152 RETURN_UNGCPRO (make_number (it.vpos));
2157 /* File's initialization. */
2159 void
2160 syms_of_indent (void)
2162 DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
2163 doc: /* *Indentation can insert tabs if this is non-nil. */);
2164 indent_tabs_mode = 1;
2166 defsubr (&Scurrent_indentation);
2167 defsubr (&Sindent_to);
2168 defsubr (&Scurrent_column);
2169 defsubr (&Smove_to_column);
2170 defsubr (&Svertical_motion);
2171 defsubr (&Scompute_motion);
2174 /* arch-tag: 9adfea44-71f7-4988-8ee3-96da15c502cc
2175 (do not change this comment) */