Add config header templates to all AC_DEFINE and
[emacs.git] / src / indent.c
blobc084890c069f5def9c245ca25cd6ee1795437979
1 /* Indentation functions.
2 Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <config.h>
23 #include "lisp.h"
24 #include "buffer.h"
25 #include "charset.h"
26 #include "category.h"
27 #include "indent.h"
28 #include "keyboard.h"
29 #include "frame.h"
30 #include "window.h"
31 #include "termchar.h"
32 #include "termopts.h"
33 #include "disptab.h"
34 #include "intervals.h"
35 #include "region-cache.h"
37 /* Indentation can insert tabs if this is non-zero;
38 otherwise always uses spaces. */
40 int indent_tabs_mode;
42 #define CR 015
44 /* These three values memorize the current column to avoid recalculation. */
46 /* Last value returned by current_column.
47 Some things in set last_known_column_point to -1
48 to mark the memorized value as invalid. */
50 int last_known_column;
52 /* Value of point when current_column was called. */
54 int last_known_column_point;
56 /* Value of MODIFF when current_column was called. */
58 int last_known_column_modified;
60 static int current_column_1 P_ ((void));
61 static int position_indentation P_ ((int));
63 /* Cache of beginning of line found by the last call of
64 current_column. */
66 int current_column_bol_cache;
68 /* Get the display table to use for the current buffer. */
70 struct Lisp_Char_Table *
71 buffer_display_table ()
73 Lisp_Object thisbuf;
75 thisbuf = current_buffer->display_table;
76 if (DISP_TABLE_P (thisbuf))
77 return XCHAR_TABLE (thisbuf);
78 if (DISP_TABLE_P (Vstandard_display_table))
79 return XCHAR_TABLE (Vstandard_display_table);
80 return 0;
83 /* Width run cache considerations. */
85 /* Return the width of character C under display table DP. */
87 static int
88 character_width (c, dp)
89 int c;
90 struct Lisp_Char_Table *dp;
92 Lisp_Object elt;
94 /* These width computations were determined by examining the cases
95 in display_text_line. */
97 /* Everything can be handled by the display table, if it's
98 present and the element is right. */
99 if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
100 return XVECTOR (elt)->size;
102 /* Some characters are special. */
103 if (c == '\n' || c == '\t' || c == '\015')
104 return 0;
106 /* Printing characters have width 1. */
107 else if (c >= 040 && c < 0177)
108 return 1;
110 /* Everybody else (control characters, metacharacters) has other
111 widths. We could return their actual widths here, but they
112 depend on things like ctl_arrow and crud like that, and they're
113 not very common at all. So we'll just claim we don't know their
114 widths. */
115 else
116 return 0;
119 /* Return true iff the display table DISPTAB specifies the same widths
120 for characters as WIDTHTAB. We use this to decide when to
121 invalidate the buffer's width_run_cache. */
124 disptab_matches_widthtab (disptab, widthtab)
125 struct Lisp_Char_Table *disptab;
126 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 (buf, disptab)
145 struct buffer *buf;
146 struct Lisp_Char_Table *disptab;
148 int i;
149 struct Lisp_Vector *widthtab;
151 if (!VECTORP (buf->width_table))
152 buf->width_table = Fmake_vector (make_number (256), make_number (0));
153 widthtab = XVECTOR (buf->width_table);
154 if (widthtab->size != 256)
155 abort ();
157 for (i = 0; i < 256; i++)
158 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
161 /* Allocate or free the width run cache, as requested by the current
162 state of current_buffer's cache_long_line_scans variable. */
164 static void
165 width_run_cache_on_off ()
167 if (NILP (current_buffer->cache_long_line_scans)
168 /* And, for the moment, this feature doesn't work on multibyte
169 characters. */
170 || !NILP (current_buffer->enable_multibyte_characters))
172 /* It should be off. */
173 if (current_buffer->width_run_cache)
175 free_region_cache (current_buffer->width_run_cache);
176 current_buffer->width_run_cache = 0;
177 current_buffer->width_table = Qnil;
180 else
182 /* It should be on. */
183 if (current_buffer->width_run_cache == 0)
185 current_buffer->width_run_cache = new_region_cache ();
186 recompute_width_table (current_buffer, buffer_display_table ());
192 /* Skip some invisible characters starting from POS.
193 This includes characters invisible because of text properties
194 and characters invisible because of overlays.
196 If position POS is followed by invisible characters,
197 skip some of them and return the position after them.
198 Otherwise return POS itself.
200 Set *NEXT_BOUNDARY_P to the next position at which
201 it will be necessary to call this function again.
203 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
204 to a value greater than TO.
206 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
207 take account of overlays that apply only in WINDOW.
209 We don't necessarily skip all the invisible characters after POS
210 because that could take a long time. We skip a reasonable number
211 which can be skipped quickly. If there might be more invisible
212 characters immediately following, then *NEXT_BOUNDARY_P
213 will equal the return value. */
216 skip_invisible (pos, next_boundary_p, to, window)
217 int pos;
218 int *next_boundary_p;
219 int to;
220 Lisp_Object window;
222 Lisp_Object prop, position, overlay_limit, proplimit;
223 Lisp_Object buffer;
224 int end, inv_p;
226 XSETFASTINT (position, pos);
227 XSETBUFFER (buffer, current_buffer);
229 /* Give faster response for overlay lookup near POS. */
230 recenter_overlay_lists (current_buffer, pos);
232 /* We must not advance farther than the next overlay change.
233 The overlay change might change the invisible property;
234 or there might be overlay strings to be displayed there. */
235 overlay_limit = Fnext_overlay_change (position);
236 /* As for text properties, this gives a lower bound
237 for where the invisible text property could change. */
238 proplimit = Fnext_property_change (position, buffer, Qt);
239 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
240 proplimit = overlay_limit;
241 /* PROPLIMIT is now a lower bound for the next change
242 in invisible status. If that is plenty far away,
243 use that lower bound. */
244 if (XFASTINT (proplimit) > pos + 100 || XFASTINT (proplimit) >= to)
245 *next_boundary_p = XFASTINT (proplimit);
246 /* Otherwise, scan for the next `invisible' property change. */
247 else
249 /* Don't scan terribly far. */
250 XSETFASTINT (proplimit, min (pos + 100, to));
251 /* No matter what. don't go past next overlay change. */
252 if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
253 proplimit = overlay_limit;
254 end = XFASTINT (Fnext_single_property_change (position, Qinvisible,
255 buffer, proplimit));
256 #if 0
257 /* Don't put the boundary in the middle of multibyte form if
258 there is no actual property change. */
259 if (end == pos + 100
260 && !NILP (current_buffer->enable_multibyte_characters)
261 && end < ZV)
262 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
263 end--;
264 #endif
265 *next_boundary_p = end;
267 /* if the `invisible' property is set, we can skip to
268 the next property change */
269 prop = Fget_char_property (position, Qinvisible,
270 (!NILP (window)
271 && EQ (XWINDOW (window)->buffer, buffer))
272 ? window : buffer);
273 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
274 /* When counting columns (window == nil), don't skip over ellipsis text. */
275 if (NILP (window) ? inv_p == 1 : inv_p)
276 return *next_boundary_p;
277 return pos;
280 /* If a composition starts at POS/POS_BYTE and it doesn't stride over
281 POINT, set *LEN / *LEN_BYTE to the character and byte lengths, *WIDTH
282 to the width, and return 1. Otherwise, return 0. */
284 static int
285 check_composition (pos, pos_byte, point, len, len_byte, width)
286 int pos, pos_byte, point;
287 int *len, *len_byte, *width;
289 Lisp_Object prop;
290 int start, end;
291 int id;
293 if (! find_composition (pos, -1, &start, &end, &prop, Qnil)
294 || pos != start || point < end
295 || !COMPOSITION_VALID_P (start, end, prop))
296 return 0;
297 if ((id = get_composition_id (pos, pos_byte, end - pos, prop, Qnil)) < 0)
298 return 0;
300 *len = COMPOSITION_LENGTH (prop);
301 *len_byte = CHAR_TO_BYTE (end) - pos_byte;
302 *width = composition_table[id]->width;
303 return 1;
306 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
308 DP is a display table or NULL.
310 This macro is used in current_column_1, Fmove_to_column, and
311 compute_motion. */
313 #define MULTIBYTE_BYTES_WIDTH(p, dp) \
314 do { \
315 int c; \
317 wide_column = 0; \
318 c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, bytes); \
319 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
320 width = bytes * 4; \
321 else \
323 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) \
324 width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; \
325 else \
326 width = WIDTH_BY_CHAR_HEAD (*p); \
327 if (width > 1) \
328 wide_column = width; \
330 } while (0)
332 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
333 doc: /* Return the horizontal position of point. Beginning of line is column 0.
334 This is calculated by adding together the widths of all the displayed
335 representations of the character between the start of the previous line
336 and point. (eg control characters will have a width of 2 or 4, tabs
337 will have a variable width)
338 Ignores finite width of frame, which means that this function may return
339 values greater than (frame-width).
340 Whether the line is visible (if `selective-display' is t) has no effect;
341 however, ^M is treated as end of line when `selective-display' is t. */)
344 Lisp_Object temp;
345 XSETFASTINT (temp, current_column ());
346 return temp;
349 /* Cancel any recorded value of the horizontal position. */
351 void
352 invalidate_current_column ()
354 last_known_column_point = 0;
358 current_column ()
360 register int col;
361 register unsigned char *ptr, *stop;
362 register int tab_seen;
363 int post_tab;
364 register int c;
365 register int tab_width = XINT (current_buffer->tab_width);
366 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
367 register struct Lisp_Char_Table *dp = buffer_display_table ();
369 if (PT == last_known_column_point
370 && MODIFF == last_known_column_modified)
371 return last_known_column;
373 /* If the buffer has overlays, text properties,
374 or multibyte characters, use a more general algorithm. */
375 if (BUF_INTERVALS (current_buffer)
376 || !NILP (current_buffer->overlays_before)
377 || !NILP (current_buffer->overlays_after)
378 || Z != Z_BYTE)
379 return current_column_1 ();
381 /* Scan backwards from point to the previous newline,
382 counting width. Tab characters are the only complicated case. */
384 /* Make a pointer for decrementing through the chars before point. */
385 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
386 /* Make a pointer to where consecutive chars leave off,
387 going backwards from point. */
388 if (PT == BEGV)
389 stop = ptr;
390 else if (PT <= GPT || BEGV > GPT)
391 stop = BEGV_ADDR;
392 else
393 stop = GAP_END_ADDR;
395 if (tab_width <= 0 || tab_width > 1000)
396 tab_width = 8;
398 col = 0, tab_seen = 0, post_tab = 0;
400 while (1)
402 EMACS_INT i, n;
403 Lisp_Object charvec;
405 if (ptr == stop)
407 /* We stopped either for the beginning of the buffer
408 or for the gap. */
409 if (ptr == BEGV_ADDR)
410 break;
412 /* It was the gap. Jump back over it. */
413 stop = BEGV_ADDR;
414 ptr = GPT_ADDR;
416 /* Check whether that brings us to beginning of buffer. */
417 if (BEGV >= GPT)
418 break;
421 c = *--ptr;
423 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
425 charvec = DISP_CHAR_VECTOR (dp, c);
426 n = ASIZE (charvec);
428 else
430 charvec = Qnil;
431 n = 1;
434 for (i = n - 1; i >= 0; --i)
436 if (VECTORP (charvec))
438 /* This should be handled the same as
439 next_element_from_display_vector does it. */
440 Lisp_Object entry = AREF (charvec, i);
442 if (INTEGERP (entry)
443 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
444 c = FAST_GLYPH_CHAR (XFASTINT (entry));
445 else
446 c = ' ';
449 if (c >= 040 && c < 0177)
450 col++;
451 else if (c == '\n'
452 || (c == '\r'
453 && EQ (current_buffer->selective_display, Qt)))
455 ptr++;
456 goto start_of_line_found;
458 else if (c == '\t')
460 if (tab_seen)
461 col = ((col + tab_width) / tab_width) * tab_width;
463 post_tab += col;
464 col = 0;
465 tab_seen = 1;
467 else if (VECTORP (charvec))
468 /* With a display table entry, C is displayed as is, and
469 not displayed as \NNN or as ^N. If C is a single-byte
470 character, it takes one column. If C is multi-byte in
471 an unibyte buffer, it's translated to unibyte, so it
472 also takes one column. */
473 ++col;
474 else
475 col += (ctl_arrow && c < 0200) ? 2 : 4;
479 start_of_line_found:
481 if (tab_seen)
483 col = ((col + tab_width) / tab_width) * tab_width;
484 col += post_tab;
487 if (ptr == BEGV_ADDR)
488 current_column_bol_cache = BEGV;
489 else
490 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
492 last_known_column = col;
493 last_known_column_point = PT;
494 last_known_column_modified = MODIFF;
496 return col;
499 /* Return the column number of position POS
500 by scanning forward from the beginning of the line.
501 This function handles characters that are invisible
502 due to text properties or overlays. */
504 static int
505 current_column_1 ()
507 register int tab_width = XINT (current_buffer->tab_width);
508 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
509 register struct Lisp_Char_Table *dp = buffer_display_table ();
510 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
512 /* Start the scan at the beginning of this line with column number 0. */
513 register int col = 0;
514 int scan, scan_byte;
515 int next_boundary, next_boundary_byte;
516 int opoint = PT, opoint_byte = PT_BYTE;
518 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
519 current_column_bol_cache = PT;
520 scan = PT, scan_byte = PT_BYTE;
521 SET_PT_BOTH (opoint, opoint_byte);
522 next_boundary = scan;
523 next_boundary_byte = scan_byte;
525 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
527 /* Scan forward to the target position. */
528 while (scan < opoint)
530 int c;
532 /* Occasionally we may need to skip invisible text. */
533 while (scan == next_boundary)
535 int old_scan = scan;
536 /* This updates NEXT_BOUNDARY to the next place
537 where we might need to skip more invisible text. */
538 scan = skip_invisible (scan, &next_boundary, opoint, Qnil);
539 if (scan >= opoint)
540 goto endloop;
541 if (scan != old_scan)
542 scan_byte = CHAR_TO_BYTE (scan);
543 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
546 /* Check composition sequence. */
548 int len, len_byte, width;
550 if (check_composition (scan, scan_byte, opoint,
551 &len, &len_byte, &width))
553 scan += len;
554 scan_byte += len_byte;
555 if (scan <= opoint)
556 col += width;
557 continue;
561 c = FETCH_BYTE (scan_byte);
563 if (dp != 0
564 && ! (multibyte && BASE_LEADING_CODE_P (c))
565 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
567 Lisp_Object charvec;
568 EMACS_INT i, n;
570 /* This character is displayed using a vector of glyphs.
571 Update the column based on those glyphs. */
573 charvec = DISP_CHAR_VECTOR (dp, c);
574 n = ASIZE (charvec);
576 for (i = 0; i < n; i++)
578 /* This should be handled the same as
579 next_element_from_display_vector does it. */
580 Lisp_Object entry;
581 entry = AREF (charvec, i);
583 if (INTEGERP (entry)
584 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
585 c = FAST_GLYPH_CHAR (XFASTINT (entry));
586 else
587 c = ' ';
589 if (c == '\n')
590 goto endloop;
591 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
592 goto endloop;
593 if (c == '\t')
595 col += tab_width;
596 col = col / tab_width * tab_width;
598 else
599 ++col;
602 else
604 /* The display table says nothing for this character.
605 Display it as itself. */
607 if (c == '\n')
608 goto endloop;
609 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
610 goto endloop;
611 if (c == '\t')
613 col += tab_width;
614 col = col / tab_width * tab_width;
616 else if (multibyte && BASE_LEADING_CODE_P (c))
618 unsigned char *ptr;
619 int bytes, width, wide_column;
621 ptr = BYTE_POS_ADDR (scan_byte);
622 MULTIBYTE_BYTES_WIDTH (ptr, dp);
623 scan_byte += bytes;
624 /* Subtract one to compensate for the increment
625 that is going to happen below. */
626 scan_byte--;
627 col += width;
629 else if (ctl_arrow && (c < 040 || c == 0177))
630 col += 2;
631 else if (c < 040 || c >= 0177)
632 col += 4;
633 else
634 col++;
636 scan++;
637 scan_byte++;
640 endloop:
642 last_known_column = col;
643 last_known_column_point = PT;
644 last_known_column_modified = MODIFF;
646 return col;
650 #if 0 /* Not used. */
652 /* Return the width in columns of the part of STRING from BEG to END.
653 If BEG is nil, that stands for the beginning of STRING.
654 If END is nil, that stands for the end of STRING. */
656 static int
657 string_display_width (string, beg, end)
658 Lisp_Object string, beg, end;
660 register int col;
661 register unsigned char *ptr, *stop;
662 register int tab_seen;
663 int post_tab;
664 register int c;
665 register int tab_width = XINT (current_buffer->tab_width);
666 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
667 register struct Lisp_Char_Table *dp = buffer_display_table ();
668 int b, e;
670 if (NILP (end))
671 e = XSTRING (string)->size;
672 else
674 CHECK_NUMBER (end);
675 e = XINT (end);
678 if (NILP (beg))
679 b = 0;
680 else
682 CHECK_NUMBER (beg);
683 b = XINT (beg);
686 /* Make a pointer for decrementing through the chars before point. */
687 ptr = XSTRING (string)->data + e;
688 /* Make a pointer to where consecutive chars leave off,
689 going backwards from point. */
690 stop = XSTRING (string)->data + b;
692 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
694 col = 0, tab_seen = 0, post_tab = 0;
696 while (1)
698 if (ptr == stop)
699 break;
701 c = *--ptr;
702 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
703 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
704 else if (c >= 040 && c < 0177)
705 col++;
706 else if (c == '\n')
707 break;
708 else if (c == '\t')
710 if (tab_seen)
711 col = ((col + tab_width) / tab_width) * tab_width;
713 post_tab += col;
714 col = 0;
715 tab_seen = 1;
717 else
718 col += (ctl_arrow && c < 0200) ? 2 : 4;
721 if (tab_seen)
723 col = ((col + tab_width) / tab_width) * tab_width;
724 col += post_tab;
727 return col;
730 #endif /* 0 */
733 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
734 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
735 Optional second argument MININUM says always do at least MININUM spaces
736 even if that goes past COLUMN; by default, MININUM is zero. */)
737 (column, minimum)
738 Lisp_Object column, minimum;
740 int mincol;
741 register int fromcol;
742 register int tab_width = XINT (current_buffer->tab_width);
744 CHECK_NUMBER (column);
745 if (NILP (minimum))
746 XSETFASTINT (minimum, 0);
747 CHECK_NUMBER (minimum);
749 fromcol = current_column ();
750 mincol = fromcol + XINT (minimum);
751 if (mincol < XINT (column)) mincol = XINT (column);
753 if (fromcol == mincol)
754 return make_number (mincol);
756 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
758 if (indent_tabs_mode)
760 Lisp_Object n;
761 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
762 if (XFASTINT (n) != 0)
764 Finsert_char (make_number ('\t'), n, Qt);
766 fromcol = (mincol / tab_width) * tab_width;
770 XSETFASTINT (column, mincol - fromcol);
771 Finsert_char (make_number (' '), column, Qt);
773 last_known_column = mincol;
774 last_known_column_point = PT;
775 last_known_column_modified = MODIFF;
777 XSETINT (column, mincol);
778 return column;
782 static int position_indentation P_ ((int));
784 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
785 0, 0, 0,
786 doc: /* Return the indentation of the current line.
787 This is the horizontal position of the character
788 following any initial whitespace. */)
791 Lisp_Object val;
792 int opoint = PT, opoint_byte = PT_BYTE;
794 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
796 XSETFASTINT (val, position_indentation (PT_BYTE));
797 SET_PT_BOTH (opoint, opoint_byte);
798 return val;
801 static int
802 position_indentation (pos_byte)
803 register int pos_byte;
805 register int column = 0;
806 register int tab_width = XINT (current_buffer->tab_width);
807 register unsigned char *p;
808 register unsigned char *stop;
809 unsigned char *start;
810 int next_boundary_byte = pos_byte;
811 int ceiling = next_boundary_byte;
813 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
815 p = BYTE_POS_ADDR (pos_byte);
816 /* STOP records the value of P at which we will need
817 to think about the gap, or about invisible text,
818 or about the end of the buffer. */
819 stop = p;
820 /* START records the starting value of P. */
821 start = p;
822 while (1)
824 while (p == stop)
826 int stop_pos_byte;
828 /* If we have updated P, set POS_BYTE to match.
829 The first time we enter the loop, POS_BYTE is already right. */
830 if (p != start)
831 pos_byte = PTR_BYTE_POS (p);
832 /* Consider the various reasons STOP might have been set here. */
833 if (pos_byte == ZV_BYTE)
834 return column;
835 if (pos_byte == next_boundary_byte)
837 int next_boundary;
838 int pos = BYTE_TO_CHAR (pos_byte);
839 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
840 pos_byte = CHAR_TO_BYTE (pos);
841 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
843 if (pos_byte >= ceiling)
844 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
845 /* Compute the next place we need to stop and think,
846 and set STOP accordingly. */
847 stop_pos_byte = min (ceiling, next_boundary_byte);
848 /* The -1 and +1 arrange to point at the first byte of gap
849 (if STOP_POS_BYTE is the position of the gap)
850 rather than at the data after the gap. */
852 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
853 p = BYTE_POS_ADDR (pos_byte);
855 switch (*p++)
857 case 0240:
858 if (! NILP (current_buffer->enable_multibyte_characters))
859 return column;
860 case ' ':
861 column++;
862 break;
863 case '\t':
864 column += tab_width - column % tab_width;
865 break;
866 default:
867 if (ASCII_BYTE_P (p[-1])
868 || NILP (current_buffer->enable_multibyte_characters))
869 return column;
871 int c;
872 pos_byte = PTR_BYTE_POS (p - 1);
873 c = FETCH_MULTIBYTE_CHAR (pos_byte);
874 if (CHAR_HAS_CATEGORY (c, ' '))
876 column++;
877 INC_POS (pos_byte);
878 p = BYTE_POS_ADDR (pos_byte);
880 else
881 return column;
887 /* Test whether the line beginning at POS is indented beyond COLUMN.
888 Blank lines are treated as if they had the same indentation as the
889 preceding line. */
892 indented_beyond_p (pos, pos_byte, column)
893 int pos, pos_byte, column;
895 int val;
896 int opoint = PT, opoint_byte = PT_BYTE;
898 SET_PT_BOTH (pos, pos_byte);
899 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
900 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
902 val = position_indentation (PT_BYTE);
903 SET_PT_BOTH (opoint, opoint_byte);
904 return val >= column;
907 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
908 doc: /* Move point to column COLUMN in the current line.
909 The column of a character is calculated by adding together the widths
910 as displayed of the previous characters in the line.
911 This function ignores line-continuation;
912 there is no upper limit on the column number a character can have
913 and horizontal scrolling has no effect.
915 If specified column is within a character, point goes after that character.
916 If it's past end of line, point goes to end of line.
918 A non-nil second (optional) argument FORCE means,
919 if COLUMN is in the middle of a tab character, change it to spaces.
920 In addition, if FORCE is t, and the line is too short
921 to reach column COLUMN, add spaces/tabs to get there.
923 The return value is the current column. */)
924 (column, force)
925 Lisp_Object column, force;
927 register int pos;
928 register int col = current_column ();
929 register int goal;
930 register int end;
931 register int tab_width = XINT (current_buffer->tab_width);
932 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
933 register struct Lisp_Char_Table *dp = buffer_display_table ();
934 register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
936 Lisp_Object val;
937 int prev_col = 0;
938 int c = 0;
939 int next_boundary;
941 int pos_byte, end_byte, next_boundary_byte;
943 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
944 CHECK_NATNUM (column);
945 goal = XINT (column);
947 pos = PT;
948 pos_byte = PT_BYTE;
949 end = ZV;
950 end_byte = ZV_BYTE;
951 next_boundary = pos;
952 next_boundary_byte = PT_BYTE;
954 /* If we're starting past the desired column,
955 back up to beginning of line and scan from there. */
956 if (col > goal)
958 end = pos;
959 pos = current_column_bol_cache;
960 pos_byte = CHAR_TO_BYTE (pos);
961 col = 0;
964 while (pos < end)
966 while (pos == next_boundary)
968 int prev = pos;
969 pos = skip_invisible (pos, &next_boundary, end, Qnil);
970 if (pos != prev)
971 pos_byte = CHAR_TO_BYTE (pos);
972 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
973 if (pos >= end)
974 goto endloop;
977 /* Test reaching the goal column. We do this after skipping
978 invisible characters, so that we put point before the
979 character on which the cursor will appear. */
980 if (col >= goal)
981 break;
983 /* Check composition sequence. */
985 int len, len_byte, width;
987 if (check_composition (pos, pos_byte, Z, &len, &len_byte, &width))
989 pos += len;
990 pos_byte += len_byte;
991 col += width;
992 continue;
996 c = FETCH_BYTE (pos_byte);
998 /* See if there is a display table and it relates
999 to this character. */
1001 if (dp != 0
1002 && ! (multibyte && BASE_LEADING_CODE_P (c))
1003 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1005 Lisp_Object charvec;
1006 EMACS_INT i, n;
1008 /* This character is displayed using a vector of glyphs.
1009 Update the position based on those glyphs. */
1011 charvec = DISP_CHAR_VECTOR (dp, c);
1012 n = ASIZE (charvec);
1014 for (i = 0; i < n; i++)
1016 /* This should be handled the same as
1017 next_element_from_display_vector does it. */
1019 Lisp_Object entry;
1020 entry = AREF (charvec, i);
1022 if (INTEGERP (entry)
1023 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
1024 c = FAST_GLYPH_CHAR (XFASTINT (entry));
1025 else
1026 c = ' ';
1028 if (c == '\n')
1029 goto endloop;
1030 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
1031 goto endloop;
1032 if (c == '\t')
1034 prev_col = col;
1035 col += tab_width;
1036 col = col / tab_width * tab_width;
1038 else
1039 ++col;
1042 else
1044 /* The display table doesn't affect this character;
1045 it displays as itself. */
1047 if (c == '\n')
1048 goto endloop;
1049 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
1050 goto endloop;
1051 if (c == '\t')
1053 prev_col = col;
1054 col += tab_width;
1055 col = col / tab_width * tab_width;
1057 else if (ctl_arrow && (c < 040 || c == 0177))
1058 col += 2;
1059 else if (c < 040 || c == 0177)
1060 col += 4;
1061 else if (c < 0177)
1062 col++;
1063 else if (multibyte && BASE_LEADING_CODE_P (c))
1065 /* Start of multi-byte form. */
1066 unsigned char *ptr;
1067 int bytes, width, wide_column;
1069 ptr = BYTE_POS_ADDR (pos_byte);
1070 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1071 pos_byte += bytes - 1;
1072 col += width;
1074 else
1075 col += 4;
1078 pos++;
1079 pos_byte++;
1081 endloop:
1083 SET_PT_BOTH (pos, pos_byte);
1085 /* If a tab char made us overshoot, change it to spaces
1086 and scan through it again. */
1087 if (!NILP (force) && col > goal && c == '\t' && prev_col < goal)
1089 int goal_pt, goal_pt_byte;
1091 /* Insert spaces in front of the tab to reach GOAL. Do this
1092 first so that a marker at the end of the tab gets
1093 adjusted. */
1094 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1095 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1097 /* Now delete the tab, and indent to COL. */
1098 del_range (PT, PT + 1);
1099 goal_pt = PT;
1100 goal_pt_byte = PT_BYTE;
1101 Findent_to (make_number (col), Qnil);
1102 SET_PT_BOTH (goal_pt, goal_pt_byte);
1104 /* Set the last_known... vars consistently. */
1105 col = goal;
1108 /* If line ends prematurely, add space to the end. */
1109 if (col < goal && EQ (force, Qt))
1110 Findent_to (make_number (col = goal), Qnil);
1112 last_known_column = col;
1113 last_known_column_point = PT;
1114 last_known_column_modified = MODIFF;
1116 XSETFASTINT (val, col);
1117 return val;
1120 /* compute_motion: compute buffer posn given screen posn and vice versa */
1122 struct position val_compute_motion;
1124 /* Scan the current buffer forward from offset FROM, pretending that
1125 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1126 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1127 and return the ending buffer position and screen location. If we
1128 can't hit the requested column exactly (because of a tab or other
1129 multi-column character), overshoot.
1131 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1132 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1133 earlier call to compute_motion. The other common case is that FROMHPOS
1134 is zero and FROM is a position that "belongs" at column zero, but might
1135 be shifted by overlay strings; in this case DID_MOTION should be 0.
1137 WIDTH is the number of columns available to display text;
1138 compute_motion uses this to handle continuation lines and such.
1139 HSCROLL is the number of columns not being displayed at the left
1140 margin; this is usually taken from a window's hscroll member.
1141 TAB_OFFSET is the number of columns of the first tab that aren't
1142 being displayed, perhaps because of a continuation line or
1143 something.
1145 compute_motion returns a pointer to a struct position. The bufpos
1146 member gives the buffer position at the end of the scan, and hpos
1147 and vpos give its cartesian location. prevhpos is the column at
1148 which the character before bufpos started, and contin is non-zero
1149 if we reached the current line by continuing the previous.
1151 Note that FROMHPOS and TOHPOS should be expressed in real screen
1152 columns, taking HSCROLL and the truncation glyph at the left margin
1153 into account. That is, beginning-of-line moves you to the hpos
1154 -HSCROLL + (HSCROLL > 0).
1156 For example, to find the buffer position of column COL of line LINE
1157 of a certain window, pass the window's starting location as FROM
1158 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1159 Pass the buffer's ZV as TO, to limit the scan to the end of the
1160 visible section of the buffer, and pass LINE and COL as TOVPOS and
1161 TOHPOS.
1163 When displaying in window w, a typical formula for WIDTH is:
1165 window_width - 1
1166 - (has_vertical_scroll_bars
1167 ? FRAME_SCROLL_BAR_COLS (XFRAME (window->frame))
1168 : (window_width + window_left != frame_width))
1170 where
1171 window_width is XFASTINT (w->width),
1172 window_left is XFASTINT (w->left),
1173 has_vertical_scroll_bars is
1174 FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (WINDOW_FRAME (window)))
1175 and frame_width = FRAME_WIDTH (XFRAME (window->frame))
1177 Or you can let window_internal_width do this all for you, and write:
1178 window_internal_width (w) - 1
1180 The `-1' accounts for the continuation-line backslashes; the rest
1181 accounts for window borders if the window is split horizontally, and
1182 the scroll bars if they are turned on. */
1184 struct position *
1185 compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, hscroll, tab_offset, win)
1186 int from, fromvpos, fromhpos, to, tovpos, tohpos;
1187 int did_motion;
1188 register int width;
1189 int hscroll, tab_offset;
1190 struct window *win;
1192 register int hpos = fromhpos;
1193 register int vpos = fromvpos;
1195 register int pos;
1196 int pos_byte;
1197 register int c = 0;
1198 register int tab_width = XFASTINT (current_buffer->tab_width);
1199 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
1200 register struct Lisp_Char_Table *dp = window_display_table (win);
1201 int selective
1202 = (INTEGERP (current_buffer->selective_display)
1203 ? XINT (current_buffer->selective_display)
1204 : !NILP (current_buffer->selective_display) ? -1 : 0);
1205 int prev_hpos = 0;
1206 int selective_rlen
1207 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1208 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
1209 /* The next location where the `invisible' property changes, or an
1210 overlay starts or ends. */
1211 int next_boundary = from;
1213 /* For computing runs of characters with similar widths.
1214 Invariant: width_run_width is zero, or all the characters
1215 from width_run_start to width_run_end have a fixed width of
1216 width_run_width. */
1217 int width_run_start = from;
1218 int width_run_end = from;
1219 int width_run_width = 0;
1220 Lisp_Object *width_table;
1221 Lisp_Object buffer;
1223 /* The next buffer pos where we should consult the width run cache. */
1224 int next_width_run = from;
1225 Lisp_Object window;
1227 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
1228 /* If previous char scanned was a wide character,
1229 this is the column where it ended. Otherwise, this is 0. */
1230 int wide_column_end_hpos = 0;
1231 int prev_pos; /* Previous buffer position. */
1232 int prev_pos_byte; /* Previous buffer position. */
1233 int contin_hpos; /* HPOS of last column of continued line. */
1234 int prev_tab_offset; /* Previous tab offset. */
1236 XSETBUFFER (buffer, current_buffer);
1237 XSETWINDOW (window, win);
1239 width_run_cache_on_off ();
1240 if (dp == buffer_display_table ())
1241 width_table = (VECTORP (current_buffer->width_table)
1242 ? XVECTOR (current_buffer->width_table)->contents
1243 : 0);
1244 else
1245 /* If the window has its own display table, we can't use the width
1246 run cache, because that's based on the buffer's display table. */
1247 width_table = 0;
1249 if (tab_width <= 0 || tab_width > 1000)
1250 tab_width = 8;
1252 immediate_quit = 1;
1253 QUIT;
1255 pos = prev_pos = from;
1256 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1257 contin_hpos = 0;
1258 prev_tab_offset = tab_offset;
1259 while (1)
1261 while (pos == next_boundary)
1263 int pos_here = pos;
1264 int newpos;
1266 /* Don't skip invisible if we are already at the margin. */
1267 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1269 if (contin_hpos && prev_hpos == 0
1270 && hpos > tohpos
1271 && (contin_hpos == width || wide_column_end_hpos > width))
1272 { /* Line breaks because we can't put the character at the
1273 previous line any more. It is not the multi-column
1274 character continued in middle. Go back to previous
1275 buffer position, screen position, and set tab offset
1276 to previous value. It's the beginning of the
1277 line. */
1278 pos = prev_pos;
1279 pos_byte = prev_pos_byte;
1280 hpos = prev_hpos;
1281 tab_offset = prev_tab_offset;
1283 break;
1286 /* If the caller says that the screen position came from an earlier
1287 call to compute_motion, then we've already accounted for the
1288 overlay strings at point. This is only true the first time
1289 through, so clear the flag after testing it. */
1290 if (!did_motion)
1291 /* We need to skip past the overlay strings. Currently those
1292 strings must not contain TAB;
1293 if we want to relax that restriction, something will have
1294 to be changed here. */
1296 unsigned char *ovstr;
1297 int ovlen = overlay_strings (pos, win, &ovstr);
1298 hpos += ((multibyte && ovlen > 0)
1299 ? strwidth (ovstr, ovlen) : ovlen);
1301 did_motion = 0;
1303 if (pos >= to)
1304 break;
1306 /* Advance POS past invisible characters
1307 (but not necessarily all that there are here),
1308 and store in next_boundary the next position where
1309 we need to call skip_invisible. */
1310 newpos = skip_invisible (pos, &next_boundary, to, window);
1312 if (newpos >= to)
1314 pos = min (to, newpos);
1315 pos_byte = CHAR_TO_BYTE (pos);
1316 goto after_loop;
1319 if (newpos != pos_here)
1321 pos = newpos;
1322 pos_byte = CHAR_TO_BYTE (pos);
1326 /* Handle right margin. */
1327 /* Note on a wide-column character.
1329 Characters are classified into the following three categories
1330 according to the width (columns occupied on screen).
1332 (1) single-column character: ex. `a'
1333 (2) multi-column character: ex. `^A', TAB, `\033'
1334 (3) wide-column character: ex. Japanese character, Chinese character
1335 (In the following example, `W_' stands for them.)
1337 Multi-column characters can be divided around the right margin,
1338 but wide-column characters cannot.
1340 NOTE:
1342 (*) The cursor is placed on the next character after the point.
1344 ----------
1345 abcdefghi\
1346 j ^---- next after the point
1347 ^--- next char. after the point.
1348 ----------
1349 In case of sigle-column character
1351 ----------
1352 abcdefgh\\
1353 033 ^---- next after the point, next char. after the point.
1354 ----------
1355 In case of multi-column character
1357 ----------
1358 abcdefgh\\
1359 W_ ^---- next after the point
1360 ^---- next char. after the point.
1361 ----------
1362 In case of wide-column character
1364 The problem here is continuation at a wide-column character.
1365 In this case, the line may shorter less than WIDTH.
1366 And we find the continuation AFTER it occurs.
1370 if (hpos > width)
1372 if (hscroll
1373 || (truncate_partial_width_windows
1374 && width + 1 < FRAME_WIDTH (XFRAME (WINDOW_FRAME (win))))
1375 || !NILP (current_buffer->truncate_lines))
1377 /* Truncating: skip to newline, unless we are already past
1378 TO (we need to go back below). */
1379 if (pos <= to)
1381 pos = find_before_next_newline (pos, to, 1);
1382 pos_byte = CHAR_TO_BYTE (pos);
1383 hpos = width;
1384 /* If we just skipped next_boundary,
1385 loop around in the main while
1386 and handle it. */
1387 if (pos >= next_boundary)
1388 next_boundary = pos + 1;
1389 prev_hpos = width;
1390 prev_tab_offset = tab_offset;
1393 else
1395 /* Continuing. */
1396 /* Remember the previous value. */
1397 prev_tab_offset = tab_offset;
1399 if (wide_column_end_hpos > width)
1401 hpos -= prev_hpos;
1402 tab_offset += prev_hpos;
1404 else
1406 tab_offset += width;
1407 hpos -= width;
1409 vpos++;
1410 contin_hpos = prev_hpos;
1411 prev_hpos = 0;
1415 /* Stop if past the target buffer position or screen position. */
1416 if (pos > to)
1418 /* Go back to the previous position. */
1419 pos = prev_pos;
1420 pos_byte = prev_pos_byte;
1421 hpos = prev_hpos;
1422 tab_offset = prev_tab_offset;
1424 /* NOTE on contin_hpos, hpos, and prev_hpos.
1426 ----------
1427 abcdefgh\\
1428 W_ ^---- contin_hpos
1429 | ^----- hpos
1430 \---- prev_hpos
1431 ----------
1434 if (contin_hpos && prev_hpos == 0
1435 && contin_hpos < width && !wide_column_end_hpos)
1437 /* Line breaking occurs in the middle of multi-column
1438 character. Go back to previous line. */
1439 hpos = contin_hpos;
1440 vpos = vpos - 1;
1442 else if (c == '\n')
1443 /* If previous character is NEWLINE,
1444 set VPOS back to previous line */
1445 vpos = vpos - 1;
1446 break;
1449 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1451 if (contin_hpos && prev_hpos == 0
1452 && hpos > tohpos
1453 && (contin_hpos == width || wide_column_end_hpos > width))
1454 { /* Line breaks because we can't put the character at the
1455 previous line any more. It is not the multi-column
1456 character continued in middle. Go back to previous
1457 buffer position, screen position, and set tab offset
1458 to previous value. It's the beginning of the
1459 line. */
1460 pos = prev_pos;
1461 pos_byte = prev_pos_byte;
1462 hpos = prev_hpos;
1463 tab_offset = prev_tab_offset;
1465 break;
1467 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1468 break;
1470 prev_hpos = hpos;
1471 prev_pos = pos;
1472 prev_pos_byte = pos_byte;
1473 wide_column_end_hpos = 0;
1475 /* Consult the width run cache to see if we can avoid inspecting
1476 the text character-by-character. */
1477 if (current_buffer->width_run_cache && pos >= next_width_run)
1479 int run_end;
1480 int common_width
1481 = region_cache_forward (current_buffer,
1482 current_buffer->width_run_cache,
1483 pos, &run_end);
1485 /* A width of zero means the character's width varies (like
1486 a tab), is meaningless (like a newline), or we just don't
1487 want to skip over it for some other reason. */
1488 if (common_width != 0)
1490 int run_end_hpos;
1492 /* Don't go past the final buffer posn the user
1493 requested. */
1494 if (run_end > to)
1495 run_end = to;
1497 run_end_hpos = hpos + (run_end - pos) * common_width;
1499 /* Don't go past the final horizontal position the user
1500 requested. */
1501 if (vpos == tovpos && run_end_hpos > tohpos)
1503 run_end = pos + (tohpos - hpos) / common_width;
1504 run_end_hpos = hpos + (run_end - pos) * common_width;
1507 /* Don't go past the margin. */
1508 if (run_end_hpos >= width)
1510 run_end = pos + (width - hpos) / common_width;
1511 run_end_hpos = hpos + (run_end - pos) * common_width;
1514 hpos = run_end_hpos;
1515 if (run_end > pos)
1516 prev_hpos = hpos - common_width;
1517 if (pos != run_end)
1519 pos = run_end;
1520 pos_byte = CHAR_TO_BYTE (pos);
1524 next_width_run = run_end + 1;
1527 /* We have to scan the text character-by-character. */
1528 else
1530 EMACS_INT i, n;
1531 Lisp_Object charvec;
1533 c = FETCH_BYTE (pos_byte);
1535 /* Check composition sequence. */
1537 int len, len_byte, width;
1539 if (check_composition (pos, pos_byte, to, &len, &len_byte, &width))
1541 pos += len;
1542 pos_byte += len_byte;
1543 hpos += width;
1544 continue;
1548 pos++, pos_byte++;
1550 /* Perhaps add some info to the width_run_cache. */
1551 if (current_buffer->width_run_cache)
1553 /* Is this character part of the current run? If so, extend
1554 the run. */
1555 if (pos - 1 == width_run_end
1556 && XFASTINT (width_table[c]) == width_run_width)
1557 width_run_end = pos;
1559 /* The previous run is over, since this is a character at a
1560 different position, or a different width. */
1561 else
1563 /* Have we accumulated a run to put in the cache?
1564 (Currently, we only cache runs of width == 1). */
1565 if (width_run_start < width_run_end
1566 && width_run_width == 1)
1567 know_region_cache (current_buffer,
1568 current_buffer->width_run_cache,
1569 width_run_start, width_run_end);
1571 /* Start recording a new width run. */
1572 width_run_width = XFASTINT (width_table[c]);
1573 width_run_start = pos - 1;
1574 width_run_end = pos;
1578 if (dp != 0
1579 && ! (multibyte && BASE_LEADING_CODE_P (c))
1580 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1582 charvec = DISP_CHAR_VECTOR (dp, c);
1583 n = ASIZE (charvec);
1585 else
1587 charvec = Qnil;
1588 n = 1;
1591 for (i = n - 1; i >= 0; --i)
1593 if (VECTORP (charvec))
1595 /* This should be handled the same as
1596 next_element_from_display_vector does it. */
1597 Lisp_Object entry = AREF (charvec, i);
1599 if (INTEGERP (entry)
1600 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
1601 c = FAST_GLYPH_CHAR (XFASTINT (entry));
1602 else
1603 c = ' ';
1606 if (c >= 040 && c < 0177)
1607 hpos++;
1608 else if (c == '\t')
1610 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1611 % tab_width);
1612 if (tem < 0)
1613 tem += tab_width;
1614 hpos += tab_width - tem;
1616 else if (c == '\n')
1618 if (selective > 0
1619 && indented_beyond_p (pos, pos_byte, selective))
1621 /* If (pos == to), we don't have to take care of
1622 selective display. */
1623 if (pos < to)
1625 /* Skip any number of invisible lines all at once */
1628 pos = find_before_next_newline (pos, to, 1);
1629 if (pos < to)
1630 pos++;
1631 pos_byte = CHAR_TO_BYTE (pos);
1633 while (pos < to
1634 && indented_beyond_p (pos, pos_byte, selective));
1635 /* Allow for the " ..." that is displayed for them. */
1636 if (selective_rlen)
1638 hpos += selective_rlen;
1639 if (hpos >= width)
1640 hpos = width;
1642 DEC_BOTH (pos, pos_byte);
1643 /* We have skipped the invis text, but not the
1644 newline after. */
1647 else
1649 /* A visible line. */
1650 vpos++;
1651 hpos = 0;
1652 hpos -= hscroll;
1653 /* Count the truncation glyph on column 0 */
1654 if (hscroll > 0)
1655 hpos++;
1656 tab_offset = 0;
1658 contin_hpos = 0;
1660 else if (c == CR && selective < 0)
1662 /* In selective display mode,
1663 everything from a ^M to the end of the line is invisible.
1664 Stop *before* the real newline. */
1665 if (pos < to)
1667 pos = find_before_next_newline (pos, to, 1);
1668 pos_byte = CHAR_TO_BYTE (pos);
1670 /* If we just skipped next_boundary,
1671 loop around in the main while
1672 and handle it. */
1673 if (pos > next_boundary)
1674 next_boundary = pos;
1675 /* Allow for the " ..." that is displayed for them. */
1676 if (selective_rlen)
1678 hpos += selective_rlen;
1679 if (hpos >= width)
1680 hpos = width;
1683 else if (multibyte && BASE_LEADING_CODE_P (c))
1685 /* Start of multi-byte form. */
1686 unsigned char *ptr;
1687 int bytes, width, wide_column;
1689 pos_byte--; /* rewind POS_BYTE */
1690 ptr = BYTE_POS_ADDR (pos_byte);
1691 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1692 pos_byte += bytes;
1693 if (wide_column)
1694 wide_column_end_hpos = hpos + wide_column;
1695 hpos += width;
1697 else if (VECTORP (charvec))
1698 ++hpos;
1699 else
1700 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1705 after_loop:
1707 /* Remember any final width run in the cache. */
1708 if (current_buffer->width_run_cache
1709 && width_run_width == 1
1710 && width_run_start < width_run_end)
1711 know_region_cache (current_buffer, current_buffer->width_run_cache,
1712 width_run_start, width_run_end);
1714 val_compute_motion.bufpos = pos;
1715 val_compute_motion.bytepos = pos_byte;
1716 val_compute_motion.hpos = hpos;
1717 val_compute_motion.vpos = vpos;
1718 if (contin_hpos && prev_hpos == 0)
1719 val_compute_motion.prevhpos = contin_hpos;
1720 else
1721 val_compute_motion.prevhpos = prev_hpos;
1722 /* We alalways handle all of them here; none of them remain to do. */
1723 val_compute_motion.ovstring_chars_done = 0;
1725 /* Nonzero if have just continued a line */
1726 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1728 immediate_quit = 0;
1729 return &val_compute_motion;
1733 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1734 doc: /* Scan through the current buffer, calculating screen position.
1735 Scan the current buffer forward from offset FROM,
1736 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1737 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1738 and return the ending buffer position and screen location.
1740 There are three additional arguments:
1742 WIDTH is the number of columns available to display text;
1743 this affects handling of continuation lines.
1744 This is usually the value returned by `window-width', less one (to allow
1745 for the continuation glyph).
1747 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1748 HSCROLL is the number of columns not being displayed at the left
1749 margin; this is usually taken from a window's hscroll member.
1750 TAB-OFFSET is the number of columns of the first tab that aren't
1751 being displayed, perhaps because the line was continued within it.
1752 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1754 WINDOW is the window to operate on. It is used to choose the display table;
1755 if it is showing the current buffer, it is used also for
1756 deciding which overlay properties apply.
1757 Note that `compute-motion' always operates on the current buffer.
1759 The value is a list of five elements:
1760 (POS HPOS VPOS PREVHPOS CONTIN)
1761 POS is the buffer position where the scan stopped.
1762 VPOS is the vertical position where the scan stopped.
1763 HPOS is the horizontal position where the scan stopped.
1765 PREVHPOS is the horizontal position one character back from POS.
1766 CONTIN is t if a line was continued after (or within) the previous character.
1768 For example, to find the buffer position of column COL of line LINE
1769 of a certain window, pass the window's starting location as FROM
1770 and the window's upper-left coordinates as FROMPOS.
1771 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1772 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1773 (from, frompos, to, topos, width, offsets, window)
1774 Lisp_Object from, frompos, to, topos;
1775 Lisp_Object width, offsets, window;
1777 Lisp_Object bufpos, hpos, vpos, prevhpos;
1778 struct position *pos;
1779 int hscroll, tab_offset;
1781 CHECK_NUMBER_COERCE_MARKER (from);
1782 CHECK_CONS (frompos);
1783 CHECK_NUMBER_CAR (frompos);
1784 CHECK_NUMBER_CDR (frompos);
1785 CHECK_NUMBER_COERCE_MARKER (to);
1786 CHECK_CONS (topos);
1787 CHECK_NUMBER_CAR (topos);
1788 CHECK_NUMBER_CDR (topos);
1789 CHECK_NUMBER (width);
1790 if (!NILP (offsets))
1792 CHECK_CONS (offsets);
1793 CHECK_NUMBER_CAR (offsets);
1794 CHECK_NUMBER_CDR (offsets);
1795 hscroll = XINT (XCAR (offsets));
1796 tab_offset = XINT (XCDR (offsets));
1798 else
1799 hscroll = tab_offset = 0;
1801 if (NILP (window))
1802 window = Fselected_window ();
1803 else
1804 CHECK_LIVE_WINDOW (window);
1806 if (XINT (from) < BEGV || XINT (from) > ZV)
1807 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1808 if (XINT (to) < BEGV || XINT (to) > ZV)
1809 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1811 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1812 XINT (XCAR (frompos)), 0,
1813 XINT (to), XINT (XCDR (topos)),
1814 XINT (XCAR (topos)),
1815 XINT (width), 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 (from, vtarget, w)
1837 register int from, vtarget;
1838 struct window *w;
1840 int width = window_internal_width (w) - 1;
1841 int hscroll = XINT (w->hscroll);
1842 struct position pos;
1843 /* vpos is cumulative vertical position, changed as from is changed */
1844 register int vpos = 0;
1845 Lisp_Object prevline;
1846 register int first;
1847 int from_byte;
1848 int lmargin = hscroll > 0 ? 1 - hscroll : 0;
1849 int selective
1850 = (INTEGERP (current_buffer->selective_display)
1851 ? XINT (current_buffer->selective_display)
1852 : !NILP (current_buffer->selective_display) ? -1 : 0);
1853 Lisp_Object window;
1854 int start_hpos = 0;
1855 int did_motion;
1856 /* This is the object we use for fetching character properties. */
1857 Lisp_Object text_prop_object;
1859 XSETWINDOW (window, w);
1861 /* If the window contains this buffer, use it for getting text properties.
1862 Otherwise use the current buffer as arg for doing that. */
1863 if (EQ (w->buffer, Fcurrent_buffer ()))
1864 text_prop_object = window;
1865 else
1866 text_prop_object = Fcurrent_buffer ();
1868 if (vpos >= vtarget)
1870 /* To move upward, go a line at a time until
1871 we have gone at least far enough. */
1873 first = 1;
1875 while ((vpos > vtarget || first) && from > BEGV)
1877 Lisp_Object propval;
1879 XSETFASTINT (prevline, find_next_newline_no_quit (from - 1, -1));
1880 while (XFASTINT (prevline) > BEGV
1881 && ((selective > 0
1882 && indented_beyond_p (XFASTINT (prevline),
1883 CHAR_TO_BYTE (XFASTINT (prevline)),
1884 selective))
1885 /* watch out for newlines with `invisible' property */
1886 || (propval = Fget_char_property (prevline,
1887 Qinvisible,
1888 text_prop_object),
1889 TEXT_PROP_MEANS_INVISIBLE (propval))))
1890 XSETFASTINT (prevline,
1891 find_next_newline_no_quit (XFASTINT (prevline) - 1,
1892 -1));
1893 pos = *compute_motion (XFASTINT (prevline), 0,
1894 lmargin + (XFASTINT (prevline) == BEG
1895 ? start_hpos : 0),
1897 from,
1898 /* Don't care for VPOS... */
1899 1 << (BITS_PER_SHORT - 1),
1900 /* ... nor HPOS. */
1901 1 << (BITS_PER_SHORT - 1),
1902 width, hscroll,
1903 /* This compensates for start_hpos
1904 so that a tab as first character
1905 still occupies 8 columns. */
1906 (XFASTINT (prevline) == BEG
1907 ? -start_hpos : 0),
1909 vpos -= pos.vpos;
1910 first = 0;
1911 from = XFASTINT (prevline);
1914 /* If we made exactly the desired vertical distance,
1915 or if we hit beginning of buffer,
1916 return point found */
1917 if (vpos >= vtarget)
1919 val_vmotion.bufpos = from;
1920 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1921 val_vmotion.vpos = vpos;
1922 val_vmotion.hpos = lmargin;
1923 val_vmotion.contin = 0;
1924 val_vmotion.prevhpos = 0;
1925 val_vmotion.ovstring_chars_done = 0;
1926 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1927 return &val_vmotion;
1930 /* Otherwise find the correct spot by moving down */
1932 /* Moving downward is simple, but must calculate from beg of line
1933 to determine hpos of starting point */
1934 from_byte = CHAR_TO_BYTE (from);
1935 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1937 Lisp_Object propval;
1939 XSETFASTINT (prevline, find_next_newline_no_quit (from, -1));
1940 while (XFASTINT (prevline) > BEGV
1941 && ((selective > 0
1942 && indented_beyond_p (XFASTINT (prevline),
1943 CHAR_TO_BYTE (XFASTINT (prevline)),
1944 selective))
1945 /* watch out for newlines with `invisible' property */
1946 || (propval = Fget_char_property (prevline, Qinvisible,
1947 text_prop_object),
1948 TEXT_PROP_MEANS_INVISIBLE (propval))))
1949 XSETFASTINT (prevline,
1950 find_next_newline_no_quit (XFASTINT (prevline) - 1,
1951 -1));
1952 pos = *compute_motion (XFASTINT (prevline), 0,
1953 lmargin + (XFASTINT (prevline) == BEG
1954 ? start_hpos : 0),
1956 from,
1957 /* Don't care for VPOS... */
1958 1 << (BITS_PER_SHORT - 1),
1959 /* ... nor HPOS. */
1960 1 << (BITS_PER_SHORT - 1),
1961 width, hscroll,
1962 (XFASTINT (prevline) == BEG ? -start_hpos : 0),
1964 did_motion = 1;
1966 else
1968 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
1969 pos.vpos = 0;
1970 pos.tab_offset = 0;
1971 did_motion = 0;
1973 return compute_motion (from, vpos, pos.hpos, did_motion,
1974 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
1975 width, hscroll,
1976 pos.tab_offset - (from == BEG ? start_hpos : 0),
1980 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
1981 doc: /* Move point to start of the screen line LINES lines down.
1982 If LINES is negative, this means moving up.
1984 This function is an ordinary cursor motion function
1985 which calculates the new position based on how text would be displayed.
1986 The new position may be the start of a line,
1987 or just the start of a continuation line.
1988 The function returns number of screen lines moved over;
1989 that usually equals LINES, but may be closer to zero
1990 if beginning or end of buffer was reached.
1992 The optional second argument WINDOW specifies the window to use for
1993 parameters such as width, horizontal scrolling, and so on.
1994 The default is to use the selected window's parameters.
1996 `vertical-motion' always uses the current buffer,
1997 regardless of which buffer is displayed in WINDOW.
1998 This is consistent with other cursor motion functions
1999 and makes it possible to use `vertical-motion' in any buffer,
2000 whether or not it is currently displayed in some window. */)
2001 (lines, window)
2002 Lisp_Object lines, window;
2004 struct it it;
2005 struct text_pos pt;
2006 struct window *w;
2007 Lisp_Object old_buffer;
2008 struct gcpro gcpro1;
2010 CHECK_NUMBER (lines);
2011 if (! NILP (window))
2012 CHECK_WINDOW (window);
2013 else
2014 window = selected_window;
2015 w = XWINDOW (window);
2017 old_buffer = Qnil;
2018 GCPRO1 (old_buffer);
2019 if (XBUFFER (w->buffer) != current_buffer)
2021 /* Set the window's buffer temporarily to the current buffer. */
2022 old_buffer = w->buffer;
2023 XSETBUFFER (w->buffer, current_buffer);
2026 SET_TEXT_POS (pt, PT, PT_BYTE);
2027 start_display (&it, w, pt);
2028 move_it_by_lines (&it, XINT (lines), 0);
2029 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2031 if (BUFFERP (old_buffer))
2032 w->buffer = old_buffer;
2034 RETURN_UNGCPRO (make_number (it.vpos));
2039 /* File's initialization. */
2041 void
2042 syms_of_indent ()
2044 DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
2045 doc: /* *Indentation can insert tabs if this is non-nil.
2046 Setting this variable automatically makes it local to the current buffer. */);
2047 indent_tabs_mode = 1;
2049 defsubr (&Scurrent_indentation);
2050 defsubr (&Sindent_to);
2051 defsubr (&Scurrent_column);
2052 defsubr (&Smove_to_column);
2053 defsubr (&Svertical_motion);
2054 defsubr (&Scompute_motion);