200 lines
6.4 KiB
EmacsLisp
200 lines
6.4 KiB
EmacsLisp
;;; 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
|
|
|
|
;;;###autoload
|
|
(defun +evil/next-beginning-of-method (count)
|
|
"Jump to the beginning of the COUNT-th method/function after point."
|
|
(interactive "p")
|
|
(beginning-of-defun (- count)))
|
|
|
|
;;;###autoload
|
|
(defun +evil/previous-beginning-of-method (count)
|
|
"Jump to the beginning of the COUNT-th method/function before point."
|
|
(interactive "p")
|
|
(beginning-of-defun count))
|
|
|
|
;;;###autoload
|
|
(defalias #'+evil/next-end-of-method #'end-of-defun
|
|
"Jump to the end of the COUNT-th method/function after point.")
|
|
|
|
;;;###autoload
|
|
(defun +evil/previous-end-of-method (count)
|
|
"Jump to the end of the COUNT-th method/function before point."
|
|
(interactive "p")
|
|
(end-of-defun (- count)))
|
|
|
|
;;;###autoload
|
|
(defun +evil/next-preproc-directive (count)
|
|
"Jump to the COUNT-th preprocessor directive after point.
|
|
|
|
By default, this only recognizes C preproc directives. To change this see
|
|
`+evil-preprocessor-regexp'."
|
|
(interactive "p")
|
|
;; TODO More generalized search, to support directives in other languages?
|
|
(if (re-search-forward +evil-preprocessor-regexp nil t count)
|
|
(goto-char (match-beginning 0))
|
|
(user-error "No preprocessor directives %s point"
|
|
(if (> count 0) "after" "before"))))
|
|
|
|
;;;###autoload
|
|
(defun +evil/previous-preproc-directive (count)
|
|
"Jump to the COUNT-th preprocessor directive before point.
|
|
|
|
See `+evil/next-preproc-directive' for details."
|
|
(interactive "p")
|
|
(+evil/next-preproc-statement (- count)))
|
|
|
|
;;;###autoload
|
|
(defun +evil/next-comment (count)
|
|
"Jump to the beginning of the COUNT-th commented region after point."
|
|
(interactive "p")
|
|
(let ((orig-pt (point)))
|
|
(require 'newcomment)
|
|
(dotimes (_ (abs count))
|
|
(cond ((> count 0)
|
|
(while (and (not (eobp)) (sp-point-in-comment))
|
|
(forward-line 1))
|
|
(unless (comment-search-forward (point-max) 'noerror)
|
|
(goto-char orig-pt)
|
|
(user-error "No comment after point")))
|
|
(t
|
|
(while (and (not (bobp)) (sp-point-in-comment))
|
|
(forward-line -1))
|
|
(unless (comment-search-backward nil 'noerror)
|
|
(goto-char orig-pt)
|
|
(user-error "No comment before point")))))))
|
|
|
|
;;;###autoload
|
|
(defun +evil/previous-comment (count)
|
|
"Jump to the beginning of the COUNT-th commented region before point."
|
|
(interactive "p")
|
|
(+evil/next-comment (- count)))
|
|
|
|
;;; ] 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-glob (file-name-directory buffer-file-name) "[!.]*"))
|
|
(index (cl-position filename files :test #'file-equal-p)))
|
|
(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)
|
|
"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)
|
|
"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)
|
|
"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)
|
|
"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)))
|