editor/evil: port vim-unimpaired keybinds
Adds these keys, inspired by tpope/vim-unimpaired: [ SPC, ] SPC (or [o, ]o) Add COUNT blank lines above/below the cursor [f, ]f Visit previous/next file in current folder, alphabetically [u, ]u Url encode/decode operators [y, ]y C-string-style escaping/unescaping operators (escapes quotes, backslashes and control characters) [x, ]x XML entity encoding/decoding operators (only if :lang web is enabled) [F, ]F Focus previous/next frame (decided this is better than ]t/[t which is being used by hl-todo-{next,previous}) We already had gp and ]b/[b (buffers). We're not going to port ]e/[e because it is redundant with ddp/ddP or gx (evil-exchange). I also think these keybinds are better suited to {next,previous}-error.
This commit is contained in:
parent
be3f6fb38f
commit
0b1ecb8105
3 changed files with 166 additions and 23 deletions
|
@ -54,27 +54,49 @@
|
|||
;; misc
|
||||
:n "C-S-f" #'toggle-frame-fullscreen
|
||||
|
||||
;; Global evil keybinds
|
||||
:m "]a" #'evil-forward-arg
|
||||
:m "[a" #'evil-backward-arg
|
||||
:m "]o" #'outline-next-visible-heading
|
||||
:m "[o" #'outline-previous-visible-heading
|
||||
;; ported vim keys
|
||||
:nv "z=" #'flyspell-correct-word-generic
|
||||
:v "@" #'+evil:apply-macro
|
||||
|
||||
;; ported from vim-unimpaired
|
||||
:n "] SPC" #'+evil/insert-newline-below
|
||||
:n "[ SPC" #'+evil/insert-newline-above
|
||||
:n "]b" #'next-buffer
|
||||
:n "[b" #'previous-buffer
|
||||
:n "zx" #'kill-current-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
:n "]f" #'+evil/next-file
|
||||
:n "[f" #'+evil/previous-file
|
||||
:m "]u" #'+evil:url-encode
|
||||
:m "[u" #'+evil:url-decode
|
||||
:m "]y" #'+evil:c-string-encode
|
||||
:m "[y" #'+evil:c-string-decode
|
||||
;; NOTE hl-todo-{next,previous} have ]t/[t, use ]F/[F instead
|
||||
;; NOTE {next,previous}-error have ]e/[e, use ddp/ddP or gx instead
|
||||
(:when (featurep! :lang web)
|
||||
:m "]x" #'+web:encode-html-entities
|
||||
:m "[x" #'+web:decode-html-entities)
|
||||
|
||||
;; custom vim-unmpaired-esque keys
|
||||
:m "]a" #'evil-forward-arg
|
||||
:m "[a" #'evil-backward-arg
|
||||
:n "]F" #'+evil/next-frame
|
||||
:n "[F" #'+evil/previous-frame
|
||||
:m "]h" #'outline-next-visible-heading
|
||||
:m "[h" #'outline-previous-visible-heading
|
||||
:n "[o" #'+evil/insert-newline-above
|
||||
:n "]o" #'+evil/insert-newline-below
|
||||
:n "gp" #'+evil/reselect-paste
|
||||
:v "gp" #'+evil/paste-preserve-register
|
||||
:nv "g@" #'+evil:apply-macro
|
||||
:nv "gc" #'evil-commentary
|
||||
:nv "gx" #'evil-exchange
|
||||
:n "g=" #'evil-numbers/inc-at-pt
|
||||
:n "g-" #'evil-numbers/dec-at-pt
|
||||
:v "g=" #'evil-numbers/inc-at-pt-incremental
|
||||
:v "g-" #'evil-numbers/dec-at-pt-incremental
|
||||
:v "g+" #'evil-numbers/inc-at-pt
|
||||
:nv "z=" #'flyspell-correct-word-generic
|
||||
:nv "g@" #'+evil:apply-macro
|
||||
:nv "gc" #'evil-commentary
|
||||
:nv "gx" #'evil-exchange
|
||||
:v "gp" #'+evil/paste-preserve-register
|
||||
:v "@" #'+evil:apply-macro
|
||||
;; custom evil keybinds
|
||||
:n "zx" #'kill-current-buffer
|
||||
:n "ZX" #'bury-buffer
|
||||
;; repeat in visual mode (FIXME buggy)
|
||||
:v "." #'+evil:apply-macro
|
||||
;; don't leave visual mode after shifting
|
||||
|
|
|
@ -31,16 +31,6 @@
|
|||
(evil-normal-state)
|
||||
(evil-visual-restore))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/reselect-paste ()
|
||||
"Return to visual mode and reselect the last pasted region."
|
||||
(interactive)
|
||||
(cl-destructuring-bind (_ _ _ beg end &optional _)
|
||||
evil-last-paste
|
||||
(evil-visual-make-selection
|
||||
(save-excursion (goto-char beg) (point-marker))
|
||||
end)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/paste-preserve-register ()
|
||||
"Call `evil-paste-after' without overwriting the clipboard (by writing to the
|
||||
|
|
131
modules/editor/evil/autoload/unimpaired.el
Normal file
131
modules/editor/evil/autoload/unimpaired.el
Normal file
|
@ -0,0 +1,131 @@
|
|||
;;; editor/evil/autoload/unimpaired.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; These are ported from vim-unimpaired https://github.com/tpope/vim-unimpaired
|
||||
;; and bound in the :config default module (in +evil-bindings.el).
|
||||
|
||||
;;
|
||||
;;; Next/Previous commands
|
||||
|
||||
;;; ] SPC / [ SPC
|
||||
;;;###autoload
|
||||
(defun +evil/insert-newline-below (count)
|
||||
"Insert COUNT blank line(s) below current line. Does not change modes."
|
||||
(interactive "p")
|
||||
(dotimes (_ count)
|
||||
(save-excursion (evil-insert-newline-below))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/insert-newline-above (count)
|
||||
"Insert COUNT blank line(s) above current line. Does not change modes."
|
||||
(interactive "p")
|
||||
(dotimes (_ count)
|
||||
(save-excursion (evil-insert-newline-above))))
|
||||
|
||||
;;; ]t / [t
|
||||
;;;###autoload
|
||||
(defun +evil/next-frame (count)
|
||||
"Focus next frame."
|
||||
(interactive "p")
|
||||
(dotimes (_ (abs count))
|
||||
(let ((frame (if (> count 0) (next-frame) (previous-frame))))
|
||||
(if (eq frame (selected-frame))
|
||||
(user-error "No other frame")
|
||||
(select-frame-set-input-focus frame)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/previous-frame (count)
|
||||
"Focus previous frame."
|
||||
(interactive "p")
|
||||
(+evil/next-frame (- count)))
|
||||
|
||||
;;; ]f / [f
|
||||
(defun +evil--next-file (n)
|
||||
(unless buffer-file-name
|
||||
(user-error "Must be called from a file-visiting buffer"))
|
||||
(let* ((directory (file-name-directory buffer-file-name))
|
||||
(filename (file-name-nondirectory buffer-file-name))
|
||||
(files (doom-files-in directory :depth 0 :sort t :match "/[^._][^/]*$"))
|
||||
(index (cl-position filename files :test #'string=)))
|
||||
(when (null index)
|
||||
(user-error "Couldn't find this file in current directory"))
|
||||
(let ((index (+ index n)))
|
||||
(cond ((>= index (length files))
|
||||
(user-error "No files after this one"))
|
||||
((< index 0)
|
||||
(user-error "No files before this one"))
|
||||
((expand-file-name (nth index files) directory))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/next-file (count)
|
||||
"Open file following this one, alphabetically, in the same directory."
|
||||
(interactive "p")
|
||||
(find-file (+evil--next-file count)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +evil/previous-file (count)
|
||||
"Open file preceding this one, alphabetically, in the same directory."
|
||||
(interactive "p")
|
||||
(find-file (+evil--next-file (- count))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Encoding/Decoding
|
||||
|
||||
;; NOTE For ]x / [x see :lang web
|
||||
;; - `+web:encode-html-entities'
|
||||
;; - `+web:decode-html-entities'
|
||||
|
||||
(defun +evil--encode (beg end fn)
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(let* ((end (if (eq evil-this-type 'line) (1- end) end))
|
||||
(text (buffer-substring-no-properties beg end)))
|
||||
(delete-region beg end)
|
||||
(insert (funcall fn text)))))
|
||||
|
||||
;;; ]u / [u
|
||||
;;;###autoload (autoload '+evil:url-encode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:url-encode (count &optional beg end type)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(+evil--encode beg end #'url-encode-url))
|
||||
|
||||
;;;###autoload (autoload '+evil:url-decode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:url-decode (count &optional beg end type)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(+evil--encode beg end #'url-unhex-string))
|
||||
|
||||
;;; ]y / [y
|
||||
;;;###autoload (autoload '+evil:c-string-encode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:c-string-encode (count &optional beg end type)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(+evil--encode
|
||||
beg end
|
||||
(lambda (text)
|
||||
(replace-regexp-in-string "[\"\\]" (lambda (ch) (concat "\\" ch)) text))))
|
||||
|
||||
;;;###autoload (autoload '+evil:c-string-decode "editor/evil/autoload/unimpaired" nil t)
|
||||
(evil-define-operator +evil:c-string-decode (count &optional beg end type)
|
||||
"TODO"
|
||||
(interactive "<c><R>")
|
||||
(+evil--encode
|
||||
beg end
|
||||
(lambda (text)
|
||||
(replace-regexp-in-string "\\\\[\"\\]" (lambda (str) (substring str 1)) text))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Standalone
|
||||
|
||||
;;; gp
|
||||
;;;###autoload
|
||||
(defun +evil/reselect-paste ()
|
||||
"Return to visual mode and reselect the last pasted region."
|
||||
(interactive)
|
||||
(cl-destructuring-bind (_ _ _ beg end &optional _)
|
||||
evil-last-paste
|
||||
(evil-visual-make-selection
|
||||
(save-excursion (goto-char beg) (point-marker))
|
||||
end)))
|
Loading…
Add table
Add a link
Reference in a new issue