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