1 /* Indentation functions.
2 Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2011
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26 #include "character.h"
28 #include "composite.h"
36 #include "intervals.h"
37 #include "dispextern.h"
38 #include "region-cache.h"
42 /* These three values memorize the current column to avoid recalculation. */
44 /* Last value returned by current_column.
45 Some things in set last_known_column_point to -1
46 to mark the memorized value as invalid. */
48 static EMACS_INT last_known_column
;
50 /* Value of point when current_column was called. */
52 EMACS_INT last_known_column_point
;
54 /* Value of MODIFF when current_column was called. */
56 static int last_known_column_modified
;
58 static EMACS_INT
current_column_1 (void);
59 static EMACS_INT
position_indentation (int);
61 /* Cache of beginning of line found by the last call of
64 static EMACS_INT current_column_bol_cache
;
66 /* Get the display table to use for the current buffer. */
68 struct Lisp_Char_Table
*
69 buffer_display_table (void)
73 thisbuf
= BVAR (current_buffer
, display_table
);
74 if (DISP_TABLE_P (thisbuf
))
75 return XCHAR_TABLE (thisbuf
);
76 if (DISP_TABLE_P (Vstandard_display_table
))
77 return XCHAR_TABLE (Vstandard_display_table
);
81 /* Width run cache considerations. */
83 /* Return the width of character C under display table DP. */
86 character_width (int c
, struct Lisp_Char_Table
*dp
)
90 /* These width computations were determined by examining the cases
91 in display_text_line. */
93 /* Everything can be handled by the display table, if it's
94 present and the element is right. */
95 if (dp
&& (elt
= DISP_CHAR_VECTOR (dp
, c
), VECTORP (elt
)))
98 /* Some characters are special. */
99 if (c
== '\n' || c
== '\t' || c
== '\015')
102 /* Printing characters have width 1. */
103 else if (c
>= 040 && c
< 0177)
106 /* Everybody else (control characters, metacharacters) has other
107 widths. We could return their actual widths here, but they
108 depend on things like ctl_arrow and crud like that, and they're
109 not very common at all. So we'll just claim we don't know their
115 /* Return true if the display table DISPTAB specifies the same widths
116 for characters as WIDTHTAB. We use this to decide when to
117 invalidate the buffer's width_run_cache. */
120 disptab_matches_widthtab (struct Lisp_Char_Table
*disptab
, struct Lisp_Vector
*widthtab
)
124 if (widthtab
->header
.size
!= 256)
127 for (i
= 0; i
< 256; i
++)
128 if (character_width (i
, disptab
)
129 != XFASTINT (widthtab
->contents
[i
]))
135 /* Recompute BUF's width table, using the display table DISPTAB. */
138 recompute_width_table (struct buffer
*buf
, struct Lisp_Char_Table
*disptab
)
141 struct Lisp_Vector
*widthtab
;
143 if (!VECTORP (BVAR (buf
, width_table
)))
144 BVAR (buf
, width_table
) = Fmake_vector (make_number (256), make_number (0));
145 widthtab
= XVECTOR (BVAR (buf
, width_table
));
146 if (widthtab
->header
.size
!= 256)
149 for (i
= 0; i
< 256; i
++)
150 XSETFASTINT (widthtab
->contents
[i
], character_width (i
, disptab
));
153 /* Allocate or free the width run cache, as requested by the current
154 state of current_buffer's cache_long_line_scans variable. */
157 width_run_cache_on_off (void)
159 if (NILP (BVAR (current_buffer
, cache_long_line_scans
))
160 /* And, for the moment, this feature doesn't work on multibyte
162 || !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
164 /* It should be off. */
165 if (current_buffer
->width_run_cache
)
167 free_region_cache (current_buffer
->width_run_cache
);
168 current_buffer
->width_run_cache
= 0;
169 BVAR (current_buffer
, width_table
) = Qnil
;
174 /* It should be on. */
175 if (current_buffer
->width_run_cache
== 0)
177 current_buffer
->width_run_cache
= new_region_cache ();
178 recompute_width_table (current_buffer
, buffer_display_table ());
184 /* Skip some invisible characters starting from POS.
185 This includes characters invisible because of text properties
186 and characters invisible because of overlays.
188 If position POS is followed by invisible characters,
189 skip some of them and return the position after them.
190 Otherwise return POS itself.
192 Set *NEXT_BOUNDARY_P to the next position at which
193 it will be necessary to call this function again.
195 Don't scan past TO, and don't set *NEXT_BOUNDARY_P
196 to a value greater than TO.
198 If WINDOW is non-nil, and this buffer is displayed in WINDOW,
199 take account of overlays that apply only in WINDOW.
201 We don't necessarily skip all the invisible characters after POS
202 because that could take a long time. We skip a reasonable number
203 which can be skipped quickly. If there might be more invisible
204 characters immediately following, then *NEXT_BOUNDARY_P
205 will equal the return value. */
208 skip_invisible (EMACS_INT pos
, EMACS_INT
*next_boundary_p
, EMACS_INT to
, Lisp_Object window
)
210 Lisp_Object prop
, position
, overlay_limit
, proplimit
;
211 Lisp_Object buffer
, tmp
;
215 XSETFASTINT (position
, pos
);
216 XSETBUFFER (buffer
, current_buffer
);
218 /* Give faster response for overlay lookup near POS. */
219 recenter_overlay_lists (current_buffer
, pos
);
221 /* We must not advance farther than the next overlay change.
222 The overlay change might change the invisible property;
223 or there might be overlay strings to be displayed there. */
224 overlay_limit
= Fnext_overlay_change (position
);
225 /* As for text properties, this gives a lower bound
226 for where the invisible text property could change. */
227 proplimit
= Fnext_property_change (position
, buffer
, Qt
);
228 if (XFASTINT (overlay_limit
) < XFASTINT (proplimit
))
229 proplimit
= overlay_limit
;
230 /* PROPLIMIT is now a lower bound for the next change
231 in invisible status. If that is plenty far away,
232 use that lower bound. */
233 if (XFASTINT (proplimit
) > pos
+ 100 || XFASTINT (proplimit
) >= to
)
234 *next_boundary_p
= XFASTINT (proplimit
);
235 /* Otherwise, scan for the next `invisible' property change. */
238 /* Don't scan terribly far. */
239 XSETFASTINT (proplimit
, min (pos
+ 100, to
));
240 /* No matter what, don't go past next overlay change. */
241 if (XFASTINT (overlay_limit
) < XFASTINT (proplimit
))
242 proplimit
= overlay_limit
;
243 tmp
= Fnext_single_property_change (position
, Qinvisible
,
245 end
= XFASTINT (tmp
);
247 /* Don't put the boundary in the middle of multibyte form if
248 there is no actual property change. */
250 && !NILP (current_buffer
->enable_multibyte_characters
)
252 while (pos
< end
&& !CHAR_HEAD_P (POS_ADDR (end
)))
255 *next_boundary_p
= end
;
257 /* if the `invisible' property is set, we can skip to
258 the next property change */
259 prop
= Fget_char_property (position
, Qinvisible
,
261 && EQ (XWINDOW (window
)->buffer
, buffer
))
263 inv_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
264 /* When counting columns (window == nil), don't skip over ellipsis text. */
265 if (NILP (window
) ? inv_p
== 1 : inv_p
)
266 return *next_boundary_p
;
270 /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
272 DP is a display table or NULL.
274 This macro is used in scan_for_column and in
277 #define MULTIBYTE_BYTES_WIDTH(p, dp, bytes, width) \
281 ch = STRING_CHAR_AND_LENGTH (p, bytes); \
282 if (BYTES_BY_CHAR_HEAD (*p) != bytes) \
286 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \
287 width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \
289 width = CHAR_WIDTH (ch); \
294 DEFUN ("current-column", Fcurrent_column
, Scurrent_column
, 0, 0, 0,
295 doc
: /* Return the horizontal position of point. Beginning of line is column 0.
296 This is calculated by adding together the widths of all the displayed
297 representations of the character between the start of the previous line
298 and point (eg. control characters will have a width of 2 or 4, tabs
299 will have a variable width).
300 Ignores finite width of frame, which means that this function may return
301 values greater than (frame-width).
302 Whether the line is visible (if `selective-display' is t) has no effect;
303 however, ^M is treated as end of line when `selective-display' is t.
304 Text that has an invisible property is considered as having width 0, unless
305 `buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */)
309 XSETFASTINT (temp
, current_column ());
313 /* Cancel any recorded value of the horizontal position. */
316 invalidate_current_column (void)
318 last_known_column_point
= 0;
322 current_column (void)
324 register EMACS_INT col
;
325 register unsigned char *ptr
, *stop
;
326 register int tab_seen
;
329 register EMACS_INT tab_width
= XINT (BVAR (current_buffer
, tab_width
));
330 int ctl_arrow
= !NILP (BVAR (current_buffer
, ctl_arrow
));
331 register struct Lisp_Char_Table
*dp
= buffer_display_table ();
333 if (PT
== last_known_column_point
334 && MODIFF
== last_known_column_modified
)
335 return last_known_column
;
337 /* If the buffer has overlays, text properties,
338 or multibyte characters, use a more general algorithm. */
339 if (BUF_INTERVALS (current_buffer
)
340 || current_buffer
->overlays_before
341 || current_buffer
->overlays_after
343 return current_column_1 ();
345 /* Scan backwards from point to the previous newline,
346 counting width. Tab characters are the only complicated case. */
348 /* Make a pointer for decrementing through the chars before point. */
349 ptr
= BYTE_POS_ADDR (PT_BYTE
- 1) + 1;
350 /* Make a pointer to where consecutive chars leave off,
351 going backwards from point. */
354 else if (PT
<= GPT
|| BEGV
> GPT
)
359 if (tab_width
<= 0 || tab_width
> 1000)
362 col
= 0, tab_seen
= 0, post_tab
= 0;
371 /* We stopped either for the beginning of the buffer
373 if (ptr
== BEGV_ADDR
)
376 /* It was the gap. Jump back over it. */
380 /* Check whether that brings us to beginning of buffer. */
387 if (dp
&& VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
389 charvec
= DISP_CHAR_VECTOR (dp
, c
);
398 for (i
= n
- 1; i
>= 0; --i
)
400 if (VECTORP (charvec
))
402 /* This should be handled the same as
403 next_element_from_display_vector does it. */
404 Lisp_Object entry
= AREF (charvec
, i
);
406 if (GLYPH_CODE_P (entry
)
407 && GLYPH_CODE_CHAR_VALID_P (entry
))
408 c
= GLYPH_CODE_CHAR (entry
);
413 if (c
>= 040 && c
< 0177)
417 && EQ (BVAR (current_buffer
, selective_display
), Qt
)))
420 goto start_of_line_found
;
425 col
= ((col
+ tab_width
) / tab_width
) * tab_width
;
431 else if (VECTORP (charvec
))
432 /* With a display table entry, C is displayed as is, and
433 not displayed as \NNN or as ^N. If C is a single-byte
434 character, it takes one column. If C is multi-byte in
435 an unibyte buffer, it's translated to unibyte, so it
436 also takes one column. */
439 col
+= (ctl_arrow
&& c
< 0200) ? 2 : 4;
447 col
= ((col
+ tab_width
) / tab_width
) * tab_width
;
451 if (ptr
== BEGV_ADDR
)
452 current_column_bol_cache
= BEGV
;
454 current_column_bol_cache
= BYTE_TO_CHAR (PTR_BYTE_POS (ptr
));
456 last_known_column
= col
;
457 last_known_column_point
= PT
;
458 last_known_column_modified
= MODIFF
;
464 /* Check the presence of a display property and compute its width.
465 If a property was found and its width was found as well, return
466 its width (>= 0) and set the position of the end of the property
468 Otherwise just return -1. */
470 check_display_width (EMACS_INT pos
, EMACS_INT col
, EMACS_INT
*endpos
)
472 Lisp_Object val
, overlay
;
474 if (CONSP (val
= get_char_property_and_overlay
475 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
476 && EQ (Qspace
, XCAR (val
)))
477 { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */
478 Lisp_Object plist
= XCDR (val
), prop
;
481 if ((prop
= Fplist_get (plist
, QCwidth
), NATNUMP (prop
)))
483 else if (FLOATP (prop
))
484 width
= (int)(XFLOAT_DATA (prop
) + 0.5);
485 else if ((prop
= Fplist_get (plist
, QCalign_to
), NATNUMP (prop
)))
486 width
= XINT (prop
) - col
;
487 else if (FLOATP (prop
))
488 width
= (int)(XFLOAT_DATA (prop
) + 0.5) - col
;
493 if (OVERLAYP (overlay
))
494 *endpos
= OVERLAY_POSITION (OVERLAY_END (overlay
));
496 get_property_and_range (pos
, Qdisplay
, &val
, &start
, endpos
, Qnil
);
503 /* Scanning from the beginning of the current line, stop at the buffer
504 position ENDPOS or at the column GOALCOL or at the end of line, whichever
506 Return the resulting buffer position and column in ENDPOS and GOALCOL.
507 PREVCOL gets set to the column of the previous position (it's always
508 strictly smaller than the goal column). */
510 scan_for_column (EMACS_INT
*endpos
, EMACS_INT
*goalcol
, EMACS_INT
*prevcol
)
512 register EMACS_INT tab_width
= XINT (BVAR (current_buffer
, tab_width
));
513 register int ctl_arrow
= !NILP (BVAR (current_buffer
, ctl_arrow
));
514 register struct Lisp_Char_Table
*dp
= buffer_display_table ();
515 int multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
516 struct composition_it cmp_it
;
520 /* Start the scan at the beginning of this line with column number 0. */
521 register EMACS_INT col
= 0, prev_col
= 0;
522 EMACS_INT goal
= goalcol
? *goalcol
: MOST_POSITIVE_FIXNUM
;
523 EMACS_INT end
= endpos
? *endpos
: PT
;
524 EMACS_INT scan
, scan_byte
;
525 EMACS_INT next_boundary
;
527 EMACS_INT opoint
= PT
, opoint_byte
= PT_BYTE
;
528 scan_newline (PT
, PT_BYTE
, BEGV
, BEGV_BYTE
, -1, 1);
529 current_column_bol_cache
= PT
;
530 scan
= PT
, scan_byte
= PT_BYTE
;
531 SET_PT_BOTH (opoint
, opoint_byte
);
532 next_boundary
= scan
;
535 window
= Fget_buffer_window (Fcurrent_buffer (), Qnil
);
536 w
= ! NILP (window
) ? XWINDOW (window
) : NULL
;
538 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
539 memset (&cmp_it
, 0, sizeof cmp_it
);
541 composition_compute_stop_pos (&cmp_it
, scan
, scan_byte
, end
, Qnil
);
543 /* Scan forward to the target position. */
548 /* Occasionally we may need to skip invisible text. */
549 while (scan
== next_boundary
)
551 EMACS_INT old_scan
= scan
;
552 /* This updates NEXT_BOUNDARY to the next place
553 where we might need to skip more invisible text. */
554 scan
= skip_invisible (scan
, &next_boundary
, end
, Qnil
);
555 if (scan
!= old_scan
)
556 scan_byte
= CHAR_TO_BYTE (scan
);
561 /* Test reaching the goal column. We do this after skipping
562 invisible characters, so that we put point before the
563 character on which the cursor will appear. */
568 { /* Check display property. */
570 int width
= check_display_width (scan
, col
, &endp
);
574 if (endp
> scan
) /* Avoid infinite loops with 0-width overlays. */
576 scan
= endp
; scan_byte
= charpos_to_bytepos (scan
);
582 /* Check composition sequence. */
584 || (scan
== cmp_it
.stop_pos
585 && composition_reseat_it (&cmp_it
, scan
, scan_byte
, end
,
587 composition_update_it (&cmp_it
, scan
, scan_byte
, Qnil
);
590 scan
+= cmp_it
.nchars
;
591 scan_byte
+= cmp_it
.nbytes
;
594 if (cmp_it
.to
== cmp_it
.nglyphs
)
597 composition_compute_stop_pos (&cmp_it
, scan
, scan_byte
, end
,
601 cmp_it
.from
= cmp_it
.to
;
605 c
= FETCH_BYTE (scan_byte
);
607 /* See if there is a display table and it relates
608 to this character. */
611 && ! (multibyte
&& LEADING_CODE_P (c
))
612 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
617 /* This character is displayed using a vector of glyphs.
618 Update the column/position based on those glyphs. */
620 charvec
= DISP_CHAR_VECTOR (dp
, c
);
623 for (i
= 0; i
< n
; i
++)
625 /* This should be handled the same as
626 next_element_from_display_vector does it. */
627 Lisp_Object entry
= AREF (charvec
, i
);
629 if (GLYPH_CODE_P (entry
)
630 && GLYPH_CODE_CHAR_VALID_P (entry
))
631 c
= GLYPH_CODE_CHAR (entry
);
637 if (c
== '\r' && EQ (BVAR (current_buffer
, selective_display
), Qt
))
642 col
= col
/ tab_width
* tab_width
;
650 /* The display table doesn't affect this character;
651 it displays as itself. */
655 if (c
== '\r' && EQ (BVAR (current_buffer
, selective_display
), Qt
))
660 col
= col
/ tab_width
* tab_width
;
662 else if (multibyte
&& LEADING_CODE_P (c
))
664 /* Start of multi-byte form. */
668 ptr
= BYTE_POS_ADDR (scan_byte
);
669 MULTIBYTE_BYTES_WIDTH (ptr
, dp
, bytes
, width
);
670 /* Subtract one to compensate for the increment
671 that is going to happen below. */
672 scan_byte
+= bytes
- 1;
675 else if (ctl_arrow
&& (c
< 040 || c
== 0177))
677 else if (c
< 040 || c
>= 0177)
688 last_known_column
= col
;
689 last_known_column_point
= PT
;
690 last_known_column_modified
= MODIFF
;
700 /* Return the column number of position POS
701 by scanning forward from the beginning of the line.
702 This function handles characters that are invisible
703 due to text properties or overlays. */
706 current_column_1 (void)
708 EMACS_INT col
= MOST_POSITIVE_FIXNUM
;
709 EMACS_INT opoint
= PT
;
711 scan_for_column (&opoint
, &col
, NULL
);
716 #if 0 /* Not used. */
718 /* Return the width in columns of the part of STRING from BEG to END.
719 If BEG is nil, that stands for the beginning of STRING.
720 If END is nil, that stands for the end of STRING. */
723 string_display_width (string
, beg
, end
)
724 Lisp_Object string
, beg
, end
;
727 register unsigned char *ptr
, *stop
;
728 register int tab_seen
;
731 register int tab_width
= XINT (current_buffer
->tab_width
);
732 int ctl_arrow
= !NILP (current_buffer
->ctl_arrow
);
733 register struct Lisp_Char_Table
*dp
= buffer_display_table ();
752 /* Make a pointer for decrementing through the chars before point. */
753 ptr
= SDATA (string
) + e
;
754 /* Make a pointer to where consecutive chars leave off,
755 going backwards from point. */
756 stop
= SDATA (string
) + b
;
758 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
760 col
= 0, tab_seen
= 0, post_tab
= 0;
768 if (dp
!= 0 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
769 col
+= ASIZE (DISP_CHAR_VECTOR (dp
, c
));
770 else if (c
>= 040 && c
< 0177)
777 col
= ((col
+ tab_width
) / tab_width
) * tab_width
;
784 col
+= (ctl_arrow
&& c
< 0200) ? 2 : 4;
789 col
= ((col
+ tab_width
) / tab_width
) * tab_width
;
799 DEFUN ("indent-to", Findent_to
, Sindent_to
, 1, 2, "NIndent to column: ",
800 doc
: /* Indent from point with tabs and spaces until COLUMN is reached.
801 Optional second argument MINIMUM says always do at least MINIMUM spaces
802 even if that goes past COLUMN; by default, MINIMUM is zero.
804 The return value is COLUMN. */)
805 (Lisp_Object column
, Lisp_Object minimum
)
808 register EMACS_INT fromcol
;
809 register EMACS_INT tab_width
= XINT (BVAR (current_buffer
, tab_width
));
811 CHECK_NUMBER (column
);
813 XSETFASTINT (minimum
, 0);
814 CHECK_NUMBER (minimum
);
816 fromcol
= current_column ();
817 mincol
= fromcol
+ XINT (minimum
);
818 if (mincol
< XINT (column
)) mincol
= XINT (column
);
820 if (fromcol
== mincol
)
821 return make_number (mincol
);
823 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
825 if (indent_tabs_mode
)
828 XSETFASTINT (n
, mincol
/ tab_width
- fromcol
/ tab_width
);
829 if (XFASTINT (n
) != 0)
831 Finsert_char (make_number ('\t'), n
, Qt
);
833 fromcol
= (mincol
/ tab_width
) * tab_width
;
837 XSETFASTINT (column
, mincol
- fromcol
);
838 Finsert_char (make_number (' '), column
, Qt
);
840 last_known_column
= mincol
;
841 last_known_column_point
= PT
;
842 last_known_column_modified
= MODIFF
;
844 XSETINT (column
, mincol
);
849 DEFUN ("current-indentation", Fcurrent_indentation
, Scurrent_indentation
,
851 doc
: /* Return the indentation of the current line.
852 This is the horizontal position of the character
853 following any initial whitespace. */)
857 EMACS_INT opoint
= PT
, opoint_byte
= PT_BYTE
;
859 scan_newline (PT
, PT_BYTE
, BEGV
, BEGV_BYTE
, -1, 1);
861 XSETFASTINT (val
, position_indentation (PT_BYTE
));
862 SET_PT_BOTH (opoint
, opoint_byte
);
867 position_indentation (register int pos_byte
)
869 register EMACS_INT column
= 0;
870 register EMACS_INT tab_width
= XINT (BVAR (current_buffer
, tab_width
));
871 register unsigned char *p
;
872 register unsigned char *stop
;
873 unsigned char *start
;
874 EMACS_INT next_boundary_byte
= pos_byte
;
875 EMACS_INT ceiling
= next_boundary_byte
;
877 if (tab_width
<= 0 || tab_width
> 1000) tab_width
= 8;
879 p
= BYTE_POS_ADDR (pos_byte
);
880 /* STOP records the value of P at which we will need
881 to think about the gap, or about invisible text,
882 or about the end of the buffer. */
884 /* START records the starting value of P. */
890 EMACS_INT stop_pos_byte
;
892 /* If we have updated P, set POS_BYTE to match.
893 The first time we enter the loop, POS_BYTE is already right. */
895 pos_byte
= PTR_BYTE_POS (p
);
896 /* Consider the various reasons STOP might have been set here. */
897 if (pos_byte
== ZV_BYTE
)
899 if (pos_byte
== next_boundary_byte
)
901 EMACS_INT next_boundary
;
902 EMACS_INT pos
= BYTE_TO_CHAR (pos_byte
);
903 pos
= skip_invisible (pos
, &next_boundary
, ZV
, Qnil
);
904 pos_byte
= CHAR_TO_BYTE (pos
);
905 next_boundary_byte
= CHAR_TO_BYTE (next_boundary
);
907 if (pos_byte
>= ceiling
)
908 ceiling
= BUFFER_CEILING_OF (pos_byte
) + 1;
909 /* Compute the next place we need to stop and think,
910 and set STOP accordingly. */
911 stop_pos_byte
= min (ceiling
, next_boundary_byte
);
912 /* The -1 and +1 arrange to point at the first byte of gap
913 (if STOP_POS_BYTE is the position of the gap)
914 rather than at the data after the gap. */
916 stop
= BYTE_POS_ADDR (stop_pos_byte
- 1) + 1;
917 p
= BYTE_POS_ADDR (pos_byte
);
922 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
928 column
+= tab_width
- column
% tab_width
;
931 if (ASCII_BYTE_P (p
[-1])
932 || NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
936 pos_byte
= PTR_BYTE_POS (p
- 1);
937 c
= FETCH_MULTIBYTE_CHAR (pos_byte
);
938 if (CHAR_HAS_CATEGORY (c
, ' '))
942 p
= BYTE_POS_ADDR (pos_byte
);
951 /* Test whether the line beginning at POS is indented beyond COLUMN.
952 Blank lines are treated as if they had the same indentation as the
956 indented_beyond_p (EMACS_INT pos
, EMACS_INT pos_byte
, EMACS_INT column
)
959 EMACS_INT opoint
= PT
, opoint_byte
= PT_BYTE
;
961 SET_PT_BOTH (pos
, pos_byte
);
962 while (PT
> BEGV
&& FETCH_BYTE (PT_BYTE
) == '\n')
963 scan_newline (PT
- 1, PT_BYTE
- 1, BEGV
, BEGV_BYTE
, -1, 0);
965 val
= position_indentation (PT_BYTE
);
966 SET_PT_BOTH (opoint
, opoint_byte
);
967 return val
>= column
;
970 DEFUN ("move-to-column", Fmove_to_column
, Smove_to_column
, 1, 2, "p",
971 doc
: /* Move point to column COLUMN in the current line.
972 Interactively, COLUMN is the value of prefix numeric argument.
973 The column of a character is calculated by adding together the widths
974 as displayed of the previous characters in the line.
975 This function ignores line-continuation;
976 there is no upper limit on the column number a character can have
977 and horizontal scrolling has no effect.
979 If specified column is within a character, point goes after that character.
980 If it's past end of line, point goes to end of line.
982 Optional second argument FORCE non-nil means if COLUMN is in the
983 middle of a tab character, change it to spaces.
984 In addition, if FORCE is t, and the line is too short to reach
985 COLUMN, add spaces/tabs to get there.
987 The return value is the current column. */)
988 (Lisp_Object column
, Lisp_Object force
)
991 EMACS_INT col
, prev_col
;
994 CHECK_NATNUM (column
);
995 goal
= XINT (column
);
999 scan_for_column (&pos
, &col
, &prev_col
);
1003 /* If a tab char made us overshoot, change it to spaces
1004 and scan through it again. */
1005 if (!NILP (force
) && col
> goal
)
1008 EMACS_INT pos_byte
= PT_BYTE
;
1011 c
= FETCH_CHAR (pos_byte
);
1012 if (c
== '\t' && prev_col
< goal
)
1014 EMACS_INT goal_pt
, goal_pt_byte
;
1016 /* Insert spaces in front of the tab to reach GOAL. Do this
1017 first so that a marker at the end of the tab gets
1019 SET_PT_BOTH (PT
- 1, PT_BYTE
- 1);
1020 Finsert_char (make_number (' '), make_number (goal
- prev_col
), Qt
);
1022 /* Now delete the tab, and indent to COL. */
1023 del_range (PT
, PT
+ 1);
1025 goal_pt_byte
= PT_BYTE
;
1026 Findent_to (make_number (col
), Qnil
);
1027 SET_PT_BOTH (goal_pt
, goal_pt_byte
);
1029 /* Set the last_known... vars consistently. */
1034 /* If line ends prematurely, add space to the end. */
1035 if (col
< goal
&& EQ (force
, Qt
))
1036 Findent_to (make_number (col
= goal
), Qnil
);
1038 last_known_column
= col
;
1039 last_known_column_point
= PT
;
1040 last_known_column_modified
= MODIFF
;
1042 return make_number (col
);
1045 /* compute_motion: compute buffer posn given screen posn and vice versa */
1047 static struct position val_compute_motion
;
1049 /* Scan the current buffer forward from offset FROM, pretending that
1050 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
1051 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
1052 and return the ending buffer position and screen location. If we
1053 can't hit the requested column exactly (because of a tab or other
1054 multi-column character), overshoot.
1056 DID_MOTION is 1 if FROMHPOS has already accounted for overlay strings
1057 at FROM. This is the case if FROMVPOS and FROMVPOS came from an
1058 earlier call to compute_motion. The other common case is that FROMHPOS
1059 is zero and FROM is a position that "belongs" at column zero, but might
1060 be shifted by overlay strings; in this case DID_MOTION should be 0.
1062 WIDTH is the number of columns available to display text;
1063 compute_motion uses this to handle continuation lines and such.
1064 If WIDTH is -1, use width of window's text area adjusted for
1065 continuation glyph when needed.
1067 HSCROLL is the number of columns not being displayed at the left
1068 margin; this is usually taken from a window's hscroll member.
1069 TAB_OFFSET is the number of columns of the first tab that aren't
1070 being displayed, perhaps because of a continuation line or
1073 compute_motion returns a pointer to a struct position. The bufpos
1074 member gives the buffer position at the end of the scan, and hpos
1075 and vpos give its cartesian location. prevhpos is the column at
1076 which the character before bufpos started, and contin is non-zero
1077 if we reached the current line by continuing the previous.
1079 Note that FROMHPOS and TOHPOS should be expressed in real screen
1080 columns, taking HSCROLL and the truncation glyph at the left margin
1081 into account. That is, beginning-of-line moves you to the hpos
1082 -HSCROLL + (HSCROLL > 0).
1084 For example, to find the buffer position of column COL of line LINE
1085 of a certain window, pass the window's starting location as FROM
1086 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
1087 Pass the buffer's ZV as TO, to limit the scan to the end of the
1088 visible section of the buffer, and pass LINE and COL as TOVPOS and
1091 When displaying in window w, a typical formula for WIDTH is:
1094 - (has_vertical_scroll_bars
1095 ? WINDOW_CONFIG_SCROLL_BAR_COLS (window)
1096 : (window_width + window_left != frame_cols))
1099 window_width is XFASTINT (w->total_cols),
1100 window_left is XFASTINT (w->left_col),
1101 has_vertical_scroll_bars is
1102 WINDOW_HAS_VERTICAL_SCROLL_BAR (window)
1103 and frame_cols = FRAME_COLS (XFRAME (window->frame))
1105 Or you can let window_box_text_cols do this all for you, and write:
1106 window_box_text_cols (w) - 1
1108 The `-1' accounts for the continuation-line backslashes; the rest
1109 accounts for window borders if the window is split horizontally, and
1110 the scroll bars if they are turned on. */
1113 compute_motion (EMACS_INT from
, EMACS_INT fromvpos
, EMACS_INT fromhpos
, int did_motion
, EMACS_INT to
, EMACS_INT tovpos
, EMACS_INT tohpos
, EMACS_INT width
, EMACS_INT hscroll
, EMACS_INT tab_offset
, struct window
*win
)
1115 register EMACS_INT hpos
= fromhpos
;
1116 register EMACS_INT vpos
= fromvpos
;
1118 register EMACS_INT pos
;
1121 register EMACS_INT tab_width
= XFASTINT (BVAR (current_buffer
, tab_width
));
1122 register int ctl_arrow
= !NILP (BVAR (current_buffer
, ctl_arrow
));
1123 register struct Lisp_Char_Table
*dp
= window_display_table (win
);
1125 = (INTEGERP (BVAR (current_buffer
, selective_display
))
1126 ? XINT (BVAR (current_buffer
, selective_display
))
1127 : !NILP (BVAR (current_buffer
, selective_display
)) ? -1 : 0);
1129 = (selective
&& dp
&& VECTORP (DISP_INVIS_VECTOR (dp
))
1130 ? ASIZE (DISP_INVIS_VECTOR (dp
)) : 0);
1131 /* The next location where the `invisible' property changes, or an
1132 overlay starts or ends. */
1133 EMACS_INT next_boundary
= from
;
1135 /* For computing runs of characters with similar widths.
1136 Invariant: width_run_width is zero, or all the characters
1137 from width_run_start to width_run_end have a fixed width of
1139 EMACS_INT width_run_start
= from
;
1140 EMACS_INT width_run_end
= from
;
1141 EMACS_INT width_run_width
= 0;
1142 Lisp_Object
*width_table
;
1145 /* The next buffer pos where we should consult the width run cache. */
1146 EMACS_INT next_width_run
= from
;
1149 int multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
1150 /* If previous char scanned was a wide character,
1151 this is the column where it ended. Otherwise, this is 0. */
1152 EMACS_INT wide_column_end_hpos
= 0;
1153 EMACS_INT prev_pos
; /* Previous buffer position. */
1154 EMACS_INT prev_pos_byte
; /* Previous buffer position. */
1155 EMACS_INT prev_hpos
= 0;
1156 EMACS_INT prev_vpos
= 0;
1157 EMACS_INT contin_hpos
; /* HPOS of last column of continued line. */
1158 EMACS_INT prev_tab_offset
; /* Previous tab offset. */
1159 EMACS_INT continuation_glyph_width
;
1161 struct composition_it cmp_it
;
1163 XSETBUFFER (buffer
, current_buffer
);
1164 XSETWINDOW (window
, win
);
1166 width_run_cache_on_off ();
1167 if (dp
== buffer_display_table ())
1168 width_table
= (VECTORP (BVAR (current_buffer
, width_table
))
1169 ? XVECTOR (BVAR (current_buffer
, width_table
))->contents
1172 /* If the window has its own display table, we can't use the width
1173 run cache, because that's based on the buffer's display table. */
1176 if (tab_width
<= 0 || tab_width
> 1000)
1179 /* Negative width means use all available text columns. */
1182 width
= window_box_text_cols (win
);
1183 /* We must make room for continuation marks if we don't have fringes. */
1184 #ifdef HAVE_WINDOW_SYSTEM
1185 if (!FRAME_WINDOW_P (XFRAME (win
->frame
)))
1190 continuation_glyph_width
= 1;
1191 #ifdef HAVE_WINDOW_SYSTEM
1192 if (FRAME_WINDOW_P (XFRAME (win
->frame
)))
1193 continuation_glyph_width
= 0; /* In the fringe. */
1199 pos
= prev_pos
= from
;
1200 pos_byte
= prev_pos_byte
= CHAR_TO_BYTE (from
);
1202 prev_tab_offset
= tab_offset
;
1203 memset (&cmp_it
, 0, sizeof cmp_it
);
1205 composition_compute_stop_pos (&cmp_it
, pos
, pos_byte
, to
, Qnil
);
1209 while (pos
== next_boundary
)
1211 EMACS_INT pos_here
= pos
;
1214 /* Don't skip invisible if we are already at the margin. */
1215 if (vpos
> tovpos
|| (vpos
== tovpos
&& hpos
>= tohpos
))
1217 if (contin_hpos
&& prev_hpos
== 0
1219 && (contin_hpos
== width
|| wide_column_end_hpos
> width
))
1220 { /* Line breaks because we can't put the character at the
1221 previous line any more. It is not the multi-column
1222 character continued in middle. Go back to previous
1223 buffer position, screen position, and set tab offset
1224 to previous value. It's the beginning of the
1227 pos_byte
= prev_pos_byte
;
1230 tab_offset
= prev_tab_offset
;
1235 /* If the caller says that the screen position came from an earlier
1236 call to compute_motion, then we've already accounted for the
1237 overlay strings at point. This is only true the first time
1238 through, so clear the flag after testing it. */
1240 /* We need to skip past the overlay strings. Currently those
1241 strings must not contain TAB;
1242 if we want to relax that restriction, something will have
1243 to be changed here. */
1245 unsigned char *ovstr
;
1246 EMACS_INT ovlen
= overlay_strings (pos
, win
, &ovstr
);
1247 hpos
+= ((multibyte
&& ovlen
> 0)
1248 ? strwidth ((char *) ovstr
, ovlen
) : ovlen
);
1255 /* Advance POS past invisible characters
1256 (but not necessarily all that there are here),
1257 and store in next_boundary the next position where
1258 we need to call skip_invisible. */
1259 newpos
= skip_invisible (pos
, &next_boundary
, to
, window
);
1263 pos
= min (to
, newpos
);
1264 pos_byte
= CHAR_TO_BYTE (pos
);
1268 if (newpos
!= pos_here
)
1271 pos_byte
= CHAR_TO_BYTE (pos
);
1275 /* Handle right margin. */
1276 /* Note on a wide-column character.
1278 Characters are classified into the following three categories
1279 according to the width (columns occupied on screen).
1281 (1) single-column character: ex. `a'
1282 (2) multi-column character: ex. `^A', TAB, `\033'
1283 (3) wide-column character: ex. Japanese character, Chinese character
1284 (In the following example, `W_' stands for them.)
1286 Multi-column characters can be divided around the right margin,
1287 but wide-column characters cannot.
1291 (*) The cursor is placed on the next character after the point.
1295 j ^---- next after the point
1296 ^--- next char. after the point.
1298 In case of sigle-column character
1302 033 ^---- next after the point, next char. after the point.
1304 In case of multi-column character
1308 W_ ^---- next after the point
1309 ^---- next char. after the point.
1311 In case of wide-column character
1313 The problem here is continuation at a wide-column character.
1314 In this case, the line may shorter less than WIDTH.
1315 And we find the continuation AFTER it occurs.
1321 int total_width
= width
+ continuation_glyph_width
;
1324 if (!NILP (Vtruncate_partial_width_windows
)
1325 && (total_width
< FRAME_COLS (XFRAME (WINDOW_FRAME (win
)))))
1327 if (INTEGERP (Vtruncate_partial_width_windows
))
1329 = total_width
< XFASTINT (Vtruncate_partial_width_windows
);
1334 if (hscroll
|| truncate
1335 || !NILP (BVAR (current_buffer
, truncate_lines
)))
1337 /* Truncating: skip to newline, unless we are already past
1338 TO (we need to go back below). */
1341 pos
= find_before_next_newline (pos
, to
, 1);
1342 pos_byte
= CHAR_TO_BYTE (pos
);
1344 /* If we just skipped next_boundary,
1345 loop around in the main while
1347 if (pos
>= next_boundary
)
1348 next_boundary
= pos
+ 1;
1351 prev_tab_offset
= tab_offset
;
1357 /* Remember the previous value. */
1358 prev_tab_offset
= tab_offset
;
1360 if (wide_column_end_hpos
> width
)
1363 tab_offset
+= prev_hpos
;
1367 tab_offset
+= width
;
1371 contin_hpos
= prev_hpos
;
1377 /* Stop if past the target buffer position or screen position. */
1380 /* Go back to the previous position. */
1382 pos_byte
= prev_pos_byte
;
1385 tab_offset
= prev_tab_offset
;
1387 /* NOTE on contin_hpos, hpos, and prev_hpos.
1391 W_ ^---- contin_hpos
1397 if (contin_hpos
&& prev_hpos
== 0
1398 && contin_hpos
< width
&& !wide_column_end_hpos
)
1400 /* Line breaking occurs in the middle of multi-column
1401 character. Go back to previous line. */
1408 if (vpos
> tovpos
|| (vpos
== tovpos
&& hpos
>= tohpos
))
1410 if (contin_hpos
&& prev_hpos
== 0
1412 && (contin_hpos
== width
|| wide_column_end_hpos
> width
))
1413 { /* Line breaks because we can't put the character at the
1414 previous line any more. It is not the multi-column
1415 character continued in middle. Go back to previous
1416 buffer position, screen position, and set tab offset
1417 to previous value. It's the beginning of the
1420 pos_byte
= prev_pos_byte
;
1423 tab_offset
= prev_tab_offset
;
1427 if (pos
== ZV
) /* We cannot go beyond ZV. Stop here. */
1433 prev_pos_byte
= pos_byte
;
1434 wide_column_end_hpos
= 0;
1436 /* Consult the width run cache to see if we can avoid inspecting
1437 the text character-by-character. */
1438 if (current_buffer
->width_run_cache
&& pos
>= next_width_run
)
1442 = region_cache_forward (current_buffer
,
1443 current_buffer
->width_run_cache
,
1446 /* A width of zero means the character's width varies (like
1447 a tab), is meaningless (like a newline), or we just don't
1448 want to skip over it for some other reason. */
1449 if (common_width
!= 0)
1451 EMACS_INT run_end_hpos
;
1453 /* Don't go past the final buffer posn the user
1458 run_end_hpos
= hpos
+ (run_end
- pos
) * common_width
;
1460 /* Don't go past the final horizontal position the user
1462 if (vpos
== tovpos
&& run_end_hpos
> tohpos
)
1464 run_end
= pos
+ (tohpos
- hpos
) / common_width
;
1465 run_end_hpos
= hpos
+ (run_end
- pos
) * common_width
;
1468 /* Don't go past the margin. */
1469 if (run_end_hpos
>= width
)
1471 run_end
= pos
+ (width
- hpos
) / common_width
;
1472 run_end_hpos
= hpos
+ (run_end
- pos
) * common_width
;
1475 hpos
= run_end_hpos
;
1477 prev_hpos
= hpos
- common_width
;
1481 pos_byte
= CHAR_TO_BYTE (pos
);
1485 next_width_run
= run_end
+ 1;
1488 /* We have to scan the text character-by-character. */
1492 Lisp_Object charvec
;
1494 /* Check composition sequence. */
1496 || (pos
== cmp_it
.stop_pos
1497 && composition_reseat_it (&cmp_it
, pos
, pos_byte
, to
, win
,
1499 composition_update_it (&cmp_it
, pos
, pos_byte
, Qnil
);
1502 pos
+= cmp_it
.nchars
;
1503 pos_byte
+= cmp_it
.nbytes
;
1504 hpos
+= cmp_it
.width
;
1505 if (cmp_it
.to
== cmp_it
.nglyphs
)
1508 composition_compute_stop_pos (&cmp_it
, pos
, pos_byte
, to
,
1512 cmp_it
.from
= cmp_it
.to
;
1516 c
= FETCH_BYTE (pos_byte
);
1519 /* Perhaps add some info to the width_run_cache. */
1520 if (current_buffer
->width_run_cache
)
1522 /* Is this character part of the current run? If so, extend
1524 if (pos
- 1 == width_run_end
1525 && XFASTINT (width_table
[c
]) == width_run_width
)
1526 width_run_end
= pos
;
1528 /* The previous run is over, since this is a character at a
1529 different position, or a different width. */
1532 /* Have we accumulated a run to put in the cache?
1533 (Currently, we only cache runs of width == 1). */
1534 if (width_run_start
< width_run_end
1535 && width_run_width
== 1)
1536 know_region_cache (current_buffer
,
1537 current_buffer
->width_run_cache
,
1538 width_run_start
, width_run_end
);
1540 /* Start recording a new width run. */
1541 width_run_width
= XFASTINT (width_table
[c
]);
1542 width_run_start
= pos
- 1;
1543 width_run_end
= pos
;
1548 && ! (multibyte
&& LEADING_CODE_P (c
))
1549 && VECTORP (DISP_CHAR_VECTOR (dp
, c
)))
1551 charvec
= DISP_CHAR_VECTOR (dp
, c
);
1552 n
= ASIZE (charvec
);
1560 for (i
= n
- 1; i
>= 0; --i
)
1562 if (VECTORP (charvec
))
1564 /* This should be handled the same as
1565 next_element_from_display_vector does it. */
1566 Lisp_Object entry
= AREF (charvec
, i
);
1568 if (GLYPH_CODE_P (entry
)
1569 && GLYPH_CODE_CHAR_VALID_P (entry
))
1570 c
= GLYPH_CODE_CHAR (entry
);
1575 if (c
>= 040 && c
< 0177)
1579 int tem
= ((hpos
+ tab_offset
+ hscroll
- (hscroll
> 0))
1583 hpos
+= tab_width
- tem
;
1588 && indented_beyond_p (pos
, pos_byte
, selective
))
1590 /* If (pos == to), we don't have to take care of
1591 selective display. */
1594 /* Skip any number of invisible lines all at once */
1597 pos
= find_before_next_newline (pos
, to
, 1);
1600 pos_byte
= CHAR_TO_BYTE (pos
);
1603 && indented_beyond_p (pos
, pos_byte
,
1605 /* Allow for the " ..." that is displayed for them. */
1608 hpos
+= selective_rlen
;
1612 DEC_BOTH (pos
, pos_byte
);
1613 /* We have skipped the invis text, but not the
1619 /* A visible line. */
1623 /* Count the truncation glyph on column 0 */
1625 hpos
+= continuation_glyph_width
;
1630 else if (c
== CR
&& selective
< 0)
1632 /* In selective display mode,
1633 everything from a ^M to the end of the line is invisible.
1634 Stop *before* the real newline. */
1637 pos
= find_before_next_newline (pos
, to
, 1);
1638 pos_byte
= CHAR_TO_BYTE (pos
);
1640 /* If we just skipped next_boundary,
1641 loop around in the main while
1643 if (pos
> next_boundary
)
1644 next_boundary
= pos
;
1645 /* Allow for the " ..." that is displayed for them. */
1648 hpos
+= selective_rlen
;
1653 else if (multibyte
&& LEADING_CODE_P (c
))
1655 /* Start of multi-byte form. */
1657 int mb_bytes
, mb_width
;
1659 pos_byte
--; /* rewind POS_BYTE */
1660 ptr
= BYTE_POS_ADDR (pos_byte
);
1661 MULTIBYTE_BYTES_WIDTH (ptr
, dp
, mb_bytes
, mb_width
);
1662 pos_byte
+= mb_bytes
;
1663 if (mb_width
> 1 && BYTES_BY_CHAR_HEAD (*ptr
) == mb_bytes
)
1664 wide_column_end_hpos
= hpos
+ mb_width
;
1667 else if (VECTORP (charvec
))
1670 hpos
+= (ctl_arrow
&& c
< 0200) ? 2 : 4;
1677 /* Remember any final width run in the cache. */
1678 if (current_buffer
->width_run_cache
1679 && width_run_width
== 1
1680 && width_run_start
< width_run_end
)
1681 know_region_cache (current_buffer
, current_buffer
->width_run_cache
,
1682 width_run_start
, width_run_end
);
1684 val_compute_motion
.bufpos
= pos
;
1685 val_compute_motion
.bytepos
= pos_byte
;
1686 val_compute_motion
.hpos
= hpos
;
1687 val_compute_motion
.vpos
= vpos
;
1688 if (contin_hpos
&& prev_hpos
== 0)
1689 val_compute_motion
.prevhpos
= contin_hpos
;
1691 val_compute_motion
.prevhpos
= prev_hpos
;
1692 /* We alalways handle all of them here; none of them remain to do. */
1693 val_compute_motion
.ovstring_chars_done
= 0;
1695 /* Nonzero if have just continued a line */
1696 val_compute_motion
.contin
= (contin_hpos
&& prev_hpos
== 0);
1699 return &val_compute_motion
;
1703 DEFUN ("compute-motion", Fcompute_motion
, Scompute_motion
, 7, 7, 0,
1704 doc
: /* Scan through the current buffer, calculating screen position.
1705 Scan the current buffer forward from offset FROM,
1706 assuming it is at position FROMPOS--a cons of the form (HPOS . VPOS)--
1707 to position TO or position TOPOS--another cons of the form (HPOS . VPOS)--
1708 and return the ending buffer position and screen location.
1710 If TOPOS is nil, the actual width and height of the window's
1713 There are three additional arguments:
1715 WIDTH is the number of columns available to display text;
1716 this affects handling of continuation lines. A value of nil
1717 corresponds to the actual number of available text columns.
1719 OFFSETS is either nil or a cons cell (HSCROLL . TAB-OFFSET).
1720 HSCROLL is the number of columns not being displayed at the left
1721 margin; this is usually taken from a window's hscroll member.
1722 TAB-OFFSET is the number of columns of the first tab that aren't
1723 being displayed, perhaps because the line was continued within it.
1724 If OFFSETS is nil, HSCROLL and TAB-OFFSET are assumed to be zero.
1726 WINDOW is the window to operate on. It is used to choose the display table;
1727 if it is showing the current buffer, it is used also for
1728 deciding which overlay properties apply.
1729 Note that `compute-motion' always operates on the current buffer.
1731 The value is a list of five elements:
1732 (POS HPOS VPOS PREVHPOS CONTIN)
1733 POS is the buffer position where the scan stopped.
1734 VPOS is the vertical position where the scan stopped.
1735 HPOS is the horizontal position where the scan stopped.
1737 PREVHPOS is the horizontal position one character back from POS.
1738 CONTIN is t if a line was continued after (or within) the previous character.
1740 For example, to find the buffer position of column COL of line LINE
1741 of a certain window, pass the window's starting location as FROM
1742 and the window's upper-left coordinates as FROMPOS.
1743 Pass the buffer's (point-max) as TO, to limit the scan to the end of the
1744 visible section of the buffer, and pass LINE and COL as TOPOS. */)
1745 (Lisp_Object from
, Lisp_Object frompos
, Lisp_Object to
, Lisp_Object topos
, Lisp_Object width
, Lisp_Object offsets
, Lisp_Object window
)
1748 Lisp_Object bufpos
, hpos
, vpos
, prevhpos
;
1749 struct position
*pos
;
1750 int hscroll
, tab_offset
;
1752 CHECK_NUMBER_COERCE_MARKER (from
);
1753 CHECK_CONS (frompos
);
1754 CHECK_NUMBER_CAR (frompos
);
1755 CHECK_NUMBER_CDR (frompos
);
1756 CHECK_NUMBER_COERCE_MARKER (to
);
1760 CHECK_NUMBER_CAR (topos
);
1761 CHECK_NUMBER_CDR (topos
);
1764 CHECK_NUMBER (width
);
1766 if (!NILP (offsets
))
1768 CHECK_CONS (offsets
);
1769 CHECK_NUMBER_CAR (offsets
);
1770 CHECK_NUMBER_CDR (offsets
);
1771 hscroll
= XINT (XCAR (offsets
));
1772 tab_offset
= XINT (XCDR (offsets
));
1775 hscroll
= tab_offset
= 0;
1778 window
= Fselected_window ();
1780 CHECK_LIVE_WINDOW (window
);
1781 w
= XWINDOW (window
);
1783 if (XINT (from
) < BEGV
|| XINT (from
) > ZV
)
1784 args_out_of_range_3 (from
, make_number (BEGV
), make_number (ZV
));
1785 if (XINT (to
) < BEGV
|| XINT (to
) > ZV
)
1786 args_out_of_range_3 (to
, make_number (BEGV
), make_number (ZV
));
1788 pos
= compute_motion (XINT (from
), XINT (XCDR (frompos
)),
1789 XINT (XCAR (frompos
)), 0,
1792 ? window_internal_height (w
)
1793 : XINT (XCDR (topos
))),
1795 ? (window_box_text_cols (w
)
1797 #ifdef HAVE_WINDOW_SYSTEM
1798 FRAME_WINDOW_P (XFRAME (w
->frame
)) ? 0 :
1801 : XINT (XCAR (topos
))),
1802 (NILP (width
) ? -1 : XINT (width
)),
1803 hscroll
, tab_offset
,
1806 XSETFASTINT (bufpos
, pos
->bufpos
);
1807 XSETINT (hpos
, pos
->hpos
);
1808 XSETINT (vpos
, pos
->vpos
);
1809 XSETINT (prevhpos
, pos
->prevhpos
);
1811 return Fcons (bufpos
,
1815 Fcons (pos
->contin
? Qt
: Qnil
, Qnil
)))));
1819 /* Fvertical_motion and vmotion */
1821 static struct position val_vmotion
;
1824 vmotion (register EMACS_INT from
, register EMACS_INT vtarget
, struct window
*w
)
1826 EMACS_INT hscroll
= XINT (w
->hscroll
);
1827 struct position pos
;
1828 /* vpos is cumulative vertical position, changed as from is changed */
1829 register int vpos
= 0;
1831 register EMACS_INT first
;
1832 EMACS_INT from_byte
;
1833 EMACS_INT lmargin
= hscroll
> 0 ? 1 - hscroll
: 0;
1835 = (INTEGERP (BVAR (current_buffer
, selective_display
))
1836 ? XINT (BVAR (current_buffer
, selective_display
))
1837 : !NILP (BVAR (current_buffer
, selective_display
)) ? -1 : 0);
1839 EMACS_INT start_hpos
= 0;
1841 /* This is the object we use for fetching character properties. */
1842 Lisp_Object text_prop_object
;
1844 XSETWINDOW (window
, w
);
1846 /* If the window contains this buffer, use it for getting text properties.
1847 Otherwise use the current buffer as arg for doing that. */
1848 if (EQ (w
->buffer
, Fcurrent_buffer ()))
1849 text_prop_object
= window
;
1851 text_prop_object
= Fcurrent_buffer ();
1853 if (vpos
>= vtarget
)
1855 /* To move upward, go a line at a time until
1856 we have gone at least far enough. */
1860 while ((vpos
> vtarget
|| first
) && from
> BEGV
)
1862 Lisp_Object propval
;
1864 prevline
= find_next_newline_no_quit (from
- 1, -1);
1865 while (prevline
> BEGV
1867 && indented_beyond_p (prevline
,
1868 CHAR_TO_BYTE (prevline
),
1870 /* Watch out for newlines with `invisible' property.
1871 When moving upward, check the newline before. */
1872 || (propval
= Fget_char_property (make_number (prevline
- 1),
1875 TEXT_PROP_MEANS_INVISIBLE (propval
))))
1876 prevline
= find_next_newline_no_quit (prevline
- 1, -1);
1877 pos
= *compute_motion (prevline
, 0,
1878 lmargin
+ (prevline
== BEG
? start_hpos
: 0),
1881 /* Don't care for VPOS... */
1882 1 << (BITS_PER_SHORT
- 1),
1884 1 << (BITS_PER_SHORT
- 1),
1886 /* This compensates for start_hpos
1887 so that a tab as first character
1888 still occupies 8 columns. */
1889 (prevline
== BEG
? -start_hpos
: 0),
1896 /* If we made exactly the desired vertical distance,
1897 or if we hit beginning of buffer,
1898 return point found */
1899 if (vpos
>= vtarget
)
1901 val_vmotion
.bufpos
= from
;
1902 val_vmotion
.bytepos
= CHAR_TO_BYTE (from
);
1903 val_vmotion
.vpos
= vpos
;
1904 val_vmotion
.hpos
= lmargin
;
1905 val_vmotion
.contin
= 0;
1906 val_vmotion
.prevhpos
= 0;
1907 val_vmotion
.ovstring_chars_done
= 0;
1908 val_vmotion
.tab_offset
= 0; /* For accumulating tab offset. */
1909 return &val_vmotion
;
1912 /* Otherwise find the correct spot by moving down */
1914 /* Moving downward is simple, but must calculate from beg of line
1915 to determine hpos of starting point */
1916 from_byte
= CHAR_TO_BYTE (from
);
1917 if (from
> BEGV
&& FETCH_BYTE (from_byte
- 1) != '\n')
1919 Lisp_Object propval
;
1921 prevline
= find_next_newline_no_quit (from
, -1);
1922 while (prevline
> BEGV
1924 && indented_beyond_p (prevline
,
1925 CHAR_TO_BYTE (prevline
),
1927 /* Watch out for newlines with `invisible' property.
1928 When moving downward, check the newline after. */
1929 || (propval
= Fget_char_property (make_number (prevline
),
1932 TEXT_PROP_MEANS_INVISIBLE (propval
))))
1933 prevline
= find_next_newline_no_quit (prevline
- 1, -1);
1934 pos
= *compute_motion (prevline
, 0,
1935 lmargin
+ (prevline
== BEG
1939 /* Don't care for VPOS... */
1940 1 << (BITS_PER_SHORT
- 1),
1942 1 << (BITS_PER_SHORT
- 1),
1944 (prevline
== BEG
? -start_hpos
: 0),
1950 pos
.hpos
= lmargin
+ (from
== BEG
? start_hpos
: 0);
1955 return compute_motion (from
, vpos
, pos
.hpos
, did_motion
,
1956 ZV
, vtarget
, - (1 << (BITS_PER_SHORT
- 1)),
1958 pos
.tab_offset
- (from
== BEG
? start_hpos
: 0),
1962 DEFUN ("vertical-motion", Fvertical_motion
, Svertical_motion
, 1, 2, 0,
1963 doc
: /* Move point to start of the screen line LINES lines down.
1964 If LINES is negative, this means moving up.
1966 This function is an ordinary cursor motion function
1967 which calculates the new position based on how text would be displayed.
1968 The new position may be the start of a line,
1969 or just the start of a continuation line.
1970 The function returns number of screen lines moved over;
1971 that usually equals LINES, but may be closer to zero
1972 if beginning or end of buffer was reached.
1974 The optional second argument WINDOW specifies the window to use for
1975 parameters such as width, horizontal scrolling, and so on.
1976 The default is to use the selected window's parameters.
1978 LINES can optionally take the form (COLS . LINES), in which case
1979 the motion will not stop at the start of a screen line but on
1980 its column COLS (if such exists on that line, that is).
1982 `vertical-motion' always uses the current buffer,
1983 regardless of which buffer is displayed in WINDOW.
1984 This is consistent with other cursor motion functions
1985 and makes it possible to use `vertical-motion' in any buffer,
1986 whether or not it is currently displayed in some window. */)
1987 (Lisp_Object lines
, Lisp_Object window
)
1992 Lisp_Object old_buffer
;
1993 struct gcpro gcpro1
;
1994 Lisp_Object lcols
= Qnil
;
1995 double cols
IF_LINT (= 0);
1997 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
1998 if (CONSP (lines
) && (NUMBERP (XCAR (lines
))))
2000 lcols
= XCAR (lines
);
2001 cols
= INTEGERP (lcols
) ? (double) XINT (lcols
) : XFLOAT_DATA (lcols
);
2002 lines
= XCDR (lines
);
2005 CHECK_NUMBER (lines
);
2006 if (! NILP (window
))
2007 CHECK_WINDOW (window
);
2009 window
= selected_window
;
2010 w
= XWINDOW (window
);
2013 GCPRO1 (old_buffer
);
2014 if (XBUFFER (w
->buffer
) != current_buffer
)
2016 /* Set the window's buffer temporarily to the current buffer. */
2017 old_buffer
= w
->buffer
;
2018 XSETBUFFER (w
->buffer
, current_buffer
);
2023 struct position pos
;
2024 pos
= *vmotion (PT
, XINT (lines
), w
);
2025 SET_PT_BOTH (pos
.bufpos
, pos
.bytepos
);
2030 int first_x
, it_overshoot_expected
IF_LINT (= 0);
2032 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
2033 start_display (&it
, w
, pt
);
2034 first_x
= it
.first_visible_x
;
2035 it_start
= IT_CHARPOS (it
);
2037 /* See comments below for why we calculate this. */
2038 if (XINT (lines
) > 0)
2040 if (it
.cmp_it
.id
>= 0)
2041 it_overshoot_expected
= 1;
2042 else if (it
.method
== GET_FROM_STRING
)
2044 const char *s
= SSDATA (it
.string
);
2045 const char *e
= s
+ SBYTES (it
.string
);
2046 while (s
< e
&& *s
!= '\n')
2048 it_overshoot_expected
= (s
== e
) ? -1 : 0;
2051 it_overshoot_expected
= (it
.method
== GET_FROM_IMAGE
2052 || it
.method
== GET_FROM_STRETCH
);
2055 /* Scan from the start of the line containing PT. If we don't
2056 do this, we start moving with IT->current_x == 0, while PT is
2057 really at some x > 0. */
2058 reseat_at_previous_visible_line_start (&it
);
2059 it
.current_x
= it
.hpos
= 0;
2060 if (IT_CHARPOS (it
) != PT
)
2061 /* We used to temporarily disable selective display here; the
2062 comment said this is "so we don't move too far" (2005-01-19
2063 checkin by kfs). But this does nothing useful that I can
2064 tell, and it causes Bug#2694 . -- cyd */
2065 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
2067 if (XINT (lines
) <= 0)
2070 /* Do this even if LINES is 0, so that we move back to the
2071 beginning of the current line as we ought. */
2072 if (XINT (lines
) == 0 || IT_CHARPOS (it
) > 0)
2073 move_it_by_lines (&it
, XINT (lines
));
2077 if (IT_CHARPOS (it
) > it_start
)
2079 /* IT may move too far if truncate-lines is on and PT
2080 lies beyond the right margin. In that case,
2081 backtrack unless the starting point is on an image,
2082 stretch glyph, composition, or Lisp string. */
2083 if (!it_overshoot_expected
2084 /* Also, backtrack if the Lisp string contains no
2085 newline, but there is a newline right after it.
2086 In this case, IT overshoots if there is an
2087 after-string just before the newline. */
2088 || (it_overshoot_expected
< 0
2089 && it
.method
== GET_FROM_BUFFER
2091 move_it_by_lines (&it
, -1);
2093 move_it_by_lines (&it
, XINT (lines
));
2097 /* Otherwise, we are at the first row occupied by PT,
2098 which might span multiple screen lines (e.g., if it's
2099 on a multi-line display string). We want to start
2100 from the last line that it occupies. */
2103 while (IT_CHARPOS (it
) <= it_start
)
2106 move_it_by_lines (&it
, 1);
2108 if (XINT (lines
) > 1)
2109 move_it_by_lines (&it
, XINT (lines
) - 1);
2114 move_it_by_lines (&it
, XINT (lines
));
2119 /* Move to the goal column, if one was specified. */
2122 /* If the window was originally hscrolled, move forward by
2123 the hscrolled amount first. */
2126 move_it_in_display_line (&it
, ZV
, first_x
, MOVE_TO_X
);
2129 move_it_in_display_line
2131 (int)(cols
* FRAME_COLUMN_WIDTH (XFRAME (w
->frame
)) + 0.5),
2135 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
2138 if (BUFFERP (old_buffer
))
2139 w
->buffer
= old_buffer
;
2141 RETURN_UNGCPRO (make_number (it
.vpos
));
2146 /* File's initialization. */
2149 syms_of_indent (void)
2151 DEFVAR_BOOL ("indent-tabs-mode", indent_tabs_mode
,
2152 doc
: /* *Indentation can insert tabs if this is non-nil. */);
2153 indent_tabs_mode
= 1;
2155 defsubr (&Scurrent_indentation
);
2156 defsubr (&Sindent_to
);
2157 defsubr (&Scurrent_column
);
2158 defsubr (&Smove_to_column
);
2159 defsubr (&Svertical_motion
);
2160 defsubr (&Scompute_motion
);