diff options
| author | Miquel Sabaté Solà <msabate@suse.com> | 2017-01-31 15:31:19 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <msabate@suse.com> | 2017-01-31 15:31:19 +0100 |
| commit | 29d6092d4800f551e69054913e2f15ffb089af1b (patch) | |
| tree | ea1ff19a1dafa3ee4776ca01c31c65e8229a5a19 /emacs/init.org | |
| parent | d69d16ec10ef22f11eeee74cf7617bc6abfac81f (diff) | |
| download | dotfiles-29d6092d4800f551e69054913e2f15ffb089af1b.tar.gz dotfiles-29d6092d4800f551e69054913e2f15ffb089af1b.zip | |
emacs: be more verbose on the explanation behind Evil mode
Signed-off-by: Miquel Sabaté Solà <msabate@suse.com>
Diffstat (limited to 'emacs/init.org')
| -rw-r--r-- | emacs/init.org | 374 |
1 files changed, 211 insertions, 163 deletions
diff --git a/emacs/init.org b/emacs/init.org index 36b22ab..10c8f52 100644 --- a/emacs/init.org +++ b/emacs/init.org @@ -425,52 +425,57 @@ Ayo silver! Then, for keeping up with my projects I use the Projectile + Helm combination. #+BEGIN_SRC elisp - (use-package projectile - :ensure t - :config - (projectile-mode 1) - (setq projectile-mode-line - '(:eval (format " %s" (projectile-project-name))))) +(use-package projectile + :ensure t + :config + (projectile-mode 1) + (setq projectile-mode-line + '(:eval (format " %s" (projectile-project-name))))) - (use-package helm - :ensure t - :config - (setq projectile-completion-system 'helm) +(use-package helm + :ensure t + :config + (setq projectile-completion-system 'helm) - ; Allow the search pattern to be on the header. Taken from this Reddit thread: - ; https://www.reddit.com/r/emacs/comments/3asbyn/new_and_very_useful_helm_feature_enter_search/ - (setq helm-echo-input-in-header-line t) + ; Allow the search pattern to be on the header. Taken from this Reddit thread: + ; https://www.reddit.com/r/emacs/comments/3asbyn/new_and_very_useful_helm_feature_enter_search/ + (setq helm-echo-input-in-header-line t) - (defun helm-hide-minibuffer-maybe () - "Hide the minibuffer if we are in a Helm session" + (defun helm-hide-minibuffer-maybe () + "Hide the minibuffer if we are in a Helm session" - (when (with-helm-buffer helm-echo-input-in-header-line) - (let ((ov (make-overlay (point-min) (point-max) nil nil t))) - (overlay-put ov 'window (selected-window)) - (overlay-put ov 'face (let ((bg-color (face-background 'default nil))) - `(:background ,bg-color :foreground ,bg-color))) - (setq-local cursor-type nil)))) + (when (with-helm-buffer helm-echo-input-in-header-line) + (let ((ov (make-overlay (point-min) (point-max) nil nil t))) + (overlay-put ov 'window (selected-window)) + (overlay-put ov 'face (let ((bg-color (face-background 'default nil))) + `(:background ,bg-color :foreground ,bg-color))) + (setq-local cursor-type nil)))) - (add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe) - (setq helm-split-window-in-side-p t) + (add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe) + (setq helm-split-window-in-side-p t) - ; Preview files with tab - (define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action) + ; Preview files with tab + (define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action) - ; Show available options - (define-key helm-map (kbd "C-a") 'helm-select-action) + ; Show available options + (define-key helm-map (kbd "C-a") 'helm-select-action) - ; Some vim-like bindings - (define-key helm-map (kbd "C-j") 'helm-next-line) - (define-key helm-map (kbd "C-k") 'helm-previous-line) + ; Some vim-like bindings + (define-key helm-map (kbd "C-j") 'helm-next-line) + (define-key helm-map (kbd "C-k") 'helm-previous-line) - (use-package helm-ag - :ensure t)) + (use-package helm-ag + :ensure t)) - (use-package helm-projectile - :ensure t - :config - (helm-projectile-on)) +(use-package helm-projectile + :ensure t + :config + (helm-projectile-on) + + ; Define M-p as a way to quickly list all the available projects. + (with-eval-after-load 'evil + (define-key evil-normal-state-map (kbd "M-p") + 'helm-projectile-switch-project))) #+END_SRC I use @@html:<kbd>C-p</kbd>@@ as the binding for listing relevant files. This @@ -688,7 +693,7 @@ whenever I use it, I want basic evil movement. (kbd "w") 'evil-forward-word-begin)) #+END_SRC -That being said, I also extend =dired= with some handy tweaks. +I also extend =dired= with some handy tweaks. #+BEGIN_SRC elisp (setq directory-free-space-args "-Pkh" @@ -728,142 +733,177 @@ from the [[https://www.djcbsoftware.nl/code/mu/mu4e/Dired.html#Dired][mu4e docum Forgive me, [[https://stallman.org/saint.html][Father]], for I have sinned. I've been exposed to modal editing through Vim, and that has changed how I view editing for the foreseeable future. -Because of this, I use Evil. The following block includes some heavy-lifting so +Because of this, I use Evil. The following blocks include some heavy-lifting so Evil and GNU Emacs work without hitting each other, and it also includes some Evil extensions. +First of all, let's define a function that will be called whenever Evil is loaded. + #+BEGIN_SRC elisp - (defun mssola-evil () - "Configure evil mode." - - ; We can safely remap <C-u> because the counting will be handled a-la Vim. - (define-key evil-normal-state-map (kbd "C-u") 'evil-scroll-up) - - ; Make window navigation easier. - (define-key evil-normal-state-map (kbd "C-j") 'evil-window-down) - (define-key evil-normal-state-map (kbd "C-k") 'evil-window-up) - (define-key evil-normal-state-map (kbd "C-l") 'evil-window-right) - (define-key evil-normal-state-map (kbd "C-h") 'evil-window-left) - - ; The window navigation tweaks effectively wipe out the help prefix, which - ; is bad. Fortunately we can workaround this by providing "M-h" as the new - ; help prefix. This prefix is only used in emacs mode to mark lines, which is - ; something already handled by Evil. - (define-key global-map (kbd "M-h") 'help-command) - (fset 'help-command help-map) - - ; Helm + Projectile shortcuts. - (with-eval-after-load 'helm-projectile - (define-key evil-normal-state-map (kbd "M-p") - 'helm-projectile-switch-project)) - - ; I use the Super key in combination with j & k to move around i3. Let's unset - ; M- combos for these two fellows for whenever I misstype them. - (global-unset-key (kbd "M-j")) - (global-unset-key (kbd "M-k")) - - ; both this function and the subsequent lines about [escape] are taken from - ; @aaronbieber configuration. - (defun minibuffer-keyboard-quit () - "Abort recursive edit. - In Delete Selection mode, if the mark is active, just deactivate it; - then it takes a second \\[keyboard-quit] to abort the minibuffer." - (interactive) - (if (and delete-selection-mode transient-mark-mode mark-active) - (setq deactivate-mark t) - (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) - (abort-recursive-edit))) - - ;; Make escape quit everything, whenever possible. - (define-key evil-normal-state-map [escape] 'keyboard-quit) - (define-key evil-visual-state-map [escape] 'keyboard-quit) - (define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit) - (define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit) - (define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit) - (define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit) - (define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit) - - ; I store macros on the <q> register for convenience, so I used to use the - ; <C-q> combo to execute this macro in Vim. In Emacs though, this combo is - ; reserved to a rather useful function, and I'd like to keep it that way. So, - ; now the mapping is set to <C-2> (mnemonic: where the @ symbol is). Moreover, - ; it's applied as many times as specified by the numeric prefix argument. - (define-key evil-normal-state-map (kbd "C-2") - (lambda (n) - (interactive "p") - (evil-execute-macro n "@q"))) - - ; C-s: switch to normal mode and save the buffer. I know :) - (define-key evil-normal-state-map (kbd "C-s") 'save-buffer) - (define-key evil-insert-state-map (kbd "C-s") - (lambda () (interactive) (save-buffer) (evil-force-normal-state)))) - - (use-package evil +(defun mssola-evil () + "Configure evil mode." + + ; We can safely remap <C-u> because the counting will be handled a-la Vim. + (define-key evil-normal-state-map (kbd "C-u") 'evil-scroll-up) + + ; Make window navigation easier. + (define-key evil-normal-state-map (kbd "C-j") 'evil-window-down) + (define-key evil-normal-state-map (kbd "C-k") 'evil-window-up) + (define-key evil-normal-state-map (kbd "C-l") 'evil-window-right) + (define-key evil-normal-state-map (kbd "C-h") 'evil-window-left) + + ; The window navigation tweaks effectively wipe out the help prefix, which + ; is bad. Fortunately we can workaround this by providing "M-h" as the new + ; help prefix. This prefix is only used in emacs mode to mark lines, which is + ; something already handled by Evil. + (define-key global-map (kbd "M-h") 'help-command) + (fset 'help-command help-map) + + ; I use the Super key in combination with j & k to move around i3. Let's unset + ; M- combos for these two fellows for whenever I misstype them. + (global-unset-key (kbd "M-j")) + (global-unset-key (kbd "M-k")) + + ; both this function and the subsequent lines about [escape] are taken from + ; @aaronbieber configuration. + (defun minibuffer-keyboard-quit () + "Abort recursive edit. +In Delete Selection mode, if the mark is active, just deactivate it; +then it takes a second \\[keyboard-quit] to abort the minibuffer." + (interactive) + (if (and delete-selection-mode transient-mark-mode mark-active) + (setq deactivate-mark t) + (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) + (abort-recursive-edit))) + + ;; Make escape quit everything, whenever possible. + (define-key evil-normal-state-map [escape] 'keyboard-quit) + (define-key evil-visual-state-map [escape] 'keyboard-quit) + (define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit) + (define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit) + (define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit) + (define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit) + (define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit) + + ; I store macros on the <q> register for convenience, so I used to use the + ; <C-q> combo to execute this macro in Vim. In Emacs though, this combo is + ; reserved to a rather useful function, and I'd like to keep it that way. So, + ; now the mapping is set to <C-2> (mnemonic: where the @ symbol is). Moreover, + ; it's applied as many times as specified by the numeric prefix argument. + (define-key evil-normal-state-map (kbd "C-2") + (lambda (n) + (interactive "p") + (evil-execute-macro n "@q"))) + + ; C-s: switch to normal mode and save the buffer. I know :) + (define-key evil-normal-state-map (kbd "C-s") 'save-buffer) + (define-key evil-insert-state-map (kbd "C-s") + (lambda () (interactive) (save-buffer) (evil-force-normal-state)))) +#+END_SRC + +Now make sure that Evil is installed, and call the relevant configuration functions. + +#+BEGIN_SRC elisp +(use-package evil + :ensure t + :config + + (add-hook 'evil-mode-hook 'mssola-evil) + (evil-mode 1) + + ;; C-z is unused and it's close to my beloved C-c. Since I don't want to mess + ;; with one of the most sacred Emacs prefixes, I'm moving to C-z. + (define-key key-translation-map (kbd "C-z") [escape]) + (define-key evil-operator-state-map (kbd "C-z") 'keyboard-quit) + (set-quit-char "C-z") + + ;; Use the proper initial evil state for the following modes. + (evil-set-initial-state 'help-mode 'normal) + (evil-set-initial-state 'debugger-mode 'normal) + (evil-set-initial-state 'describe-mode 'normal) + (evil-set-initial-state 'Buffer-menu-mode 'normal) +#+END_SRC + +If Evil was properly loaded, then make sure that the following Evil-related +packages are installed and configured as well. I start by defining the +=evil-leader= package, which brings the @@html:<kbd>leader</kbd>@@ feature from +Vim into Evil. + +#+BEGIN_SRC elisp + (use-package evil-leader :ensure t :config + (global-evil-leader-mode) + (evil-leader/set-leader ",") + (setq evil-leader/in-all-states 1) + (evil-leader/set-key + "," 'back-to-indentation + "c" 'delete-window + "k" 'kill-buffer-and-window + "v" 'split-window-right + "V" (lambda () (interactive) (split-window-right) (other-window 1)) + "f" 'flycheck-list-errors + "e" 'eval-last-sexp + "b" 'view-buffer + "o" 'browse-url-at-point)) +#+END_SRC + +Another handy Vim plugin that has made it into Evil is =evil-surround=, which +defines a new text object for surrounding characters (e.g. change a string from +having double quotes with single quotes in a single command). - (add-hook 'evil-mode-hook 'mssola-evil) - (evil-mode 1) +#+BEGIN_SRC elisp + (use-package evil-surround + :ensure t + :config + (global-evil-surround-mode 1)) +#+END_SRC - ;; C-z is unused and it's close to my beloved C-c. Since I don't want to mess - ;; with one of the most sacred Emacs prefixes, I'm moving to C-z. - (define-key key-translation-map (kbd "C-z") [escape]) - (define-key evil-operator-state-map (kbd "C-z") 'keyboard-quit) - (set-quit-char "C-z") +Next is another Vim plugin that has been ported to Evil: =evil-commentary=. This +package defines a new motion for comments, which is bound to +@@html:<kbd>gc</kbd>@@. So, for example, @@html:<kbd>gcc</kbd>@@ will comment +the current line, regardless of the programming language. - ;; Use the proper initial evil state for the following modes. - (evil-set-initial-state 'help-mode 'normal) - (evil-set-initial-state 'debugger-mode 'normal) - (evil-set-initial-state 'describe-mode 'normal) - (evil-set-initial-state 'Buffer-menu-mode 'normal) +#+BEGIN_SRC elisp + (use-package evil-commentary + :ensure t + :config + (evil-commentary-mode t)) +#+END_SRC - (use-package evil-leader - :ensure t - :config - (global-evil-leader-mode) - (evil-leader/set-leader ",") - (setq evil-leader/in-all-states 1) - (evil-leader/set-key - "," 'back-to-indentation - "c" 'delete-window - "k" 'kill-buffer-and-window - "v" 'split-window-right - "V" (lambda () (interactive) (split-window-right) (other-window 1)) - "f" 'flycheck-list-errors - "e" 'eval-last-sexp - "b" 'view-buffer - "o" 'browse-url-at-point)) - - (use-package evil-surround - :ensure t - :config - (global-evil-surround-mode 1)) +Another cool package is =evil-args= which defines the argument text object. This +text object can be targeted with the =a= character, and we can move backward and +forward through arguments with @@html:<kbd>H</kbd>@@ and @@html:<kbd>L</kbd>@@ +respectively. - (use-package evil-commentary - :ensure t - :config - (evil-commentary-mode t)) +#+BEGIN_SRC elisp + (use-package evil-args + :ensure t + :config + ; Configuration taken from the documentation of evil-args. - (use-package evil-args - :ensure t - :config - ; Configuration taken from the documentation of evil-args. + ;; Bind evil-args text objects + (define-key evil-inner-text-objects-map "a" 'evil-inner-arg) + (define-key evil-outer-text-objects-map "a" 'evil-outer-arg) - ;; Bind evil-args text objects - (define-key evil-inner-text-objects-map "a" 'evil-inner-arg) - (define-key evil-outer-text-objects-map "a" 'evil-outer-arg) + ;; Bind evil-forward/backward-args + (define-key evil-normal-state-map "L" 'evil-forward-arg) + (define-key evil-normal-state-map "H" 'evil-backward-arg) + (define-key evil-motion-state-map "L" 'evil-forward-arg) + (define-key evil-motion-state-map "H" 'evil-backward-arg)) +#+END_SRC - ;; Bind evil-forward/backward-args - (define-key evil-normal-state-map "L" 'evil-forward-arg) - (define-key evil-normal-state-map "H" 'evil-backward-arg) - (define-key evil-motion-state-map "L" 'evil-forward-arg) - (define-key evil-motion-state-map "H" 'evil-backward-arg)) +Last but not least, =evil-numbers= brings a couple of bindings available to Vim +into Evil: @@html:<kbd>C-a</kbd>@@ for increasing a number, and +@@html:<kbd>C-c -</kbd>@@ for decreasing it (modified because +@@html:<kbd>C-z</kbd>@@ is my escape sequence). - (use-package evil-numbers - :ensure t - :config - (define-key evil-normal-state-map (kbd "C-a") 'evil-numbers/inc-at-pt) - (define-key evil-normal-state-map (kbd "C-c -") 'evil-numbers/dec-at-pt))) +#+BEGIN_SRC elisp + (use-package evil-numbers + :ensure t + :config + (define-key evil-normal-state-map (kbd "C-a") 'evil-numbers/inc-at-pt) + (define-key evil-normal-state-map (kbd "C-c -") 'evil-numbers/dec-at-pt))) #+END_SRC * Magit @@ -1450,7 +1490,7 @@ I'm giving ERC a chance. First of all, I'm setting up basic stuff. ("*.suse.de" "#suse" "#docker"))) #+END_SRC -Setup desktop notifications. +I want to have a desktop notification whenever someone mentions my name. #+BEGIN_SRC elisp (require 'notifications) @@ -1472,15 +1512,16 @@ Setup desktop notifications. (add-hook 'erc-text-matched-hook 'erc-global-notify)) #+END_SRC -Add some helper packages and update the loaded ERC modules. +Use the =erc-hl-nicks= package, so highlight support for nicknames is better. #+BEGIN_SRC elisp - (add-hook 'erc-connect-pre-hook - (lambda (x) (erc-update-modules))) - (use-package erc-hl-nicks :ensure t) +#+END_SRC +Some extra cookies: allow ERC to display images and Youtube thumbnails. + +#+BEGIN_SRC elisp (use-package erc-yt :ensure t :init @@ -1494,6 +1535,13 @@ Add some helper packages and update the loaded ERC modules. (add-to-list 'erc-modules 'image))) #+END_SRC +At this point, we can safely update all the loaded ERC modules. + +#+BEGIN_SRC elisp + (add-hook 'erc-connect-pre-hook + (lambda (x) (erc-update-modules))) +#+END_SRC + And now define a function to connect to both IRC servers. #+BEGIN_SRC elisp |
