Major overhaul
This commit is contained in:
parent
4ab3ae1125
commit
6bda25da1f
76 changed files with 7431 additions and 571 deletions
372
core/core-evil.el
Normal file
372
core/core-evil.el
Normal file
|
@ -0,0 +1,372 @@
|
|||
(provide 'core-evil)
|
||||
|
||||
;;;; Eeeeeeevil ;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(use-package evil
|
||||
:pre-load
|
||||
(setq evil-want-visual-char-semi-exclusive t
|
||||
evil-search-module 'evil-search
|
||||
evil-magic 'very-magic
|
||||
evil-want-C-u-scroll t ; enable C-u for scrolling
|
||||
evil-ex-visual-char-range t ; column range for ex commands
|
||||
evil-ex-search-vim-style-regexp t
|
||||
|
||||
;; Color-coded state cursors
|
||||
evil-normal-state-cursor '("white" box)
|
||||
evil-emacs-state-cursor '("cyan" bar)
|
||||
evil-insert-state-cursor '("white" bar)
|
||||
evil-god-state-cursor '("orange" box)
|
||||
evil-visual-state-cursor 'hollow
|
||||
|
||||
ace-jump-mode-scope 'window
|
||||
ace-jump-mode-move-keys (nconc (loop for i from ?a to ?z collect i)
|
||||
(loop for i from ?A to ?Z collect i)))
|
||||
:config
|
||||
(progn
|
||||
(evil-mode)
|
||||
;; Always ensure evil-shift-width is consistent with tab-width
|
||||
(add-hook! 'find-file-hook (setq evil-shift-width tab-width))
|
||||
|
||||
;; highlight matching delimiters where it's important
|
||||
(defun show-paren-mode-off () (show-paren-mode -1))
|
||||
(add-hook 'evil-insert-state-entry-hook 'show-paren-mode)
|
||||
(add-hook 'evil-insert-state-exit-hook 'show-paren-mode-off)
|
||||
(add-hook 'evil-visual-state-entry-hook 'show-paren-mode)
|
||||
(add-hook 'evil-visual-state-exit-hook 'show-paren-mode-off)
|
||||
(add-hook 'evil-motion-state-entry-hook 'show-paren-mode)
|
||||
(add-hook 'evil-motion-state-exit-hook 'show-paren-mode-off)
|
||||
(add-hook 'evil-operator-state-entry-hook 'show-paren-mode)
|
||||
(add-hook 'evil-operator-state-exit-hook 'show-paren-mode-off)
|
||||
|
||||
;; Disable highlights on insert-mode
|
||||
(add-hook 'evil-insert-state-entry-hook 'evil-ex-nohighlight)
|
||||
|
||||
;; modes to map to different default states
|
||||
(dolist (mode-map '((cider-repl-mode . emacs)
|
||||
(comint-mode . emacs)
|
||||
(fundamental-mode . normal)
|
||||
(help-mode . normal)
|
||||
(term-mode . emacs)))
|
||||
(evil-set-initial-state `,(car mode-map) `,(cdr mode-map)))
|
||||
|
||||
(progn ; evil plugins
|
||||
(use-package evil-space :init (evil-space-default-setup))
|
||||
|
||||
(use-package evil-exchange
|
||||
:config
|
||||
(defadvice evil-force-normal-state (before evil-esc-quit-exchange activate)
|
||||
(shut-up (evil-exchange-cancel))))
|
||||
|
||||
(use-package evil-ex-registers)
|
||||
|
||||
(use-package evil-indent-textobject) ; vii/vai/vaI
|
||||
|
||||
(use-package evil-numbers)
|
||||
|
||||
(use-package evil-god-state)
|
||||
|
||||
(use-package evil-matchit :init (global-evil-matchit-mode 1))
|
||||
|
||||
(use-package evil-snipe
|
||||
:disabled t
|
||||
:init (global-evil-snipe-mode 1)
|
||||
:config
|
||||
(progn
|
||||
(evil-snipe-override-surround)
|
||||
(setq evil-snipe-search-highlight t)
|
||||
(setq evil-snipe-search-incremental-highlight t)))
|
||||
|
||||
(use-package evil-surround
|
||||
:init (global-evil-surround-mode 1)
|
||||
:config (evil-define-key 'visual evil-surround-mode-map (kbd "S") 'evil-surround-region))
|
||||
|
||||
(use-package evil-nerd-commenter
|
||||
:pre-load (setq evilnc-hotkey-comment-operator "gc"))
|
||||
|
||||
(use-package evil-jumper
|
||||
:pre-load (setq evil-jumper-file (expand-file-name "jumplist" my-tmp-dir))
|
||||
:config
|
||||
(progn
|
||||
(setq evil-jumper-auto-center t
|
||||
evil-jumper-auto-save-interval 3600)
|
||||
(define-key evil-motion-state-map (kbd "H-i") 'evil-jumper/forward)))
|
||||
|
||||
(use-package ace-window
|
||||
:config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
|
||||
|
||||
(use-package evil-visualstar))
|
||||
|
||||
(bind evil-ex-completion-map
|
||||
"C-r" #'evil-ex-paste-from-register ; registers in ex-mode
|
||||
"C-a" 'move-beginning-of-line
|
||||
"<s-left>" 'move-beginning-of-line
|
||||
"<s-right>" 'move-beginning-of-line
|
||||
"<s-backspace>" 'evil-delete-whole-line)
|
||||
|
||||
(progn ; evil hacks
|
||||
(defadvice evil-force-normal-state (before evil-esc-quit activate)
|
||||
(shut-up (evil-ex-nohighlight) ; turn off highlights
|
||||
;; Exit minibuffer is alive
|
||||
(if (minibuffer-window-active-p (minibuffer-window))
|
||||
(my--minibuffer-quit))))
|
||||
|
||||
;; Popwin: close popup window, if any
|
||||
(after "popwin"
|
||||
(defadvice evil-force-normal-state (before evil-esc-quit-popwin activate)
|
||||
(shut-up (popwin:close-popup-window))))
|
||||
|
||||
;; Ace-Jump: Enable half-cursor blink when using ace-jump
|
||||
(defadvice evil-ace-jump-char-mode (before evil-ace-jump-char-mode-op activate)
|
||||
(evil-half-cursor))
|
||||
(defadvice evil-ace-jump-word-mode (before evil-ace-jump-word-mode-op activate)
|
||||
(evil-half-cursor))
|
||||
|
||||
;; https://github.com/winterTTr/ace-jump-mode/issues/23
|
||||
(evil-define-motion evil-ace-jump-two-chars-mode (count)
|
||||
:type exclusive
|
||||
:repeat abort
|
||||
(evil-without-repeat
|
||||
(evil-enclose-ace-jump-for-motion
|
||||
(call-interactively 'ace-jump-two-chars-mode))))
|
||||
|
||||
(defun ace-jump-two-chars-mode (&optional query-char query-char-2)
|
||||
"AceJump two chars mode"
|
||||
(interactive)
|
||||
|
||||
(evil-half-cursor)
|
||||
(setq query-char (or query-char (read-char ">")))
|
||||
(setq query-char-2 (or query-char-2 (read-char (concat ">" (string query-char)))))
|
||||
|
||||
(if (eq (ace-jump-char-category query-char) 'other)
|
||||
(error "[AceJump] Non-printable character"))
|
||||
|
||||
;; others : digit , alpha, punc
|
||||
(setq ace-jump-query-char query-char)
|
||||
(setq ace-jump-current-mode 'ace-jump-char-mode)
|
||||
(ace-jump-do (regexp-quote (concat (char-to-string query-char)
|
||||
(char-to-string query-char-2)))))
|
||||
|
||||
;; Jump to new splits
|
||||
(defadvice evil-window-split (after evil-window-split-jump activate)
|
||||
(evil-window-down 1))
|
||||
(defadvice evil-window-vsplit (after evil-window-vsplit-jump activate)
|
||||
(evil-window-right 1))
|
||||
|
||||
(defadvice undo-tree-load-history-hook (around undo-tree-load-history-shut-up activate)
|
||||
(shut-up ad-do-it))
|
||||
(defadvice undo-tree-save-history-hook (around undo-tree-save-history-shut-up activate)
|
||||
(shut-up ad-do-it)))
|
||||
|
||||
(progn ; extensions
|
||||
(defun evil-visual-line-state-p ()
|
||||
"Returns non-nil if in visual-line mode, nil otherwise."
|
||||
(and (evil-visual-state-p)
|
||||
(eq (evil-visual-type) 'line)))
|
||||
|
||||
(defun evil-ex-replace-special-filenames (file-name)
|
||||
"Replace special symbols in FILE-NAME.
|
||||
|
||||
% => 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)"
|
||||
(let ((current-fname (buffer-file-name))
|
||||
(alternate-fname (and (other-buffer)
|
||||
(buffer-file-name (other-buffer)))))
|
||||
(setq file-name
|
||||
;; %:p:h => the project root (or current directory otherwise)
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:p\\)"
|
||||
(my--project-root) file-name t t 2))
|
||||
(setq file-name
|
||||
;; %:p => the project root (or current directory otherwise)
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:d\\)"
|
||||
default-directory file-name t t 2))
|
||||
(when current-fname
|
||||
(setq file-name
|
||||
;; %:e => ext
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:e\\)"
|
||||
(f-ext current-fname) file-name t t 2))
|
||||
(setq file-name
|
||||
;; %:r => filename
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:r\\)"
|
||||
(f-no-ext current-fname) file-name t t 2))
|
||||
(setq file-name
|
||||
;; %:t => filename.ext
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%:t\\)"
|
||||
(f-base current-fname) file-name t t 2))
|
||||
(setq file-name
|
||||
;; % => file path for current frame
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)"
|
||||
current-fname file-name t t 2)))
|
||||
(when alternate-fname
|
||||
(setq file-name
|
||||
;; # => file path for alternative frame
|
||||
(replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)"
|
||||
alternate-fname file-name t t 2)))
|
||||
(setq file-name
|
||||
(replace-regexp-in-string "\\\\\\([#%]\\)"
|
||||
"\\1" file-name t)))
|
||||
file-name))
|
||||
|
||||
(progn ; ex-commands
|
||||
(evil-ex-define-cmd "pres[ent]" 'toggle-theme)
|
||||
(evil-ex-define-cmd "full[scr]" 'toggle-frame-fullscreen)
|
||||
(evil-ex-define-cmd "k[ill]" 'kill-this-buffer) ; Kill current buffer
|
||||
(evil-ex-define-cmd "k[ill]o" 'cleanup-buffers) ; Kill current project buffers
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(evil-ex-define-cmd "echo" 'my:echo)
|
||||
(evil-define-command my:echo (&optional output)
|
||||
(interactive "<a>")
|
||||
(message "%s" output))
|
||||
|
||||
(evil-ex-define-cmd "k[ill]all" 'my:kill-buffers) ; Kill all buffers (bang = project buffers only)
|
||||
(evil-define-command my:kill-buffers (&optional bang)
|
||||
:repeat nil
|
||||
(interactive "<!>")
|
||||
(if (and bang (projectile-project-p))
|
||||
(projectile-kill-buffers)
|
||||
(mapc 'kill-buffer (buffer-list)))
|
||||
(delete-other-windows))
|
||||
|
||||
(evil-ex-define-cmd "ini" 'my:init-files)
|
||||
(evil-define-command my:init-files (&optional bang)
|
||||
:repeat nil
|
||||
(interactive "<!>")
|
||||
(if bang
|
||||
(ido-find-file-in-dir my-modules-dir)
|
||||
(ido-find-file-in-dir my-dir)))
|
||||
|
||||
(evil-ex-define-cmd "n[otes]" 'my:notes)
|
||||
(evil-define-command my:notes ()
|
||||
:repeat nil
|
||||
(interactive)
|
||||
(ido-find-file-in-dir org-directory))
|
||||
|
||||
(evil-ex-define-cmd "recompile" 'my:byte-compile)
|
||||
(evil-define-command my:byte-compile (&optional bang)
|
||||
:repeat nil
|
||||
(interactive "<!>")
|
||||
(if bang
|
||||
(byte-recompile-directory (concat my-dir ".cask") 0 t)
|
||||
(byte-recompile-directory my-dir 0 t)))
|
||||
|
||||
(evil-ex-define-cmd "build" 'my:build)
|
||||
(evil-define-command my:build (arguments &optional bang)
|
||||
:repeat t
|
||||
(interactive "<a><!>")
|
||||
(my-build arguments))
|
||||
|
||||
(evil-ex-define-cmd "cd" 'my:cd)
|
||||
(evil-define-command my:cd (dir)
|
||||
:repeat nil
|
||||
(interactive "<f>")
|
||||
(cd (if (zerop (length dir)) "~" dir)))
|
||||
|
||||
(defun --save-exit() (save-buffer) (kill-buffer) (remove-hook 'yas-after-exit-snippet-hook '--save-exit))
|
||||
(evil-ex-define-cmd "en[ew]" 'my:create-file)
|
||||
(evil-define-command my:create-file (path &optional bang)
|
||||
"Deploy files (and their associated templates) quickly. Will prompt
|
||||
you to fill in each snippet field before buffer closes unless BANG is
|
||||
provided."
|
||||
:repeat nil
|
||||
(interactive "<f><!>")
|
||||
(let ((dir (f-dirname path))
|
||||
(fullpath (f-full path))
|
||||
(is-auto t))
|
||||
(when (and bang (not (f-exists? dir))) (f-mkdir dir))
|
||||
(if (f-exists? dir)
|
||||
(if (f-exists? fullpath)
|
||||
(error "File already exists: %s" path)
|
||||
(find-file fullpath)
|
||||
(add-hook 'yas-after-exit-snippet-hook '--save-exit)
|
||||
(if bang (--save-exit)))
|
||||
(error "Directory doesn't exist: %s" dir))))
|
||||
|
||||
(evil-ex-define-cmd "ren[ame]" 'my:rename-this-file) ; Rename file . Bang: Delete old one
|
||||
(evil-define-command my:rename-this-file (new-name &optional bang)
|
||||
"Renames current buffer and file it is visiting. Replaces %, # and other
|
||||
variables (see `evil-ex-replace-special-filenames')"
|
||||
:repeat nil
|
||||
(interactive "<f><!>")
|
||||
(let ((name (buffer-name))
|
||||
(filename (buffer-file-name)))
|
||||
(if (not (and filename (file-exists-p filename)))
|
||||
(error "Buffer '%s' is not visiting a file!" name)
|
||||
(let ((new-name
|
||||
(evil-ex-replace-special-filenames (if new-name
|
||||
new-name
|
||||
(read-file-name "New name: " filename)))))
|
||||
(if (get-buffer new-name)
|
||||
(error "A buffer named '%s' already exists!" new-name)
|
||||
(rename-file filename new-name 1)
|
||||
(rename-buffer new-name)
|
||||
(set-visited-file-name new-name)
|
||||
(set-buffer-modified-p nil)
|
||||
(save-place-forget-unreadable-files)
|
||||
(when bang
|
||||
(delete-file filename))
|
||||
(message "File '%s' successfully renamed to '%s'"
|
||||
name (file-name-nondirectory new-name)))))))
|
||||
|
||||
(evil-ex-define-cmd "x" 'my:scratch-buffer)
|
||||
(evil-define-operator my:scratch-buffer (beg end &optional bang)
|
||||
"Send a selection to the scratch buffer. If BANG, then send it to org-capture
|
||||
instead."
|
||||
:move-point nil
|
||||
:type inclusive
|
||||
(interactive "<r><!>")
|
||||
(let ((mode major-mode)
|
||||
(text (when (and (evil-visual-state-p) beg end)
|
||||
(buffer-substring beg end))))
|
||||
(if bang
|
||||
;; use org-capture with bang
|
||||
(if text
|
||||
(org-capture-string text)
|
||||
(org-capture))
|
||||
;; or scratch buffer by default
|
||||
(let ((project-dir (projectile-project-root))
|
||||
(buffer-name (if (projectile-project-p)
|
||||
(format "*scratch* (%s)" (projectile-project-name))
|
||||
"*scratch*")))
|
||||
(popwin:popup-buffer (get-buffer-create buffer-name))
|
||||
(when (eq (get-buffer buffer-name) (current-buffer))
|
||||
(cd project-dir)
|
||||
(if text (insert text))
|
||||
(funcall mode))))))
|
||||
|
||||
(evil-ex-define-cmd "al[ign]" 'my:align)
|
||||
(evil-define-command my:align (beg end &optional regexp bang)
|
||||
:repeat nil
|
||||
(interactive "<r><a><!>")
|
||||
(when regexp
|
||||
(align-regexp beg end
|
||||
(concat "\\(\\s-*\\)" (rxt-pcre-to-elisp regexp)) 1 1)))
|
||||
|
||||
(evil-ex-define-cmd "retab" 'my:retab)
|
||||
(evil-define-operator my:retab (beg end)
|
||||
"Akin to vim's :retab, this changes all tabs-to-spaces or spaces-to-tabs,
|
||||
depending on `indent-tab-mode'. Untested."
|
||||
:motion nil
|
||||
:move-point nil
|
||||
:type line
|
||||
(interactive "<r>")
|
||||
(unless (and beg end)
|
||||
(setq beg (point-min))
|
||||
(setq end (point-max)))
|
||||
(if indent-tabs-mode
|
||||
(tabify beg end)
|
||||
(untabify beg end)))
|
||||
|
||||
(evil-ex-define-cmd "sq[uint]" 'my:narrow-indirect) ; Narrow buffer to selection
|
||||
(evil-define-operator my:narrow-indirect (beg end)
|
||||
"Indirectly narrow the region from BEG to END."
|
||||
:move-point nil
|
||||
:type exclusive
|
||||
:repeat nil
|
||||
(interactive "<r>")
|
||||
(evil-normal-state)
|
||||
(narrow-to-region-indirect beg end)))))
|
Loading…
Add table
Add a link
Reference in a new issue