From bc33e39823208e74ee9a68d8421cafa98b6999a4 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 4 Jun 2016 22:47:20 -0400 Subject: [PATCH] Goodbye Helm, hello Ivy --- Cask | 24 ++++++++------ core/core-editor.el | 2 ++ core/core-eval.el | 3 +- core/core-ivy.el | 35 ++++++++++++++++++++ core/core-popup.el | 56 ++++++++++++++++---------------- core/core-yasnippet.el | 3 +- core/core.el | 7 ++++ core/defuns/defuns-ivy.el | 57 +++++++++++++++++++++++++++++++++ core/defuns/defuns-yasnippet.el | 7 ++-- init.el | 2 +- modules/defuns/defuns-org.el | 12 +++---- modules/module-css.el | 9 +++--- private/my-bindings.el | 45 +++++++++++++------------- private/my-commands.el | 12 +++---- 14 files changed, 191 insertions(+), 83 deletions(-) create mode 100644 core/core-ivy.el create mode 100644 core/defuns/defuns-ivy.el diff --git a/Cask b/Cask index af31e7461..1e2506221 100644 --- a/Cask +++ b/Cask @@ -21,6 +21,7 @@ (depends-on "persistent-soft") (depends-on "s") (depends-on "use-package") +(depends-on "smex" :git "https://github.com/syl20bnr/smex") ;; OSX --- core/core-os-osx.el (depends-on "applescript-mode") @@ -74,6 +75,7 @@ (depends-on "rotate-text" :git "https://github.com/debug-ito/rotate-text.el") (depends-on "smart-forward") (depends-on "smartparens") +(depends-on "swiper") ;; Documentation --- core/core-docs.el (depends-on "dash-at-point") @@ -95,10 +97,14 @@ (depends-on "flyspell") ;; Project --- core/core-project.el +(depends-on "counsel") +(depends-on "counsel-projectile") (depends-on "flx-ido") ;;(depends-on "ido-ubiquitous") (depends-on "ido-vertical-mode") +(depends-on "ivy") (depends-on "neotree") +(depends-on "projectile") ;; VCS --- core/core-vcs.el (depends-on "browse-at-remote") @@ -110,15 +116,14 @@ (depends-on "magit") ;; Helm -- core/core-helm.el -(depends-on "helm") -(depends-on "helm-ag") -(depends-on "helm-c-yasnippet") -(depends-on "helm-company") -(depends-on "helm-css-scss") -(depends-on "helm-describe-modes" :git "https://github.com/emacs-helm/helm-describe-modes") -(depends-on "helm-projectile") -(depends-on "helm-swoop") -(depends-on "projectile") +;;(depends-on "helm") +;;(depends-on "helm-ag") +;;(depends-on "helm-c-yasnippet") +;;(depends-on "helm-company") +;;(depends-on "helm-css-scss") +;;(depends-on "helm-describe-modes" :git "https://github.com/emacs-helm/helm-describe-modes") +;;(depends-on "helm-projectile") +;;(depends-on "helm-swoop") ;; Code evaluation/REPLs/debug -- core/core-eval.el (depends-on "quickrun") @@ -156,6 +161,7 @@ (depends-on "sass-mode") (depends-on "scss-mode") (depends-on "stylus-mode") +(depends-on "counsel-css" :git "https://github.com/hlissner/emacs-counsel-css") ;; Data -- modules/module-data.el (depends-on "company-ansible") diff --git a/core/core-editor.el b/core/core-editor.el index ebbb2aefa..37534cec8 100644 --- a/core/core-editor.el +++ b/core/core-editor.el @@ -253,6 +253,8 @@ (sp-with-modes '(xml-mode nxml-mode php-mode) (sp-local-pair "" :post-handlers '(("| " "SPC"))))) +(use-package swiper :commands (swiper swiper-all)) + ;; ;; Keybinding fixes diff --git a/core/core-eval.el b/core/core-eval.el index 4d5defe30..03b09750e 100644 --- a/core/core-eval.el +++ b/core/core-eval.el @@ -15,8 +15,7 @@ quickrun-with-arg quickrun-shell quickrun-compile-only - quickrun-replace-region - helm-quickrun) + quickrun-replace-region) :init (add-hook 'quickrun/mode-hook 'linum-mode) :config (setq quickrun-focus-p nil) diff --git a/core/core-ivy.el b/core/core-ivy.el new file mode 100644 index 000000000..3238bb971 --- /dev/null +++ b/core/core-ivy.el @@ -0,0 +1,35 @@ +;;; core-ivy.el +;; see defuns/defuns-ivy.el + +(use-package ivy + :init + (setq projectile-completion-system 'ivy + ivy-height 15 + ivy-do-completion-in-region nil) + + :config + (ivy-mode +1) + (map! :map ivy-minibuffer-map + [escape] 'keyboard-escape-quit + "C-w" 'backward-kill-word + "C-u" 'backward-kill-sentence + "C-b" 'backward-word + "C-f" 'forward-word) + + (require 'counsel) + (defun counsel-ag-function (string) + "Grep in the current directory for STRING." + (if (< (length string) 1) + (counsel-more-chars 1) + (let ((default-directory counsel--git-grep-dir) + (regex (counsel-unquote-regex-parens + (setq ivy--old-re + (ivy--regex string))))) + (counsel--async-command + (format counsel-ag-base-command (shell-quote-argument regex))) + nil)))) + +(use-package counsel-projectile :after projectile) + +(provide 'core-ivy) +;;; core-ivy.el ends here diff --git a/core/core-popup.el b/core/core-popup.el index 5eb9fba8f..e49f9a7e0 100644 --- a/core/core-popup.el +++ b/core/core-popup.el @@ -141,37 +141,37 @@ (message "Unable to find location in file")))) 'help-echo (purecopy "mouse-2, RET: find face's definition"))) -(after! helm - ;; This is a good alternative to either popwin or shackle, specifically for - ;; helm. If either fail me (for the last time), this is where I'll turn. - ;;(add-to-list 'display-buffer-alist - ;; `(,(rx bos "*helm" (* not-newline) "*" eos) - ;; (display-buffer-in-side-window) - ;; (inhibit-same-window . t) - ;; (window-height . 0.4))) +;; (after! helm +;; ;; This is a good alternative to either popwin or shackle, specifically for +;; ;; helm. If either fail me (for the last time), this is where I'll turn. +;; ;;(add-to-list 'display-buffer-alist +;; ;; `(,(rx bos "*helm" (* not-newline) "*" eos) +;; ;; (display-buffer-in-side-window) +;; ;; (inhibit-same-window . t) +;; ;; (window-height . 0.4))) - ;; Helm tries to clean up after itself, but shackle has already done this. - ;; This fixes that. To reproduce, add a helm rule in `shackle-rules', open two - ;; splits side-by-side, move to the buffer on the right and invoke helm. It - ;; will close all but the left-most buffer. - (setq-default helm-reuse-last-window-split-state t - helm-split-window-in-side-p t)) +;; ;; Helm tries to clean up after itself, but shackle has already done this. +;; ;; This fixes that. To reproduce, add a helm rule in `shackle-rules', open two +;; ;; splits side-by-side, move to the buffer on the right and invoke helm. It +;; ;; will close all but the left-most buffer. +;; (setq-default helm-reuse-last-window-split-state t +;; helm-split-window-in-side-p t)) -(after! helm-swoop - (setq helm-swoop-split-window-function (lambda (b) (doom/popup-buffer b)))) +;; (after! helm-swoop +;; (setq helm-swoop-split-window-function (lambda (b) (doom/popup-buffer b)))) -(after! helm-ag - ;; This prevents helm-ag from switching between windows and buffers. - (defadvice helm-ag--edit-abort (around helm-ag-edit-abort-popup-compat activate) - (cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it) - (doom/popup-close nil t t)) - (defadvice helm-ag--edit-commit (around helm-ag-edit-commit-popup-compat activate) - (cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it) - (doom/popup-close nil t t)) - (defadvice helm-ag--edit (around helm-ag-edit-popup-compat activate) - (cl-letf (((symbol-function 'other-window) 'ignore) - ((symbol-function 'switch-to-buffer) 'doom/popup-buffer)) - ad-do-it))) +;; (after! helm-ag +;; ;; This prevents helm-ag from switching between windows and buffers. +;; (defadvice helm-ag--edit-abort (around helm-ag-edit-abort-popup-compat activate) +;; (cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it) +;; (doom/popup-close nil t t)) +;; (defadvice helm-ag--edit-commit (around helm-ag-edit-commit-popup-compat activate) +;; (cl-letf (((symbol-function 'select-window) 'ignore)) ad-do-it) +;; (doom/popup-close nil t t)) +;; (defadvice helm-ag--edit (around helm-ag-edit-popup-compat activate) +;; (cl-letf (((symbol-function 'other-window) 'ignore) +;; ((symbol-function 'switch-to-buffer) 'doom/popup-buffer)) +;; ad-do-it))) (after! quickrun ;; This allows us to rerun code from inside a quickrun buffer. diff --git a/core/core-yasnippet.el b/core/core-yasnippet.el index 87709d05a..11ed24161 100644 --- a/core/core-yasnippet.el +++ b/core/core-yasnippet.el @@ -13,8 +13,7 @@ (setq yas-verbosity 0 yas-indent-line 'auto yas-also-auto-indent-first-line t - yas-wrap-around-region nil - yas-prompt-functions '(yas-ido-prompt yas-no-prompt) + yas-prompt-functions '(doom/yas-ivy-prompt yas-ido-prompt yas-no-prompt) ;; Only load personal snippets yas-snippet-dirs (list (concat doom-private-dir "/snippets") (concat doom-private-dir "/templates"))) diff --git a/core/core.el b/core/core.el index 4e87dba13..73a2ca927 100644 --- a/core/core.el +++ b/core/core.el @@ -159,6 +159,13 @@ :commands (describe-buffer describe-command describe-file describe-keymap describe-option describe-option-of-type)) +(use-package smex + :commands (smex smex-major-mode-commands) + :config + (setq smex-completion-method 'ivy + smex-save-file (concat doom-temp-dir "/smex-items")) + (smex-initialize)) + ;; ;; Automatic minor modes diff --git a/core/defuns/defuns-ivy.el b/core/defuns/defuns-ivy.el new file mode 100644 index 000000000..cbd4a667a --- /dev/null +++ b/core/defuns/defuns-ivy.el @@ -0,0 +1,57 @@ +;;; defuns-ivy.el + +;;;###autoload +(defun doom/ivy-switch-buffer (&optional all-p) + "Displays open buffers in current project. If ALL-P, then show all open +buffers." + (interactive) + (let ((this-command 'ivy-switch-buffer)) + (ivy-read "Switch to buffer: " (doom/get-buffer-names (not all-p)) + :matcher #'ivy--switch-buffer-matcher + :preselect (buffer-name (other-buffer (current-buffer))) + :action #'ivy--switch-buffer-action + :keymap ivy-switch-buffer-map + :caller 'doom/ivy-switch-buffer))) + +;;;###autoload +(defun doom/ivy-kill-ring () + (interactive) + (ivy-read "Kill ring:" (--filter (not (or (< (length it) 3) + (string-match-p "\\`[\n[:blank:]]+\\'" it))) + (remove-duplicates kill-ring :test' equal)))) + +;;;###autoload (autoload 'doom:ivy-recentf "defuns-ivy" nil t) +(evil-define-command doom:ivy-recentf (&optional bang) + "Ex-mode interface for `ivy-recentf' and `projectile-recentf'." + :repeat nil + (interactive "") + (if bang (ivy-recentf) (projectile-recentf))) + +;;;###autoload (autoload 'doom:ivy-swipe "defuns-ivy" nil t) +(evil-define-command doom:ivy-swiper (&optional search) + (interactive "") + (swiper (or search (thing-at-point 'symbol)))) + +;;;###autoload (autoload 'doom:ivy-ag-search "defuns-ivy" nil t) +(evil-define-operator doom:ivy-ag-search (beg end search regex-p &optional dir) + "Preform a counsel search with SEARCH. If SEARCH is nil and in visual mode, +use the selection, otherwise activate live ag searching in helm. + +If REGEX-P is non-nil, SEARCH will be treated as a regular expression. +DIR specifies the default-directory from which ag is run." + :type inclusive :repeat nil + (interactive "") + (let ((counsel-ag-base-command + (format "ag --nocolor --nogroup %s %%s -- ." + (if regex-p "-Q" ""))) + (search (or search (and beg end (buffer-substring-no-properties beg end))))) + (counsel-ag search (or dir (f-slash (doom/project-root)))))) + +;;;###autoload (autoload 'doom:ivy-ag-search-cwd "defuns-ivy" nil t) +(evil-define-operator doom:ivy-ag-search-cwd (beg end search regex-p) + :type inclusive :repeat nil + (interactive "") + (doom:ivy-ag-search beg end search regex-p default-directory)) + +(provide 'defuns-ivy) +;;; defuns-ivy.el ends here diff --git a/core/defuns/defuns-yasnippet.el b/core/defuns/defuns-yasnippet.el index 1da1eda48..3e210e987 100644 --- a/core/defuns/defuns-yasnippet.el +++ b/core/defuns/defuns-yasnippet.el @@ -92,9 +92,12 @@ normal mode if there are no fields." ;;;###autoload (defun doom/yas-find-file () "Browse through snippets folder" - ;; FIXME (interactive) - (doom/ido-find-file (car doom-snippet-dirs))) + (projectile-find-file-in-directory (car yas-snippet-dirs))) + +;;;###autoload +(defun doom/yas-ivy-prompt (prompt choices &optional display-fn) + (yas-completing-prompt prompt choices display-fn #'ivy-completing-read)) (provide 'defuns-yasnippet) ;;; nlinum-defuns.el ends here diff --git a/init.el b/init.el index e582f8998..985ca265e 100644 --- a/init.el +++ b/init.el @@ -48,7 +48,7 @@ core-flycheck ; get tazed for every semicolon you forget core-project ; for project navigation aficionados core-vcs ; remember remember, that commit in November - core-helm ; a search engine for life and love + core-ivy ; a search engine for life and love core-workgroups ; cure Emacs alzheimers + tab emulation core-eval ; run code, run; debug too diff --git a/modules/defuns/defuns-org.el b/modules/defuns/defuns-org.el index f4d427d90..efb5e65e7 100644 --- a/modules/defuns/defuns-org.el +++ b/modules/defuns/defuns-org.el @@ -3,20 +3,20 @@ ;;;###autoload (defun doom/org-find-file-in-notes () (interactive) - (in! (f-slash org-directory) - (helm-projectile-find-file))) + (let ((default-directory (f-slash org-directory))) + (projectile-find-file))) ;;;###autoload (defun doom/org-find-file () (interactive) - (in! (f-slash org-directory) - (helm-find-files nil))) + (let ((default-directory (f-slash org-directory))) + (counsel-find-file))) ;;;###autoload (defun doom/org-find-exported-file () (interactive) - (in! (f-slash doom-org-export-directory) - (helm-find-files nil))) + (let ((default-directory (f-slash doom-org-export-directory))) + (counsel-find-file))) ;;;###autoload (defun doom/org-get-property (name) diff --git a/modules/module-css.el b/modules/module-css.el index f50bcd31f..ff0cd572d 100644 --- a/modules/module-css.el +++ b/modules/module-css.el @@ -25,6 +25,10 @@ :mode "\\.less$" :config (push '("less" "css") projectile-other-file-alist)) +(use-package counsel-css + :commands (counsel-css counsel-css-imenu-setup) + :init (add-hook 'css-mode-hook 'counsel-css-imenu-setup)) + ;; ;; Sass @@ -50,10 +54,7 @@ (map! :map (css-mode-map sass-mode-map scss-mode-map) :n "M-R" 'doom/web-refresh-browser - (:localleader :nv ";" 'doom/append-semicolon) - (:leader - :n ";" 'helm-css-scss - :n ":" 'helm-css-scss-multi)) + (:localleader :nv ";" 'doom/append-semicolon)) (provide 'module-css) ;;; module-css.el ends here diff --git a/private/my-bindings.el b/private/my-bindings.el index e477ca646..6e5a9e21e 100644 --- a/private/my-bindings.el +++ b/private/my-bindings.el @@ -4,8 +4,10 @@ (map! "" 'what-face ;; Essential - "M-x" 'helm-M-x - "A-x" 'helm-M-x + "M-x" 'smex + "A-x" 'smex + "M-X" 'smex-major-mode-commands + "A-X" 'smex-major-mode-commands "M-;" 'eval-expression "A-;" 'eval-expression ;; Tools @@ -54,7 +56,7 @@ "A-SPC" 'just-one-space "M-a" 'mark-whole-buffer "M-c" 'evil-yank - "M-o" 'helm-find-files + "M-o" 'counsel-find-file "M-q" 'evil-quit-all "M-s" 'save-buffer "M-v" 'clipboard-yank @@ -76,24 +78,23 @@ ;;; and :m ";" 'evil-ex (:leader - :nv "," 'doom/helm-buffers-dwim - :nv "." 'helm-find-files - :nv "/" 'helm-projectile-find-file - :nv ":" 'helm-imenu-in-all-buffers - :nv ";" 'helm-semantic-or-imenu - :nv "<" 'helm-buffers-list + :nv "," 'doom/switch-to-project-buffer + :nv "<" 'doom/switch-to-buffer + :nv "." 'counsel-find-file + :nv ">" 'projectile-find-file-in-known-projects + :nv "/" 'counsel-projectile-find-file + :n ":" 'imenu-list-minor-mode + :nv ";" 'counsel-imenu :v "=" 'align-regexp - :nv ">" 'helm-projectile-find-file-in-known-projects - :nv "]" 'helm-etags-select - :nv "a" 'helm-projectile-find-other-file - :n "b" 'helm-bookmarks + :nv "a" 'projectile-find-other-file + :n "b" 'counsel-bookmark :n "e" 'doom/flycheck-errors :n "k" 'doom:docs-lookup :nv "l" 'doom/nlinum-toggle - :nv "m" 'helm-recentf - :nv "M" 'helm-projectile-recentf - :nv "p" 'helm-show-kill-ring - :nv "P" 'helm-projectile-switch-project + :nv "m" 'ivy-recentf + :nv "M" 'projectile-recentf + :nv "p" 'counsel-yank-pop + :nv "P" 'counsel-projectile :n "R" 'doom/reset-theme :n "s" 'yas-visit-snippet-file :n "S" 'doom/yas-find-file @@ -101,8 +102,8 @@ :nv "Q" 'evil-save-and-quit :nv "C-q" 'doom/kill-all-buffers-do-not-remember ;; Quick access to config files - :nv "E" 'doom/helm-find-in-emacsd - :nv "\\" 'doom/helm-find-in-dotfiles + :nv "E" 'doom/find-file-in-emacsd + :nv "\\" 'doom/find-file-in-dotfiles ;; Alternative to C-h (used as window shortcut) :n "h" 'help-command (:prefix "d" ; @@ -139,7 +140,6 @@ (:localleader :n "\\" 'doom/neotree - :n "]" 'imenu-list-minor-mode :n "b" 'doom:build :n "R" 'doom:repl :v "R" 'doom:repl-eval @@ -175,8 +175,7 @@ ;; Increment/decrement number under cursor :n "g=" 'evil-numbers/inc-at-pt :n "g-" 'evil-numbers/dec-at-pt - ;; NOTE: Helm is too bulky for ffap (which I use for quick file navigation) - :n "gf" (λ! (helm-mode -1) (call-interactively 'find-file-at-point) (helm-mode 1)) + :n "gf" 'find-file-at-point ;; Navigation :nv "K" 'smart-up :m "gD" 'doom/find-def @@ -298,7 +297,7 @@ [tab] 'doom/company-complete-common-or-complete-full "" 'company-select-previous [escape] (λ! (company-abort) (evil-normal-state 1)) - "" 'helm-company) + [C-return] 'counsel-company) (:map company-search-map "C-n" 'company-search-repeat-forward "C-p" 'company-search-repeat-backward diff --git a/private/my-commands.el b/private/my-commands.el index 881e4af57..f59192068 100644 --- a/private/my-commands.el +++ b/private/my-commands.el @@ -8,7 +8,7 @@ ;;; Custom commands ;; Emacs utilities (ex! "echo" 'doom:echo) -(ex! "minor" 'helm-describe-modes) ; list minor modes +(ex! "minor" 'describe-minor-mode) ; list minor modes (ex! "bc[omp]" 'doom:byte-compile) (ex! "re[load]" 'doom-reload) (ex! "re[load]au" 'doom-reload-autoloads) @@ -26,7 +26,7 @@ (ex! "htmle[nt]" 'doom/html-entities) ; encode/decode html entities (ex! "ie[dit]" 'evil-multiedit-ex-match) (ex! "na[rrow]" 'doom:narrow) -(ex! "rec[ent]" 'doom:helm-recentf) ; show recent files +(ex! "mru" 'doom:ivy-recentf) ; show recent files (ex! "ref[actor]" 'emr-show-refactor-menu) (ex! "reo[rient]" 'doom/window-reorient) ; scroll all windows to left (ex! "retab" 'doom:whitespace-retab) @@ -65,11 +65,11 @@ (ex! "m[sg]" 'doom/popup-messages) ; open *messages* in popup ;; Project navigation -(ex! "a" 'helm-projectile-find-other-file) -(ex! "ag" 'doom:helm-ag-search) -(ex! "ag[cw]d" 'doom:helm-ag-search-cwd) +(ex! "a" 'projectile-find-other-file) +(ex! "ag" 'doom:ivy-ag-search) +(ex! "ag[cw]d" 'doom:ivy-ag-search-cwd) (ex! "cd" 'doom:cd) -(ex! "se[arch]" 'doom:helm-swoop) ; in-file search +(ex! "sw[iper]" 'doom:ivy-swiper) ; in-file search ;; Project tools (ex! "build" 'doom:build)