Skip to content

Commit

Permalink
Add :retab command
Browse files Browse the repository at this point in the history
See "Changing tabs" section in the Vim manual
https://vimhelp.org/change.txt.html#change.txt
  • Loading branch information
FrostyX authored and tomdl89 committed Dec 18, 2023
1 parent eced308 commit fc6bd00
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
17 changes: 17 additions & 0 deletions evil-commands.el
Original file line number Diff line number Diff line change
Expand Up @@ -5172,6 +5172,23 @@ event that triggered the execution of this command."
(push event unread-command-events)))
(evil-declare-ignore-repeat 'evil-exit-visual-and-repeat)

(evil-define-command evil-retab (tabstop)
"Convert all tabs to spaces or the other way around.
Replace all sequences of white-space containing a <Tab> with new
strings of white-space using the new TABSTOP value given.
If you do not specify a new TABSTOP size or it is zero, Evil uses the
current value of `tab-width'."
(interactive "<a>")
(unless (or (not tabstop) (string-match-p "^[0-9]*$" tabstop))
(user-error "Invalid argument: %s" tabstop))
(let ((beg (if (use-region-p) (region-beginning) (point-min)))
(end (if (use-region-p) (region-end) (point-max)))
(retab (if indent-tabs-mode #'tabify #'untabify))
(tab-width (cond ((not tabstop) tab-width)
((equal tabstop "0") tab-width)
(t (string-to-number tabstop)))))
(funcall retab beg end)))

(provide 'evil-commands)

;;; evil-commands.el ends here
1 change: 1 addition & 0 deletions evil-maps.el
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ included in `evil-insert-state-bindings' by default."
(evil-ex-define-cmd "nu[mber]" 'evil-ex-numbered-print)
(evil-ex-define-cmd "#" 'evil-ex-numbered-print)
(evil-ex-define-cmd "z" 'evil-ex-z)
(evil-ex-define-cmd "ret[ab]" 'evil-retab)

(when (featurep 'tab-bar)
(evil-ex-define-cmd "tabnew" 'tab-bar-new-tab)
Expand Down
43 changes: 43 additions & 0 deletions evil-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -9809,6 +9809,49 @@ main(argc, argv) char **argv; {
(should (equal evil-input-method "german-prefix"))))
(remove-hook 'text-mode-hook #'use-german-input-method))))

(ert-deftest evil-retab ()
"Test the :retab command"
:tags '(evil)
(ert-info ("From tabs to spaces")
(evil-test-buffer
"def foo():\n\twhile True:\n\t\treturn\n"
(setq indent-tabs-mode nil)
(setq tab-width 4)
(":retab" [return])
"def foo():\n while True:\n return\n"))
(ert-info ("From spaces to tabs")
(evil-test-buffer
"def foo():\n while True:\n return\n"
(setq indent-tabs-mode t)
(setq tab-width 4)
(":retab" [return])
"def foo():\n\twhile True:\n\t\treturn\n"))
(ert-info ("Specify tab width as an argument")
(evil-test-buffer
"def foo():\n\twhile True:\n\t\treturn\n"
(setq indent-tabs-mode nil)
(setq tab-width 4)
(":retab 2" [return])
"def foo():\n while True:\n return\n"))
(ert-info ("Invalid argument")
(evil-test-buffer
"def foo():\n\twhile True:\n\t\treturn\n"
(should-error (execute-kbd-macro ":retab foo" [return])))))

(ert-deftest evil-retab-visual ()
"Test the :retab command on visual line selection.
This test fails in the batch mode (and therefore in the GitHub CI)
but it works fine in `M-x ert-run-tests-interactively'."
:tags '(evil visual)
(skip-unless (not noninteractive))
(ert-info ("Retab only selected lines")
(evil-test-buffer
"def foo():\n\twhile True:\n\t\treturn\n"
(setq indent-tabs-mode nil)
(setq tab-width 4)
("Vj" ":retab" [return])
"def foo():\n while True:\n\t\treturn\n")))

(provide 'evil-tests)

;;; evil-tests.el ends here

0 comments on commit fc6bd00

Please sign in to comment.