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