Commit 650cf0bbf21e

Vincent Demeester <vincent@sbr.pm>
2018-03-20 23:01:31
Add initial ivy, keybindings and vcs
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent f381bc4
lisp/vde-ivy.el
@@ -0,0 +1,99 @@
+;; This file stores my configuration for Ivy and related packages.
+(use-package ivy
+  :ensure t
+  :bind (:map vde-mode-map
+         ("M-u" . ivy-resume)    ;Override the default binding for `upcase-word'
+         ("C-c w" . ivy-push-view) ;Push window configuration to `ivy-views'
+         ("C-c W" . ivy-pop-view)) ;Remove window configuration from `ivy-views'
+  :init
+  (progn
+    (bind-to-vde-map "v" #'counsel-set-variable))
+  :config
+  (progn
+    ;; Disable ido
+    (with-eval-after-load 'ido
+      (ido-mode -1)
+      ;; Enable ivy
+      (ivy-mode 1))
+
+    ;; Show recently killed buffers when calling `ivy-switch-buffer'
+    (setq ivy-use-virtual-buffers t)
+    (setq ivy-virtual-abbreviate 'full) ;Show the full virtual file paths
+
+    ;; Jump back to first candidate when on the last one
+    ivy-wrap t
+    (setq ivy-count-format "%d/%d ")
+    (setq ivy-re-builders-alist '((t . ivy--regex-plus))) ;Default
+    ;; (setq ivy-re-builders-alist '((t . ivy--regex-fuzzy)))
+
+    ;; Do not show "./" and "../" in the `counsel-find-file' completion list
+    (setq ivy-extra-directories nil)    ;Default value: ("../" "./")
+    ))
+
+(use-package ivy-hydra                  ; Additional bindings for Ivy
+  :ensure t
+  :after ivy)
+
+(use-package counsel
+  :ensure t
+  :bind (:map vde-mode-map
+	      ("M-i" . counsel-grep-or-swiper)
+	      ("C-M-y" . counsel-yank-pop)
+	      ("C-h F" . counsel-faces)       ;Overrides `Info-goto-emacs-command-node'
+	      ("C-h S" . counsel-info-lookup-symbol)
+	      ("C-c u" . counsel-unicode-char)
+	      ("C-c C" . counsel-colors-emacs) ;Alternative to `list-colors-display'
+	      ([remap execute-extended-command] . counsel-M-x)
+	      ([remap bookmark-jump] . counsel-bookmark) ;Jump to book or set it if it doesn't exist, C-x r b
+	      ([remap bookmark-set] . counsel-bookmark)  ;C-x r m
+	      ([remap find-file]  . counsel-find-file)
+	      ([remap describe-bindings] . counsel-descbinds)
+	      ([remap finder-by-keyword] . counsel-package) ;C-h p
+	      ([remap describe-variable] . counsel-describe-variable)
+	      ([remap describe-function] . counsel-describe-function))
+  :init
+  (progn
+    (bind-to-vde-map "s" #'counsel-rg))
+  :config
+  (progn
+    ;; counsel-find-file
+    (setq counsel-find-file-at-point t)
+    (setq counsel-find-file-ignore-regexp
+          (concat
+           ;; file names beginning with # or .
+           "\\(?:\\`[#.]\\)"
+           ;; file names ending with # or ~
+           "\\|\\(?:[#~]\\'\\)"))
+    ;; Note that `ivy-extra-directories' should also not contain the "../" and
+    ;; "./" elements if you don't want to see those in the `counsel-find-file'
+    ;; completion list.
+    (ivy-set-actions
+     'counsel-find-file
+     `(("x"
+        (lambda (x) (delete-file (expand-file-name x ivy--directory)))
+        ,(propertize "delete" 'face 'font-lock-warning-face))))
+
+    ;; Show parent directory in the prompt
+    (ivy-set-prompt 'counsel-ag #'counsel-prompt-function-dir)
+
+    ;; counsel-rg
+    ;; Redefine `counsel-rg-base-command' with my required options, especially
+    ;; the `--follow' option to allow search through symbolic links (part of
+    ;; `modi/rg-arguments').
+    (setq counsel-rg-base-command
+          (concat (mapconcat #'shell-quote-argument
+                             (append '("rg")
+                                     vde/rg-arguments
+                                     '("--no-heading" ;No file names above matching content
+                                       ))
+                             " ")
+                  " %s"            ;This MUST be %s, not %S
+                                        ;https://github.com/abo-abo/swiper/issues/427
+                  ))))
+
+(provide 'vde-ivy)
+
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
lisp/vde-keybindings.el
@@ -0,0 +1,17 @@
+(use-package which-key
+  :ensure t
+  :init (which-key-mode)
+  :config
+  (setq
+   which-key-idle-delay 0.4
+   which-key-sort-order 'which-key-prefix-then-key-order))
+
+;; Disable C-x C-n to avoid the disabled command buffer
+(unbind-key "C-x C-n" global-map)
+
+(provide 'vde-keybindings)
+
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
lisp/vde-mode.el
@@ -0,0 +1,63 @@
+;; My minor mode
+;; Main use is to have my key bindings have the highest priority
+
+(defvar vde-special-keymap-prefix (kbd "C-x m")
+  "`vde-mode' keymap prefix.
+Overrides the default binding for `compose-mail'.")
+
+(defvar vde-mode-special-map (make-sparse-keymap)
+  "Special keymap for `vde-mode' whose bindings begin with
+`vde-special-keymap-prefix'.")
+(fset 'vde-mode-special-map vde-mode-special-map)
+
+(defvar vde-mode-map (let ((map (make-sparse-keymap)))
+                        (define-key map vde-special-keymap-prefix 'vde-mode-special-map)
+                        map)
+  "Keymap for `vde-mode'.")
+
+;;;###autoload
+(define-minor-mode vde-mode
+  "A minor mode so that my key settings override annoying major modes."
+  ;; If init-value is not set to t, this mode does not get enabled in
+  ;; `fundamental-mode' buffers even after doing \"(global-vde-mode 1)\".
+  ;; More info: http://emacs.stackexchange.com/q/16693/115
+  :init-value t
+  :lighter    " μ"
+  :keymap     vde-mode-map)
+
+;;;###autoload
+(define-globalized-minor-mode global-vde-mode vde-mode vde-mode)
+
+;; https://github.com/jwiegley/use-package/blob/master/bind-key.el
+;; The keymaps in `emulation-mode-map-alists' take precedence over
+;; `minor-mode-map-alist'
+(add-to-list 'emulation-mode-map-alists `((vde-mode . ,vde-mode-map)))
+
+;; Turn off the minor mode in the minibuffer
+(defun turn-off-vde-mode ()
+  "Turn off vde-mode."
+  (vde-mode -1))
+(add-hook 'minibuffer-setup-hook #'turn-off-vde-mode)
+
+(defmacro bind-to-vde-map (key fn)
+  "Bind a function to the `vde-mode-special-map'.
+USAGE: (bind-to-vde-map \"f\" #'full-screen-center)."
+  `(define-key vde-mode-special-map (kbd ,key) ,fn))
+
+;; http://emacs.stackexchange.com/a/12906/115
+(defun unbind-from-vde-map (key)
+  "Unbind a function from the `vde-mode-map'
+USAGE: (unbind-from-vde-map \"C-x m f\")
+"
+  (interactive "kUnset key from vde-mode-map: ")
+  (define-key vde-mode-map (kbd (key-description key)) nil)
+  (message "%s" (format "Unbound %s key from the %s."
+                        (propertize (key-description key)
+                                    'face 'font-lock-function-name-face)
+                        (propertize "vde-mode-map"
+                                    'face 'font-lock-function-name-face))))
+
+
+(provide 'vde-mode)
+
+;; Minor mode tutorial: http://nullprogram.com/blog/2013/02/06/
lisp/vde-style.el
@@ -1,3 +1,23 @@
+;;; -*- lexical-binding: t; -*-
+;;; Fonts setup
+;; Fonts used:
+;; - Iosevka (https://github.com/be5invis/Iosevka)
+;; - Fira Sans (https://github.com/mozilla/Fira/)
+(set-face-attribute 'default nil
+		    :family "Fire Code"
+                    :height 130)
+(set-face-attribute 'variable-pitch nil
+                    :family "Fira Sans"
+                    :height 130
+                    :weight 'regular)
+
+;;; Interface
+(use-package frame                      ; Frames
+  :bind ("C-c w f" . toggle-frame-fullscreen)
+  :init
+  ;; Kill `suspend-frame'
+  (unbind-key "C-x C-z")
+  :config (add-to-list 'initial-frame-alist '(fullscreen . maximized)))
 
 (setq echo-keystrokes 0.1)     ; Faster echo keystrokes
 
@@ -10,6 +30,111 @@
 (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
 (when (fboundp 'horizontal-scroll-bar-mode) (horizontal-scroll-bar-mode -1))
 
+;;; Theme
+(setq custom-safe-themes t)    ; Treat themes as safe
+
+(use-package doom-themes
+  :ensure t
+  :config
+  (setq doom-themes-enable-bolt t)
+  (setq doom-themes-enable-italic t)
+  (load-theme 'doom-one t))
+
+(use-package solaire-mode
+  :ensure t
+  :config
+  (setq solaire-mode-remap-modeline nil)
+  (add-hook 'after-change-major-mode-hook #'turn-on-solaire-mode)
+  (add-hook 'after-revert-hook #'turn-on-solaire-mode)
+  (add-hook 'minibuffer-setup-hook #'solaire-mode-in-minibuffer)
+  (add-hook 'ediff-prepare-buffer-hook #'solaire-mode)
+  (advice-add #'persp-load-state-from-file :after #'solaire-mode-restore-persp-mode-buffers))
+
+;;; The mode line
+;; Slightly decrease the font in the mode line
+(set-face-attribute 'mode-line nil
+                    :family "Iosevka"
+		    :height 130)
+
+(line-number-mode)
+(column-number-mode)
+
+;; Show buffer position percentage starting from top
+(setq mode-line-percent-position '(-3 "%o"))
+(defvar mu-eyebrowse-mode-line
+  '(:propertize
+    (:eval
+     (when (bound-and-true-p eyebrowse-mode)
+       (let* ((num (eyebrowse--get 'current-slot))
+              (tag (when num
+                     (nth 2 (assoc num (eyebrowse--get 'window-configs)))))
+              (str (concat
+                    " "
+                    (if (and tag (< 0 (length tag)))
+                        tag
+                      (when num (int-to-string num)))
+                    " ")))
+         str)))
+    face (:background "#81a2be" :foreground "#373b41"))
+  "Mode line format for Eyebrowse.")
+
+(put 'mu-eyebrowse-mode-line 'risky-local-variable t)
+
+(setq-default mode-line-format
+              '("%e"
+                mu-eyebrowse-mode-line
+                mode-line-front-space
+                mode-line-mule-info
+                mode-line-client
+                mode-line-modified
+                mode-line-remote
+                mode-line-frame-identification
+                mode-line-buffer-identification " " mode-line-position
+                (vc-mode vc-mode)
+                (multiple-cursors-mode mc/mode-line)
+                " " mode-line-modes mode-line-end-spaces))
+
+(defmacro rename-modeline (package-name mode new-name)
+  "Rename PACKAGE-NAME with MODE into NEW-NAME in the mode line."
+  `(eval-after-load ,package-name
+     '(defadvice ,mode (after rename-modeline activate)
+        (setq mode-name ,new-name))))
+
+(rename-modeline "js2-mode" js2-mode "JS2")
+
+(line-number-mode 1)
+(column-number-mode 1)
+(global-hl-line-mode 1)
+
+(use-package minions                    ; A minor-mode menu for the mode line
+  :ensure t
+  :init (minions-mode)
+  :config
+  (setq
+   minions-mode-line-lighter "λ="
+   minions-direct '(flycheck-mode
+                    cider-mode)))
+
+(setq-default indicate-buffer-boundaries 'left)
+(setq-default indicate-empty-lines +1)
+
+;;; Utilities and key bindings
+(defun mu-reset-fonts ()
+  "Reset fonts to my preferences."
+  (interactive)
+  (set-face-attribute 'default nil
+		      :family "Fire Code"
+                      :height 130)
+  (set-face-attribute 'variable-pitch nil
+                      :family "Fira Sans"
+                      :height 130
+                      :weight 'regular)
+  (set-face-attribute 'mode-line nil
+                      :family "Iosevka"
+                      :height 130))
+
+(bind-key "C-c t f" #'mu-reset-fonts)
+
 (provide 'vde-style)
 
 ;; Local Variables:
lisp/vde-style.el~
lisp/vde-vcs.el
@@ -0,0 +1,86 @@
+
+(use-package vc-hooks                   ; Simple version control
+  :bind (("S-<f5>" . vc-revert)
+         ("C-c v r" . vc-refresh-state))
+  :config
+  ;; Always follow symlinks to files in VCS repos
+  (setq vc-follow-symlinks t))
+
+(use-package magit                      ; The best Git client out there
+  :ensure t
+  :bind (("C-c v c" . magit-clone)
+         ("C-c v C" . magit-checkout)
+         ("C-c v d" . magit-dispatch-popup)
+         ("C-c v g" . magit-blame)
+         ("C-c v l" . magit-log-buffer-file)
+         ("C-c v p" . magit-pull)
+         ("C-c v v" . magit-status))
+  :config
+  (setq
+   magit-save-repository-buffers 'dontask
+   magit-refs-show-commit-count 'all
+   magit-branch-prefer-remote-upstream '("master")
+   ;; magit-branch-adjust-remote-upstream-alist '(("origin/master" "master"))
+   magit-completing-read-function 'ivy-completing-read
+   magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
+
+  ;; Hide "Recent Commits"
+  (magit-add-section-hook 'magit-status-sections-hook
+                          'magit-insert-unpushed-to-upstream
+                          'magit-insert-unpushed-to-upstream-or-recent
+                          'replace)
+
+  ;; Show refined hunks during diffs
+  (set-default 'magit-diff-refine-hunk t)
+
+  (add-hook 'projectile-switch-project-hook
+            #'mu-magit-set-repo-dirs-from-projectile)
+
+  ;; Refresh `diff-hl' accordingly
+  (add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
+
+  ;; Refresh `magit-status' after saving a buffer
+  (add-hook 'after-save-hook #'magit-after-save-refresh-status)
+
+  ;; Free C-c C-w for Eyebrowse
+  (unbind-key "C-c C-w" git-commit-mode-map)
+
+  (defun mu-magit-kill-buffers ()
+    "Restore window configuration and kill all Magit buffers."
+    (interactive)
+    (let ((buffers (magit-mode-get-buffers)))
+      (magit-restore-window-configuration)
+      (mapc #'kill-buffer buffers)))
+
+  (bind-key "q" #'mu-magit-kill-buffers magit-status-mode-map))
+
+(use-package magit-gitflow              ; gitflow extension for Magit
+  :ensure t
+  :after magit
+  :config
+  ;; Free C-f and use a more suitable key binding
+  (unbind-key "C-f" magit-gitflow-mode-map)
+  (bind-key "C-c v f" #'magit-gitflow-popup magit-gitflow-mode-map)
+
+  (add-hook 'magit-mode-hook 'turn-on-magit-gitflow))
+
+(use-package git-commit                 ; Git commit message mode
+  :ensure t
+  :init (global-git-commit-mode)
+  :config
+  (remove-hook 'git-commit-finish-query-functions
+               #'git-commit-check-style-conventions))
+
+(use-package gitconfig-mode             ; Git configuration mode
+  :ensure t
+  :defer t)
+
+(use-package gitignore-mode             ; .gitignore mode
+  :ensure t
+  :defer t)
+
+(use-package gitattributes-mode         ; Git attributes mode
+  :ensure t
+  :defer t)
+
+(provide 'vde-vcs)
init.el
@@ -105,9 +105,31 @@ gc-cons-percentage 0.1))
 ;; Confirm before quitting Emacs
 (setq confirm-kill-emacs #'y-or-n-p)
 
+;;; Default rg arguments
+;; https://github.com/BurntSushi/ripgrep
+(defconst vde/rg-arguments
+  `("--no-ignore-vcs"                   ;Ignore files/dirs ONLY from `.ignore'
+    "--line-number"                     ;Line numbers
+    "--smart-case"
+    "--follow"                 ;Follow symlinks
+    "--max-columns" "150"      ;Emacs doesn't handle long line lengths very well
+    "--ignore-file" ,(expand-file-name ".ignore" (getenv "HOME")))
+  "Default rg arguments used in the functions in `counsel' and `projectile'
+packages.")
+
 ;;; Require files under ~/.emacs.d/lisp
 (add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
+
+;; Enable `vde-mode' unless `disable-pkg-vde-mode' is set to `t' in
+;; `setup-var-overrides.el'.
+(when (not (bound-and-true-p disable-pkg-vde-mode))
+  (require 'vde-mode))
+;;(require 'vde-mode)
+
 (use-package vde-style)
+(use-package vde-keybindings)
+(use-package vde-ivy)
+(use-package vde-vcs)
 
 ;; Reset default values
 (add-hook 'emacs-startup-hook #'vde-set-gc-threshold)