Merge from emacs--devo--0
[bpt/emacs.git] / src / indent.c
1 /* Indentation functions.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 #include <config.h>
23 #include "lisp.h"
24 #include "buffer.h"
25 #include "character.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"
36
37 /* Indentation can insert tabs if this is non-zero;
38 otherwise always uses spaces. */
39
40 int indent_tabs_mode;
41
42 #define CR 015
43
44 /* These three values memorize the current column to avoid recalculation. */
45
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. */
49
50 double last_known_column;
51
52 /* Value of point when current_column was called. */
53
54 int last_known_column_point;
55
56 /* Value of MODIFF when current_column was called. */
57
58 int last_known_column_modified;
59
60 static double current_column_1 P_ ((void));
61 static double position_indentation P_ ((int));
62
63 /* Cache of beginning of line found by the last call of
64 current_column. */
65
66 int current_column_bol_cache;
67
68 /* Get the display table to use for the current buffer. */
69
70 struct Lisp_Char_Table *
71 buffer_display_table ()
72 {
73 Lisp_Object thisbuf;
74
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;
81 }
82 \f
83 /* Width run cache considerations. */
84
85 /* Return the width of character C under display table DP. */
86
87 static int
88 character_width (c, dp)
89 int c;
90 struct Lisp_Char_Table *dp;
91 {
92 Lisp_Object elt;
93
94 /* These width computations were determined by examining the cases
95 in display_text_line. */
96
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;
101
102 /* Some characters are special. */
103 if (c == '\n' || c == '\t' || c == '\015')
104 return 0;
105
106 /* Printing characters have width 1. */
107 else if (c >= 040 && c < 0177)
108 return 1;
109
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;
117 }
118
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. */
122
123 int
124 disptab_matches_widthtab (disptab, widthtab)
125 struct Lisp_Char_Table *disptab;
126 struct Lisp_Vector *widthtab;
127 {
128 int i;
129
130 if (widthtab->size != 256)
131 abort ();
132
133 for (i = 0; i < 256; i++)
134 if (character_width (i, disptab)
135 != XFASTINT (widthtab->contents[i]))
136 return 0;
137
138 return 1;
139 }
140
141 /* Recompute BUF's width table, using the display table DISPTAB. */
142
143 void
144 recompute_width_table (buf, disptab)
145 struct buffer *buf;
146 struct Lisp_Char_Table *disptab;
147 {
148 int i;
149 struct Lisp_Vector *widthtab;
150
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 ();
156
157 for (i = 0; i < 256; i++)
158 XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
159 }
160
161 /* Allocate or free the width run cache, as requested by the current
162 state of current_buffer's cache_long_line_scans variable. */
163
164 static void
165 width_run_cache_on_off ()
166 {
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))
171 {
172 /* It should be off. */
173 if (current_buffer->width_run_cache)
174 {
175 free_region_cache (current_buffer->width_run_cache);
176 current_buffer->width_run_cache = 0;
177 current_buffer->width_table = Qnil;
178 }
179 }
180 else
181 {
182 /* It should be on. */
183 if (current_buffer->width_run_cache == 0)
184 {
185 current_buffer->width_run_cache = new_region_cache ();
186 recompute_width_table (current_buffer, buffer_display_table ());
187 }
188 }
189 }
190
191 \f
192 /* Skip some invisible characters starting from POS.
193 This includes characters invisible because of text properties
194 and characters invisible because of overlays.
195
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.
199
200 Set *NEXT_BOUNDARY_P to the next position at which
201 it will be necessary to call this function again.
202
203 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
204 to a value greater than TO.
205
206 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
207 take account of overlays that apply only in WINDOW.
208
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. */
214
215 int
216 skip_invisible (pos, next_boundary_p, to, window)
217 int pos;
218 int *next_boundary_p;
219 int to;
220 Lisp_Object window;
221 {
222 Lisp_Object prop, position, overlay_limit, proplimit;
223 Lisp_Object buffer, tmp;
224 int end, inv_p;
225
226 XSETFASTINT (position, pos);
227 XSETBUFFER (buffer, current_buffer);
228
229 /* Give faster response for overlay lookup near POS. */
230 recenter_overlay_lists (current_buffer, pos);
231
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
248 {
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 tmp = Fnext_single_property_change (position, Qinvisible,
255 buffer, proplimit);
256 end = XFASTINT (tmp);
257 #if 0
258 /* Don't put the boundary in the middle of multibyte form if
259 there is no actual property change. */
260 if (end == pos + 100
261 && !NILP (current_buffer->enable_multibyte_characters)
262 && end < ZV)
263 while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
264 end--;
265 #endif
266 *next_boundary_p = end;
267 }
268 /* if the `invisible' property is set, we can skip to
269 the next property change */
270 prop = Fget_char_property (position, Qinvisible,
271 (!NILP (window)
272 && EQ (XWINDOW (window)->buffer, buffer))
273 ? window : buffer);
274 inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
275 /* When counting columns (window == nil), don't skip over ellipsis text. */
276 if (NILP (window) ? inv_p == 1 : inv_p)
277 return *next_boundary_p;
278 return pos;
279 }
280 \f
281 /* If a composition starts at POS/POS_BYTE and it doesn't stride over
282 POINT, set *LEN / *LEN_BYTE to the character and byte lengths, *WIDTH
283 to the width, and return 1. Otherwise, return 0. */
284
285 static int
286 check_composition (pos, pos_byte, point, len, len_byte, width)
287 int pos, pos_byte, point;
288 int *len, *len_byte, *width;
289 {
290 Lisp_Object prop;
291 EMACS_INT start, end;
292 int id;
293
294 if (! find_composition (pos, -1, &start, &end, &prop, Qnil)
295 || pos != start || point < end
296 || !COMPOSITION_VALID_P (start, end, prop))
297 return 0;
298 if ((id = get_composition_id (pos, pos_byte, end - pos, prop, Qnil)) < 0)
299 return 0;
300
301 *len = COMPOSITION_LENGTH (prop);
302 *len_byte = CHAR_TO_BYTE (end) - pos_byte;
303 *width = composition_table[id]->width;
304 return 1;
305 }
306 \f
307 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
308
309 DP is a display table or NULL.
310
311 This macro is used in current_column_1, Fmove_to_column, and
312 compute_motion. */
313
314 #define MULTIBYTE_BYTES_WIDTH(p, dp) \
315 do { \
316 int c; \
317 \
318 wide_column = 0; \
319 c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, bytes); \
320 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
321 width = bytes * 4; \
322 else \
323 { \
324 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) \
325 width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size; \
326 else \
327 width = CHAR_WIDTH (c); \
328 if (width > 1) \
329 wide_column = width; \
330 } \
331 } while (0)
332
333
334 DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
335 doc: /* Return the horizontal position of point. Beginning of line is column 0.
336 This is calculated by adding together the widths of all the displayed
337 representations of the character between the start of the previous line
338 and point (eg. control characters will have a width of 2 or 4, tabs
339 will have a variable width).
340 Ignores finite width of frame, which means that this function may return
341 values greater than (frame-width).
342 Whether the line is visible (if `selective-display' is t) has no effect;
343 however, ^M is treated as end of line when `selective-display' is t.
344 Text that has an invisible property is considered as having width 0, unless
345 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
346 ()
347 {
348 Lisp_Object temp;
349 XSETFASTINT (temp, (int) current_column ()); /* iftc */
350 return temp;
351 }
352
353 /* Cancel any recorded value of the horizontal position. */
354
355 void
356 invalidate_current_column ()
357 {
358 last_known_column_point = 0;
359 }
360
361 double
362 current_column ()
363 {
364 register int col;
365 register unsigned char *ptr, *stop;
366 register int tab_seen;
367 int post_tab;
368 register int c;
369 register int tab_width = XINT (current_buffer->tab_width);
370 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
371 register struct Lisp_Char_Table *dp = buffer_display_table ();
372
373 if (PT == last_known_column_point
374 && MODIFF == last_known_column_modified)
375 return last_known_column;
376
377 /* If the buffer has overlays, text properties,
378 or multibyte characters, use a more general algorithm. */
379 if (BUF_INTERVALS (current_buffer)
380 || current_buffer->overlays_before
381 || current_buffer->overlays_after
382 || Z != Z_BYTE)
383 return current_column_1 ();
384
385 /* Scan backwards from point to the previous newline,
386 counting width. Tab characters are the only complicated case. */
387
388 /* Make a pointer for decrementing through the chars before point. */
389 ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
390 /* Make a pointer to where consecutive chars leave off,
391 going backwards from point. */
392 if (PT == BEGV)
393 stop = ptr;
394 else if (PT <= GPT || BEGV > GPT)
395 stop = BEGV_ADDR;
396 else
397 stop = GAP_END_ADDR;
398
399 if (tab_width <= 0 || tab_width > 1000)
400 tab_width = 8;
401
402 col = 0, tab_seen = 0, post_tab = 0;
403
404 while (1)
405 {
406 EMACS_INT i, n;
407 Lisp_Object charvec;
408
409 if (ptr == stop)
410 {
411 /* We stopped either for the beginning of the buffer
412 or for the gap. */
413 if (ptr == BEGV_ADDR)
414 break;
415
416 /* It was the gap. Jump back over it. */
417 stop = BEGV_ADDR;
418 ptr = GPT_ADDR;
419
420 /* Check whether that brings us to beginning of buffer. */
421 if (BEGV >= GPT)
422 break;
423 }
424
425 c = *--ptr;
426
427 if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
428 {
429 charvec = DISP_CHAR_VECTOR (dp, c);
430 n = ASIZE (charvec);
431 }
432 else
433 {
434 charvec = Qnil;
435 n = 1;
436 }
437
438 for (i = n - 1; i >= 0; --i)
439 {
440 if (VECTORP (charvec))
441 {
442 /* This should be handled the same as
443 next_element_from_display_vector does it. */
444 Lisp_Object entry = AREF (charvec, i);
445
446 if (INTEGERP (entry)
447 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
448 c = FAST_GLYPH_CHAR (XFASTINT (entry));
449 else
450 c = ' ';
451 }
452
453 if (c >= 040 && c < 0177)
454 col++;
455 else if (c == '\n'
456 || (c == '\r'
457 && EQ (current_buffer->selective_display, Qt)))
458 {
459 ptr++;
460 goto start_of_line_found;
461 }
462 else if (c == '\t')
463 {
464 if (tab_seen)
465 col = ((col + tab_width) / tab_width) * tab_width;
466
467 post_tab += col;
468 col = 0;
469 tab_seen = 1;
470 }
471 else if (VECTORP (charvec))
472 /* With a display table entry, C is displayed as is, and
473 not displayed as \NNN or as ^N. If C is a single-byte
474 character, it takes one column. If C is multi-byte in
475 an unibyte buffer, it's translated to unibyte, so it
476 also takes one column. */
477 ++col;
478 else
479 col += (ctl_arrow && c < 0200) ? 2 : 4;
480 }
481 }
482
483 start_of_line_found:
484
485 if (tab_seen)
486 {
487 col = ((col + tab_width) / tab_width) * tab_width;
488 col += post_tab;
489 }
490
491 if (ptr == BEGV_ADDR)
492 current_column_bol_cache = BEGV;
493 else
494 current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
495
496 last_known_column = col;
497 last_known_column_point = PT;
498 last_known_column_modified = MODIFF;
499
500 return col;
501 }
502 \f
503 /* Return the column number of position POS
504 by scanning forward from the beginning of the line.
505 This function handles characters that are invisible
506 due to text properties or overlays. */
507
508 static double
509 current_column_1 ()
510 {
511 register int tab_width = XINT (current_buffer->tab_width);
512 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
513 register struct Lisp_Char_Table *dp = buffer_display_table ();
514 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
515
516 /* Start the scan at the beginning of this line with column number 0. */
517 register int col = 0;
518 int scan, scan_byte;
519 int next_boundary;
520 int opoint = PT, opoint_byte = PT_BYTE;
521
522 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
523 current_column_bol_cache = PT;
524 scan = PT, scan_byte = PT_BYTE;
525 SET_PT_BOTH (opoint, opoint_byte);
526 next_boundary = scan;
527
528 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
529
530 /* Scan forward to the target position. */
531 while (scan < opoint)
532 {
533 int c;
534
535 /* Occasionally we may need to skip invisible text. */
536 while (scan == next_boundary)
537 {
538 int old_scan = scan;
539 /* This updates NEXT_BOUNDARY to the next place
540 where we might need to skip more invisible text. */
541 scan = skip_invisible (scan, &next_boundary, opoint, Qnil);
542 if (scan >= opoint)
543 goto endloop;
544 if (scan != old_scan)
545 scan_byte = CHAR_TO_BYTE (scan);
546 }
547
548 /* Check composition sequence. */
549 {
550 int len, len_byte, width;
551
552 if (check_composition (scan, scan_byte, opoint,
553 &len, &len_byte, &width))
554 {
555 scan += len;
556 scan_byte += len_byte;
557 if (scan <= opoint)
558 col += width;
559 continue;
560 }
561 }
562
563 c = FETCH_BYTE (scan_byte);
564
565 if (dp != 0
566 && ! (multibyte && BASE_LEADING_CODE_P (c))
567 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
568 {
569 Lisp_Object charvec;
570 EMACS_INT i, n;
571
572 /* This character is displayed using a vector of glyphs.
573 Update the column based on those glyphs. */
574
575 charvec = DISP_CHAR_VECTOR (dp, c);
576 n = ASIZE (charvec);
577
578 for (i = 0; i < n; i++)
579 {
580 /* This should be handled the same as
581 next_element_from_display_vector does it. */
582 Lisp_Object entry;
583 entry = AREF (charvec, i);
584
585 if (INTEGERP (entry)
586 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
587 c = FAST_GLYPH_CHAR (XFASTINT (entry));
588 else
589 c = ' ';
590
591 if (c == '\n')
592 goto endloop;
593 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
594 goto endloop;
595 if (c == '\t')
596 {
597 col += tab_width;
598 col = col / tab_width * tab_width;
599 }
600 else
601 ++col;
602 }
603 }
604 else
605 {
606 /* The display table says nothing for this character.
607 Display it as itself. */
608
609 if (c == '\n')
610 goto endloop;
611 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
612 goto endloop;
613 if (c == '\t')
614 {
615 col += tab_width;
616 col = col / tab_width * tab_width;
617 }
618 else if (multibyte && BASE_LEADING_CODE_P (c))
619 {
620 unsigned char *ptr;
621 int bytes, width, wide_column;
622
623 ptr = BYTE_POS_ADDR (scan_byte);
624 MULTIBYTE_BYTES_WIDTH (ptr, dp);
625 scan_byte += bytes;
626 /* Subtract one to compensate for the increment
627 that is going to happen below. */
628 scan_byte--;
629 col += width;
630 }
631 else if (ctl_arrow && (c < 040 || c == 0177))
632 col += 2;
633 else if (c < 040 || c >= 0177)
634 col += 4;
635 else
636 col++;
637 }
638 scan++;
639 scan_byte++;
640
641 }
642 endloop:
643
644 last_known_column = col;
645 last_known_column_point = PT;
646 last_known_column_modified = MODIFF;
647
648 return col;
649 }
650 \f
651
652 #if 0 /* Not used. */
653
654 /* Return the width in columns of the part of STRING from BEG to END.
655 If BEG is nil, that stands for the beginning of STRING.
656 If END is nil, that stands for the end of STRING. */
657
658 static double
659 string_display_width (string, beg, end)
660 Lisp_Object string, beg, end;
661 {
662 register int col;
663 register unsigned char *ptr, *stop;
664 register int tab_seen;
665 int post_tab;
666 register int c;
667 register int tab_width = XINT (current_buffer->tab_width);
668 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
669 register struct Lisp_Char_Table *dp = buffer_display_table ();
670 int b, e;
671
672 if (NILP (end))
673 e = SCHARS (string);
674 else
675 {
676 CHECK_NUMBER (end);
677 e = XINT (end);
678 }
679
680 if (NILP (beg))
681 b = 0;
682 else
683 {
684 CHECK_NUMBER (beg);
685 b = XINT (beg);
686 }
687
688 /* Make a pointer for decrementing through the chars before point. */
689 ptr = SDATA (string) + e;
690 /* Make a pointer to where consecutive chars leave off,
691 going backwards from point. */
692 stop = SDATA (string) + b;
693
694 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
695
696 col = 0, tab_seen = 0, post_tab = 0;
697
698 while (1)
699 {
700 if (ptr == stop)
701 break;
702
703 c = *--ptr;
704 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
705 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
706 else if (c >= 040 && c < 0177)
707 col++;
708 else if (c == '\n')
709 break;
710 else if (c == '\t')
711 {
712 if (tab_seen)
713 col = ((col + tab_width) / tab_width) * tab_width;
714
715 post_tab += col;
716 col = 0;
717 tab_seen = 1;
718 }
719 else
720 col += (ctl_arrow && c < 0200) ? 2 : 4;
721 }
722
723 if (tab_seen)
724 {
725 col = ((col + tab_width) / tab_width) * tab_width;
726 col += post_tab;
727 }
728
729 return col;
730 }
731
732 #endif /* 0 */
733
734 \f
735 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
736 doc: /* Indent from point with tabs and spaces until COLUMN is reached.
737 Optional second argument MINIMUM says always do at least MINIMUM spaces
738 even if that goes past COLUMN; by default, MINIMUM is zero. */)
739 (column, minimum)
740 Lisp_Object column, minimum;
741 {
742 int mincol;
743 register int fromcol;
744 register int tab_width = XINT (current_buffer->tab_width);
745
746 CHECK_NUMBER (column);
747 if (NILP (minimum))
748 XSETFASTINT (minimum, 0);
749 CHECK_NUMBER (minimum);
750
751 fromcol = current_column ();
752 mincol = fromcol + XINT (minimum);
753 if (mincol < XINT (column)) mincol = XINT (column);
754
755 if (fromcol == mincol)
756 return make_number (mincol);
757
758 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
759
760 if (indent_tabs_mode)
761 {
762 Lisp_Object n;
763 XSETFASTINT (n, mincol / tab_width - fromcol / tab_width);
764 if (XFASTINT (n) != 0)
765 {
766 Finsert_char (make_number ('\t'), n, Qt);
767
768 fromcol = (mincol / tab_width) * tab_width;
769 }
770 }
771
772 XSETFASTINT (column, mincol - fromcol);
773 Finsert_char (make_number (' '), column, Qt);
774
775 last_known_column = mincol;
776 last_known_column_point = PT;
777 last_known_column_modified = MODIFF;
778
779 XSETINT (column, mincol);
780 return column;
781 }
782
783 \f
784 static double position_indentation P_ ((int));
785
786 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
787 0, 0, 0,
788 doc: /* Return the indentation of the current line.
789 This is the horizontal position of the character
790 following any initial whitespace. */)
791 ()
792 {
793 Lisp_Object val;
794 int opoint = PT, opoint_byte = PT_BYTE;
795
796 scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
797
798 XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */
799 SET_PT_BOTH (opoint, opoint_byte);
800 return val;
801 }
802
803 static double
804 position_indentation (pos_byte)
805 register int pos_byte;
806 {
807 register int column = 0;
808 register int tab_width = XINT (current_buffer->tab_width);
809 register unsigned char *p;
810 register unsigned char *stop;
811 unsigned char *start;
812 int next_boundary_byte = pos_byte;
813 int ceiling = next_boundary_byte;
814
815 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
816
817 p = BYTE_POS_ADDR (pos_byte);
818 /* STOP records the value of P at which we will need
819 to think about the gap, or about invisible text,
820 or about the end of the buffer. */
821 stop = p;
822 /* START records the starting value of P. */
823 start = p;
824 while (1)
825 {
826 while (p == stop)
827 {
828 int stop_pos_byte;
829
830 /* If we have updated P, set POS_BYTE to match.
831 The first time we enter the loop, POS_BYTE is already right. */
832 if (p != start)
833 pos_byte = PTR_BYTE_POS (p);
834 /* Consider the various reasons STOP might have been set here. */
835 if (pos_byte == ZV_BYTE)
836 return column;
837 if (pos_byte == next_boundary_byte)
838 {
839 int next_boundary;
840 int pos = BYTE_TO_CHAR (pos_byte);
841 pos = skip_invisible (pos, &next_boundary, ZV, Qnil);
842 pos_byte = CHAR_TO_BYTE (pos);
843 next_boundary_byte = CHAR_TO_BYTE (next_boundary);
844 }
845 if (pos_byte >= ceiling)
846 ceiling = BUFFER_CEILING_OF (pos_byte) + 1;
847 /* Compute the next place we need to stop and think,
848 and set STOP accordingly. */
849 stop_pos_byte = min (ceiling, next_boundary_byte);
850 /* The -1 and +1 arrange to point at the first byte of gap
851 (if STOP_POS_BYTE is the position of the gap)
852 rather than at the data after the gap. */
853
854 stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
855 p = BYTE_POS_ADDR (pos_byte);
856 }
857 switch (*p++)
858 {
859 case 0240:
860 if (! NILP (current_buffer->enable_multibyte_characters))
861 return column;
862 case ' ':
863 column++;
864 break;
865 case '\t':
866 column += tab_width - column % tab_width;
867 break;
868 default:
869 if (ASCII_BYTE_P (p[-1])
870 || NILP (current_buffer->enable_multibyte_characters))
871 return column;
872 {
873 int c;
874 pos_byte = PTR_BYTE_POS (p - 1);
875 c = FETCH_MULTIBYTE_CHAR (pos_byte);
876 if (CHAR_HAS_CATEGORY (c, ' '))
877 {
878 column++;
879 INC_POS (pos_byte);
880 p = BYTE_POS_ADDR (pos_byte);
881 }
882 else
883 return column;
884 }
885 }
886 }
887 }
888
889 /* Test whether the line beginning at POS is indented beyond COLUMN.
890 Blank lines are treated as if they had the same indentation as the
891 preceding line. */
892
893 int
894 indented_beyond_p (pos, pos_byte, column)
895 int pos, pos_byte;
896 double column;
897 {
898 double val;
899 int opoint = PT, opoint_byte = PT_BYTE;
900
901 SET_PT_BOTH (pos, pos_byte);
902 while (PT > BEGV && FETCH_BYTE (PT_BYTE) == '\n')
903 scan_newline (PT - 1, PT_BYTE - 1, BEGV, BEGV_BYTE, -1, 0);
904
905 val = position_indentation (PT_BYTE);
906 SET_PT_BOTH (opoint, opoint_byte);
907 return val >= column; /* hmm, float comparison */
908 }
909 \f
910 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
911 doc: /* Move point to column COLUMN in the current line.
912 Interactively, COLUMN is the value of prefix numeric argument.
913 The column of a character is calculated by adding together the widths
914 as displayed of the previous characters in the line.
915 This function ignores line-continuation;
916 there is no upper limit on the column number a character can have
917 and horizontal scrolling has no effect.
918
919 If specified column is within a character, point goes after that character.
920 If it's past end of line, point goes to end of line.
921
922 Optional second argument FORCE non-nil means if COLUMN is in the
923 middle of a tab character, change it to spaces.
924 In addition, if FORCE is t, and the line is too short to reach
925 COLUMN, add spaces/tabs to get there.
926
927 The return value is the current column. */)
928 (column, force)
929 Lisp_Object column, force;
930 {
931 register int pos;
932 register int col = current_column ();
933 register int goal;
934 register int end;
935 register int tab_width = XINT (current_buffer->tab_width);
936 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
937 register struct Lisp_Char_Table *dp = buffer_display_table ();
938 register int multibyte = !NILP (current_buffer->enable_multibyte_characters);
939
940 Lisp_Object val;
941 int prev_col = 0;
942 int c = 0;
943 int next_boundary, pos_byte;
944
945 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
946 CHECK_NATNUM (column);
947 goal = XINT (column);
948
949 pos = PT;
950 pos_byte = PT_BYTE;
951 end = ZV;
952 next_boundary = pos;
953
954 /* If we're starting past the desired column,
955 back up to beginning of line and scan from there. */
956 if (col > goal)
957 {
958 end = pos;
959 pos = current_column_bol_cache;
960 pos_byte = CHAR_TO_BYTE (pos);
961 col = 0;
962 }
963
964 while (pos < end)
965 {
966 while (pos == next_boundary)
967 {
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 if (pos >= end)
973 goto endloop;
974 }
975
976 /* Test reaching the goal column. We do this after skipping
977 invisible characters, so that we put point before the
978 character on which the cursor will appear. */
979 if (col >= goal)
980 break;
981
982 /* Check composition sequence. */
983 {
984 int len, len_byte, width;
985
986 if (check_composition (pos, pos_byte, Z, &len, &len_byte, &width))
987 {
988 pos += len;
989 pos_byte += len_byte;
990 col += width;
991 continue;
992 }
993 }
994
995 c = FETCH_BYTE (pos_byte);
996
997 /* See if there is a display table and it relates
998 to this character. */
999
1000 if (dp != 0
1001 && ! (multibyte && BASE_LEADING_CODE_P (c))
1002 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1003 {
1004 Lisp_Object charvec;
1005 EMACS_INT i, n;
1006
1007 /* This character is displayed using a vector of glyphs.
1008 Update the position based on those glyphs. */
1009
1010 charvec = DISP_CHAR_VECTOR (dp, c);
1011 n = ASIZE (charvec);
1012
1013 for (i = 0; i < n; i++)
1014 {
1015 /* This should be handled the same as
1016 next_element_from_display_vector does it. */
1017
1018 Lisp_Object entry;
1019 entry = AREF (charvec, i);
1020
1021 if (INTEGERP (entry)
1022 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
1023 c = FAST_GLYPH_CHAR (XFASTINT (entry));
1024 else
1025 c = ' ';
1026
1027 if (c == '\n')
1028 goto endloop;
1029 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
1030 goto endloop;
1031 if (c == '\t')
1032 {
1033 prev_col = col;
1034 col += tab_width;
1035 col = col / tab_width * tab_width;
1036 }
1037 else
1038 ++col;
1039 }
1040 }
1041 else
1042 {
1043 /* The display table doesn't affect this character;
1044 it displays as itself. */
1045
1046 if (c == '\n')
1047 goto endloop;
1048 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
1049 goto endloop;
1050 if (c == '\t')
1051 {
1052 prev_col = col;
1053 col += tab_width;
1054 col = col / tab_width * tab_width;
1055 }
1056 else if (ctl_arrow && (c < 040 || c == 0177))
1057 col += 2;
1058 else if (c < 040 || c == 0177)
1059 col += 4;
1060 else if (c < 0177)
1061 col++;
1062 else if (multibyte && BASE_LEADING_CODE_P (c))
1063 {
1064 /* Start of multi-byte form. */
1065 unsigned char *ptr;
1066 int bytes, width, wide_column;
1067
1068 ptr = BYTE_POS_ADDR (pos_byte);
1069 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1070 pos_byte += bytes - 1;
1071 col += width;
1072 }
1073 else
1074 col += 4;
1075 }
1076
1077 pos++;
1078 pos_byte++;
1079 }
1080 endloop:
1081
1082 SET_PT_BOTH (pos, pos_byte);
1083
1084 /* If a tab char made us overshoot, change it to spaces
1085 and scan through it again. */
1086 if (!NILP (force) && col > goal && c == '\t' && prev_col < goal)
1087 {
1088 int goal_pt, goal_pt_byte;
1089
1090 /* Insert spaces in front of the tab to reach GOAL. Do this
1091 first so that a marker at the end of the tab gets
1092 adjusted. */
1093 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
1094 Finsert_char (make_number (' '), make_number (goal - prev_col), Qt);
1095
1096 /* Now delete the tab, and indent to COL. */
1097 del_range (PT, PT + 1);
1098 goal_pt = PT;
1099 goal_pt_byte = PT_BYTE;
1100 Findent_to (make_number (col), Qnil);
1101 SET_PT_BOTH (goal_pt, goal_pt_byte);
1102
1103 /* Set the last_known... vars consistently. */
1104 col = goal;
1105 }
1106
1107 /* If line ends prematurely, add space to the end. */
1108 if (col < goal && EQ (force, Qt))
1109 Findent_to (make_number (col = goal), Qnil);
1110
1111 last_known_column = col;
1112 last_known_column_point = PT;
1113 last_known_column_modified = MODIFF;
1114
1115 XSETFASTINT (val, col);
1116 return val;
1117 }
1118 \f
1119 /* compute_motion: compute buffer posn given screen posn and vice versa */
1120
1121 struct position val_compute_motion;
1122
1123 /* Scan the current buffer forward from offset FROM, pretending that
1124 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1125 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1126 and return the ending buffer position and screen location. If we
1127 can't hit the requested column exactly (because of a tab or other
1128 multi-column character), overshoot.
1129
1130 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1131 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1132 earlier call to compute_motion. The other common case is that FROMHPOS
1133 is zero and FROM is a position that "belongs" at column zero, but might
1134 be shifted by overlay strings; in this case DID_MOTION should be 0.
1135
1136 WIDTH is the number of columns available to display text;
1137 compute_motion uses this to handle continuation lines and such.
1138 If WIDTH is -1, use width of window's text area adjusted for
1139 continuation glyph when needed.
1140
1141 HSCROLL is the number of columns not being displayed at the left
1142 margin; this is usually taken from a window's hscroll member.
1143 TAB_OFFSET is the number of columns of the first tab that aren't
1144 being displayed, perhaps because of a continuation line or
1145 something.
1146
1147 compute_motion returns a pointer to a struct position. The bufpos
1148 member gives the buffer position at the end of the scan, and hpos
1149 and vpos give its cartesian location. prevhpos is the column at
1150 which the character before bufpos started, and contin is non-zero
1151 if we reached the current line by continuing the previous.
1152
1153 Note that FROMHPOS and TOHPOS should be expressed in real screen
1154 columns, taking HSCROLL and the truncation glyph at the left margin
1155 into account. That is, beginning-of-line moves you to the hpos
1156 -HSCROLL + (HSCROLL > 0).
1157
1158 For example, to find the buffer position of column COL of line LINE
1159 of a certain window, pass the window's starting location as FROM
1160 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1161 Pass the buffer's ZV as TO, to limit the scan to the end of the
1162 visible section of the buffer, and pass LINE and COL as TOVPOS and
1163 TOHPOS.
1164
1165 When displaying in window w, a typical formula for WIDTH is:
1166
1167 window_width - 1
1168 - (has_vertical_scroll_bars
1169 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1170 : (window_width + window_left != frame_cols))
1171
1172 where
1173 window_width is XFASTINT (w->total_cols),
1174 window_left is XFASTINT (w->left_col),
1175 has_vertical_scroll_bars is
1176 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1177 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1178
1179 Or you can let window_box_text_cols do this all for you, and write:
1180 window_box_text_cols (w) - 1
1181
1182 The `-1' accounts for the continuation-line backslashes; the rest
1183 accounts for window borders if the window is split horizontally, and
1184 the scroll bars if they are turned on. */
1185
1186 struct position *
1187 compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, hscroll, tab_offset, win)
1188 int from, fromvpos, fromhpos, to, tovpos, tohpos;
1189 int did_motion;
1190 register int width;
1191 int hscroll, tab_offset;
1192 struct window *win;
1193 {
1194 register int hpos = fromhpos;
1195 register int vpos = fromvpos;
1196
1197 register int pos;
1198 int pos_byte;
1199 register int c = 0;
1200 register int tab_width = XFASTINT (current_buffer->tab_width);
1201 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
1202 register struct Lisp_Char_Table *dp = window_display_table (win);
1203 int selective
1204 = (INTEGERP (current_buffer->selective_display)
1205 ? XINT (current_buffer->selective_display)
1206 : !NILP (current_buffer->selective_display) ? -1 : 0);
1207 int selective_rlen
1208 = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
1209 ? XVECTOR (DISP_INVIS_VECTOR (dp))->size : 0);
1210 /* The next location where the `invisible' property changes, or an
1211 overlay starts or ends. */
1212 int next_boundary = from;
1213
1214 /* For computing runs of characters with similar widths.
1215 Invariant: width_run_width is zero, or all the characters
1216 from width_run_start to width_run_end have a fixed width of
1217 width_run_width. */
1218 int width_run_start = from;
1219 int width_run_end = from;
1220 int width_run_width = 0;
1221 Lisp_Object *width_table;
1222 Lisp_Object buffer;
1223
1224 /* The next buffer pos where we should consult the width run cache. */
1225 int next_width_run = from;
1226 Lisp_Object window;
1227
1228 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
1229 /* If previous char scanned was a wide character,
1230 this is the column where it ended. Otherwise, this is 0. */
1231 int wide_column_end_hpos = 0;
1232 int prev_pos; /* Previous buffer position. */
1233 int prev_pos_byte; /* Previous buffer position. */
1234 int prev_hpos = 0;
1235 int prev_vpos = 0;
1236 int contin_hpos; /* HPOS of last column of continued line. */
1237 int prev_tab_offset; /* Previous tab offset. */
1238 int continuation_glyph_width;
1239
1240 XSETBUFFER (buffer, current_buffer);
1241 XSETWINDOW (window, win);
1242
1243 width_run_cache_on_off ();
1244 if (dp == buffer_display_table ())
1245 width_table = (VECTORP (current_buffer->width_table)
1246 ? XVECTOR (current_buffer->width_table)->contents
1247 : 0);
1248 else
1249 /* If the window has its own display table, we can't use the width
1250 run cache, because that's based on the buffer's display table. */
1251 width_table = 0;
1252
1253 if (tab_width <= 0 || tab_width > 1000)
1254 tab_width = 8;
1255
1256 /* Negative width means use all available text columns. */
1257 if (width < 0)
1258 {
1259 width = window_box_text_cols (win);
1260 /* We must make room for continuation marks if we don't have fringes. */
1261 #ifdef HAVE_WINDOW_SYSTEM
1262 if (!FRAME_WINDOW_P (XFRAME (win->frame)))
1263 #endif
1264 width -= 1;
1265 }
1266
1267 continuation_glyph_width = 1;
1268 #ifdef HAVE_WINDOW_SYSTEM
1269 if (FRAME_WINDOW_P (XFRAME (win->frame)))
1270 continuation_glyph_width = 0; /* In the fringe. */
1271 #endif
1272
1273 immediate_quit = 1;
1274 QUIT;
1275
1276 pos = prev_pos = from;
1277 pos_byte = prev_pos_byte = CHAR_TO_BYTE (from);
1278 contin_hpos = 0;
1279 prev_tab_offset = tab_offset;
1280 while (1)
1281 {
1282 while (pos == next_boundary)
1283 {
1284 int pos_here = pos;
1285 int newpos;
1286
1287 /* Don't skip invisible if we are already at the margin. */
1288 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1289 {
1290 if (contin_hpos && prev_hpos == 0
1291 && hpos > tohpos
1292 && (contin_hpos == width || wide_column_end_hpos > width))
1293 { /* Line breaks because we can't put the character at the
1294 previous line any more. It is not the multi-column
1295 character continued in middle. Go back to previous
1296 buffer position, screen position, and set tab offset
1297 to previous value. It's the beginning of the
1298 line. */
1299 pos = prev_pos;
1300 pos_byte = prev_pos_byte;
1301 hpos = prev_hpos;
1302 vpos = prev_vpos;
1303 tab_offset = prev_tab_offset;
1304 }
1305 break;
1306 }
1307
1308 /* If the caller says that the screen position came from an earlier
1309 call to compute_motion, then we've already accounted for the
1310 overlay strings at point. This is only true the first time
1311 through, so clear the flag after testing it. */
1312 if (!did_motion)
1313 /* We need to skip past the overlay strings. Currently those
1314 strings must not contain TAB;
1315 if we want to relax that restriction, something will have
1316 to be changed here. */
1317 {
1318 unsigned char *ovstr;
1319 int ovlen = overlay_strings (pos, win, &ovstr);
1320 hpos += ((multibyte && ovlen > 0)
1321 ? strwidth (ovstr, ovlen) : ovlen);
1322 }
1323 did_motion = 0;
1324
1325 if (pos >= to)
1326 break;
1327
1328 /* Advance POS past invisible characters
1329 (but not necessarily all that there are here),
1330 and store in next_boundary the next position where
1331 we need to call skip_invisible. */
1332 newpos = skip_invisible (pos, &next_boundary, to, window);
1333
1334 if (newpos >= to)
1335 {
1336 pos = min (to, newpos);
1337 pos_byte = CHAR_TO_BYTE (pos);
1338 goto after_loop;
1339 }
1340
1341 if (newpos != pos_here)
1342 {
1343 pos = newpos;
1344 pos_byte = CHAR_TO_BYTE (pos);
1345 }
1346 }
1347
1348 /* Handle right margin. */
1349 /* Note on a wide-column character.
1350
1351 Characters are classified into the following three categories
1352 according to the width (columns occupied on screen).
1353
1354 (1) single-column character: ex. `a'
1355 (2) multi-column character: ex. `^A', TAB, `\033'
1356 (3) wide-column character: ex. Japanese character, Chinese character
1357 (In the following example, `W_' stands for them.)
1358
1359 Multi-column characters can be divided around the right margin,
1360 but wide-column characters cannot.
1361
1362 NOTE:
1363
1364 (*) The cursor is placed on the next character after the point.
1365
1366 ----------
1367 abcdefghi\
1368 j ^---- next after the point
1369 ^--- next char. after the point.
1370 ----------
1371 In case of sigle-column character
1372
1373 ----------
1374 abcdefgh\\
1375 033 ^---- next after the point, next char. after the point.
1376 ----------
1377 In case of multi-column character
1378
1379 ----------
1380 abcdefgh\\
1381 W_ ^---- next after the point
1382 ^---- next char. after the point.
1383 ----------
1384 In case of wide-column character
1385
1386 The problem here is continuation at a wide-column character.
1387 In this case, the line may shorter less than WIDTH.
1388 And we find the continuation AFTER it occurs.
1389
1390 */
1391
1392 if (hpos > width)
1393 {
1394 if (hscroll
1395 || (truncate_partial_width_windows
1396 && ((width + continuation_glyph_width)
1397 < FRAME_COLS (XFRAME (WINDOW_FRAME (win)))))
1398 || !NILP (current_buffer->truncate_lines))
1399 {
1400 /* Truncating: skip to newline, unless we are already past
1401 TO (we need to go back below). */
1402 if (pos <= to)
1403 {
1404 pos = find_before_next_newline (pos, to, 1);
1405 pos_byte = CHAR_TO_BYTE (pos);
1406 hpos = width;
1407 /* If we just skipped next_boundary,
1408 loop around in the main while
1409 and handle it. */
1410 if (pos >= next_boundary)
1411 next_boundary = pos + 1;
1412 prev_hpos = width;
1413 prev_vpos = vpos;
1414 prev_tab_offset = tab_offset;
1415 }
1416 }
1417 else
1418 {
1419 /* Continuing. */
1420 /* Remember the previous value. */
1421 prev_tab_offset = tab_offset;
1422
1423 if (wide_column_end_hpos > width)
1424 {
1425 hpos -= prev_hpos;
1426 tab_offset += prev_hpos;
1427 }
1428 else
1429 {
1430 tab_offset += width;
1431 hpos -= width;
1432 }
1433 vpos++;
1434 contin_hpos = prev_hpos;
1435 prev_hpos = 0;
1436 prev_vpos = vpos;
1437 }
1438 }
1439
1440 /* Stop if past the target buffer position or screen position. */
1441 if (pos > to)
1442 {
1443 /* Go back to the previous position. */
1444 pos = prev_pos;
1445 pos_byte = prev_pos_byte;
1446 hpos = prev_hpos;
1447 vpos = prev_vpos;
1448 tab_offset = prev_tab_offset;
1449
1450 /* NOTE on contin_hpos, hpos, and prev_hpos.
1451
1452 ----------
1453 abcdefgh\\
1454 W_ ^---- contin_hpos
1455 | ^----- hpos
1456 \---- prev_hpos
1457 ----------
1458 */
1459
1460 if (contin_hpos && prev_hpos == 0
1461 && contin_hpos < width && !wide_column_end_hpos)
1462 {
1463 /* Line breaking occurs in the middle of multi-column
1464 character. Go back to previous line. */
1465 hpos = contin_hpos;
1466 vpos = vpos - 1;
1467 }
1468 break;
1469 }
1470
1471 if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
1472 {
1473 if (contin_hpos && prev_hpos == 0
1474 && hpos > tohpos
1475 && (contin_hpos == width || wide_column_end_hpos > width))
1476 { /* Line breaks because we can't put the character at the
1477 previous line any more. It is not the multi-column
1478 character continued in middle. Go back to previous
1479 buffer position, screen position, and set tab offset
1480 to previous value. It's the beginning of the
1481 line. */
1482 pos = prev_pos;
1483 pos_byte = prev_pos_byte;
1484 hpos = prev_hpos;
1485 vpos = prev_vpos;
1486 tab_offset = prev_tab_offset;
1487 }
1488 break;
1489 }
1490 if (pos == ZV) /* We cannot go beyond ZV. Stop here. */
1491 break;
1492
1493 prev_hpos = hpos;
1494 prev_vpos = vpos;
1495 prev_pos = pos;
1496 prev_pos_byte = pos_byte;
1497 wide_column_end_hpos = 0;
1498
1499 /* Consult the width run cache to see if we can avoid inspecting
1500 the text character-by-character. */
1501 if (current_buffer->width_run_cache && pos >= next_width_run)
1502 {
1503 int run_end;
1504 int common_width
1505 = region_cache_forward (current_buffer,
1506 current_buffer->width_run_cache,
1507 pos, &run_end);
1508
1509 /* A width of zero means the character's width varies (like
1510 a tab), is meaningless (like a newline), or we just don't
1511 want to skip over it for some other reason. */
1512 if (common_width != 0)
1513 {
1514 int run_end_hpos;
1515
1516 /* Don't go past the final buffer posn the user
1517 requested. */
1518 if (run_end > to)
1519 run_end = to;
1520
1521 run_end_hpos = hpos + (run_end - pos) * common_width;
1522
1523 /* Don't go past the final horizontal position the user
1524 requested. */
1525 if (vpos == tovpos && run_end_hpos > tohpos)
1526 {
1527 run_end = pos + (tohpos - hpos) / common_width;
1528 run_end_hpos = hpos + (run_end - pos) * common_width;
1529 }
1530
1531 /* Don't go past the margin. */
1532 if (run_end_hpos >= width)
1533 {
1534 run_end = pos + (width - hpos) / common_width;
1535 run_end_hpos = hpos + (run_end - pos) * common_width;
1536 }
1537
1538 hpos = run_end_hpos;
1539 if (run_end > pos)
1540 prev_hpos = hpos - common_width;
1541 if (pos != run_end)
1542 {
1543 pos = run_end;
1544 pos_byte = CHAR_TO_BYTE (pos);
1545 }
1546 }
1547
1548 next_width_run = run_end + 1;
1549 }
1550
1551 /* We have to scan the text character-by-character. */
1552 else
1553 {
1554 EMACS_INT i, n;
1555 Lisp_Object charvec;
1556
1557 c = FETCH_BYTE (pos_byte);
1558
1559 /* Check composition sequence. */
1560 {
1561 int len, len_byte, width;
1562
1563 if (check_composition (pos, pos_byte, to, &len, &len_byte, &width))
1564 {
1565 pos += len;
1566 pos_byte += len_byte;
1567 hpos += width;
1568 continue;
1569 }
1570 }
1571
1572 pos++, pos_byte++;
1573
1574 /* Perhaps add some info to the width_run_cache. */
1575 if (current_buffer->width_run_cache)
1576 {
1577 /* Is this character part of the current run? If so, extend
1578 the run. */
1579 if (pos - 1 == width_run_end
1580 && XFASTINT (width_table[c]) == width_run_width)
1581 width_run_end = pos;
1582
1583 /* The previous run is over, since this is a character at a
1584 different position, or a different width. */
1585 else
1586 {
1587 /* Have we accumulated a run to put in the cache?
1588 (Currently, we only cache runs of width == 1). */
1589 if (width_run_start < width_run_end
1590 && width_run_width == 1)
1591 know_region_cache (current_buffer,
1592 current_buffer->width_run_cache,
1593 width_run_start, width_run_end);
1594
1595 /* Start recording a new width run. */
1596 width_run_width = XFASTINT (width_table[c]);
1597 width_run_start = pos - 1;
1598 width_run_end = pos;
1599 }
1600 }
1601
1602 if (dp != 0
1603 && ! (multibyte && BASE_LEADING_CODE_P (c))
1604 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
1605 {
1606 charvec = DISP_CHAR_VECTOR (dp, c);
1607 n = ASIZE (charvec);
1608 }
1609 else
1610 {
1611 charvec = Qnil;
1612 n = 1;
1613 }
1614
1615 for (i = n - 1; i >= 0; --i)
1616 {
1617 if (VECTORP (charvec))
1618 {
1619 /* This should be handled the same as
1620 next_element_from_display_vector does it. */
1621 Lisp_Object entry = AREF (charvec, i);
1622
1623 if (INTEGERP (entry)
1624 && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
1625 c = FAST_GLYPH_CHAR (XFASTINT (entry));
1626 else
1627 c = ' ';
1628 }
1629
1630 if (c >= 040 && c < 0177)
1631 hpos++;
1632 else if (c == '\t')
1633 {
1634 int tem = ((hpos + tab_offset + hscroll - (hscroll > 0))
1635 % tab_width);
1636 if (tem < 0)
1637 tem += tab_width;
1638 hpos += tab_width - tem;
1639 }
1640 else if (c == '\n')
1641 {
1642 if (selective > 0
1643 && indented_beyond_p (pos, pos_byte,
1644 (double) selective)) /* iftc */
1645 {
1646 /* If (pos == to), we don't have to take care of
1647 selective display. */
1648 if (pos < to)
1649 {
1650 /* Skip any number of invisible lines all at once */
1651 do
1652 {
1653 pos = find_before_next_newline (pos, to, 1);
1654 if (pos < to)
1655 pos++;
1656 pos_byte = CHAR_TO_BYTE (pos);
1657 }
1658 while (pos < to
1659 && indented_beyond_p (pos, pos_byte,
1660 (double) selective)); /* iftc */
1661 /* Allow for the " ..." that is displayed for them. */
1662 if (selective_rlen)
1663 {
1664 hpos += selective_rlen;
1665 if (hpos >= width)
1666 hpos = width;
1667 }
1668 DEC_BOTH (pos, pos_byte);
1669 /* We have skipped the invis text, but not the
1670 newline after. */
1671 }
1672 }
1673 else
1674 {
1675 /* A visible line. */
1676 vpos++;
1677 hpos = 0;
1678 hpos -= hscroll;
1679 /* Count the truncation glyph on column 0 */
1680 if (hscroll > 0)
1681 hpos += continuation_glyph_width;
1682 tab_offset = 0;
1683 }
1684 contin_hpos = 0;
1685 }
1686 else if (c == CR && selective < 0)
1687 {
1688 /* In selective display mode,
1689 everything from a ^M to the end of the line is invisible.
1690 Stop *before* the real newline. */
1691 if (pos < to)
1692 {
1693 pos = find_before_next_newline (pos, to, 1);
1694 pos_byte = CHAR_TO_BYTE (pos);
1695 }
1696 /* If we just skipped next_boundary,
1697 loop around in the main while
1698 and handle it. */
1699 if (pos > next_boundary)
1700 next_boundary = pos;
1701 /* Allow for the " ..." that is displayed for them. */
1702 if (selective_rlen)
1703 {
1704 hpos += selective_rlen;
1705 if (hpos >= width)
1706 hpos = width;
1707 }
1708 }
1709 else if (multibyte && BASE_LEADING_CODE_P (c))
1710 {
1711 /* Start of multi-byte form. */
1712 unsigned char *ptr;
1713 int bytes, width, wide_column;
1714
1715 pos_byte--; /* rewind POS_BYTE */
1716 ptr = BYTE_POS_ADDR (pos_byte);
1717 MULTIBYTE_BYTES_WIDTH (ptr, dp);
1718 pos_byte += bytes;
1719 if (wide_column)
1720 wide_column_end_hpos = hpos + wide_column;
1721 hpos += width;
1722 }
1723 else if (VECTORP (charvec))
1724 ++hpos;
1725 else
1726 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
1727 }
1728 }
1729 }
1730
1731 after_loop:
1732
1733 /* Remember any final width run in the cache. */
1734 if (current_buffer->width_run_cache
1735 && width_run_width == 1
1736 && width_run_start < width_run_end)
1737 know_region_cache (current_buffer, current_buffer->width_run_cache,
1738 width_run_start, width_run_end);
1739
1740 val_compute_motion.bufpos = pos;
1741 val_compute_motion.bytepos = pos_byte;
1742 val_compute_motion.hpos = hpos;
1743 val_compute_motion.vpos = vpos;
1744 if (contin_hpos && prev_hpos == 0)
1745 val_compute_motion.prevhpos = contin_hpos;
1746 else
1747 val_compute_motion.prevhpos = prev_hpos;
1748 /* We alalways handle all of them here; none of them remain to do. */
1749 val_compute_motion.ovstring_chars_done = 0;
1750
1751 /* Nonzero if have just continued a line */
1752 val_compute_motion.contin = (contin_hpos && prev_hpos == 0);
1753
1754 immediate_quit = 0;
1755 return &val_compute_motion;
1756 }
1757
1758
1759 DEFUN ("compute-motion", Fcompute_motion, Scompute_motion, 7, 7, 0,
1760 doc: /* Scan through the current buffer, calculating screen position.
1761 Scan the current buffer forward from offset FROM,
1762 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1763 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1764 and return the ending buffer position and screen location.
1765
1766 If TOPOS is nil, the actual width and height of the window's
1767 text area are used.
1768
1769 There are three additional arguments:
1770
1771 WIDTH is the number of columns available to display text;
1772 this affects handling of continuation lines. A value of nil
1773 corresponds to the actual number of available text columns.
1774
1775 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1776 HSCROLL is the number of columns not being displayed at the left
1777 margin; this is usually taken from a window's hscroll member.
1778 TAB-OFFSET is the number of columns of the first tab that aren't
1779 being displayed, perhaps because the line was continued within it.
1780 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1781
1782 WINDOW is the window to operate on. It is used to choose the display table;
1783 if it is showing the current buffer, it is used also for
1784 deciding which overlay properties apply.
1785 Note that `compute-motion' always operates on the current buffer.
1786
1787 The value is a list of five elements:
1788 (POS HPOS VPOS PREVHPOS CONTIN)
1789 POS is the buffer position where the scan stopped.
1790 VPOS is the vertical position where the scan stopped.
1791 HPOS is the horizontal position where the scan stopped.
1792
1793 PREVHPOS is the horizontal position one character back from POS.
1794 CONTIN is t if a line was continued after (or within) the previous character.
1795
1796 For example, to find the buffer position of column COL of line LINE
1797 of a certain window, pass the window's starting location as FROM
1798 and the window's upper-left coordinates as FROMPOS.
1799 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1800 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1801 (from, frompos, to, topos, width, offsets, window)
1802 Lisp_Object from, frompos, to, topos;
1803 Lisp_Object width, offsets, window;
1804 {
1805 struct window *w;
1806 Lisp_Object bufpos, hpos, vpos, prevhpos;
1807 struct position *pos;
1808 int hscroll, tab_offset;
1809
1810 CHECK_NUMBER_COERCE_MARKER (from);
1811 CHECK_CONS (frompos);
1812 CHECK_NUMBER_CAR (frompos);
1813 CHECK_NUMBER_CDR (frompos);
1814 CHECK_NUMBER_COERCE_MARKER (to);
1815 if (!NILP (topos))
1816 {
1817 CHECK_CONS (topos);
1818 CHECK_NUMBER_CAR (topos);
1819 CHECK_NUMBER_CDR (topos);
1820 }
1821 if (!NILP (width))
1822 CHECK_NUMBER (width);
1823
1824 if (!NILP (offsets))
1825 {
1826 CHECK_CONS (offsets);
1827 CHECK_NUMBER_CAR (offsets);
1828 CHECK_NUMBER_CDR (offsets);
1829 hscroll = XINT (XCAR (offsets));
1830 tab_offset = XINT (XCDR (offsets));
1831 }
1832 else
1833 hscroll = tab_offset = 0;
1834
1835 if (NILP (window))
1836 window = Fselected_window ();
1837 else
1838 CHECK_LIVE_WINDOW (window);
1839 w = XWINDOW (window);
1840
1841 if (XINT (from) < BEGV || XINT (from) > ZV)
1842 args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
1843 if (XINT (to) < BEGV || XINT (to) > ZV)
1844 args_out_of_range_3 (to, make_number (BEGV), make_number (ZV));
1845
1846 pos = compute_motion (XINT (from), XINT (XCDR (frompos)),
1847 XINT (XCAR (frompos)), 0,
1848 XINT (to),
1849 (NILP (topos)
1850 ? window_internal_height (w)
1851 : XINT (XCDR (topos))),
1852 (NILP (topos)
1853 ? (window_box_text_cols (w)
1854 - (
1855 #ifdef HAVE_WINDOW_SYSTEM
1856 FRAME_WINDOW_P (XFRAME (w->frame)) ? 0 :
1857 #endif
1858 1))
1859 : XINT (XCAR (topos))),
1860 (NILP (width) ? -1 : XINT (width)),
1861 hscroll, tab_offset,
1862 XWINDOW (window));
1863
1864 XSETFASTINT (bufpos, pos->bufpos);
1865 XSETINT (hpos, pos->hpos);
1866 XSETINT (vpos, pos->vpos);
1867 XSETINT (prevhpos, pos->prevhpos);
1868
1869 return Fcons (bufpos,
1870 Fcons (hpos,
1871 Fcons (vpos,
1872 Fcons (prevhpos,
1873 Fcons (pos->contin ? Qt : Qnil, Qnil)))));
1874
1875 }
1876 \f
1877 /* Fvertical_motion and vmotion */
1878
1879 struct position val_vmotion;
1880
1881 struct position *
1882 vmotion (from, vtarget, w)
1883 register int from, vtarget;
1884 struct window *w;
1885 {
1886 int hscroll = XINT (w->hscroll);
1887 struct position pos;
1888 /* vpos is cumulative vertical position, changed as from is changed */
1889 register int vpos = 0;
1890 int prevline;
1891 register int first;
1892 int from_byte;
1893 int lmargin = hscroll > 0 ? 1 - hscroll : 0;
1894 int selective
1895 = (INTEGERP (current_buffer->selective_display)
1896 ? XINT (current_buffer->selective_display)
1897 : !NILP (current_buffer->selective_display) ? -1 : 0);
1898 Lisp_Object window;
1899 int start_hpos = 0;
1900 int did_motion;
1901 /* This is the object we use for fetching character properties. */
1902 Lisp_Object text_prop_object;
1903
1904 XSETWINDOW (window, w);
1905
1906 /* If the window contains this buffer, use it for getting text properties.
1907 Otherwise use the current buffer as arg for doing that. */
1908 if (EQ (w->buffer, Fcurrent_buffer ()))
1909 text_prop_object = window;
1910 else
1911 text_prop_object = Fcurrent_buffer ();
1912
1913 if (vpos >= vtarget)
1914 {
1915 /* To move upward, go a line at a time until
1916 we have gone at least far enough. */
1917
1918 first = 1;
1919
1920 while ((vpos > vtarget || first) && from > BEGV)
1921 {
1922 Lisp_Object propval;
1923
1924 prevline = find_next_newline_no_quit (from - 1, -1);
1925 while (prevline > BEGV
1926 && ((selective > 0
1927 && indented_beyond_p (prevline,
1928 CHAR_TO_BYTE (prevline),
1929 (double) selective)) /* iftc */
1930 /* Watch out for newlines with `invisible' property.
1931 When moving upward, check the newline before. */
1932 || (propval = Fget_char_property (make_number (prevline - 1),
1933 Qinvisible,
1934 text_prop_object),
1935 TEXT_PROP_MEANS_INVISIBLE (propval))))
1936 prevline = find_next_newline_no_quit (prevline - 1, -1);
1937 pos = *compute_motion (prevline, 0,
1938 lmargin + (prevline == BEG ? start_hpos : 0),
1939 0,
1940 from,
1941 /* Don't care for VPOS... */
1942 1 << (BITS_PER_SHORT - 1),
1943 /* ... nor HPOS. */
1944 1 << (BITS_PER_SHORT - 1),
1945 -1, hscroll,
1946 /* This compensates for start_hpos
1947 so that a tab as first character
1948 still occupies 8 columns. */
1949 (prevline == BEG ? -start_hpos : 0),
1950 w);
1951 vpos -= pos.vpos;
1952 first = 0;
1953 from = prevline;
1954 }
1955
1956 /* If we made exactly the desired vertical distance,
1957 or if we hit beginning of buffer,
1958 return point found */
1959 if (vpos >= vtarget)
1960 {
1961 val_vmotion.bufpos = from;
1962 val_vmotion.bytepos = CHAR_TO_BYTE (from);
1963 val_vmotion.vpos = vpos;
1964 val_vmotion.hpos = lmargin;
1965 val_vmotion.contin = 0;
1966 val_vmotion.prevhpos = 0;
1967 val_vmotion.ovstring_chars_done = 0;
1968 val_vmotion.tab_offset = 0; /* For accumulating tab offset. */
1969 return &val_vmotion;
1970 }
1971
1972 /* Otherwise find the correct spot by moving down */
1973 }
1974 /* Moving downward is simple, but must calculate from beg of line
1975 to determine hpos of starting point */
1976 from_byte = CHAR_TO_BYTE (from);
1977 if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
1978 {
1979 Lisp_Object propval;
1980
1981 prevline = find_next_newline_no_quit (from, -1);
1982 while (prevline > BEGV
1983 && ((selective > 0
1984 && indented_beyond_p (prevline,
1985 CHAR_TO_BYTE (prevline),
1986 (double) selective)) /* iftc */
1987 /* Watch out for newlines with `invisible' property.
1988 When moving downward, check the newline after. */
1989 || (propval = Fget_char_property (make_number (prevline),
1990 Qinvisible,
1991 text_prop_object),
1992 TEXT_PROP_MEANS_INVISIBLE (propval))))
1993 prevline = find_next_newline_no_quit (prevline - 1, -1);
1994 pos = *compute_motion (prevline, 0,
1995 lmargin + (prevline == BEG
1996 ? start_hpos : 0),
1997 0,
1998 from,
1999 /* Don't care for VPOS... */
2000 1 << (BITS_PER_SHORT - 1),
2001 /* ... nor HPOS. */
2002 1 << (BITS_PER_SHORT - 1),
2003 -1, hscroll,
2004 (prevline == BEG ? -start_hpos : 0),
2005 w);
2006 did_motion = 1;
2007 }
2008 else
2009 {
2010 pos.hpos = lmargin + (from == BEG ? start_hpos : 0);
2011 pos.vpos = 0;
2012 pos.tab_offset = 0;
2013 did_motion = 0;
2014 }
2015 return compute_motion (from, vpos, pos.hpos, did_motion,
2016 ZV, vtarget, - (1 << (BITS_PER_SHORT - 1)),
2017 -1, hscroll,
2018 pos.tab_offset - (from == BEG ? start_hpos : 0),
2019 w);
2020 }
2021
2022 DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
2023 doc: /* Move point to start of the screen line LINES lines down.
2024 If LINES is negative, this means moving up.
2025
2026 This function is an ordinary cursor motion function
2027 which calculates the new position based on how text would be displayed.
2028 The new position may be the start of a line,
2029 or just the start of a continuation line.
2030 The function returns number of screen lines moved over;
2031 that usually equals LINES, but may be closer to zero
2032 if beginning or end of buffer was reached.
2033
2034 The optional second argument WINDOW specifies the window to use for
2035 parameters such as width, horizontal scrolling, and so on.
2036 The default is to use the selected window's parameters.
2037
2038 `vertical-motion' always uses the current buffer,
2039 regardless of which buffer is displayed in WINDOW.
2040 This is consistent with other cursor motion functions
2041 and makes it possible to use `vertical-motion' in any buffer,
2042 whether or not it is currently displayed in some window. */)
2043 (lines, window)
2044 Lisp_Object lines, window;
2045 {
2046 struct it it;
2047 struct text_pos pt;
2048 struct window *w;
2049 Lisp_Object old_buffer;
2050 struct gcpro gcpro1;
2051
2052 CHECK_NUMBER (lines);
2053 if (! NILP (window))
2054 CHECK_WINDOW (window);
2055 else
2056 window = selected_window;
2057 w = XWINDOW (window);
2058
2059 old_buffer = Qnil;
2060 GCPRO1 (old_buffer);
2061 if (XBUFFER (w->buffer) != current_buffer)
2062 {
2063 /* Set the window's buffer temporarily to the current buffer. */
2064 old_buffer = w->buffer;
2065 XSETBUFFER (w->buffer, current_buffer);
2066 }
2067
2068 if (noninteractive)
2069 {
2070 struct position pos;
2071 pos = *vmotion (PT, XINT (lines), w);
2072 SET_PT_BOTH (pos.bufpos, pos.bytepos);
2073 }
2074 else
2075 {
2076 int it_start;
2077 int oselective;
2078 int it_overshoot_expected;
2079
2080 SET_TEXT_POS (pt, PT, PT_BYTE);
2081 start_display (&it, w, pt);
2082
2083 /* Scan from the start of the line containing PT. If we don't
2084 do this, we start moving with IT->current_x == 0, while PT is
2085 really at some x > 0. The effect is, in continuation lines, that
2086 we end up with the iterator placed at where it thinks X is 0,
2087 while the end position is really at some X > 0, the same X that
2088 PT had. */
2089 it_start = IT_CHARPOS (it);
2090
2091 /* We expect the call to move_it_to, further down, to overshoot
2092 if the starting point is on an image, stretch glyph,
2093 composition, or Lisp string. We won't need to backtrack in
2094 this situation, except for one corner case: when the Lisp
2095 string contains a newline. */
2096 if (it.method == GET_FROM_STRING)
2097 {
2098 const char *s = SDATA (it.string);
2099 const char *e = s + SBYTES (it.string);
2100
2101 while (s < e && *s != '\n')
2102 ++s;
2103
2104 /* If there is no newline in the string, we need to check
2105 whether there is a newline immediately after the string
2106 in move_it_to below. This may happen if there is an
2107 overlay with an after-string just before the newline. */
2108 it_overshoot_expected = (s == e) ? -1 : 0;
2109 }
2110 else
2111 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2112 || it.method == GET_FROM_STRETCH
2113 || it.method == GET_FROM_COMPOSITION);
2114
2115 reseat_at_previous_visible_line_start (&it);
2116 it.current_x = it.hpos = 0;
2117 /* Temporarily disable selective display so we don't move too far */
2118 oselective = it.selective;
2119 it.selective = 0;
2120 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2121 it.selective = oselective;
2122
2123 /* Move back if we got too far. This may happen if
2124 truncate-lines is on and PT is beyond right margin.
2125 Don't go back if the overshoot is expected (see above). */
2126 if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
2127 && (!it_overshoot_expected
2128 || (it_overshoot_expected < 0
2129 && it.method == GET_FROM_BUFFER
2130 && it.c == '\n')))
2131 move_it_by_lines (&it, -1, 0);
2132
2133 it.vpos = 0;
2134 /* Do this even if LINES is 0, so that we move back
2135 to the beginning of the current line as we ought. */
2136 if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0)
2137 move_it_by_lines (&it, XINT (lines), 0);
2138
2139 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2140 }
2141
2142 if (BUFFERP (old_buffer))
2143 w->buffer = old_buffer;
2144
2145 RETURN_UNGCPRO (make_number (it.vpos));
2146 }
2147
2148
2149 \f
2150 /* File's initialization. */
2151
2152 void
2153 syms_of_indent ()
2154 {
2155 DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
2156 doc: /* *Indentation can insert tabs if this is non-nil.
2157 Setting this variable automatically makes it local to the current buffer. */);
2158 indent_tabs_mode = 1;
2159
2160 defsubr (&Scurrent_indentation);
2161 defsubr (&Sindent_to);
2162 defsubr (&Scurrent_column);
2163 defsubr (&Smove_to_column);
2164 defsubr (&Svertical_motion);
2165 defsubr (&Scompute_motion);
2166 }
2167
2168 /* arch-tag: 9adfea44-71f7-4988-8ee3-96da15c502cc
2169 (do not change this comment) */