[TMP] enable load_prefer_newer
[bpt/emacs.git] / lisp / tabify.el
CommitLineData
c88ab9ce
ER
1;;; tabify.el --- tab conversion commands for Emacs
2
ba318903 3;; Copyright (C) 1985, 1994, 2001-2014 Free Software Foundation, Inc.
a2535589 4
34dc21db 5;; Maintainer: emacs-devel@gnu.org
bd78fa1d 6;; Package: emacs
58142744 7
a2535589
JA
8;; This file is part of GNU Emacs.
9
eb3fa2cf 10;; GNU Emacs is free software: you can redistribute it and/or modify
a2535589 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.
a2535589
JA
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/>.
a2535589 22
d9ecc911
ER
23;;; Commentary:
24
25;; Commands to optimize spaces to tabs or expand tabs to spaces in a region
26;; (`tabify' and `untabify'). The variable tab-width does the obvious.
27
22a89ee8 28;;; Code:
a2535589 29
f9f9507e 30;;;###autoload
45fdb482 31(defun untabify (start end &optional _arg)
a2535589 32 "Convert all tabs in region to multiple spaces, preserving columns.
9a08a617
MM
33If called interactively with prefix ARG, convert for the entire
34buffer.
35
e47b2570
RS
36Called non-interactively, the region is specified by arguments
37START and END, rather than by the position of point and mark.
38The variable `tab-width' controls the spacing of tab stops."
9a08a617
MM
39 (interactive (if current-prefix-arg
40 (list (point-min) (point-max) current-prefix-arg)
41 (list (region-beginning) (region-end) nil)))
bead9a43
JB
42 (let ((c (current-column)))
43 (save-excursion
44 (save-restriction
45 (narrow-to-region (point-min) end)
46 (goto-char start)
47 (while (search-forward "\t" nil t) ; faster than re-search
48 (forward-char -1)
49 (let ((tab-beg (point))
50 (indent-tabs-mode nil)
51 column)
52 (skip-chars-forward "\t")
53 (setq column (current-column))
54 (delete-region tab-beg (point))
55 (indent-to column)))))
56 (move-to-column c)))
a2535589 57
49c7d1ac 58(defvar tabify-regexp " [ \t]+"
bb8143d9 59 "Regexp matching whitespace that tabify should consider.
e5b1b45c 60Usually this will be \" [ \\t]+\" to match a space followed by whitespace.
49c7d1ac 61\"^\\t* [ \\t]+\" is also useful, for tabifying only initial whitespace.")
bb8143d9 62
f9f9507e 63;;;###autoload
45fdb482 64(defun tabify (start end &optional _arg)
a2535589
JA
65 "Convert multiple spaces in region to tabs when possible.
66A group of spaces is partially replaced by tabs
67when this can be done without changing the column they end at.
9a08a617
MM
68If called interactively with prefix ARG, convert for the entire
69buffer.
70
e47b2570
RS
71Called non-interactively, the region is specified by arguments
72START and END, rather than by the position of point and mark.
73The variable `tab-width' controls the spacing of tab stops."
9a08a617
MM
74 (interactive (if current-prefix-arg
75 (list (point-min) (point-max) current-prefix-arg)
76 (list (region-beginning) (region-end) nil)))
a2535589
JA
77 (save-excursion
78 (save-restriction
7be313ea
RS
79 ;; Include the beginning of the line in the narrowing
80 ;; since otherwise it will throw off current-column.
81 (goto-char start)
82 (beginning-of-line)
83 (narrow-to-region (point) end)
a2535589 84 (goto-char start)
49c7d1ac
SM
85 (let ((indent-tabs-mode t))
86 (while (re-search-forward tabify-regexp nil t)
87 ;; The region between (match-beginning 0) and (match-end 0) is just
88 ;; spacing which we want to adjust to use TABs where possible.
89 (let ((end-col (current-column))
90 (beg-col (save-excursion (goto-char (match-beginning 0))
91 (skip-chars-forward "\t")
92 (current-column))))
93 (if (= (/ end-col tab-width) (/ beg-col tab-width))
94 ;; The spacing (after some leading TABs which we wouldn't
95 ;; want to touch anyway) does not straddle a TAB boundary,
96 ;; so it neither contains a TAB, nor will we be able to use
97 ;; a TAB here anyway: there's nothing to do.
98 nil
99 (delete-region (match-beginning 0) (point))
100 (indent-to end-col))))))))
c88ab9ce 101
85588571
RS
102(provide 'tabify)
103
c88ab9ce 104;;; tabify.el ends here