(completion-ignored-extensions): Add .p64fsl, .d64fsl, and .dx64fsl.
[bpt/emacs.git] / lisp / indent.el
CommitLineData
1a06eabd
ER
1;;; indent.el --- indentation commands for Emacs
2
0d30b337 3;; Copyright (C) 1985, 1995, 2001, 2002, 2003, 2004,
409cc4a3 4;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
483e630e 5
9750e079
ER
6;; Maintainer: FSF
7
483e630e
RM
8;; This file is part of GNU Emacs.
9
eb3fa2cf 10;; GNU Emacs is free software: you can redistribute it and/or modify
483e630e 11;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
483e630e
RM
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
eb3fa2cf 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
483e630e 22
e41b2db1
ER
23;;; Commentary:
24
25;; Commands for making and changing indentation in text. These are
26;; described in the Emacs manual.
27
e5167999 28;;; Code:
483e630e 29
ddb3136e 30(defgroup indent nil
21751995 31 "Indentation commands."
ddb3136e 32 :group 'editing)
106b6d0e 33
ddb3136e
RS
34(defcustom standard-indent 4
35 "*Default number of columns for margin-changing functions to indent."
36 :group 'indent
37 :type 'integer)
38
f059f703 39(defvar indent-line-function 'indent-relative
a17b712b
SM
40 "Function to indent the current line.
41This function will be called with no arguments.
42If it is called somewhere where auto-indentation cannot be done
43\(f.ex. inside a string), the function should simply return `noindent'.
44Setting this function is all you need to make TAB indent appropriately.
45Don't rebind TAB unless you really need to.")
483e630e 46
20b1d079
SM
47(defcustom tab-always-indent t
48 "*Controls the operation of the TAB key.
49If t, hitting TAB always just indents the current line.
50If nil, hitting TAB indents the current line if point is at the left margin
9450aaa0
SM
51or in the line's indentation, otherwise it inserts a \"real\" TAB character.
52Some programming language modes have their own variable to control this,
f321348b 53e.g., `c-tab-always-indent', and do not respect this variable."
20b1d079 54 :group 'indent
fe552b4c 55 :type '(choice (const nil) (const t) (const always)))
20b1d079 56
483e630e 57(defun indent-according-to-mode ()
1a2f8b73
RS
58 "Indent line in proper way for current major mode.
59The buffer-local variable `indent-line-function' determines how to do this,
60but the functions `indent-relative' and `indent-relative-maybe' are
61special; we don't actually use them here."
483e630e 62 (interactive)
a17b712b
SM
63 (if (memq indent-line-function
64 '(indent-relative indent-relative-maybe))
65 ;; These functions are used for tabbing, but can't be used for
66 ;; indenting. Replace with something ad-hoc.
67 (let ((column (save-excursion
68 (beginning-of-line)
69 (skip-chars-backward "\n \t")
70 (beginning-of-line)
71 (current-indentation))))
72 (if (<= (current-column) (current-indentation))
73 (indent-line-to column)
74 (save-excursion (indent-line-to column))))
75 ;; The normal case.
76 (funcall indent-line-function)))
483e630e 77
a17b712b 78(defun indent-for-tab-command (&optional arg)
6dd697d9 79 "Indent line or region in proper way for current major mode or insert a tab.
20b1d079 80Depending on `tab-always-indent', either insert a tab or indent.
b9ce5694
GM
81If initial point was within line's indentation, position after
82the indentation. Else stay at same point in text.
1225a933
MB
83
84If a prefix argument is given, also rigidly indent the entire
85balanced expression which starts at the beginning the current
86line to reflect the current line's change in indentation.
87
d6a4ad74 88If `transient-mark-mode' is turned on and the region is active,
1225a933
MB
89indent the region (in this case, any prefix argument is ignored).
90
6dd697d9 91The function actually called to indent the line is determined by the value of
eca1e29e 92`indent-line-function'."
1225a933 93 (interactive "P")
a17b712b 94 (cond
17ee4625 95 ;; The region is active, indent it.
1225a933 96 ((and transient-mark-mode mark-active
17ee4625
DN
97 (not (eq (region-beginning) (region-end))))
98 (indent-region (region-beginning) (region-end)))
fe552b4c 99 ((or ;; indent-to-left-margin is only meant for indenting,
a17b712b
SM
100 ;; so we force it to always insert a tab here.
101 (eq indent-line-function 'indent-to-left-margin)
102 (and (not tab-always-indent)
f202a7a2
SM
103 (or (> (current-column) (current-indentation))
104 (eq this-command last-command))))
a17b712b 105 (insert-tab arg))
6dd697d9 106 (t
1225a933
MB
107 (let ((end-marker
108 (and arg
109 (save-excursion
110 (forward-line 0) (forward-sexp) (point-marker))))
111 (old-indent
112 (current-indentation)))
113
114 ;; Indent the line.
115 (funcall indent-line-function)
116
117 ;; If a prefix argument was given, rigidly indent the following
118 ;; sexp to match the change in the current line's indentation.
119 ;;
120 (when arg
121 (let ((indentation-change (- (current-indentation) old-indent)))
122 (unless (zerop indentation-change)
123 (save-excursion
124 (forward-line 1)
125 (when (< (point) end-marker)
126 (indent-rigidly (point) end-marker indentation-change))))))))))
a17b712b
SM
127
128(defun insert-tab (&optional arg)
129 (let ((count (prefix-numeric-value arg)))
5e9f80a8
RS
130 (if (and abbrev-mode
131 (eq (char-syntax (preceding-char)) ?w))
10992b01
RS
132 (expand-abbrev))
133 (if indent-tabs-mode
4424ce6f 134 (insert-char ?\t count)
10992b01 135 (indent-to (* tab-width (+ count (/ (current-column) tab-width)))))))
483e630e
RM
136
137(defun indent-rigidly (start end arg)
138 "Indent all lines starting in the region sideways by ARG columns.
5a0f9388
EZ
139Called from a program, takes three arguments, START, END and ARG.
140You can remove all indentation from a region by giving a large negative ARG."
483e630e
RM
141 (interactive "r\np")
142 (save-excursion
143 (goto-char end)
144 (setq end (point-marker))
145 (goto-char start)
146 (or (bolp) (forward-line 1))
147 (while (< (point) end)
c1194ae8
RS
148 (let ((indent (current-indentation))
149 eol-flag)
150 (save-excursion
151 (skip-chars-forward " \t")
152 (setq eol-flag (eolp)))
153 (or eol-flag
154 (indent-to (max 0 (+ indent arg)) 0))
155 (delete-region (point) (progn (skip-chars-forward " \t") (point))))
483e630e
RM
156 (forward-line 1))
157 (move-marker end nil)))
158
106b6d0e
RS
159(defun indent-line-to (column)
160 "Indent current line to COLUMN.
161This function removes or adds spaces and tabs at beginning of line
162only if necessary. It leaves point at end of indentation."
ca2a3cb7
BG
163 (back-to-indentation)
164 (let ((cur-col (current-column)))
165 (cond ((< cur-col column)
cd6d305e 166 (if (>= (- column (* (/ cur-col tab-width) tab-width)) tab-width)
a80a30b3
RS
167 (delete-region (point)
168 (progn (skip-chars-backward " ") (point))))
ca2a3cb7
BG
169 (indent-to column))
170 ((> cur-col column) ; too far right (after tab?)
34c3f2b8 171 (delete-region (progn (move-to-column column t) (point))
ca2a3cb7 172 (progn (back-to-indentation) (point)))))))
106b6d0e
RS
173
174(defun current-left-margin ()
175 "Return the left margin to use for this line.
176This is the value of the buffer-local variable `left-margin' plus the value
177of the `left-margin' text-property at the start of the line."
178 (save-excursion
179 (back-to-indentation)
180 (max 0
34c3f2b8
BG
181 (+ left-margin (or (get-text-property
182 (if (and (eobp) (not (bobp)))
183 (1- (point)) (point))
184 'left-margin) 0)))))
106b6d0e 185
34c3f2b8 186(defun move-to-left-margin (&optional n force)
106b6d0e
RS
187 "Move to the left margin of the current line.
188With optional argument, move forward N-1 lines first.
34c3f2b8
BG
189The column moved to is the one given by the `current-left-margin' function.
190If the line's indentation appears to be wrong, and this command is called
191interactively or with optional argument FORCE, it will be fixed."
192 (interactive (list (prefix-numeric-value current-prefix-arg) t))
106b6d0e 193 (beginning-of-line n)
54505d72 194 (skip-chars-forward " \t")
1d1c5af9
RS
195 (if (minibufferp (current-buffer))
196 (if (save-excursion (beginning-of-line) (bobp))
197 (goto-char (minibuffer-prompt-end))
198 (beginning-of-line))
199 (let ((lm (current-left-margin))
200 (cc (current-column)))
201 (cond ((> cc lm)
202 (if (> (move-to-column lm force) lm)
203 ;; If lm is in a tab and we are not forcing, move before tab
204 (backward-char 1)))
205 ((and force (< cc lm))
206 (indent-to-left-margin))))))
106b6d0e 207
f202a7a2 208;; This used to be the default indent-line-function,
483e630e
RM
209;; used in Fundamental Mode, Text Mode, etc.
210(defun indent-to-left-margin ()
34c3f2b8 211 "Indent current line to the column given by `current-left-margin'."
caadec43
RS
212 (save-excursion (indent-line-to (current-left-margin)))
213 ;; If we are within the indentation, move past it.
214 (when (save-excursion
215 (skip-chars-backward " \t")
216 (bolp))
217 (skip-chars-forward " \t")))
106b6d0e 218
34c3f2b8
BG
219(defun delete-to-left-margin (&optional from to)
220 "Remove left margin indentation from a region.
221This deletes to the column given by `current-left-margin'.
222In no case will it delete non-whitespace.
223Args FROM and TO are optional; default is the whole buffer."
106b6d0e 224 (save-excursion
34c3f2b8 225 (goto-char (or to (point-max)))
106b6d0e 226 (setq to (point-marker))
34c3f2b8 227 (goto-char (or from (point-min)))
106b6d0e
RS
228 (or (bolp) (forward-line 1))
229 (while (< (point) to)
34c3f2b8 230 (delete-region (point) (progn (move-to-left-margin nil t) (point)))
106b6d0e
RS
231 (forward-line 1))
232 (move-marker to nil)))
233
a5b3d1b8 234(defun set-left-margin (from to width)
106b6d0e 235 "Set the left margin of the region to WIDTH.
a5b3d1b8
LT
236If `auto-fill-mode' is active, re-fill the region to fit the new margin.
237
238Interactively, WIDTH is the prefix argument, if specified.
239Without prefix argument, the command prompts for WIDTH."
106b6d0e 240 (interactive "r\nNSet left margin to column: ")
106b6d0e
RS
241 (save-excursion
242 ;; If inside indentation, start from BOL.
243 (goto-char from)
244 (skip-chars-backward " \t")
245 (if (bolp) (setq from (point)))
34c3f2b8 246 ;; Place end after whitespace
106b6d0e 247 (goto-char to)
34c3f2b8 248 (skip-chars-forward " \t")
106b6d0e 249 (setq to (point-marker)))
34c3f2b8
BG
250 ;; Delete margin indentation first, but keep paragraph indentation.
251 (delete-to-left-margin from to)
a5b3d1b8
LT
252 (put-text-property from to 'left-margin width)
253 (indent-rigidly from to width)
34c3f2b8 254 (if auto-fill-function (save-excursion (fill-region from to nil t t)))
106b6d0e
RS
255 (move-marker to nil))
256
a5b3d1b8 257(defun set-right-margin (from to width)
106b6d0e 258 "Set the right margin of the region to WIDTH.
a5b3d1b8
LT
259If `auto-fill-mode' is active, re-fill the region to fit the new margin.
260
261Interactively, WIDTH is the prefix argument, if specified.
262Without prefix argument, the command prompts for WIDTH."
8cf19007 263 (interactive "r\nNSet right margin to width: ")
106b6d0e
RS
264 (save-excursion
265 (goto-char from)
266 (skip-chars-backward " \t")
267 (if (bolp) (setq from (point))))
a5b3d1b8 268 (put-text-property from to 'right-margin width)
34c3f2b8 269 (if auto-fill-function (save-excursion (fill-region from to nil t t))))
106b6d0e
RS
270
271(defun alter-text-property (from to prop func &optional object)
272 "Programmatically change value of a text-property.
273For each region between FROM and TO that has a single value for PROPERTY,
274apply FUNCTION to that value and sets the property to the function's result.
275Optional fifth argument OBJECT specifies the string or buffer to operate on."
276 (let ((begin from)
277 end val)
278 (while (setq val (get-text-property begin prop object)
279 end (text-property-not-all begin to prop val object))
280 (put-text-property begin end prop (funcall func val) object)
281 (setq begin end))
282 (if (< begin to)
283 (put-text-property begin to prop (funcall func val) object))))
284
285(defun increase-left-margin (from to inc)
286 "Increase or decrease the left-margin of the region.
287With no prefix argument, this adds `standard-indent' of indentation.
288A prefix arg (optional third arg INC noninteractively) specifies the amount
289to change the margin by, in characters.
290If `auto-fill-mode' is active, re-fill the region to fit the new margin."
291 (interactive "*r\nP")
292 (setq inc (if inc (prefix-numeric-value inc) standard-indent))
293 (save-excursion
294 (goto-char from)
295 (skip-chars-backward " \t")
296 (if (bolp) (setq from (point)))
297 (goto-char to)
298 (setq to (point-marker)))
106b6d0e 299 (alter-text-property from to 'left-margin
34c3f2b8
BG
300 (lambda (v) (max (- left-margin) (+ inc (or v 0)))))
301 (indent-rigidly from to inc)
302 (if auto-fill-function (save-excursion (fill-region from to nil t t)))
106b6d0e
RS
303 (move-marker to nil))
304
305(defun decrease-left-margin (from to inc)
306 "Make the left margin of the region smaller.
307With no prefix argument, decrease the indentation by `standard-indent'.
308A prefix arg (optional third arg INC noninteractively) specifies the amount
309to change the margin by, in characters.
310If `auto-fill-mode' is active, re-fill the region to fit the new margin."
311 (interactive "*r\nP")
312 (setq inc (if inc (prefix-numeric-value inc) standard-indent))
313 (increase-left-margin from to (- inc)))
314
315(defun increase-right-margin (from to inc)
316 "Increase the right-margin of the region.
317With no prefix argument, increase the right margin by `standard-indent'.
318A prefix arg (optional third arg INC noninteractively) specifies the amount
319to change the margin by, in characters. A negative argument decreases
320the right margin width.
321If `auto-fill-mode' is active, re-fill the region to fit the new margin."
322 (interactive "r\nP")
6faab05f 323 (setq inc (if inc (prefix-numeric-value inc) standard-indent))
106b6d0e
RS
324 (save-excursion
325 (alter-text-property from to 'right-margin
6faab05f 326 (lambda (v) (+ inc (or v 0))))
106b6d0e
RS
327 (if auto-fill-function
328 (fill-region from to nil t t))))
329
330(defun decrease-right-margin (from to inc)
331 "Make the right margin of the region smaller.
332With no prefix argument, decrease the right margin by `standard-indent'.
333A prefix arg (optional third arg INC noninteractively) specifies the amount
334of width to remove, in characters. A negative argument increases
335the right margin width.
336If `auto-fill-mode' is active, re-fills region to fit in new margin."
337 (interactive "*r\nP")
338 (setq inc (if inc (prefix-numeric-value inc) standard-indent))
339 (increase-right-margin from to (- inc)))
483e630e 340
34c3f2b8
BG
341(defun beginning-of-line-text (&optional n)
342 "Move to the beginning of the text on this line.
343With optional argument, move forward N-1 lines first.
344From the beginning of the line, moves past the left-margin indentation, the
345fill-prefix, and any indentation used for centering or right-justifying the
f1180544 346line, but does not move past any whitespace that was explicitly inserted
34c3f2b8
BG
347\(such as a tab used to indent the first line of a paragraph)."
348 (interactive "p")
349 (beginning-of-line n)
350 (skip-chars-forward " \t")
351 ;; Skip over fill-prefix.
f1180544 352 (if (and fill-prefix
34c3f2b8
BG
353 (not (string-equal fill-prefix "")))
354 (if (equal fill-prefix
f1180544 355 (buffer-substring
34c3f2b8
BG
356 (point) (min (point-max) (+ (length fill-prefix) (point)))))
357 (forward-char (length fill-prefix)))
7d43e2ad 358 (if (and adaptive-fill-mode adaptive-fill-regexp
34c3f2b8
BG
359 (looking-at adaptive-fill-regexp))
360 (goto-char (match-end 0))))
361 ;; Skip centering or flushright indentation
362 (if (memq (current-justification) '(center right))
363 (skip-chars-forward " \t")))
364
483e630e 365(defvar indent-region-function nil
3704e77e
RS
366 "Short cut function to indent region using `indent-according-to-mode'.
367A value of nil means really run `indent-according-to-mode' on each line.")
483e630e 368
1d9cc345 369(defun indent-region (start end &optional column)
483e630e 370 "Indent each nonblank line in the region.
1a2f8b73
RS
371A numeric prefix argument specifies a column: indent each line to that column.
372
373With no prefix argument, the command chooses one of these methods and
374indents all the lines with it:
375
376 1) If `fill-prefix' is non-nil, insert `fill-prefix' at the
377 beginning of each line in the region that does not already begin
378 with it.
379 2) If `indent-region-function' is non-nil, call that function
380 to indent the region.
381 3) Indent each line as specified by the variable `indent-line-function'.
382
383Called from a program, START and END specify the region to indent.
384If the third argument COLUMN is an integer, it specifies the
385column to indent to; if it is nil, use one of the three methods above."
483e630e 386 (interactive "r\nP")
88a2603a 387 (if (null column)
483e630e
RM
388 (if fill-prefix
389 (save-excursion
390 (goto-char end)
391 (setq end (point-marker))
392 (goto-char start)
393 (let ((regexp (regexp-quote fill-prefix)))
88a2603a
RS
394 (while (< (point) end)
395 (or (looking-at regexp)
396 (and (bolp) (eolp))
397 (insert fill-prefix))
398 (forward-line 1))))
483e630e
RM
399 (if indent-region-function
400 (funcall indent-region-function start end)
401 (save-excursion
a17b712b 402 (setq end (copy-marker end))
88a2603a 403 (goto-char start)
88a2603a 404 (while (< (point) end)
232acca7 405 (or (and (bolp) (eolp))
88a2603a
RS
406 (funcall indent-line-function))
407 (forward-line 1))
408 (move-marker end nil))))
409 (setq column (prefix-numeric-value column))
483e630e
RM
410 (save-excursion
411 (goto-char end)
412 (setq end (point-marker))
413 (goto-char start)
414 (or (bolp) (forward-line 1))
415 (while (< (point) end)
416 (delete-region (point) (progn (skip-chars-forward " \t") (point)))
417 (or (eolp)
106b6d0e 418 (indent-to column 0))
483e630e
RM
419 (forward-line 1))
420 (move-marker end nil))))
421
422(defun indent-relative-maybe ()
1fd63d9b
EZ
423 "Indent a new line like previous nonblank line.
424If the previous nonblank line has no indent points beyond the
425column point starts at, this command does nothing.
426
427See also `indent-relative'."
483e630e
RM
428 (interactive)
429 (indent-relative t))
430
431(defun indent-relative (&optional unindented-ok)
432 "Space out to under next indent point in previous nonblank line.
433An indent point is a non-whitespace character following whitespace.
f6f53207
RS
434The following line shows the indentation points in this line.
435 ^ ^ ^ ^ ^ ^ ^ ^ ^
483e630e 436If the previous nonblank line has no indent points beyond the
1fd63d9b
EZ
437column point starts at, `tab-to-tab-stop' is done instead, unless
438this command is invoked with a numeric argument, in which case it
439does nothing.
440
441See also `indent-relative-maybe'."
483e630e 442 (interactive "P")
5e9f80a8
RS
443 (if (and abbrev-mode
444 (eq (char-syntax (preceding-char)) ?w))
445 (expand-abbrev))
483e630e
RM
446 (let ((start-column (current-column))
447 indent)
448 (save-excursion
449 (beginning-of-line)
450 (if (re-search-backward "^[^\n]" nil t)
451 (let ((end (save-excursion (forward-line 1) (point))))
452 (move-to-column start-column)
453 ;; Is start-column inside a tab on this line?
454 (if (> (current-column) start-column)
455 (backward-char 1))
456 (or (looking-at "[ \t]")
457 unindented-ok
458 (skip-chars-forward "^ \t" end))
459 (skip-chars-forward " \t" end)
460 (or (= (point) end) (setq indent (current-column))))))
461 (if indent
462 (let ((opoint (point-marker)))
483e630e
RM
463 (indent-to indent 0)
464 (if (> opoint (point))
465 (goto-char opoint))
466 (move-marker opoint nil))
467 (tab-to-tab-stop))))
468
ddb3136e 469(defcustom tab-stop-list
483e630e 470 '(8 16 24 32 40 48 56 64 72 80 88 96 104 112 120)
0f6ca6cf 471 "*List of tab stop positions used by `tab-to-tab-stop'.
ddb3136e
RS
472This should be a list of integers, ordered from smallest to largest."
473 :group 'indent
474 :type '(repeat integer))
44b275c4 475(put 'tab-stop-list 'safe-local-variable 'listp)
483e630e 476
a17b712b
SM
477(defvar edit-tab-stops-map
478 (let ((map (make-sparse-keymap)))
479 (define-key map "\C-x\C-s" 'edit-tab-stops-note-changes)
480 (define-key map "\C-c\C-c" 'edit-tab-stops-note-changes)
481 map)
482 "Keymap used in `edit-tab-stops'.")
483e630e
RM
483
484(defvar edit-tab-stops-buffer nil
bc57b735
LT
485 "Buffer whose tab stops are being edited.
486This matters if the variable `tab-stop-list' is local in that buffer.")
483e630e
RM
487
488(defun edit-tab-stops ()
489 "Edit the tab stops used by `tab-to-tab-stop'.
490Creates a buffer *Tab Stops* containing text describing the tab stops.
491A colon indicates a column where there is a tab stop.
492You can add or remove colons and then do \\<edit-tab-stops-map>\\[edit-tab-stops-note-changes] to make changes take effect."
493 (interactive)
494 (setq edit-tab-stops-buffer (current-buffer))
495 (switch-to-buffer (get-buffer-create "*Tab Stops*"))
496 (use-local-map edit-tab-stops-map)
497 (make-local-variable 'indent-tabs-mode)
498 (setq indent-tabs-mode nil)
499 (overwrite-mode 1)
500 (setq truncate-lines t)
501 (erase-buffer)
502 (let ((tabs tab-stop-list))
503 (while tabs
504 (indent-to (car tabs) 0)
505 (insert ?:)
506 (setq tabs (cdr tabs))))
507 (let ((count 0))
508 (insert ?\n)
509 (while (< count 8)
510 (insert (+ count ?0))
511 (insert " ")
512 (setq count (1+ count)))
513 (insert ?\n)
514 (while (> count 0)
515 (insert "0123456789")
516 (setq count (1- count))))
517 (insert "\nTo install changes, type C-c C-c")
518 (goto-char (point-min)))
519
520(defun edit-tab-stops-note-changes ()
521 "Put edited tab stops into effect."
522 (interactive)
523 (let (tabs)
524 (save-excursion
525 (goto-char 1)
526 (end-of-line)
527 (while (search-backward ":" nil t)
528 (setq tabs (cons (current-column) tabs))))
529 (bury-buffer (prog1 (current-buffer)
530 (switch-to-buffer edit-tab-stops-buffer)))
531 (setq tab-stop-list tabs))
532 (message "Tab stops installed"))
533
534(defun tab-to-tab-stop ()
535 "Insert spaces or tabs to next defined tab-stop column.
536The variable `tab-stop-list' is a list of columns at which there are tab stops.
537Use \\[edit-tab-stops] to edit them interactively."
538 (interactive)
a2964053
RS
539 (and abbrev-mode (= (char-syntax (preceding-char)) ?w)
540 (expand-abbrev))
483e630e
RM
541 (let ((tabs tab-stop-list))
542 (while (and tabs (>= (current-column) (car tabs)))
543 (setq tabs (cdr tabs)))
544 (if tabs
9d840bec 545 (let ((opoint (point)))
19b70460 546 (delete-horizontal-space t)
9d840bec 547 (indent-to (car tabs)))
b379356a 548 (insert ?\s))))
483e630e
RM
549
550(defun move-to-tab-stop ()
551 "Move point to next defined tab-stop column.
fbf8f564
RS
552The variable `tab-stop-list' is a list of columns at which there are tab stops.
553Use \\[edit-tab-stops] to edit them interactively."
554 (interactive)
555 (let ((tabs tab-stop-list))
556 (while (and tabs (>= (current-column) (car tabs)))
557 (setq tabs (cdr tabs)))
558 (if tabs
559 (let ((before (point)))
560 (move-to-column (car tabs) t)
561 (save-excursion
562 (goto-char before)
563 ;; If we just added a tab, or moved over one,
564 ;; delete any superfluous spaces before the old point.
b379356a 565 (if (and (eq (preceding-char) ?\s)
fbf8f564
RS
566 (eq (following-char) ?\t))
567 (let ((tabend (* (/ (current-column) tab-width) tab-width)))
568 (while (and (> (current-column) tabend)
b379356a 569 (eq (preceding-char) ?\s))
fbf8f564
RS
570 (forward-char -1))
571 (delete-region (point) before))))))))
572
483e630e 573(define-key global-map "\t" 'indent-for-tab-command)
a17b712b 574(define-key esc-map "\C-\\" 'indent-region)
483e630e
RM
575(define-key ctl-x-map "\t" 'indent-rigidly)
576(define-key esc-map "i" 'tab-to-tab-stop)
1a06eabd 577
cbee283d 578;; arch-tag: f402b2a7-e44f-492f-b5b8-38996020b7c3
1a06eabd 579;;; indent.el ends here