441 lines
15 KiB
EmacsLisp
441 lines
15 KiB
EmacsLisp
|
;;; base-ivy.el --- Ayuditas y autocompletado del minibufer -*- lexical-binding: t -*-
|
||
|
|
||
|
;; Author: kj <webmaster@outcontrol.net>
|
||
|
;; URL: https://git.kj2.me/kj/confi-emacs-actual
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
|
||
|
;; Autocompletado para el minibuffer (counsel e ivy)
|
||
|
(use-package counsel
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:diminish ivy-mode counsel-mode
|
||
|
:bind (("C-s" . swiper-isearch)
|
||
|
("C-r" . swiper-isearch-backward)
|
||
|
("s-f" . swiper)
|
||
|
("C-S-s" . swiper-all)
|
||
|
|
||
|
("C-c C-r" . ivy-resume)
|
||
|
("C-c v p" . ivy-push-view)
|
||
|
("C-c v o" . ivy-pop-view)
|
||
|
("C-c v ." . ivy-switch-view)
|
||
|
|
||
|
:map counsel-mode-map
|
||
|
([remap swiper] . counsel-grep-or-swiper)
|
||
|
([remap swiper-backward] . counsel-grep-or-swiper-backward)
|
||
|
([remap dired] . counsel-dired)
|
||
|
([remap set-variable] . counsel-set-variable)
|
||
|
([remap insert-char] . counsel-unicode-char)
|
||
|
([remap recentf-open-files] . counsel-recentf)
|
||
|
([remap org-capture] . counsel-org-capture)
|
||
|
|
||
|
("C-c c B" . counsel-bookmarked-directory)
|
||
|
("C-c c F" . counsel-faces)
|
||
|
("C-c c L" . counsel-load-library)
|
||
|
("C-c c K" . counsel-ace-link)
|
||
|
("C-c c O" . counsel-find-file-extern)
|
||
|
("C-c c P" . counsel-package)
|
||
|
("C-c c R" . counsel-list-processes)
|
||
|
("C-c c a" . counsel-apropos)
|
||
|
("C-c c e" . counsel-colors-emacs)
|
||
|
("C-c c f" . counsel-find-library)
|
||
|
("C-c c g" . counsel-grep)
|
||
|
("C-c c h" . counsel-command-history)
|
||
|
("C-c c i" . counsel-git)
|
||
|
("C-c c j" . counsel-git-grep)
|
||
|
("C-c c l" . counsel-git-log)
|
||
|
("C-c c m" . counsel-minibuffer-history)
|
||
|
("C-c c o" . counsel-outline)
|
||
|
("C-c c p" . counsel-pt)
|
||
|
("C-c c r" . counsel-rg)
|
||
|
("C-c c s" . counsel-ag)
|
||
|
("C-c c t" . counsel-load-theme)
|
||
|
("C-c c u" . counsel-unicode-char)
|
||
|
("C-c c w" . counsel-colors-web)
|
||
|
("C-c c v" . counsel-set-variable)
|
||
|
("C-c c z" . counsel-fzf)
|
||
|
|
||
|
:map ivy-minibuffer-map
|
||
|
("C-w" . ivy-yank-word)
|
||
|
("<tab>" . ivy-partial)
|
||
|
("<escape>" . minibuffer-keyboard-quit)
|
||
|
|
||
|
:map counsel-find-file-map
|
||
|
("C-h" . counsel-up-directory)
|
||
|
|
||
|
:map swiper-map
|
||
|
("M-s" . swiper-isearch-toggle)
|
||
|
("M-%" . swiper-query-replace)
|
||
|
|
||
|
:map isearch-mode-map
|
||
|
("M-s" . swiper-isearch-toggle))
|
||
|
:hook ((after-init . ivy-mode)
|
||
|
(ivy-mode . counsel-mode))
|
||
|
:init
|
||
|
(setq enable-recursive-minibuffers t) ; Allow commands in minibuffers
|
||
|
|
||
|
(setq ivy-height 12
|
||
|
ivy-use-selectable-prompt t
|
||
|
ivy-use-virtual-buffers t ; Enable bookmarks and recentf
|
||
|
ivy-fixed-height-minibuffer t
|
||
|
ivy-count-format "(%d/%d) "
|
||
|
ivy-ignore-buffers '("\\` " "\\`\\*tramp/" "\\`\\*xref" "\\`\\*helpful "
|
||
|
"\\`\\*.+-posframe-buffer\\*" "\\` ?\\*company-.+\\*")
|
||
|
ivy-on-del-error-function #'ignore
|
||
|
ivy-initial-inputs-alist nil)
|
||
|
|
||
|
;; Use orderless regex strategy
|
||
|
(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order)))
|
||
|
|
||
|
;; Set minibuffer height for different commands
|
||
|
(setq ivy-height-alist '((counsel-evil-registers . 5)
|
||
|
(counsel-yank-pop . 8)
|
||
|
(counsel-git-log . 4)
|
||
|
(swiper . 15)
|
||
|
(counsel-projectile-ag . 15)
|
||
|
(counsel-projectile-rg . 15)))
|
||
|
|
||
|
|
||
|
(setq swiper-action-recenter t)
|
||
|
|
||
|
(setq counsel-find-file-at-point t
|
||
|
counsel-preselect-current-file t
|
||
|
counsel-yank-pop-separator "\n────────\n")
|
||
|
(add-hook 'counsel-grep-post-action-hook #'recenter)
|
||
|
|
||
|
;; Use the faster search tools
|
||
|
(when (executable-find "rg")
|
||
|
(setq counsel-grep-base-command "rg -S --no-heading --line-number --color never '%s' '%s'"))
|
||
|
(when (executable-find "fd")
|
||
|
(setq counsel-fzf-cmd
|
||
|
"fd --type f --hidden --follow --exclude .git --color never '%s'"))
|
||
|
|
||
|
:config
|
||
|
(with-no-warnings
|
||
|
;; persist views
|
||
|
(with-eval-after-load 'savehist
|
||
|
(add-to-list 'savehist-additional-variables 'ivy-views))
|
||
|
|
||
|
;; Highlight the selected item
|
||
|
(defun my-ivy-format-function (cands)
|
||
|
"Transform CANDS into a string for minibuffer."
|
||
|
(if (display-graphic-p)
|
||
|
(ivy-format-function-line cands)
|
||
|
(ivy-format-function-arrow cands)))
|
||
|
(setf (alist-get 't ivy-format-functions-alist) #'my-ivy-format-function)
|
||
|
|
||
|
;; Pre-fill search keywords
|
||
|
;; @see https://www.reddit.com/r/emacs/comments/b7g1px/withemacs_execute_commands_like_marty_mcfly/
|
||
|
(defvar my-ivy-fly-commands
|
||
|
'(query-replace-regexp
|
||
|
flush-lines keep-lines ivy-read
|
||
|
swiper swiper-backward swiper-all
|
||
|
swiper-isearch swiper-isearch-backward
|
||
|
lsp-ivy-workspace-symbol lsp-ivy-global-workspace-symbol
|
||
|
counsel-grep-or-swiper counsel-grep-or-swiper-backward
|
||
|
counsel-grep counsel-ack counsel-ag counsel-rg counsel-pt))
|
||
|
|
||
|
(defvar my-ivy-fly-back-commands
|
||
|
'(self-insert-command
|
||
|
ivy-forward-char ivy-delete-char delete-forward-char kill-word kill-sexp
|
||
|
end-of-line mwim-end-of-line mwim-end-of-code-or-line mwim-end-of-line-or-code
|
||
|
yank ivy-yank-word ivy-yank-char ivy-yank-symbol counsel-yank-pop))
|
||
|
|
||
|
(defvar-local my-ivy-fly--travel nil)
|
||
|
(defun my-ivy-fly-back-to-present ()
|
||
|
(cond ((and (memq last-command my-ivy-fly-commands)
|
||
|
(equal (this-command-keys-vector) (kbd "M-p")))
|
||
|
;; repeat one time to get straight to the first history item
|
||
|
(setq unread-command-events
|
||
|
(append unread-command-events
|
||
|
(listify-key-sequence (kbd "M-p")))))
|
||
|
((or (memq this-command my-ivy-fly-back-commands)
|
||
|
(equal (this-command-keys-vector) (kbd "M-n")))
|
||
|
(unless my-ivy-fly--travel
|
||
|
(delete-region (point) (point-max))
|
||
|
(when (memq this-command '(ivy-forward-char
|
||
|
ivy-delete-char delete-forward-char
|
||
|
kill-word kill-sexp
|
||
|
end-of-line mwim-end-of-line
|
||
|
mwim-end-of-code-or-line
|
||
|
mwim-end-of-line-or-code))
|
||
|
(insert (ivy-cleanup-string ivy-text))
|
||
|
(when (memq this-command '(ivy-delete-char
|
||
|
delete-forward-char
|
||
|
kill-word kill-sexp))
|
||
|
(beginning-of-line)))
|
||
|
(setq my-ivy-fly--travel t)))))
|
||
|
|
||
|
(defun my-ivy-fly-time-travel ()
|
||
|
(when (memq this-command my-ivy-fly-commands)
|
||
|
(insert (propertize
|
||
|
(save-excursion
|
||
|
(set-buffer (window-buffer (minibuffer-selected-window)))
|
||
|
(ivy-thing-at-point))
|
||
|
'face 'shadow))
|
||
|
(add-hook 'pre-command-hook 'my-ivy-fly-back-to-present nil t)
|
||
|
(beginning-of-line)))
|
||
|
|
||
|
(add-hook 'minibuffer-setup-hook #'my-ivy-fly-time-travel)
|
||
|
(add-hook 'minibuffer-exit-hook
|
||
|
(lambda ()
|
||
|
(remove-hook 'pre-command-hook 'my-ivy-fly-back-to-present t)))
|
||
|
|
||
|
;;
|
||
|
;; Improve search experience of `swiper' and `counsel'
|
||
|
;;
|
||
|
(defun my-ivy-switch-to-swiper (&rest _)
|
||
|
"Switch to `swiper' with the current input."
|
||
|
(swiper ivy-text))
|
||
|
|
||
|
(defun my-ivy-switch-to-swiper-isearch (&rest _)
|
||
|
"Switch to `swiper-isearch' with the current input."
|
||
|
(swiper-isearch ivy-text))
|
||
|
|
||
|
(defun my-ivy-switch-to-swiper-all (&rest _)
|
||
|
"Switch to `swiper-all' with the current input."
|
||
|
(swiper-all ivy-text))
|
||
|
|
||
|
(defun my-ivy-switch-to-rg-dwim (&rest _)
|
||
|
"Switch to `rg-dwim' with the current input."
|
||
|
(ivy-quit-and-run (rg-dwim default-directory)))
|
||
|
|
||
|
(defun my-ivy-switch-to-counsel-rg (&rest _)
|
||
|
"Switch to `counsel-rg' with the current input."
|
||
|
(counsel-rg ivy-text default-directory))
|
||
|
|
||
|
(defun my-ivy-switch-to-counsel-git-grep (&rest _)
|
||
|
"Switch to `counsel-git-grep' with the current input."
|
||
|
(counsel-git-grep ivy-text default-directory))
|
||
|
|
||
|
(defun my-ivy-switch-to-counsel-find-file (&rest _)
|
||
|
"Switch to `counsel-find-file' with the current input."
|
||
|
(counsel-find-file ivy-text))
|
||
|
|
||
|
(defun my-ivy-switch-to-counsel-fzf (&rest _)
|
||
|
"Switch to `counsel-fzf' with the current input."
|
||
|
(counsel-fzf ivy-text default-directory))
|
||
|
|
||
|
(defun my-ivy-switch-to-counsel-git (&rest _)
|
||
|
"Switch to `counsel-git' with the current input."
|
||
|
(counsel-git ivy-text))
|
||
|
|
||
|
(defun my-ivy-switch-to-list-bookmarks (&rest _)
|
||
|
"Switch to `list-bookmarks'."
|
||
|
(ivy-quit-and-run (call-interactively #'list-bookmarks)))
|
||
|
|
||
|
(defun my-ivy-switch-to-list-colors (&rest _)
|
||
|
"Switch to `list-colors-display'."
|
||
|
(ivy-quit-and-run (list-colors-display)))
|
||
|
|
||
|
(defun my-ivy-switch-to-list-packages (&rest _)
|
||
|
"Switch to `list-packages'."
|
||
|
(ivy-quit-and-run (list-packages)))
|
||
|
|
||
|
(defun my-ivy-switch-to-list-processes (&rest _)
|
||
|
"Switch to `list-processes'."
|
||
|
(ivy-quit-and-run (list-processes)))
|
||
|
|
||
|
(defun my-ivy-copy-library-path (lib)
|
||
|
"Copy the full path of LIB."
|
||
|
(let ((path (find-library-name lib)))
|
||
|
(kill-new path)
|
||
|
(message "Copied path: \"%s\"." path)))
|
||
|
|
||
|
;; @see https://emacs-china.org/t/swiper-swiper-isearch/9007/12
|
||
|
(defun my-swiper-toggle-counsel-rg ()
|
||
|
"Toggle `counsel-rg' and `swiper'/`swiper-isearch' with the current input."
|
||
|
(interactive)
|
||
|
(ivy-quit-and-run
|
||
|
(if (memq (ivy-state-caller ivy-last) '(swiper swiper-isearch))
|
||
|
(my-ivy-switch-to-counsel-rg)
|
||
|
(my-ivy-switch-to-swiper-isearch))))
|
||
|
(bind-key "<C-return>" #'my-swiper-toggle-counsel-rg swiper-map)
|
||
|
(bind-key "<C-return>" #'my-swiper-toggle-counsel-rg counsel-ag-map)
|
||
|
|
||
|
(with-eval-after-load 'rg
|
||
|
(defun my-swiper-toggle-rg-dwim ()
|
||
|
"Toggle `rg-dwim' with the current input."
|
||
|
(interactive)
|
||
|
(ivy-quit-and-run
|
||
|
(rg-dwim default-directory)))
|
||
|
(bind-key "<M-return>" #'my-swiper-toggle-rg-dwim swiper-map)
|
||
|
(bind-key "<M-return>" #'my-swiper-toggle-rg-dwim counsel-ag-map))
|
||
|
|
||
|
(defun my-swiper-toggle-swiper-isearch ()
|
||
|
"Toggle `swiper' and `swiper-isearch' with the current input."
|
||
|
(interactive)
|
||
|
(ivy-quit-and-run
|
||
|
(if (eq (ivy-state-caller ivy-last) 'swiper-isearch)
|
||
|
(swiper ivy-text)
|
||
|
(swiper-isearch ivy-text))))
|
||
|
(bind-key "<s-return>" #'my-swiper-toggle-swiper-isearch swiper-map)
|
||
|
|
||
|
(defun my-counsel-find-file-toggle-fzf ()
|
||
|
"Toggle `counsel-fzf' with the current `counsel-find-file' input."
|
||
|
(interactive)
|
||
|
(ivy-quit-and-run
|
||
|
(counsel-fzf (or ivy-text "") default-directory)))
|
||
|
(bind-key "<C-return>" #'my-counsel-find-file-toggle-fzf counsel-find-file-map)
|
||
|
|
||
|
(defun my-counsel-toggle ()
|
||
|
"Toggle `counsel' commands and original commands."
|
||
|
(interactive)
|
||
|
(pcase (ivy-state-caller ivy-last)
|
||
|
('counsel-bookmark (my-ivy-switch-to-list-bookmarks))
|
||
|
('counsel-colors-emacs (my-ivy-switch-to-list-colors))
|
||
|
('counsel-colors-web (my-ivy-switch-to-list-colors))
|
||
|
('counsel-list-processes (my-ivy-switch-to-list-processes))
|
||
|
('counsel-package (my-ivy-switch-to-list-packages))
|
||
|
(_ (ignore))))
|
||
|
(bind-key "<C-return>" #'my-counsel-toggle ivy-minibuffer-map)
|
||
|
|
||
|
;; More actions
|
||
|
(ivy-add-actions
|
||
|
#'swiper-isearch
|
||
|
'(("r" my-ivy-switch-to-counsel-rg "rg")
|
||
|
("d" my-ivy-switch-to-rg-dwim "rg dwim")
|
||
|
("s" my-ivy-switch-to-swiper "swiper")
|
||
|
("a" my-ivy-switch-to-swiper-all "swiper all")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'swiper
|
||
|
'(("r" my-ivy-switch-to-counsel-rg "rg")
|
||
|
("d" my-ivy-switch-to-rg-dwim "rg dwim")
|
||
|
("s" my-ivy-switch-to-swiper-isearch "swiper isearch")
|
||
|
("a" my-ivy-switch-to-swiper-all "swiper all")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'swiper-all
|
||
|
'(("g" my-ivy-switch-to-counsel-git-grep "git grep")
|
||
|
("r" my-ivy-switch-to-counsel-rg "rg")
|
||
|
("d" my-ivy-switch-to-rg-dwim "rg dwim")
|
||
|
("s" my-swiper-toggle-swiper-isearch "swiper isearch")
|
||
|
("S" my-ivy-switch-to-swiper "swiper")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-rg
|
||
|
'(("s" my-ivy-switch-to-swiper-isearch "swiper isearch")
|
||
|
("S" my-ivy-switch-to-swiper "swiper")
|
||
|
("a" my-ivy-switch-to-swiper-all "swiper all")
|
||
|
("d" my-ivy-switch-to-rg-dwim "rg dwim")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-git-grep
|
||
|
'(("s" my-ivy-switch-to-swiper-isearch "swiper isearch")
|
||
|
("S" my-ivy-switch-to-swiper "swiper")
|
||
|
("r" my-ivy-switch-to-rg-dwim "rg")
|
||
|
("d" my-ivy-switch-to-rg-dwim "rg dwim")
|
||
|
("a" my-ivy-switch-to-swiper-all "swiper all")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-find-file
|
||
|
'(("g" my-ivy-switch-to-counsel-git "git")
|
||
|
("z" my-ivy-switch-to-counsel-fzf "fzf")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-git
|
||
|
'(("f" my-ivy-switch-to-counsel-find-file "find file")
|
||
|
("z" my-ivy-switch-to-counsel-fzf "fzf")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
'counsel-fzf
|
||
|
'(("f" my-ivy-switch-to-counsel-find-file "find file")
|
||
|
("g" my-ivy-switch-to-counsel-git "git")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
'counsel-find-library
|
||
|
'(("p" my-ivy-copy-library-path "copy path")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
'counsel-load-library
|
||
|
'(("p" my-ivy-copy-library-path "copy path")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-bookmark
|
||
|
'(("l" my-ivy-switch-to-list-bookmarks "list")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-colors-emacs
|
||
|
'(("l" my-ivy-switch-to-list-colors "list")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-colors-web
|
||
|
'(("l" my-ivy-switch-to-list-colors "list")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-package
|
||
|
'(("l" my-ivy-switch-to-list-packages "list packages")))
|
||
|
|
||
|
(ivy-add-actions
|
||
|
#'counsel-list-processes
|
||
|
'(("l" my-ivy-switch-to-list-processes "list")))))
|
||
|
|
||
|
;; Autocompletado de proyectos en counsel (projectile)
|
||
|
(use-package counsel-projectile
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:bind*
|
||
|
("C-x p" . counsel-projectile)
|
||
|
:hook (counsel-mode . counsel-projectile-mode)
|
||
|
:init (setq counsel-projectile-grep-initial-input '(ivy-thing-at-point)))
|
||
|
|
||
|
|
||
|
;; Enhance M-x
|
||
|
(use-package amx
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:bind (("M-x" . amx)
|
||
|
("<menu>" . amx))
|
||
|
:init (setq amx-history-length 20))
|
||
|
|
||
|
;; Avy integration
|
||
|
(use-package ivy-avy
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:bind (:map ivy-minibuffer-map
|
||
|
("C-'" . ivy-avy)))
|
||
|
|
||
|
(use-package ivy
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:hook (after-init . ivy-mode)
|
||
|
:config
|
||
|
(setq ivy-use-virtual-buffers nil))
|
||
|
|
||
|
(use-package ivy-rich
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:ensure t
|
||
|
:hook ((counsel-projectile-mode . ivy-rich-mode) ; MUST after `counsel-projectile'
|
||
|
(ivy-rich-mode . ivy-rich-project-root-cache-mode)
|
||
|
(ivy-rich-mode . (lambda ()
|
||
|
"Use abbreviate in `ivy-rich-mode'."
|
||
|
(setq ivy-virtual-abbreviate
|
||
|
(or (and ivy-rich-mode 'abbreviate) 'name)))))
|
||
|
:init
|
||
|
;; For better performance
|
||
|
(setq ivy-rich-parse-remote-buffer nil))
|
||
|
|
||
|
;; Iconos en Ivy (allthe icons)
|
||
|
(use-package all-the-icons-ivy-rich
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:ensure t
|
||
|
:hook (ivy-mode . all-the-icons-ivy-rich-mode)
|
||
|
:config
|
||
|
(setq all-the-icons-ivy-rich-color-icon t))
|
||
|
|
||
|
|
||
|
;; Integrate yasnippet
|
||
|
(use-package ivy-yasnippet
|
||
|
:defer t
|
||
|
:straight t
|
||
|
:bind ("C-c C-y" . ivy-yasnippet))
|
||
|
|
||
|
(provide 'base-ivy)
|
||
|
;;; base-ivy.el ends here
|