(tags-loop-scan): Set default value to an error form.
[bpt/emacs.git] / src / indent.c
CommitLineData
993b6404 1/* Indentation functions.
70ee42f7 2 Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
993b6404
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "lisp.h"
23#include "buffer.h"
24#include "indent.h"
502b9b64 25#include "frame.h"
993b6404
JB
26#include "window.h"
27#include "termchar.h"
28#include "termopts.h"
29#include "disptab.h"
30
31/* Indentation can insert tabs if this is non-zero;
32 otherwise always uses spaces */
33int indent_tabs_mode;
34
35#define min(a, b) ((a) < (b) ? (a) : (b))
36#define max(a, b) ((a) > (b) ? (a) : (b))
37
38#define CR 015
39
40/* These three values memoize the current column to avoid recalculation */
41/* Some things in set last_known_column_point to -1
42 to mark the memoized value as invalid */
43/* Last value returned by current_column */
44int last_known_column;
45/* Value of point when current_column was called */
46int last_known_column_point;
47/* Value of MODIFF when current_column was called */
48int last_known_column_modified;
49
993b6404
JB
50/* Get the display table to use for the current buffer. */
51
52struct Lisp_Vector *
53buffer_display_table ()
54{
55 Lisp_Object thisbuf;
56
57 thisbuf = current_buffer->display_table;
58 if (XTYPE (thisbuf) == Lisp_Vector
59 && XVECTOR (thisbuf)->size == DISP_TABLE_SIZE)
60 return XVECTOR (thisbuf);
61 if (XTYPE (Vstandard_display_table) == Lisp_Vector
62 && XVECTOR (Vstandard_display_table)->size == DISP_TABLE_SIZE)
63 return XVECTOR (Vstandard_display_table);
64 return 0;
65}
66\f
67DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
68 "Return the horizontal position of point. Beginning of line is column 0.\n\
69This is calculated by adding together the widths of all the displayed\n\
70representations of the character between the start of the previous line\n\
71and point. (eg control characters will have a width of 2 or 4, tabs\n\
72will have a variable width)\n\
502b9b64
JB
73Ignores finite width of frame, which means that this function may return\n\
74values greater than (frame-width).\n\
993b6404
JB
75Whether the line is visible (if `selective-display' is t) has no effect;\n\
76however, ^M is treated as end of line when `selective-display' is t.")
77 ()
78{
79 Lisp_Object temp;
80 XFASTINT (temp) = current_column ();
81 return temp;
82}
83
e74928fc
JB
84/* Cancel any recorded value of the horizontal position. */
85
86invalidate_current_column ()
87{
88 last_known_column_point = 0;
89}
90
993b6404
JB
91int
92current_column ()
93{
94 register int col;
95 register unsigned char *ptr, *stop;
96 register int tab_seen;
97 int post_tab;
98 register int c;
99 register int tab_width = XINT (current_buffer->tab_width);
56a98455 100 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
993b6404
JB
101 register struct Lisp_Vector *dp = buffer_display_table ();
102 int stopchar;
103
104 if (point == last_known_column_point
105 && MODIFF == last_known_column_modified)
106 return last_known_column;
107
108 /* Make a pointer for decrementing through the chars before point. */
109 ptr = &FETCH_CHAR (point - 1) + 1;
110 /* Make a pointer to where consecutive chars leave off,
111 going backwards from point. */
112 if (point == BEGV)
113 stop = ptr;
114 else if (point <= GPT || BEGV > GPT)
115 stop = BEGV_ADDR;
116 else
117 stop = GAP_END_ADDR;
118
119 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
120
121 col = 0, tab_seen = 0, post_tab = 0;
122
123 while (1)
124 {
125 if (ptr == stop)
126 {
127 /* We stopped either for the beginning of the buffer
128 or for the gap. */
129 if (ptr == BEGV_ADDR)
130 break;
131 /* It was the gap. Jump back over it. */
132 stop = BEGV_ADDR;
133 ptr = GPT_ADDR;
134 /* Check whether that brings us to beginning of buffer. */
135 if (BEGV >= GPT) break;
136 }
137
138 c = *--ptr;
139 if (c >= 040 && c < 0177
140 && (dp == 0 || XTYPE (DISP_CHAR_ROPE (dp, c)) != Lisp_String))
141 {
142 col++;
143 }
144 else if (c == '\n')
145 break;
146 else if (c == '\r' && EQ (current_buffer->selective_display, Qt))
147 break;
148 else if (c == '\t')
149 {
150 if (tab_seen)
151 col = ((col + tab_width) / tab_width) * tab_width;
152
153 post_tab += col;
154 col = 0;
155 tab_seen = 1;
156 }
157 else if (dp != 0 && XTYPE (DISP_CHAR_ROPE (dp, c)) == Lisp_String)
158 col += XSTRING (DISP_CHAR_ROPE (dp, c))->size / sizeof (GLYPH);
159 else
160 col += (ctl_arrow && c < 0200) ? 2 : 4;
161 }
162
163 if (tab_seen)
164 {
165 col = ((col + tab_width) / tab_width) * tab_width;
166 col += post_tab;
167 }
168
169 last_known_column = col;
170 last_known_column_point = point;
171 last_known_column_modified = MODIFF;
172
173 return col;
174}
175\f
176
177DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
178 "Indent from point with tabs and spaces until COLUMN is reached.\n\
179Optional second argument MIN says always do at least MIN spaces\n\
180even if that goes past COLUMN; by default, MIN is zero.")
181 (col, minimum)
182 Lisp_Object col, minimum;
183{
184 int mincol;
185 register int fromcol;
186 register int tab_width = XINT (current_buffer->tab_width);
187
188 CHECK_NUMBER (col, 0);
56a98455 189 if (NILP (minimum))
993b6404
JB
190 XFASTINT (minimum) = 0;
191 CHECK_NUMBER (minimum, 1);
192
193 fromcol = current_column ();
194 mincol = fromcol + XINT (minimum);
195 if (mincol < XINT (col)) mincol = XINT (col);
196
197 if (fromcol == mincol)
198 return make_number (mincol);
199
200 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
201
202 if (indent_tabs_mode)
203 {
204 Lisp_Object n;
205 XFASTINT (n) = mincol / tab_width - fromcol / tab_width;
206 if (XFASTINT (n) != 0)
207 {
208 Finsert_char (make_number ('\t'), n);
209
210 fromcol = (mincol / tab_width) * tab_width;
211 }
212 }
213
214 XFASTINT (col) = mincol - fromcol;
215 Finsert_char (make_number (' '), col);
216
217 last_known_column = mincol;
218 last_known_column_point = point;
219 last_known_column_modified = MODIFF;
220
221 XSETINT (col, mincol);
222 return col;
223}
224\f
225DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
226 0, 0, 0,
227 "Return the indentation of the current line.\n\
228This is the horizontal position of the character\n\
229following any initial whitespace.")
230 ()
231{
232 Lisp_Object val;
233
234 XFASTINT (val) = position_indentation (find_next_newline (point, -1));
235 return val;
236}
237
238position_indentation (pos)
239 register int pos;
240{
241 register int column = 0;
242 register int tab_width = XINT (current_buffer->tab_width);
243 register unsigned char *p;
244 register unsigned char *stop;
245
246 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
247
248 stop = &FETCH_CHAR (BUFFER_CEILING_OF (pos)) + 1;
249 p = &FETCH_CHAR (pos);
250 while (1)
251 {
252 while (p == stop)
253 {
254 if (pos == ZV)
255 return column;
256 pos += p - &FETCH_CHAR (pos);
257 p = &FETCH_CHAR (pos);
258 stop = &FETCH_CHAR (BUFFER_CEILING_OF (pos)) + 1;
259 }
260 switch (*p++)
261 {
262 case ' ':
263 column++;
264 break;
265 case '\t':
266 column += tab_width - column % tab_width;
267 break;
268 default:
269 return column;
270 }
271 }
272}
273\f
274DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, 0,
275 "Move point to column COLUMN in the current line.\n\
276The column of a character is calculated by adding together the widths\n\
277as displayed of the previous characters in the line.\n\
278This function ignores line-continuation;\n\
279there is no upper limit on the column number a character can have\n\
230a4cbd
JB
280and horizontal scrolling has no effect.\n\
281\n\
993b6404
JB
282If specified column is within a character, point goes after that character.\n\
283If it's past end of line, point goes to end of line.\n\n\
284A non-nil second (optional) argument FORCE means, if the line\n\
285is too short to reach column COLUMN then add spaces/tabs to get there,\n\
286and if COLUMN is in the middle of a tab character, change it to spaces.")
287 (column, force)
288 Lisp_Object column, force;
289{
290 register int pos;
291 register int col = current_column ();
292 register int goal;
293 register int end;
294 register int tab_width = XINT (current_buffer->tab_width);
56a98455 295 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
993b6404
JB
296 register struct Lisp_Vector *dp = buffer_display_table ();
297
298 Lisp_Object val;
299 int prev_col;
300 int c;
301
302 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
303 CHECK_NATNUM (column, 0);
304 goal = XINT (column);
305
306 retry:
307 pos = point;
308 end = ZV;
309
310 /* If we're starting past the desired column,
311 back up to beginning of line and scan from there. */
312 if (col > goal)
313 {
314 pos = find_next_newline (pos, -1);
315 col = 0;
316 }
317
318 while (col < goal && pos < end)
319 {
320 c = FETCH_CHAR (pos);
321 if (c == '\n')
322 break;
323 if (c == '\r' && EQ (current_buffer->selective_display, Qt))
324 break;
325 pos++;
326 if (c == '\t')
327 {
328 prev_col = col;
329 col += tab_width;
330 col = col / tab_width * tab_width;
331 }
332 else if (dp != 0 && XTYPE (DISP_CHAR_ROPE (dp, c)) == Lisp_String)
333 col += XSTRING (DISP_CHAR_ROPE (dp, c))->size / sizeof (GLYPH);
334 else if (ctl_arrow && (c < 040 || c == 0177))
335 col++;
336 else if (c < 040 || c >= 0177)
337 col += 3;
338 else
339 col++;
340 }
341
342 SET_PT (pos);
343
344 /* If a tab char made us overshoot, change it to spaces
345 and scan through it again. */
56a98455 346 if (!NILP (force) && col > goal && c == '\t' && prev_col < goal)
993b6404 347 {
70ee42f7
JB
348 int old_point;
349
993b6404 350 del_range (point - 1, point);
70ee42f7
JB
351 Findent_to (make_number (goal), Qnil);
352 old_point = point;
353 Findent_to (make_number (col), Qnil);
354 SET_PT (old_point);
993b6404
JB
355 }
356
357 /* If line ends prematurely, add space to the end. */
56a98455 358 if (col < goal && !NILP (force))
230a4cbd 359 Findent_to (make_number (col = goal), Qnil);
993b6404
JB
360
361 last_known_column = col;
362 last_known_column_point = point;
363 last_known_column_modified = MODIFF;
364
365 XFASTINT (val) = col;
366 return val;
367}
368\f
369struct position val_compute_motion;
370
371/* Scan the current buffer forward from offset FROM, pretending that
372 this is at line FROMVPOS, column FROMHPOS, until reaching buffer
373 offset TO or line TOVPOS, column TOHPOS (whichever comes first),
374 and return the ending buffer position and screen location.
375
376 WIDTH is the number of columns available to display text;
377 compute_motion uses this to handle continuation lines and such.
378 HSCROLL is the number of columns not being displayed at the left
379 margin; this is usually taken from a window's hscroll member.
a9764248
JB
380 TAB_OFFSET is the number of columns of the first tab that aren't
381 being displayed, perhaps because of a continuation line or
382 something.
993b6404
JB
383
384 compute_motion returns a pointer to a struct position. The bufpos
385 member gives the buffer position at the end of the scan, and hpos
386 and vpos give its cartesian location. I'm not clear on what the
387 other members are.
388
389 For example, to find the buffer position of column COL of line LINE
390 of a certain window, pass the window's starting location as FROM
391 and the window's upper-left coordinates as FROMVPOS and FROMHPOS.
392 Pass the buffer's ZV as TO, to limit the scan to the end of the
393 visible section of the buffer, and pass LINE and COL as TOVPOS and
394 TOHPOS.
395
396 When displaying in window w, a typical formula for WIDTH is:
397
398 window_width - 1
fa61c701
JB
399 - (has_vertical_scrollbars
400 ? VERTICAL_SCROLLBAR_WIDTH
401 : (window_width + window_left != frame_width))
993b6404
JB
402
403 where
404 window_width is XFASTINT (w->width),
405 window_left is XFASTINT (w->left),
fa61c701
JB
406 has_vertical_scrollbars is
407 FRAME_HAS_VERTICAL_SCROLLBARS (XFRAME (WINDOW_FRAME (window)))
408 and frame_width = FRAME_WIDTH (XFRAME (window->frame))
993b6404 409
fa61c701
JB
410 Or,
411 window_internal_width (w) - 1
412
413 The `-1' accounts for the continuation-line backslashes; the rest
414 accounts for window borders if the window is split vertically, and
415 the scrollbars if the frame supports them. */
993b6404
JB
416
417struct position *
418compute_motion (from, fromvpos, fromhpos, to, tovpos, tohpos, width, hscroll, tab_offset)
419 int from, fromvpos, fromhpos, to, tovpos, tohpos;
420 register int width;
421 int hscroll, tab_offset;
422{
cde9337b
JB
423 register int hpos = fromhpos;
424 register int vpos = fromvpos;
425
993b6404
JB
426 register int pos;
427 register int c;
428 register int tab_width = XFASTINT (current_buffer->tab_width);
56a98455 429 register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
993b6404
JB
430 register struct Lisp_Vector *dp = buffer_display_table ();
431 int selective
432 = XTYPE (current_buffer->selective_display) == Lisp_Int
433 ? XINT (current_buffer->selective_display)
56a98455 434 : !NILP (current_buffer->selective_display) ? -1 : 0;
cde9337b 435 int prev_vpos, prev_hpos;
993b6404
JB
436 int selective_rlen
437 = (selective && dp && XTYPE (DISP_INVIS_ROPE (dp)) == Lisp_String
438 ? XSTRING (DISP_INVIS_ROPE (dp))->size / sizeof (GLYPH) : 0);
439
440 if (tab_width <= 0 || tab_width > 20) tab_width = 8;
cde9337b 441 for (pos = from; pos < to; pos++)
993b6404 442 {
cde9337b
JB
443 /* Stop if past the target screen position. */
444 if (vpos > tovpos
445 || (vpos == tovpos && hpos >= tohpos))
446 break;
447
448 prev_vpos = vpos;
449 prev_hpos = hpos;
450
993b6404
JB
451 c = FETCH_CHAR (pos);
452 if (c >= 040 && c < 0177
453 && (dp == 0 || XTYPE (DISP_CHAR_ROPE (dp, c)) != Lisp_String))
cde9337b 454 hpos++;
993b6404
JB
455 else if (c == '\t')
456 {
cde9337b
JB
457 hpos += tab_width - ((hpos + tab_offset + hscroll - (hscroll > 0)
458 /* Add tab_width here to make sure positive.
459 hpos can be negative after continuation
460 but can't be less than -tab_width. */
461 + tab_width)
462 % tab_width);
993b6404
JB
463 }
464 else if (c == '\n')
465 {
466 if (selective > 0 && position_indentation (pos + 1) >= selective)
467 {
468 /* Skip any number of invisible lines all at once */
469 do
470 {
cde9337b 471 while (++pos < to && FETCH_CHAR (pos) != '\n');
993b6404 472 }
e51eab7c 473 while (pos < to && position_indentation (pos + 1) >= selective);
993b6404
JB
474 pos--;
475 /* Allow for the " ..." that is displayed for them. */
476 if (selective_rlen)
477 {
cde9337b
JB
478 hpos += selective_rlen;
479 if (hpos >= width)
480 hpos = width;
993b6404 481 }
e51eab7c 482 /* We have skipped the invis text, but not the newline after. */
993b6404
JB
483 }
484 else
cde9337b
JB
485 {
486 /* A visible line. */
487 vpos++;
488 hpos = 0;
46947372
JB
489 hpos -= hscroll;
490 if (hscroll > 0) hpos++; /* Count the ! on column 0 */
491 tab_offset = 0;
492 }
993b6404
JB
493 }
494 else if (c == CR && selective < 0)
495 {
496 /* In selective display mode,
497 everything from a ^M to the end of the line is invisible */
cde9337b
JB
498 while (pos < to && FETCH_CHAR (pos) != '\n') pos++;
499 /* Stop *before* the real newline. */
993b6404
JB
500 pos--;
501 /* Allow for the " ..." that is displayed for them. */
502 if (selective_rlen)
503 {
cde9337b
JB
504 hpos += selective_rlen;
505 if (hpos >= width)
506 hpos = width;
993b6404
JB
507 }
508 }
509 else if (dp != 0 && XTYPE (DISP_CHAR_ROPE (dp, c)) == Lisp_String)
cde9337b 510 hpos += XSTRING (DISP_CHAR_ROPE (dp, c))->size / sizeof (GLYPH);
993b6404 511 else
cde9337b 512 hpos += (ctl_arrow && c < 0200) ? 2 : 4;
993b6404 513
cde9337b
JB
514 /* Handle right margin. */
515 if (hpos >= width
516 && (hpos > width
517 || (pos < ZV - 1
993b6404
JB
518 && FETCH_CHAR (pos + 1) != '\n')))
519 {
cde9337b
JB
520 if (vpos > tovpos
521 || (vpos == tovpos && hpos >= tohpos))
993b6404
JB
522 break;
523 if (hscroll
524 || (truncate_partial_width_windows
502b9b64 525 && width + 1 < FRAME_WIDTH (selected_frame))
56a98455 526 || !NILP (current_buffer->truncate_lines))
993b6404 527 {
cde9337b
JB
528 /* Truncating: skip to newline. */
529 while (pos < to && FETCH_CHAR (pos) != '\n') pos++;
993b6404 530 pos--;
e51eab7c 531 hpos = width;
993b6404
JB
532 }
533 else
534 {
cde9337b
JB
535 /* Continuing. */
536 vpos++;
537 hpos -= width;
993b6404
JB
538 tab_offset += width;
539 }
540
541 }
542 }
543
544 val_compute_motion.bufpos = pos;
cde9337b
JB
545 val_compute_motion.hpos = hpos;
546 val_compute_motion.vpos = vpos;
547 val_compute_motion.prevhpos = prev_hpos;
993b6404
JB
548
549 /* Nonzero if have just continued a line */
550 val_compute_motion.contin
cde9337b
JB
551 = (pos != from
552 && (val_compute_motion.vpos != prev_vpos)
553 && c != '\n');
993b6404
JB
554
555 return &val_compute_motion;
556}
993b6404
JB
557
558\f
559/* Return the column of position POS in window W's buffer,
560 rounded down to a multiple of the internal width of W.
561 This is the amount of indentation of position POS
562 that is not visible in its horizontal position in the window. */
563
564int
565pos_tab_offset (w, pos)
566 struct window *w;
567 register int pos;
568{
569 int opoint = point;
570 int col;
fa61c701 571 int width = window_internal_width (w) - 1;
993b6404
JB
572
573 if (pos == BEGV || FETCH_CHAR (pos - 1) == '\n')
574 return 0;
575 SET_PT (pos);
576 col = current_column ();
577 SET_PT (opoint);
578 return col - (col % width);
579}
580
581/* start_hpos is the hpos of the first character of the buffer:
582 zero except for the minibuffer window,
583 where it is the width of the prompt. */
584
585struct position val_vmotion;
586
587struct position *
588vmotion (from, vtarget, width, hscroll, window)
589 register int from, vtarget, width;
590 int hscroll;
591 Lisp_Object window;
592{
593 struct position pos;
594 /* vpos is cumulative vertical position, changed as from is changed */
595 register int vpos = 0;
596 register int prevline;
597 register int first;
598 int lmargin = hscroll > 0 ? 1 - hscroll : 0;
599 int selective
600 = XTYPE (current_buffer->selective_display) == Lisp_Int
601 ? XINT (current_buffer->selective_display)
56a98455 602 : !NILP (current_buffer->selective_display) ? -1 : 0;
993b6404
JB
603 int start_hpos = (EQ (window, minibuf_window) ? minibuf_prompt_width : 0);
604
605 retry:
606 if (vtarget > vpos)
607 {
608 /* Moving downward is simple, but must calculate from beg of line
609 to determine hpos of starting point */
610 if (from > BEGV && FETCH_CHAR (from - 1) != '\n')
611 {
612 prevline = find_next_newline (from, -1);
613 while (selective > 0
614 && prevline > BEGV
615 && position_indentation (prevline) >= selective)
616 prevline = find_next_newline (prevline - 1, -1);
617 pos = *compute_motion (prevline, 0,
618 lmargin + (prevline == 1 ? start_hpos : 0),
cde9337b 619 from, 1 << (INTBITS - 2), 0,
993b6404
JB
620 width, hscroll, 0);
621 }
622 else
623 {
624 pos.hpos = lmargin + (from == 1 ? start_hpos : 0);
625 pos.vpos = 0;
626 }
627 return compute_motion (from, vpos, pos.hpos,
cde9337b 628 ZV, vtarget, - (1 << (INTBITS - 2)),
993b6404
JB
629 width, hscroll, pos.vpos * width);
630 }
631
632 /* To move upward, go a line at a time until
633 we have gone at least far enough */
634
635 first = 1;
636
637 while ((vpos > vtarget || first) && from > BEGV)
638 {
639 prevline = from;
640 while (1)
641 {
642 prevline = find_next_newline (prevline - 1, -1);
643 if (prevline == BEGV
644 || selective <= 0
645 || position_indentation (prevline) < selective)
646 break;
647 }
648 pos = *compute_motion (prevline, 0,
649 lmargin + (prevline == 1 ? start_hpos : 0),
cde9337b 650 from, 1 << (INTBITS - 2), 0,
993b6404
JB
651 width, hscroll, 0);
652 vpos -= pos.vpos;
653 first = 0;
654 from = prevline;
655 }
656
657 /* If we made exactly the desired vertical distance,
658 or if we hit beginning of buffer,
659 return point found */
660 if (vpos >= vtarget)
661 {
662 val_vmotion.bufpos = from;
663 val_vmotion.vpos = vpos;
664 val_vmotion.hpos = lmargin;
665 val_vmotion.contin = 0;
666 val_vmotion.prevhpos = 0;
667 return &val_vmotion;
668 }
669
670 /* Otherwise find the correct spot by moving down */
671 goto retry;
672}
673
674DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 1, 0,
675 "Move to start of screen line LINES lines down.\n\
676If LINES is negative, this is moving up.\n\
677Sets point to position found; this may be start of line\n\
678 or just the start of a continuation line.\n\
679Returns number of lines moved; may be closer to zero than LINES\n\
680 if beginning or end of buffer was reached.")
681 (lines)
682 Lisp_Object lines;
683{
684 struct position pos;
685 register struct window *w = XWINDOW (selected_window);
fa61c701 686 int width = window_internal_width (w) - 1;
993b6404
JB
687
688 CHECK_NUMBER (lines, 0);
689
690 pos = *vmotion (point, XINT (lines), width,
691 /* Not XFASTINT since perhaps could be negative */
692 XINT (w->hscroll), selected_window);
693
694 SET_PT (pos.bufpos);
695 return make_number (pos.vpos);
696}
697\f
698syms_of_indent ()
699{
700 DEFVAR_BOOL ("indent-tabs-mode", &indent_tabs_mode,
701 "*Indentation can insert tabs if this is non-nil.\n\
702Setting this variable automatically makes it local to the current buffer.");
703 indent_tabs_mode = 1;
704
705 defsubr (&Scurrent_indentation);
706 defsubr (&Sindent_to);
707 defsubr (&Scurrent_column);
708 defsubr (&Smove_to_column);
709 defsubr (&Svertical_motion);
710}