evil-mode: more vim-like ex file modifiers

This commit is contained in:
Henrik Lissner 2016-04-19 22:08:18 -04:00
parent dbcea69193
commit 698331e4f0
2 changed files with 63 additions and 72 deletions

View file

@ -114,90 +114,81 @@
;; Hide keystroke display while isearch is active ;; Hide keystroke display while isearch is active
(add-hook! isearch-mode (setq echo-keystrokes 0)) (add-hook! isearch-mode (setq echo-keystrokes 0))
(add-hook! isearch-mode-end (setq echo-keystrokes 0.02)) (add-hook! isearch-mode-end (setq echo-keystrokes 0.02))
(let ((map evil-ex-search-keymap))
(define-key map "\C-w" 'backward-kill-word)
(define-key map "\C-u" 'evil-delete-whole-line))
;; Repeat motions with SPC/S-SPC ;; Repeat motions with SPC/S-SPC
(defmacro narf-space-setup! (command next-func prev-func) (defmacro define-repeat! (command next-func prev-func)
`(defadvice ,command `(defadvice ,command
(before ,(intern (format "narf-space--%s" (symbol-name command))) activate) (before ,(intern (format "narf-space--%s" (symbol-name command))) activate)
(define-key evil-motion-state-map (kbd "SPC") ',next-func) (define-key evil-motion-state-map (kbd "SPC") ',next-func)
(define-key evil-motion-state-map (kbd "S-SPC") ',prev-func))) (define-key evil-motion-state-map (kbd "S-SPC") ',prev-func)))
(after! evil-snipe (after! evil-snipe
(narf-space-setup! evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-f evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-F evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-t evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-T evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-s evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-S evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-x evil-snipe-repeat evil-snipe-repeat-reverse) (define-repeat! evil-snipe-x evil-snipe-repeat evil-snipe-repeat-reverse)
(narf-space-setup! evil-snipe-X evil-snipe-repeat evil-snipe-repeat-reverse)) (define-repeat! evil-snipe-X evil-snipe-repeat evil-snipe-repeat-reverse))
(after! evil-visualstar (after! evil-visualstar
(narf-space-setup! evil-visualstar/begin-search-forward evil-ex-search-next evil-ex-search-previous) (define-repeat! evil-visualstar/begin-search-forward evil-ex-search-next evil-ex-search-previous)
(narf-space-setup! evil-visualstar/begin-search-backward evil-ex-search-previous evil-ex-search-next)) (define-repeat! evil-visualstar/begin-search-backward evil-ex-search-previous evil-ex-search-next))
(narf-space-setup! evil-ex-search-next evil-ex-search-next evil-ex-search-previous) (define-repeat! evil-ex-search-next evil-ex-search-next evil-ex-search-previous)
(narf-space-setup! evil-ex-search-previous evil-ex-search-next evil-ex-search-previous) (define-repeat! evil-ex-search-previous evil-ex-search-next evil-ex-search-previous)
(define-repeat! evil-ex-search-forward evil-ex-search-next evil-ex-search-previous)
(define-repeat! evil-ex-search-backward evil-ex-search-next evil-ex-search-previous)
(narf-space-setup! evil-ex-search-forward evil-ex-search-next evil-ex-search-previous) ;; A monkey patch to add all of vim's file ex substitution flags to evil-mode.
(narf-space-setup! evil-ex-search-backward evil-ex-search-next evil-ex-search-previous)
;; A monkey patch to add several substitutions to evil-mode's ex commandline
;; other than % and #...
;;
;; % => full path to file (/project/src/thing.c)
;; # => alternative file path (/project/include/thing.h)
;; %:p => path to project root (/project/)
;; %:d => path to current directory (/project/src/)
;; %:e => the file's extension (c)
;; %:r => the full path without its extension (/project/src/thing)
;; %:t => the file's basename (thing.c)
;;
;; Requires projectile (https://github.com/bbatsov/projectile) for
;; project-awareness, and f.el (https://github.com/rejeep/f.el) for file
;; functions.
(defun evil-ex-replace-special-filenames (file-name) (defun evil-ex-replace-special-filenames (file-name)
"Replace special symbols in FILE-NAME." "Replace special symbols in FILE-NAME."
(let ((current-fname (buffer-file-name)) (let ((case-fold-search nil)
(alternate-fname (and (other-buffer) (regexp (concat "\\(?:^\\|[^\\\\]\\)"
(buffer-file-name (other-buffer))))) "\\([#%@]\\)"
(setq file-name "\\(\\(?::\\(?:[phtreS~.]\\|g?s[^: $]+\\)\\)*\\)")))
;; %:p:h => the project root (or current directory otherwise) (dolist (match (s-match-strings-all regexp file-name))
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:p\\)" (let ((flags (split-string (caddr match) ":" t))
(narf/project-root) file-name t t 2)) (path (file-relative-name
(setq file-name (pcase (cadr match)
;; %:p => the current directory ("@" (narf/project-root))
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:d\\)" ("%" (buffer-file-name))
default-directory file-name t t 2)) ("#" (and (other-buffer) (buffer-file-name (other-buffer)))))
(when current-fname default-directory))
(setq file-name flag global)
;; %:e => ext (when path
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:e\\)" (while flags
(f-ext current-fname) file-name t t 2)) (setq flag (pop flags))
(setq file-name (when (string-suffix-p "\\" flag)
;; %:r => filename (setq flag (concat flag (pop flags))))
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:r\\)" (when (string-prefix-p "gs" flag)
(f-no-ext current-fname) file-name t t 2)) (setq global t flag (string-remove-prefix "g" flag)))
(setq file-name (setq path
;; %:t => filename.ext (or (pcase (substring flag 0 1)
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:t\\)" ("p" (expand-file-name path))
(f-base current-fname) file-name t t 2)) ("~" (file-relative-name path "~"))
(setq file-name ("." (file-relative-name path default-directory))
;; % => file path for current frame ("h" (directory-file-name path))
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)" ("t" (file-name-nondirectory (directory-file-name path)))
current-fname file-name t t 2))) ("r" (file-name-sans-extension path))
(when alternate-fname ("e" (file-name-extension path))
(setq file-name ("s" (let* ((args (evil-delimited-arguments (substring flag 1) 2))
;; # => file path for alternative frame (pattern (evil-transform-vim-style-regexp (car args)))
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)" (replace (cadr args)))
alternate-fname file-name t t 2))) (replace-regexp-in-string
(setq file-name (if global pattern (concat "\\(" pattern "\\).*\\'"))
(replace-regexp-in-string "\\\\\\([#%]\\)" (evil-transform-vim-style-regexp replace) path t t
"\\1" file-name t))) (unless global 1))))
file-name)) ("S" (shell-quote-argument path))
(t path))
"")))
(setq file-name
(replace-regexp-in-string (format "\\(?:^\\|[^\\\\]\\)\\(%s\\)"
(string-trim-left (car match)))
path file-name t t 1)))))
;; Clean up
(setq file-name (replace-regexp-in-string regexp "\\1" file-name t)))))
;; Make :g[lobal] highlight matches ;; Make :g[lobal] highlight matches
;; TODO Redo this mess ;; TODO Redo this mess

View file

@ -96,10 +96,10 @@ Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/"
the buffer if it is being displayed in another window." the buffer if it is being displayed in another window."
(interactive) (interactive)
(let (new-dir) (let (new-dir)
(if (string-match-p "^\\*scratch\\*" (buffer-name)) (if (string-match-p "^\\*scratch\\*" (or (buffer-name) ""))
(message "Already in the scratch buffer") (message "Already in the scratch buffer")
(setq new-dir (narf/project-root)) (setq new-dir (narf/project-root))
(if (> (length (get-buffer-window-list (current-buffer) nil nil)) 1) (if (> (length (get-buffer-window-list (current-buffer) nil t)) 1)
(bury-buffer) (bury-buffer)
(kill-this-buffer))) (kill-this-buffer)))
(if (narf/popup-p (selected-window)) (if (narf/popup-p (selected-window))