-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathevil-set-option.el
204 lines (159 loc) · 6.62 KB
/
evil-set-option.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
;;; evil-set-option.el --- Support for :set wrap, :set number, and more
;; Copyright (C) 2022 Jakub Kadlčík
;; Author: Jakub Kadlčík <[email protected]>
;; URL: https://github.com/FrostyX/evil-set-option
;; Version: 0.1
;; Package-Requires: ((emacs "27.0"))
;; Keywords: evil, set, option
;;; License:
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; My primitive implementation of :set command for Evil.
;; It allows you to run e.g.
;; :set wrap
;; :set colorcolumn=80
;; etc, that we know from Vim.
;;
;; Currently, only a very limited subset of options is supported - only
;; those that I use regularly. Please let me know what should be added.
;;
;;
;; Options manual:
;; http://vimdoc.sourceforge.net/htmldoc/options.html
;; Some popular options:
;; https://www.shortcutfoo.com/blog/top-50-vim-configuration-options/
;;; Code
;;;; Requirements
(require 'evil)
(require 'hideshow)
(require 'hl-line)
(require 'display-fill-column-indicator)
;;;; Modes
(define-minor-mode evil-set-option-mode
"Toggle `evil-set-option-mode'.
This global minor mode overrides the default `:set' ex
command and provides support for many options, such as
`:set wrap', `:set number', `:set colorcolumn', etc. "
:global t
(if evil-set-option-mode
(evil-ex-define-cmd "set" #'evil-set-option)
(setq evil-ex-commands (assoc-delete-all "set" evil-ex-commands))))
;;;; Commands
;;;###autoload (autoload 'evil-set-option "evil-set-option" nil t)
(evil-define-command evil-set-option (arg)
(interactive "<a>")
(if (not arg)
(error "Missing argument, use e.g. :set wrap")
(let* ((split (split-string arg "="))
(option (car split))
(value (car (cdr split))))
(pcase option
;; There is a pre-existing implementation of the :set command used for
;; setting the initial evil state for a buffer. If the value is
;; recognized to be one of the states, fall back to the default
;; implementation
((or "normal" "insert" "visual" "replace" "operator" "motion")
(evil-set-option-initial-state option))
;; Indent options
("expandtab" (evil-set-option-expandtab t))
("noexpandtab" (evil-set-option-expandtab nil))
("shiftwidth" (evil-set-option-shiftwidth value))
("autoindent" (evil-set-option-autoindent t))
("noautoindent" (evil-set-option-autoindent nil))
("tabstop" (evil-set-option-tabstop value))
;; Search options
("hlsearch" (evil-set-option-hlsearch t))
("nohlsearch" (evil-set-option-hlsearch nil))
("ignorecase" (evil-set-option-ignorecase t))
("noignorecase" (evil-set-option-ignorecase nil))
("incsearch" (evil-set-option-incsearch t))
("noincsearch" (evil-set-option-incsearch nil))
;; Text rendering options
("wrap" (evil-set-option-wrap t))
("nowrap" (evil-set-option-wrap nil))
;; User interface options
("number" (evil-set-option-number t))
("nonumber" (evil-set-option-number nil))
("relativenumber" (evil-set-option-relativenumber t))
("norelativenumber" (evil-set-option-relativenumber nil))
("colorcolumn" (evil-set-option-colorcolumn value))
("cursorline" (evil-set-option-cursorline t))
("nocursorline" (evil-set-option-cursorline nil))
;; Code folding options
("foldenable" (evil-set-option-foldenable t))
("nofoldenable" (evil-set-option-foldenable nil))
;; Unknown command
(option (error "Unknown command"))))))
;; ;;;; Functions
;; ;;;;; Public
(defun evil-set-option-initial-state (value)
(evil-set-initial-state major-mode (intern value)))
(defun evil-set-option-wrap (value)
(setq truncate-lines (not value)))
(defun evil-set-option-number (value)
(display-line-numbers-mode (if value 1 0))
(setq display-line-numbers value))
(defun evil-set-option-relativenumber (value)
(setq display-line-numbers (if value 'relative t)))
(defun evil-set-option-colorcolumn (value)
(if (not (string-empty-p value))
(progn
(display-fill-column-indicator-mode 1)
(set-fill-column (string-to-number value)))
(display-fill-column-indicator-mode 0)))
(defun evil-set-option-hlsearch (value)
;; In Vim, this option is global, therefore we should ideally use
;; (global-evil-search-highlight-persist t)
;; But IMHO it doesn't work. Thus, I am implementing this option per-buffer
;; ... actually, it does work but it is applied when creating new buffers,
;; it doesn't affect already existing ones
(if (fboundp 'evil-search-highlight-persist)
(evil-search-highlight-persist (if value t -1))
(error "Install `evil-search-highlight-persist' package")))
(defun evil-set-option-ignorecase (value)
(if value
(progn
(setq case-fold-search nil)
(setq case-fold-search t)
(setq evil-ex-search-case nil)
(setq isearch-case-fold-search t)
(setq evil-search-module 'evil-search))
(error (concat "Please let me know how to implement this option - "
"https://github.com/FrostyX/evil-set-option/issues/1"))))
(defun evil-set-option-incsearch (value)
(if (not value)
(error "There is no way to disable incsearch")))
(defun evil-set-option-expandtab (value)
;; FIXME Using tabs for >> and << doesn't work
;; https://github.com/FrostyX/evil-set-option/issues/2
(setq indent-tabs-mode (not value))
(setq evil-indent-convert-tabs value))
(defun evil-set-option-shiftwidth (value)
(setq evil-shift-width (string-to-number value)))
(defun evil-set-option-tabstop (value)
(setq tab-width (string-to-number value)))
(defun evil-set-option-autoindent (value)
(setq evil-auto-indent value)
(local-set-key (kbd "RET")
(if value 'newline-and-indent 'newline)))
(defun evil-set-option-cursorline (value)
(if value
(hl-line-mode t)
(hl-line-unload-function)))
(defun evil-set-option-foldenable (value)
(hs-minor-mode value)
(if value
(hs-hide-all)
(hs-show-all)))
;;;; Footer
(provide 'evil-set-option)
;;; evil-set-option.el ends here