mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-22 02:50:24 +10:00
Moving to Doom Emacs!
This commit is contained in:
131
.emacs.d/modules/completion/company/README.org
Normal file
131
.emacs.d/modules/completion/company/README.org
Normal file
@@ -0,0 +1,131 @@
|
||||
#+TITLE: completion/company
|
||||
#+DATE: February 19, 2017
|
||||
#+SINCE: v2.0
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#code-completion][Code completion]]
|
||||
- [[#vim-esque-omni-completion-prefix-c-x][Vim-esque omni-completion prefix (C-x)]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#enable-company-backends-in-certain-modes][Enable company backend(s) in certain modes]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#x-mode-doesnt-have-code-completion-support-or-requires-extra-setup][X-mode doesn't have code completion support or requires extra setup.]]
|
||||
- [[#no-backends-or-the-incorrect-ones-have-been-registered-for-x-mode][No backends (or the incorrect ones) have been registered for X-mode.]]
|
||||
|
||||
* Description
|
||||
This module provides code completion, powered by [[https://github.com/company-mode/company-mode][company-mode]]. It is required
|
||||
for code completion in many of Doom's :lang modules.
|
||||
|
||||
https://assets.doomemacs.org/completion/company/overlay.png
|
||||
|
||||
** Module Flags
|
||||
+ =+childframe= Enables displaying completion candidates in a child frame,
|
||||
rather than an overlay or tooltip (among with other UI enhancements). *This
|
||||
requires GUI Emacs 26.1+ and is incompatible with the =+tng= flag*
|
||||
+ =+tng= Enables completion using only ~TAB~. Pressing ~TAB~ will select the
|
||||
next completion suggestion, while ~S-TAB~ will select the previous one. *This
|
||||
is incompatible with the =+childframe= flag*
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/company-mode/company-mode][company-mode]]
|
||||
+ [[https://github.com/hlissner/emacs-company-dict][company-dict]]
|
||||
+ [[https://github.com/raxod502/prescient.el][company-prescient]]
|
||||
+ [[https://github.com/sebastiencs/company-box][company-box]]* (=+childframe=)
|
||||
|
||||
* Prerequisites
|
||||
This module has no direct prerequisites.
|
||||
|
||||
However, some major modes may require additional setup for code completion to
|
||||
work in them. Some major modes may have no completion support at all. Check that
|
||||
major mode's module's documentation for details.
|
||||
|
||||
* Features
|
||||
** Code completion
|
||||
By default, completion is triggered after a short idle period or with the
|
||||
=C-SPC= key. While the popup is visible, the following keys are available:
|
||||
|
||||
| Keybind | Description |
|
||||
|---------+------------------------------------------|
|
||||
| =C-n= | Go to next candidate |
|
||||
| =C-p= | Go to previous candidate |
|
||||
| =C-j= | (evil) Go to next candidate |
|
||||
| =C-k= | (evil) Go to previous candidate |
|
||||
| =C-h= | Display documentation (if available) |
|
||||
| =C-u= | Move to previous page of candidates |
|
||||
| =C-d= | Move to next page of candidates |
|
||||
| =C-s= | Filter candidates |
|
||||
| =C-S-s= | Search candidates with helm/ivy |
|
||||
| =C-SPC= | Complete common |
|
||||
| =TAB= | Complete common or select next candidate |
|
||||
| =S-TAB= | Select previous candidate |
|
||||
|
||||
** Vim-esque omni-completion prefix (C-x)
|
||||
In the spirit of Vim's omni-completion, the following insert mode keybinds are
|
||||
available to evil users to access specific company backends:
|
||||
|
||||
| Keybind | Description |
|
||||
|-----------+-----------------------------------|
|
||||
| =C-x C-]= | Complete etags |
|
||||
| =C-x C-f= | Complete file path |
|
||||
| =C-x C-k= | Complete from dictionary/keyword |
|
||||
| =C-x C-l= | Complete full line |
|
||||
| =C-x C-o= | Invoke complete-at-point function |
|
||||
| =C-x C-n= | Complete next symbol at point |
|
||||
| =C-x C-p= | Complete previous symbol at point |
|
||||
| =C-x C-s= | Complete snippet |
|
||||
| =C-x s= | Complete spelling suggestions |
|
||||
|
||||
* Configuration
|
||||
** Enable company backend(s) in certain modes
|
||||
The ~set-company-backend!~ function exists for setting ~company-backends~
|
||||
buffer-locally in MODES, which is either a major-mode symbol, a minor-mode
|
||||
symbol, or a list of either. BACKENDS are prepended to ~company-backends~ for
|
||||
those modes.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(after! js2-mode
|
||||
(set-company-backend! 'js2-mode 'company-tide 'company-yasnippet))
|
||||
|
||||
(after! sh-script
|
||||
(set-company-backend! 'sh-mode
|
||||
'(company-shell :with company-yasnippet)))
|
||||
|
||||
(after! cc-mode
|
||||
(set-company-backend! 'c-mode
|
||||
'(:separate company-irony-c-headers company-irony)))
|
||||
#+END_SRC
|
||||
|
||||
To unset the backends for a particular mode, pass ~nil~ to it:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(after! sh-script
|
||||
(set-company-backend! 'sh-mode nil))
|
||||
#+END_SRC
|
||||
|
||||
* Troubleshooting
|
||||
If code completion isn't working for you, consider the following common causes
|
||||
before you file a bug report:
|
||||
|
||||
** X-mode doesn't have code completion support or requires extra setup.
|
||||
There is no guarantee your language mode will have completion support.
|
||||
|
||||
Some, like ~lua-mode~, don't have completion support in Emacs at all. Others may
|
||||
requires additional setup to get code completion working. For instance,
|
||||
~go-mode~ requires ~guru~ to be installed on your system, and ~enh-ruby-mode~
|
||||
requires that you have a Robe server running (~M-x robe-start~).
|
||||
|
||||
Check the relevant module's documentation for this kind of information.
|
||||
|
||||
** No backends (or the incorrect ones) have been registered for X-mode.
|
||||
Doom expects every mode to have an explicit list of company-backends (and as
|
||||
short a list as possible). This may mean you aren't getting all the completion
|
||||
you want or any at all.
|
||||
|
||||
Check the value of ~company-backends~ (=SPC h v company-backends=) from that
|
||||
mode to see what backends are available. Check the [[*Assigning company backend(s) to modes][Configuration section]] for
|
||||
details on changing what backends are available for that mode.
|
||||
156
.emacs.d/modules/completion/company/autoload.el
Normal file
156
.emacs.d/modules/completion/company/autoload.el
Normal file
@@ -0,0 +1,156 @@
|
||||
;;; completion/company/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defvar +company-backend-alist
|
||||
'((text-mode company-dabbrev company-yasnippet company-ispell)
|
||||
(prog-mode company-capf company-yasnippet)
|
||||
(conf-mode company-capf company-dabbrev-code company-yasnippet))
|
||||
"An alist matching modes to company backends. The backends for any mode is
|
||||
built from this.")
|
||||
|
||||
;;;###autodef
|
||||
(defun set-company-backend! (modes &rest backends)
|
||||
"Prepends BACKENDS (in order) to `company-backends' in MODES.
|
||||
|
||||
MODES should be one symbol or a list of them, representing major or minor modes.
|
||||
This will overwrite backends for MODES on consecutive uses.
|
||||
|
||||
If the car of BACKENDS is nil, unset the backends for MODES.
|
||||
|
||||
Examples:
|
||||
|
||||
(set-company-backend! 'js2-mode
|
||||
'company-tide 'company-yasnippet)
|
||||
|
||||
(set-company-backend! 'sh-mode
|
||||
'(company-shell :with company-yasnippet))
|
||||
|
||||
(set-company-backend! '(c-mode c++-mode)
|
||||
'(:separate company-irony-c-headers company-irony))
|
||||
|
||||
(set-company-backend! 'sh-mode nil) ; unsets backends for sh-mode"
|
||||
(declare (indent defun))
|
||||
(dolist (mode (doom-enlist modes))
|
||||
(if (null (car backends))
|
||||
(setq +company-backend-alist
|
||||
(delq (assq mode +company-backend-alist)
|
||||
+company-backend-alist))
|
||||
(setf (alist-get mode +company-backend-alist)
|
||||
backends))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
|
||||
(defun +company--backends ()
|
||||
(let (backends)
|
||||
(let ((mode major-mode)
|
||||
(modes (list major-mode)))
|
||||
(while (setq mode (get mode 'derived-mode-parent))
|
||||
(push mode modes))
|
||||
(dolist (mode modes)
|
||||
(dolist (backend (append (cdr (assq mode +company-backend-alist))
|
||||
(default-value 'company-backends)))
|
||||
(push backend backends)))
|
||||
(delete-dups
|
||||
(append (cl-loop for (mode . backends) in +company-backend-alist
|
||||
if (or (eq major-mode mode) ; major modes
|
||||
(and (boundp mode)
|
||||
(symbol-value mode))) ; minor modes
|
||||
append backends)
|
||||
(nreverse backends))))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +company-init-backends-h ()
|
||||
"Set `company-backends' for the current buffer."
|
||||
(if (not company-mode)
|
||||
(remove-hook 'change-major-mode-after-body-hook #'+company-init-backends-h 'local)
|
||||
(unless (eq major-mode 'fundamental-mode)
|
||||
(setq-local company-backends (+company--backends)))
|
||||
(add-hook 'change-major-mode-after-body-hook #'+company-init-backends-h nil 'local)))
|
||||
|
||||
(put '+company-init-backends-h 'permanent-local-hook t)
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +company-has-completion-p ()
|
||||
"Return non-nil if a completion candidate exists at point."
|
||||
(and (company-manual-begin)
|
||||
(= company-candidates-length 1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/toggle-auto-completion ()
|
||||
"Toggle as-you-type code completion."
|
||||
(interactive)
|
||||
(require 'company)
|
||||
(setq company-idle-delay (unless company-idle-delay 0.2))
|
||||
(message "Auto completion %s"
|
||||
(if company-idle-delay "enabled" "disabled")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/complete ()
|
||||
"Bring up the completion popup. If only one result, complete it."
|
||||
(interactive)
|
||||
(require 'company)
|
||||
(when (ignore-errors
|
||||
(/= (point)
|
||||
(cdr (bounds-of-thing-at-point 'symbol))))
|
||||
(save-excursion (insert " ")))
|
||||
(when (and (company-manual-begin)
|
||||
(= company-candidates-length 1))
|
||||
(company-complete-common)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/dabbrev ()
|
||||
"Invokes `company-dabbrev-code' in prog-mode buffers and `company-dabbrev'
|
||||
everywhere else."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (derived-mode-p 'prog-mode)
|
||||
#'company-dabbrev-code
|
||||
#'company-dabbrev)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/whole-lines (command &optional arg &rest ignored)
|
||||
"`company-mode' completion backend that completes whole-lines, akin to vim's
|
||||
C-x C-l."
|
||||
(interactive (list 'interactive))
|
||||
(require 'company)
|
||||
(pcase command
|
||||
(`interactive (company-begin-backend '+company/whole-lines))
|
||||
(`prefix (company-grab-line "^[\t\s]*\\(.+\\)" 1))
|
||||
(`candidates
|
||||
(all-completions
|
||||
arg
|
||||
(delete-dups
|
||||
(split-string
|
||||
(replace-regexp-in-string
|
||||
"^[\t\s]+" ""
|
||||
(concat (buffer-substring-no-properties (point-min) (line-beginning-position))
|
||||
(buffer-substring-no-properties (line-end-position) (point-max))))
|
||||
"\\(\r\n\\|[\n\r]\\)" t))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/dict-or-keywords ()
|
||||
"`company-mode' completion combining `company-dict' and `company-keywords'."
|
||||
(interactive)
|
||||
(require 'company-dict)
|
||||
(require 'company-keywords)
|
||||
(let ((company-backends '((company-keywords company-dict))))
|
||||
(call-interactively #'company-complete)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +company/dabbrev-code-previous ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(require 'company-dabbrev)
|
||||
(let ((company-selection-wrap-around t))
|
||||
(call-interactively #'+company/dabbrev)
|
||||
(company-select-previous-or-abort)))
|
||||
133
.emacs.d/modules/completion/company/config.el
Normal file
133
.emacs.d/modules/completion/company/config.el
Normal file
@@ -0,0 +1,133 @@
|
||||
;;; completion/company/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! company
|
||||
:commands company-complete-common company-manual-begin company-grab-line
|
||||
:after-call pre-command-hook after-find-file
|
||||
:init
|
||||
(setq company-minimum-prefix-length 2
|
||||
company-tooltip-limit 14
|
||||
company-dabbrev-downcase nil
|
||||
company-dabbrev-ignore-case nil
|
||||
company-dabbrev-code-other-buffers t
|
||||
company-tooltip-align-annotations t
|
||||
company-require-match 'never
|
||||
company-global-modes
|
||||
'(not erc-mode message-mode help-mode gud-mode eshell-mode)
|
||||
company-backends '(company-capf)
|
||||
company-frontends
|
||||
'(company-pseudo-tooltip-frontend
|
||||
company-echo-metadata-frontend))
|
||||
:config
|
||||
(when (featurep! :editor evil)
|
||||
(add-hook 'company-mode-hook #'evil-normalize-keymaps)
|
||||
|
||||
;; Allow users to switch between backends on the fly. E.g. C-x C-s followed
|
||||
;; by C-x C-n, will switch from `company-yasnippet' to
|
||||
;; `company-dabbrev-code'.
|
||||
(defadvice! +company--abort-previous-a (&rest _)
|
||||
:before #'company-begin-backend
|
||||
(company-abort)))
|
||||
|
||||
(add-hook 'company-mode-hook #'+company-init-backends-h)
|
||||
(global-company-mode +1))
|
||||
|
||||
|
||||
(use-package! company-tng
|
||||
:when (featurep! +tng)
|
||||
:after-call post-self-insert-hook
|
||||
:config
|
||||
(add-to-list 'company-frontends 'company-tng-frontend)
|
||||
(define-key! company-active-map
|
||||
"RET" nil
|
||||
[return] nil
|
||||
"TAB" #'company-select-next
|
||||
[tab] #'company-select-next
|
||||
[backtab] #'company-select-previous))
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(after! company-files
|
||||
(pushnew! company-files--regexps
|
||||
"file:\\(\\(?:\\.\\{1,2\\}/\\|~/\\|/\\)[^\]\n]*\\)"))
|
||||
|
||||
|
||||
(use-package! company-prescient
|
||||
:hook (company-mode . company-prescient-mode)
|
||||
:config
|
||||
;; NOTE prescient config duplicated with `ivy'
|
||||
(setq prescient-save-file (concat doom-cache-dir "prescient-save.el"))
|
||||
(prescient-persist-mode +1))
|
||||
|
||||
|
||||
(use-package! company-box
|
||||
:when (featurep! +childframe)
|
||||
:hook (company-mode . company-box-mode)
|
||||
:config
|
||||
(setq company-box-show-single-candidate t
|
||||
company-box-backends-colors nil
|
||||
company-box-max-candidates 50
|
||||
company-box-icons-alist 'company-box-icons-all-the-icons
|
||||
company-box-icons-functions
|
||||
'(+company-box-icons--yasnippet-fn
|
||||
company-box-icons--lsp
|
||||
+company-box-icons--elisp-fn
|
||||
company-box-icons--acphp)
|
||||
company-box-icons-all-the-icons
|
||||
`((Unknown . ,(all-the-icons-material "find_in_page" :height 0.8 :face 'all-the-icons-purple))
|
||||
(Text . ,(all-the-icons-material "text_fields" :height 0.8 :face 'all-the-icons-green))
|
||||
(Method . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Function . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constructor . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Field . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(Variable . ,(all-the-icons-material "adjust" :height 0.8 :face 'all-the-icons-blue))
|
||||
(Class . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
(Interface . ,(all-the-icons-material "settings_input_component" :height 0.8 :face 'all-the-icons-red))
|
||||
(Module . ,(all-the-icons-material "view_module" :height 0.8 :face 'all-the-icons-red))
|
||||
(Property . ,(all-the-icons-material "settings" :height 0.8 :face 'all-the-icons-red))
|
||||
(Unit . ,(all-the-icons-material "straighten" :height 0.8 :face 'all-the-icons-red))
|
||||
(Value . ,(all-the-icons-material "filter_1" :height 0.8 :face 'all-the-icons-red))
|
||||
(Enum . ,(all-the-icons-material "plus_one" :height 0.8 :face 'all-the-icons-red))
|
||||
(Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.8 :face 'all-the-icons-red))
|
||||
(Snippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-red))
|
||||
(Color . ,(all-the-icons-material "color_lens" :height 0.8 :face 'all-the-icons-red))
|
||||
(File . ,(all-the-icons-material "insert_drive_file" :height 0.8 :face 'all-the-icons-red))
|
||||
(Reference . ,(all-the-icons-material "collections_bookmark" :height 0.8 :face 'all-the-icons-red))
|
||||
(Folder . ,(all-the-icons-material "folder" :height 0.8 :face 'all-the-icons-red))
|
||||
(EnumMember . ,(all-the-icons-material "people" :height 0.8 :face 'all-the-icons-red))
|
||||
(Constant . ,(all-the-icons-material "pause_circle_filled" :height 0.8 :face 'all-the-icons-red))
|
||||
(Struct . ,(all-the-icons-material "streetview" :height 0.8 :face 'all-the-icons-red))
|
||||
(Event . ,(all-the-icons-material "event" :height 0.8 :face 'all-the-icons-red))
|
||||
(Operator . ,(all-the-icons-material "control_point" :height 0.8 :face 'all-the-icons-red))
|
||||
(TypeParameter . ,(all-the-icons-material "class" :height 0.8 :face 'all-the-icons-red))
|
||||
;; (Template . ,(company-box-icons-image "Template.png"))))
|
||||
(Yasnippet . ,(all-the-icons-material "short_text" :height 0.8 :face 'all-the-icons-green))
|
||||
(ElispFunction . ,(all-the-icons-material "functions" :height 0.8 :face 'all-the-icons-red))
|
||||
(ElispVariable . ,(all-the-icons-material "check_circle" :height 0.8 :face 'all-the-icons-blue))
|
||||
(ElispFeature . ,(all-the-icons-material "stars" :height 0.8 :face 'all-the-icons-orange))
|
||||
(ElispFace . ,(all-the-icons-material "format_paint" :height 0.8 :face 'all-the-icons-pink))))
|
||||
|
||||
(defun +company-box-icons--yasnippet-fn (candidate)
|
||||
(when (get-text-property 0 'yas-annotation candidate)
|
||||
'Yasnippet))
|
||||
|
||||
(defun +company-box-icons--elisp-fn (candidate)
|
||||
(when (derived-mode-p 'emacs-lisp-mode)
|
||||
(let ((sym (intern candidate)))
|
||||
(cond ((fboundp sym) 'ElispFunction)
|
||||
((boundp sym) 'ElispVariable)
|
||||
((featurep sym) 'ElispFeature)
|
||||
((facep sym) 'ElispFace))))))
|
||||
|
||||
|
||||
(use-package! company-dict
|
||||
:defer t
|
||||
:config
|
||||
(setq company-dict-dir (expand-file-name "dicts" doom-private-dir))
|
||||
(add-hook! 'doom-project-hook
|
||||
(defun +company-enable-project-dicts-h (mode &rest _)
|
||||
"Enable per-project dictionaries."
|
||||
(if (symbol-value mode)
|
||||
(add-to-list 'company-dict-minor-mode-list mode nil #'eq)
|
||||
(setq company-dict-minor-mode-list (delq mode company-dict-minor-mode-list))))))
|
||||
8
.emacs.d/modules/completion/company/packages.el
Normal file
8
.emacs.d/modules/completion/company/packages.el
Normal file
@@ -0,0 +1,8 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/company/packages.el
|
||||
|
||||
(package! company)
|
||||
(package! company-dict)
|
||||
(package! company-prescient)
|
||||
(when (featurep! +childframe)
|
||||
(package! company-box))
|
||||
75
.emacs.d/modules/completion/company/test/test-company.el
Normal file
75
.emacs.d/modules/completion/company/test/test-company.el
Normal file
@@ -0,0 +1,75 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; completion/company/test/test-company.el
|
||||
|
||||
(describe "completion/company"
|
||||
(before-all
|
||||
(load! "../autoload"))
|
||||
|
||||
(describe ":company-backend"
|
||||
:var (a +company-backend-alist backends)
|
||||
(before-each
|
||||
(setq-default company-backends '(t))
|
||||
(setq +company-backend-alist nil
|
||||
a (get-buffer-create "x"))
|
||||
(fset 'backends
|
||||
(lambda (mode)
|
||||
(let ((major-mode mode))
|
||||
(+company--backends))))
|
||||
(set-buffer a)
|
||||
(spy-on 'require))
|
||||
(after-each
|
||||
(kill-buffer a))
|
||||
|
||||
;;
|
||||
(it "sets backends for a major mode"
|
||||
(set-company-backend! 'text-mode 'a)
|
||||
(expect (backends 'text-mode) :to-equal '(a t)))
|
||||
|
||||
(it "sets backends for a derived-mode"
|
||||
(set-company-backend! 'prog-mode 'a)
|
||||
(expect (backends 'prog-mode) :to-equal '(a t))
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(a t)))
|
||||
|
||||
(it "sets multiple backends for exact major modes"
|
||||
(set-company-backend! '(text-mode emacs-lisp-mode) 'a 'b)
|
||||
(expect (backends 'text-mode) :to-equal (backends 'emacs-lisp-mode)))
|
||||
|
||||
(it "sets cumulative backends"
|
||||
(set-company-backend! 'prog-mode '(a b c))
|
||||
(set-company-backend! 'emacs-lisp-mode 'd 'e)
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(d e (a b c) t)))
|
||||
|
||||
(it "sets cumulative backends with a minor mode"
|
||||
(set-company-backend! 'prog-mode '(a b c))
|
||||
(set-company-backend! 'emacs-lisp-mode 'd 'e)
|
||||
(set-company-backend! 'some-minor-mode 'x 'y)
|
||||
(setq-local some-minor-mode t)
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(x y d e (a b c) t)))
|
||||
|
||||
(it "overwrites past backends"
|
||||
(set-company-backend! 'text-mode 'old 'backends)
|
||||
(set-company-backend! 'text-mode 'new 'backends)
|
||||
(expect (backends 'text-mode) :to-equal '(new backends t)))
|
||||
|
||||
(it "unsets past backends"
|
||||
(set-company-backend! 'text-mode 'old)
|
||||
(set-company-backend! 'text-mode nil)
|
||||
(expect (backends 'text-mode) :to-equal (default-value 'company-backends)))
|
||||
|
||||
(it "unsets past parent backends"
|
||||
(set-company-backend! 'prog-mode 'old)
|
||||
(set-company-backend! 'emacs-lisp-mode 'child)
|
||||
(set-company-backend! 'prog-mode nil)
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(child t)))
|
||||
|
||||
(it "overwrites past cumulative backends"
|
||||
(set-company-backend! 'prog-mode 'base)
|
||||
(set-company-backend! 'emacs-lisp-mode 'old)
|
||||
(set-company-backend! 'emacs-lisp-mode 'new)
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(new base t)))
|
||||
|
||||
(it "overwrites past parent backends"
|
||||
(set-company-backend! 'prog-mode 'base)
|
||||
(set-company-backend! 'emacs-lisp-mode 'child)
|
||||
(set-company-backend! 'prog-mode 'new)
|
||||
(expect (backends 'emacs-lisp-mode) :to-equal '(child new t)))))
|
||||
42
.emacs.d/modules/completion/helm/autoload/evil.el
Normal file
42
.emacs.d/modules/completion/helm/autoload/evil.el
Normal file
@@ -0,0 +1,42 @@
|
||||
;;; completion/helm/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :editor evil)
|
||||
|
||||
;;;###autoload (autoload '+helm:project-search "completion/helm/autoload/evil" nil t)
|
||||
(evil-define-command +helm:project-search (all-files-p query)
|
||||
"Ex interface for `+helm/grep'"
|
||||
(interactive "<!><a>")
|
||||
(+helm/project-search all-files-p query))
|
||||
|
||||
;;;###autoload (autoload '+helm:project-search-from-cwd "completion/helm/autoload/evil" nil t)
|
||||
(evil-define-command +helm:project-search-from-cwd (query &optional recurse-p)
|
||||
"Ex interface for `+helm/grep-from-cwd'."
|
||||
(interactive "<a><!>")
|
||||
(+helm/project-search-from-cwd (not recurse-p) query))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm--set-prompt-display (pos)
|
||||
"TODO"
|
||||
(let (beg state region-active m)
|
||||
(with-selected-window (minibuffer-window)
|
||||
(setq beg (save-excursion (vertical-motion 0 (helm-window)) (point))
|
||||
state evil-state
|
||||
region-active (region-active-p)
|
||||
m (mark t)))
|
||||
(when region-active
|
||||
(setq m (- m beg))
|
||||
;; Increment pos to handle the space before prompt (i.e `pref').
|
||||
(put-text-property (1+ (min m pos)) (+ 2 (max m pos))
|
||||
'face
|
||||
(list :background (face-background 'region))
|
||||
header-line-format))
|
||||
(put-text-property
|
||||
;; Increment pos to handle the space before prompt (i.e `pref').
|
||||
(+ 1 pos) (+ 2 pos)
|
||||
'face
|
||||
(if (eq state 'insert)
|
||||
'underline
|
||||
;; Don't just use 'cursor, this can hide the current character.
|
||||
(list :inverse-video t
|
||||
:foreground (face-background 'cursor)
|
||||
:background (face-background 'default)))
|
||||
header-line-format)))
|
||||
96
.emacs.d/modules/completion/helm/autoload/helm.el
Normal file
96
.emacs.d/modules/completion/helm/autoload/helm.el
Normal file
@@ -0,0 +1,96 @@
|
||||
;;; completion/helm/autoload/helm.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/projectile-find-file ()
|
||||
"Call `helm-find-files' if called from HOME, otherwise
|
||||
`helm-projectile-find-file'."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(if (or (file-equal-p default-directory "~")
|
||||
(if-let* ((proot (doom-project-root)))
|
||||
(file-equal-p proot "~")
|
||||
t))
|
||||
#'helm-find-files
|
||||
#'helm-projectile-find-file)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/workspace-buffer-list ()
|
||||
"A version of `helm-buffers-list' with its buffer list restricted to the
|
||||
current workspace."
|
||||
(interactive)
|
||||
(unless (featurep! :ui workspaces)
|
||||
(user-error "This command requires the :ui workspaces module"))
|
||||
(with-no-warnings
|
||||
(with-persp-buffer-list nil (helm-buffers-list))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/workspace-mini ()
|
||||
"A version of `helm-mini' with its buffer list restricted to the current
|
||||
workspace."
|
||||
(interactive)
|
||||
(unless (featurep! :ui workspaces)
|
||||
(user-error "This command requires the :ui workspaces module"))
|
||||
(with-no-warnings
|
||||
(with-persp-buffer-list nil (helm-mini))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Project search
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun +helm-file-search (&key query in all-files (recursive t))
|
||||
"Conduct a file search using ripgrep.
|
||||
|
||||
:query STRING
|
||||
Determines the initial input to search for.
|
||||
:in PATH
|
||||
Sets what directory to base the search out of. Defaults to the current
|
||||
project's root.
|
||||
:recursive BOOL
|
||||
Whether or not to search files recursively from the base directory."
|
||||
(declare (indent defun))
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
(require 'helm-rg)
|
||||
(let ((helm-rg-default-directory (or in (doom-project-root) default-directory))
|
||||
(helm-rg-default-extra-args
|
||||
(delq nil (list (when all-files "-z -uu")
|
||||
(unless recursive "--maxdepth 1")))))
|
||||
(helm-rg (or query
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(buffer-substring-no-properties beg end))))
|
||||
""))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/project-search (&optional arg initial-query directory)
|
||||
"Performs a project search from the project root with ripgrep.
|
||||
|
||||
ARG (universal argument), include all files, even hidden or compressed ones, in
|
||||
the search."
|
||||
(interactive "P")
|
||||
(+helm-file-search
|
||||
:query initial-query
|
||||
:in directory
|
||||
:all-files (and (not (null arg))
|
||||
(listp arg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/project-search-from-cwd (&optional arg initial-query)
|
||||
"Performs a project search recursively from the current directory.
|
||||
|
||||
If ARG (universal argument), include all files, even hidden or compressed ones."
|
||||
(interactive "P")
|
||||
(+helm-file-search
|
||||
:query initial-query
|
||||
:in default-directory
|
||||
:all-files (and (not (null arg))
|
||||
(listp arg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm/jump-list ()
|
||||
"TODO"
|
||||
(interactive)
|
||||
(error "not implemented yet"))
|
||||
59
.emacs.d/modules/completion/helm/autoload/posframe.el
Normal file
59
.emacs.d/modules/completion/helm/autoload/posframe.el
Normal file
@@ -0,0 +1,59 @@
|
||||
;;; completion/helm/autoload/posframe.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm-poshandler-frame-center-near-bottom-fn (info)
|
||||
"Display the child frame in the center of the frame, slightly closer to the
|
||||
bottom, which is easier on the eyes on big displays."
|
||||
(let ((parent-frame (plist-get info :parent-frame))
|
||||
(pos (posframe-poshandler-frame-center info)))
|
||||
(cons (car pos)
|
||||
(truncate (/ (frame-pixel-height parent-frame)
|
||||
2)))))
|
||||
|
||||
(defvar +helm--posframe-buffer nil)
|
||||
;;;###autoload
|
||||
(defun +helm-posframe-display-fn (buffer &optional _resume)
|
||||
"TODO"
|
||||
(setq helm--buffer-in-new-frame-p t)
|
||||
(let ((solaire-p (bound-and-true-p solaire-mode))
|
||||
(params (copy-sequence +helm-posframe-parameters)))
|
||||
(let-alist params
|
||||
(require 'posframe)
|
||||
(posframe-show
|
||||
(setq +helm--posframe-buffer buffer)
|
||||
:position (point)
|
||||
:poshandler +helm-posframe-handler
|
||||
:width
|
||||
(max (cl-typecase .width
|
||||
(integer .width)
|
||||
(float (truncate (* (frame-width) .width)))
|
||||
(function (funcall .width))
|
||||
(t 0))
|
||||
.min-width)
|
||||
:height
|
||||
(max (cl-typecase .height
|
||||
(integer .height)
|
||||
(float (truncate (* (frame-height) .height)))
|
||||
(function (funcall .height))
|
||||
(t 0))
|
||||
.min-height)
|
||||
:override-parameters
|
||||
(dolist (p '(width height min-width min-height) params)
|
||||
(setq params (delq (assq p params) params)))))
|
||||
;;
|
||||
(unless (or (null +helm-posframe-text-scale)
|
||||
(= +helm-posframe-text-scale 0))
|
||||
(with-current-buffer buffer
|
||||
(when (and (featurep 'solaire-mode)
|
||||
(not solaire-p))
|
||||
(solaire-mode +1))
|
||||
(text-scale-set +helm-posframe-text-scale)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +helm-posframe-cleanup-h ()
|
||||
"TODO"
|
||||
;; Ensure focus is properly returned to the underlying window. This gives the
|
||||
;; modeline a chance to refresh.
|
||||
(switch-to-buffer +helm--posframe-buffer t))
|
||||
|
||||
(add-hook 'helm-cleanup-hook #'+helm-posframe-cleanup-h)
|
||||
185
.emacs.d/modules/completion/helm/config.el
Normal file
185
.emacs.d/modules/completion/helm/config.el
Normal file
@@ -0,0 +1,185 @@
|
||||
;;; completion/helm/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; Posframe (requires +childframe)
|
||||
(defvar +helm-posframe-handler #'+helm-poshandler-frame-center-near-bottom-fn
|
||||
"The function that determines the location of the childframe. It should return
|
||||
a cons cell representing the X and Y coordinates. See
|
||||
`posframe-poshandler-frame-center' as a reference.")
|
||||
|
||||
(defvar +helm-posframe-text-scale 1
|
||||
"The text-scale to use in the helm childframe. Set to nil for no scaling. Can
|
||||
be negative.")
|
||||
|
||||
(defvar +helm-posframe-parameters
|
||||
'((internal-border-width . 8)
|
||||
(width . 0.5)
|
||||
(height . 0.35)
|
||||
(min-width . 80)
|
||||
(min-height . 16))
|
||||
"TODO")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! helm-mode
|
||||
:defer t
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(map! [remap apropos] #'helm-apropos
|
||||
[remap find-library] #'helm-locate-library
|
||||
[remap bookmark-jump] #'helm-bookmarks
|
||||
[remap execute-extended-command] #'helm-M-x
|
||||
[remap find-file] #'helm-find-files
|
||||
[remap locate] #'helm-locate
|
||||
[remap imenu] #'helm-semantic-or-imenu
|
||||
[remap noop-show-kill-ring] #'helm-show-kill-ring
|
||||
[remap persp-switch-to-buffer] #'+helm/workspace-mini
|
||||
[remap switch-to-buffer] #'helm-buffers-list
|
||||
[remap projectile-find-file] #'+helm/projectile-find-file
|
||||
[remap projectile-recentf] #'helm-projectile-recentf
|
||||
[remap projectile-switch-project] #'helm-projectile-switch-project
|
||||
[remap projectile-switch-to-buffer] #'helm-projectile-switch-to-buffer
|
||||
[remap recentf-open-files] #'helm-recentf
|
||||
[remap yank-pop] #'helm-show-kill-ring)
|
||||
:config
|
||||
(helm-mode +1)
|
||||
;; helm is too heavy for `find-file-at-point'
|
||||
(add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil)))
|
||||
|
||||
|
||||
(use-package! helm
|
||||
:after helm-mode
|
||||
:preface
|
||||
(setq helm-candidate-number-limit 50
|
||||
;; Remove extraineous helm UI elements
|
||||
helm-display-header-line nil
|
||||
helm-mode-line-string nil
|
||||
helm-ff-auto-update-initial-value nil
|
||||
helm-find-files-doc-header nil
|
||||
;; Don't override evil-ex's completion
|
||||
helm-mode-handle-completion-in-region nil
|
||||
;; Default helm window sizes
|
||||
helm-display-buffer-default-width nil
|
||||
helm-display-buffer-default-height 0.25
|
||||
;; When calling `helm-semantic-or-imenu', don't immediately jump to
|
||||
;; symbol at point
|
||||
helm-imenu-execute-action-at-once-if-one nil
|
||||
;; disable special behavior for left/right, M-left/right keys.
|
||||
helm-ff-lynx-style-map nil)
|
||||
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(setq helm-default-prompt-display-function #'+helm--set-prompt-display))
|
||||
|
||||
:init
|
||||
(when (featurep! +childframe)
|
||||
(setq helm-display-function #'+helm-posframe-display-fn))
|
||||
|
||||
(let ((fuzzy (featurep! +fuzzy)))
|
||||
(setq helm-M-x-fuzzy-match fuzzy
|
||||
helm-apropos-fuzzy-match fuzzy
|
||||
helm-apropos-fuzzy-match fuzzy
|
||||
helm-bookmark-show-location fuzzy
|
||||
helm-buffers-fuzzy-matching fuzzy
|
||||
helm-completion-in-region-fuzzy-match fuzzy
|
||||
helm-completion-in-region-fuzzy-match fuzzy
|
||||
helm-ff-fuzzy-matching fuzzy
|
||||
helm-file-cache-fuzzy-match fuzzy
|
||||
helm-flx-for-helm-locate fuzzy
|
||||
helm-imenu-fuzzy-match fuzzy
|
||||
helm-lisp-fuzzy-completion fuzzy
|
||||
helm-locate-fuzzy-match fuzzy
|
||||
helm-mode-fuzzy-match fuzzy
|
||||
helm-projectile-fuzzy-match fuzzy
|
||||
helm-recentf-fuzzy-match fuzzy
|
||||
helm-semantic-fuzzy-match fuzzy))
|
||||
|
||||
:config
|
||||
(set-popup-rule! "^\\*helm" :vslot -100 :size 0.22 :ttl nil)
|
||||
|
||||
;; HACK Doom doesn't support these commands, which invite the user to install
|
||||
;; the package via ELPA. Force them to use +helm/* instead, because they work
|
||||
;; out of the box.
|
||||
(advice-add #'helm-projectile-rg :override #'+helm/project-search)
|
||||
(advice-add #'helm-projectile-ag :override #'+helm/project-search)
|
||||
(advice-add #'helm-projectile-grep :override #'+helm/project-search)
|
||||
|
||||
;; Hide the modeline
|
||||
(defun +helm--hide-mode-line (&rest _)
|
||||
(with-current-buffer (helm-buffer-get)
|
||||
(unless helm-mode-line-string
|
||||
(hide-mode-line-mode +1))))
|
||||
(add-hook 'helm-after-initialize-hook #'+helm--hide-mode-line)
|
||||
(advice-add #'helm-display-mode-line :override #'+helm--hide-mode-line)
|
||||
(advice-add #'helm-ag-show-status-default-mode-line :override #'ignore)
|
||||
|
||||
;; Use helpful instead of describe-* to display documentation
|
||||
(dolist (fn '(helm-describe-variable helm-describe-function))
|
||||
(advice-add fn :around #'doom-use-helpful-a)))
|
||||
|
||||
|
||||
(use-package! helm-flx
|
||||
:when (featurep! +fuzzy)
|
||||
:hook (helm-mode . helm-flx-mode)
|
||||
:config (helm-flx-mode +1))
|
||||
|
||||
|
||||
(after! helm-rg
|
||||
(setq helm-rg-display-buffer-normal-method #'pop-to-buffer)
|
||||
(set-popup-rule! "^helm-rg-" :ttl nil :select t :size 0.45)
|
||||
(map! :map helm-rg-map
|
||||
"C-c C-e" #'helm-rg--bounce)
|
||||
(map! :map helm-rg--bounce-mode-map
|
||||
"q" #'kill-current-buffer
|
||||
"C-c C-c" (λ! (helm-rg--bounce-dump) (kill-current-buffer))
|
||||
"C-x C-c" #'helm-rg--bounce-dump-current-file
|
||||
"C-c C-k" #'kill-current-buffer))
|
||||
|
||||
|
||||
;;;###package helm-bookmark
|
||||
(setq helm-bookmark-show-location t)
|
||||
|
||||
|
||||
(after! helm-files
|
||||
(setq helm-boring-file-regexp-list
|
||||
(append (list "\\.projects$" "\\.DS_Store$")
|
||||
helm-boring-file-regexp-list)))
|
||||
|
||||
|
||||
(defvar helm-generic-files-map (make-sparse-keymap))
|
||||
(after! helm-locate
|
||||
(when (and IS-MAC
|
||||
(null helm-locate-command)
|
||||
(executable-find "mdfind"))
|
||||
(setq helm-locate-command "mdfind -name %s"))
|
||||
(set-keymap-parent helm-generic-files-map helm-map))
|
||||
|
||||
|
||||
(use-package! helm-org
|
||||
:when (featurep! :lang org)
|
||||
:defer t
|
||||
:init
|
||||
(after! helm-mode
|
||||
(pushnew! helm-completing-read-handlers-alist
|
||||
'(org-capture . helm-org-completing-read-tags)
|
||||
'(org-set-tags . helm-org-completing-read-tags))))
|
||||
|
||||
|
||||
(use-package! helm-projectile
|
||||
:commands (helm-projectile-find-file
|
||||
helm-projectile-recentf
|
||||
helm-projectile-switch-project
|
||||
helm-projectile-switch-to-buffer)
|
||||
:init
|
||||
(setq projectile-completion-system 'helm)
|
||||
(defvar helm-projectile-find-file-map (make-sparse-keymap))
|
||||
:config
|
||||
(set-keymap-parent helm-projectile-find-file-map helm-map))
|
||||
|
||||
|
||||
(setq ivy-height 20) ; for `swiper-isearch'
|
||||
(after! swiper-helm
|
||||
(setq swiper-helm-display-function
|
||||
(lambda (buf &optional _resume) (pop-to-buffer buf)))
|
||||
(global-set-key [remap swiper] #'swiper-helm)
|
||||
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode nil #'eq))
|
||||
16
.emacs.d/modules/completion/helm/packages.el
Normal file
16
.emacs.d/modules/completion/helm/packages.el
Normal file
@@ -0,0 +1,16 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/helm/packages.el
|
||||
|
||||
(package! helm)
|
||||
(package! helm-rg)
|
||||
(package! helm-c-yasnippet)
|
||||
(package! helm-company)
|
||||
(package! helm-describe-modes :recipe (:host github :repo "emacs-helm/helm-describe-modes"))
|
||||
(package! helm-projectile)
|
||||
(package! swiper-helm)
|
||||
(when (featurep! +fuzzy)
|
||||
(package! helm-flx))
|
||||
(when (featurep! +childframe)
|
||||
(package! posframe))
|
||||
(when (featurep! :lang org)
|
||||
(package! helm-org))
|
||||
59
.emacs.d/modules/completion/ido/config.el
Normal file
59
.emacs.d/modules/completion/ido/config.el
Normal file
@@ -0,0 +1,59 @@
|
||||
;;; completion/ido/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +ido-init-h ()
|
||||
(setq ido-ignore-buffers
|
||||
'("\\` " "^\\*ESS\\*" "^\\*Messages\\*" "^\\*Help\\*" "^\\*Buffer"
|
||||
"^\\*.*Completions\\*$" "^\\*Ediff" "^\\*tramp" "^\\*cvs-"
|
||||
"_region_" " output\\*$" "^TAGS$" "^\*Ido")
|
||||
ido-use-faces nil
|
||||
ido-confirm-unique-completion t
|
||||
ido-case-fold t
|
||||
ido-enable-tramp-completion nil
|
||||
ido-enable-flex-matching t
|
||||
ido-create-new-buffer 'always
|
||||
ido-enable-tramp-completion t
|
||||
ido-enable-last-directory-history t
|
||||
ido-save-directory-list-file (concat doom-cache-dir "ido.last"))
|
||||
|
||||
(unless (member "\\`.DS_Store$" ido-ignore-files)
|
||||
(push "\\`.DS_Store$" ido-ignore-files)
|
||||
(push "Icon\\?$" ido-ignore-files))
|
||||
|
||||
(define-key! (ido-common-completion-map ido-completion-map ido-file-completion-map)
|
||||
"\C-n" #'ido-next-match
|
||||
"\C-p" #'ido-prev-match
|
||||
"\C-w" #'ido-delete-backward-word-updir
|
||||
;; Go to $HOME with ~
|
||||
"~" (λ! (if (looking-back "/" (point-min))
|
||||
(insert "~/")
|
||||
(call-interactively #'self-insert-command))))
|
||||
|
||||
(defadvice! +ido--sort-mtime-a ()
|
||||
"Sort ido filelist by mtime instead of alphabetically."
|
||||
:override #'ido-sort-mtime
|
||||
(setq ido-temp-list
|
||||
(sort ido-temp-list
|
||||
(lambda (a b)
|
||||
(time-less-p
|
||||
(sixth (file-attributes (concat ido-current-directory b)))
|
||||
(sixth (file-attributes (concat ido-current-directory a)))))))
|
||||
(ido-to-end ;; move . files to end (again)
|
||||
(cl-loop for x in ido-temp-list
|
||||
if (char-equal (string-to-char x) ?.)
|
||||
collect x)))
|
||||
(add-hook! '(ido-make-file-list-hook ido-make-dir-list-hook)
|
||||
#'ido-sort-mtime)
|
||||
|
||||
;;
|
||||
(ido-mode 1)
|
||||
(ido-everywhere 1)
|
||||
(ido-ubiquitous-mode 1)
|
||||
(ido-vertical-mode 1)
|
||||
(flx-ido-mode +1)
|
||||
(crm-custom-mode +1)
|
||||
|
||||
;;
|
||||
(remove-hook 'ido-setup-hook #'+ido-init-h))
|
||||
|
||||
;;
|
||||
(add-hook 'ido-setup-hook #'+ido-init-h)
|
||||
7
.emacs.d/modules/completion/ido/packages.el
Normal file
7
.emacs.d/modules/completion/ido/packages.el
Normal file
@@ -0,0 +1,7 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/ido/packages.el
|
||||
|
||||
(package! flx-ido)
|
||||
(package! ido-completing-read+)
|
||||
(package! ido-vertical-mode)
|
||||
(package! crm-custom)
|
||||
194
.emacs.d/modules/completion/ivy/README.org
Normal file
194
.emacs.d/modules/completion/ivy/README.org
Normal file
@@ -0,0 +1,194 @@
|
||||
#+TITLE: completion/ivy
|
||||
#+DATE: February 13, 2017
|
||||
#+SINCE: v2.0
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#install][Install]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#opensuse][openSUSE]]
|
||||
- [[#features][Features]]
|
||||
- [[#jump-to-navigation][Jump-to navigation]]
|
||||
- [[#project-search--replace][Project search & replace]]
|
||||
- [[#in-buffer-searching][In-buffer searching]]
|
||||
- [[#ivy-integration-for-various-completing-commands][Ivy integration for various completing commands]]
|
||||
- [[#general][General]]
|
||||
- [[#jump-to-files-buffers-or-projects][Jump to files, buffers or projects)]]
|
||||
- [[#search][Search]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#enable-fuzzynon-fuzzy-search-for-specific-commands][Enable fuzzy/non-fuzzy search for specific commands]]
|
||||
- [[#change-the-position-of-the-ivy-childframe][Change the position of the ivy childframe]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module provides Ivy integration for a variety of Emacs commands, as well as
|
||||
a unified interface for project search and replace, powered by ripgrep.
|
||||
|
||||
#+begin_quote
|
||||
I prefer ivy over ido for its flexibility. I prefer ivy over helm because it's
|
||||
lighter, simpler and faster in many cases.
|
||||
#+end_quote
|
||||
|
||||
** Module Flags
|
||||
+ =+fuzzy= Enables fuzzy completion for Ivy searches.
|
||||
+ =+prescient= Enables prescient filtering and sorting for Ivy searches.
|
||||
+ =+childframe= Causes Ivy to display in a floating child frame, above Emacs.
|
||||
+ =+icons= Enables file icons for switch-{buffer,project}/find-file counsel
|
||||
commands.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/abo-abo/swiper][ivy]]
|
||||
+ [[https://github.com/abo-abo/swiper][counsel]]
|
||||
+ [[https://github.com/ericdanan/counsel-projectile][counsel-projectile]]
|
||||
+ [[https://github.com/abo-abo/swiper][swiper]]
|
||||
+ [[https://github.com/abo-abo/swiper][ivy-hydra]]
|
||||
+ [[https://github.com/yevgnen/ivy-rich][ivy-rich]]
|
||||
+ [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]]
|
||||
+ [[https://github.com/DarwinAwardWinner/amx][amx]]
|
||||
+ [[https://github.com/lewang/flx][flx]]* (=+fuzzy=)
|
||||
+ [[https://github.com/raxod502/prescient.el][prescient]]* (=+prescient=)
|
||||
+ [[https://github.com/tumashu/ivy-posframe][ivy-posframe]]* (=+childframe=)
|
||||
+ [[https://github.com/asok/all-the-icons-ivy][all-the-icons-ivy]]* (=+icons=)
|
||||
|
||||
** Hacks
|
||||
+ Functions with ivy/counsel equivalents have been globally remapped (like
|
||||
~find-file~ => ~counsel-find-file~). So a keybinding to ~find-file~ will
|
||||
invoke ~counsel-find-file~ instead.
|
||||
+ ~counsel-[arp]g~'s 3-character limit was reduced to 1 (mainly for the ex
|
||||
command)
|
||||
|
||||
* Prerequisites
|
||||
This module depends on:
|
||||
|
||||
+ [[https://github.com/BurntSushi/ripgrep][ripgrep]] (rg)
|
||||
|
||||
** Install
|
||||
*** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install ripgrep
|
||||
#+END_SRC
|
||||
|
||||
*** Arch Linux
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo pacman --needed --noconfirm -S ripgrep
|
||||
#+END_SRC
|
||||
|
||||
*** openSUSE
|
||||
#+BEGIN_SRC sh :dir /sudo::
|
||||
sudo zypper install ripgrep
|
||||
#+END_SRC
|
||||
|
||||
* Features
|
||||
Ivy and its ilk are large plugins. Covering everything about them is outside of
|
||||
this documentation's scope, so only Doom-specific Ivy features are listed here:
|
||||
|
||||
** Jump-to navigation
|
||||
Inspired by Sublime Text's jump-to-anywhere, CtrlP/Unite in Vim, and Textmate's
|
||||
Command-T, this module provides similar functionality by bringing ~projectile~
|
||||
and ~ivy~ together.
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/projectile.png
|
||||
|
||||
| Keybind | Description |
|
||||
|----------------------+-------------------------------------|
|
||||
| =SPC p f=, =SPC SPC= | Jump to file in project |
|
||||
| =SPC f f=, =SPC .= | Jump to file from current directory |
|
||||
| =SPC s i= | Jump to symbol in file |
|
||||
|
||||
** Project search & replace
|
||||
This module provides interactive text search and replace using ripgrep.
|
||||
|
||||
| Keybind | Description |
|
||||
|-----------+--------------------------|
|
||||
| =SPC s p= | Search project |
|
||||
| =SPC s P= | Search another project |
|
||||
| =SPC s d= | Search this directory |
|
||||
| =SPC s D= | Search another directory |
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/search.png
|
||||
|
||||
Prefixing these keys with the universal argument (=SPC u= for evil users; =C-u=
|
||||
otherwise) changes the behavior of these commands, instructing the underlying
|
||||
search engine to include ignored files.
|
||||
|
||||
This module also provides Ex Commands for evil users:
|
||||
|
||||
| Ex command | Description |
|
||||
|------------------------+------------------------------------------------------------------|
|
||||
| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) |
|
||||
| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) |
|
||||
|
||||
The optional `!` is equivalent to the universal argument for the previous
|
||||
commands.
|
||||
|
||||
-----
|
||||
|
||||
These keybindings are available while a search is active:
|
||||
|
||||
| Keybind | Description |
|
||||
|-----------+-----------------------------------------------|
|
||||
| =C-c C-o= | Open a buffer with your search results |
|
||||
| =C-c C-e= | Open a writable buffer of your search results |
|
||||
| =C-SPC= | Preview the current candidate |
|
||||
| =M-RET= | Open the selected candidate in other-window |
|
||||
|
||||
Changes to the resulting wgrep buffer (opened by =C-c C-e=) can be committed
|
||||
with =C-c C-c= and aborted with =C-c C-k= (alternatively =ZZ= and =ZQ=, for evil
|
||||
users).
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/search-replace.png
|
||||
|
||||
** In-buffer searching
|
||||
The =swiper= package provides an interactive buffer search powered by ivy. It
|
||||
can be invoked with:
|
||||
|
||||
+ =SPC s s= (~swiper-isearch~)
|
||||
+ =SPC s S= (~swiper-isearch-thing-at-point~)
|
||||
+ =SPC s b= (~swiper~)
|
||||
+ ~:sw[iper] [QUERY]~
|
||||
|
||||
https://assets.doomemacs.org/completion/ivy/swiper.png
|
||||
|
||||
A wgrep buffer can be opened from swiper with =C-c C-e=.
|
||||
|
||||
** Ivy integration for various completing commands
|
||||
*** General
|
||||
| Keybind | Description |
|
||||
|----------------+---------------------------|
|
||||
| =M-x=, =SPC := | Smarter, smex-powered M-x |
|
||||
| =SPC '= | Resume last ivy session |
|
||||
|
||||
*** Jump to files, buffers or projects)
|
||||
| Keybind | Description |
|
||||
|----------------------+---------------------------------------|
|
||||
| =SPC RET= | Find bookmark |
|
||||
| =SPC f f=, =SPC .= | Browse from current directory |
|
||||
| =SPC p f=, =SPC SPC= | Find file in project |
|
||||
| =SPC f r= | Find recently opened file |
|
||||
| =SPC p p= | Open another project |
|
||||
| =SPC b b=, =SPC ,= | Switch to buffer in current workspace |
|
||||
| =SPC b B=, =SPC <= | Switch to buffer |
|
||||
|
||||
*** Search
|
||||
| Keybind | Description |
|
||||
|-----------+-------------------------------------------|
|
||||
| =SPC p t= | List all TODO/FIXMEs in project |
|
||||
| =SPC s b= | Search the current buffer |
|
||||
| =SPC s d= | Search this directory |
|
||||
| =SPC s D= | Search another directory |
|
||||
| =SPC s i= | Search for symbol in current buffer |
|
||||
| =SPC s p= | Search project |
|
||||
| =SPC s P= | Search another project |
|
||||
| =SPC s s= | Search the current buffer (incrementally) |
|
||||
|
||||
* Configuration
|
||||
** TODO Enable fuzzy/non-fuzzy search for specific commands
|
||||
** TODO Change the position of the ivy childframe
|
||||
|
||||
* TODO Troubleshooting
|
||||
14
.emacs.d/modules/completion/ivy/autoload/evil.el
Normal file
14
.emacs.d/modules/completion/ivy/autoload/evil.el
Normal file
@@ -0,0 +1,14 @@
|
||||
;; completion/ivy/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :editor evil)
|
||||
|
||||
;;;###autoload (autoload '+ivy:project-search "completion/ivy/autoload/evil" nil t)
|
||||
(evil-define-command +ivy:project-search (query &optional all-files-p)
|
||||
"Ex interface for `+ivy/project-search'."
|
||||
(interactive "<a><!>")
|
||||
(+ivy/project-search all-files-p query))
|
||||
|
||||
;;;###autoload (autoload '+ivy:project-search-from-cwd "completion/ivy/autoload/evil" nil t)
|
||||
(evil-define-command +ivy:project-search-from-cwd (query &optional recurse-p)
|
||||
"Ex interface for `+ivy/project-search-from-cwd'."
|
||||
(interactive "<a><!>")
|
||||
(+ivy/project-search-from-cwd (not recurse-p) query))
|
||||
33
.emacs.d/modules/completion/ivy/autoload/hydras.el
Normal file
33
.emacs.d/modules/completion/ivy/autoload/hydras.el
Normal file
@@ -0,0 +1,33 @@
|
||||
;;; completion/ivy/autoload/hydras.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :ui hydra)
|
||||
|
||||
(eval-when-compile (require 'ivy-hydra))
|
||||
|
||||
;;;###autoload (autoload 'hydra-ivy/body "completion/ivy/autoload/hydras" nil nil)
|
||||
(defhydra+ hydra-ivy (:hint nil :color pink)
|
||||
"
|
||||
Move ^^^^^^^^^^ | Call ^^^^ | Cancel^^ | Options^^ | Action _w_/_s_/_a_: %s(ivy-action-name)
|
||||
----------^^^^^^^^^^-+--------------^^^^-+-------^^-+--------^^-+---------------------------------
|
||||
_g_ ^ ^ _k_ ^ ^ _u_ | _f_orward _o_ccur | _i_nsert | _c_alling: %-7s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search
|
||||
^↨^ _h_ ^+^ _l_ ^↕^ | _RET_ done ^^ | _q_uit | _m_atcher: %-7s(ivy--matcher-desc) _t_runcate: %-11`truncate-lines
|
||||
_G_ ^ ^ _j_ ^ ^ _d_ | _TAB_ alt-done ^^ | ^ ^ | _<_/_>_: shrink/grow
|
||||
"
|
||||
;; arrows
|
||||
("l" ivy-alt-done)
|
||||
("h" ivy-backward-delete-char)
|
||||
("g" ivy-beginning-of-buffer)
|
||||
("G" ivy-end-of-buffer)
|
||||
("d" ivy-scroll-up-command)
|
||||
("u" ivy-scroll-down-command)
|
||||
("e" ivy-scroll-down-command)
|
||||
;; actions
|
||||
("q" keyboard-escape-quit :exit t)
|
||||
("<escape>" keyboard-escape-quit :exit t)
|
||||
("TAB" ivy-alt-done :exit nil)
|
||||
("RET" ivy-done :exit t)
|
||||
("C-SPC" ivy-call-and-recenter :exit nil)
|
||||
("f" ivy-call)
|
||||
("c" ivy-toggle-calling)
|
||||
("m" ivy-toggle-fuzzy)
|
||||
("t" (setq truncate-lines (not truncate-lines)))
|
||||
("o" ivy-occur :exit t))
|
||||
366
.emacs.d/modules/completion/ivy/autoload/ivy.el
Normal file
366
.emacs.d/modules/completion/ivy/autoload/ivy.el
Normal file
@@ -0,0 +1,366 @@
|
||||
;;; completion/ivy/autoload/ivy.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +ivy--is-workspace-buffer-p (buffer)
|
||||
(let ((buffer (car buffer)))
|
||||
(when (stringp buffer)
|
||||
(setq buffer (get-buffer buffer)))
|
||||
(+workspace-contains-buffer-p buffer)))
|
||||
|
||||
(defun +ivy--is-workspace-other-buffer-p (buffer)
|
||||
(let ((buffer (car buffer)))
|
||||
(when (stringp buffer)
|
||||
(setq buffer (get-buffer buffer)))
|
||||
(and (not (eq buffer (current-buffer)))
|
||||
(+workspace-contains-buffer-p buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-standard-search (str)
|
||||
"TODO"
|
||||
(funcall +ivy-standard-search-fn str))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-alternative-search (str)
|
||||
"TODO"
|
||||
(funcall +ivy-alternative-search-fn str))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-rich-buffer-name (candidate)
|
||||
"Display the buffer name.
|
||||
|
||||
Buffers that are considered unreal (see `doom-real-buffer-p') are dimmed with
|
||||
`+ivy-buffer-unreal-face'."
|
||||
(let ((b (get-buffer candidate)))
|
||||
(when (null uniquify-buffer-name-style)
|
||||
(setq candidate (replace-regexp-in-string "<[0-9]+>$" "" candidate)))
|
||||
(cond ((ignore-errors
|
||||
(file-remote-p
|
||||
(buffer-local-value 'default-directory b)))
|
||||
(ivy-append-face candidate 'ivy-remote))
|
||||
((doom-unreal-buffer-p b)
|
||||
(ivy-append-face candidate +ivy-buffer-unreal-face))
|
||||
((not (buffer-file-name b))
|
||||
(ivy-append-face candidate 'ivy-subdir))
|
||||
((buffer-modified-p b)
|
||||
(ivy-append-face candidate 'ivy-modified-buffer))
|
||||
(candidate))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-rich-buffer-icon (candidate)
|
||||
"Display the icon for CANDIDATE buffer."
|
||||
;; NOTE This is inspired by `all-the-icons-ivy-buffer-transformer', minus the
|
||||
;; buffer name and extra padding as those are handled by `ivy-rich'.
|
||||
(propertize "\t" 'display
|
||||
(if-let* ((buffer (get-buffer candidate))
|
||||
(mode (buffer-local-value 'major-mode buffer)))
|
||||
(or
|
||||
(all-the-icons-ivy--icon-for-mode mode)
|
||||
(all-the-icons-ivy--icon-for-mode (get mode 'derived-mode-parent))
|
||||
(funcall
|
||||
all-the-icons-ivy-family-fallback-for-buffer
|
||||
all-the-icons-ivy-name-fallback-for-buffer))
|
||||
(all-the-icons-icon-for-file candidate))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-rich-describe-variable-transformer (cand)
|
||||
"Previews the value of the variable in the minibuffer"
|
||||
(let* ((sym (intern cand))
|
||||
(val (and (boundp sym) (symbol-value sym)))
|
||||
(print-level 3))
|
||||
(replace-regexp-in-string
|
||||
"[\n\t\^[\^M\^@\^G]" " "
|
||||
(cond ((booleanp val)
|
||||
(propertize (format "%s" val) 'face
|
||||
(if (null val)
|
||||
'font-lock-comment-face
|
||||
'success)))
|
||||
((symbolp val)
|
||||
(propertize (format "'%s" val)
|
||||
'face 'highlight-quoted-symbol))
|
||||
((keymapp val)
|
||||
(propertize "<keymap>" 'face 'font-lock-constant-face))
|
||||
((listp val)
|
||||
(prin1-to-string val))
|
||||
((stringp val)
|
||||
(propertize (format "%S" val) 'face 'font-lock-string-face))
|
||||
((numberp val)
|
||||
(propertize (format "%s" val) 'face 'highlight-numbers-number))
|
||||
((format "%s" val)))
|
||||
t)))
|
||||
|
||||
|
||||
;;
|
||||
;; Library
|
||||
|
||||
(defun +ivy--switch-buffer-preview ()
|
||||
(let (ivy-use-virtual-buffers ivy--virtual-buffers)
|
||||
(counsel--switch-buffer-update-fn)))
|
||||
|
||||
(defalias '+ivy--switch-buffer-preview-all #'counsel--switch-buffer-update-fn)
|
||||
(defalias '+ivy--switch-buffer-unwind #'counsel--switch-buffer-unwind)
|
||||
|
||||
(defun +ivy--switch-buffer (workspace other)
|
||||
(let ((current (not other))
|
||||
prompt action filter update unwind)
|
||||
(cond ((and workspace current)
|
||||
(setq prompt "Switch to workspace buffer: "
|
||||
action #'ivy--switch-buffer-action
|
||||
filter #'+ivy--is-workspace-other-buffer-p))
|
||||
(workspace
|
||||
(setq prompt "Switch to workspace buffer in other window: "
|
||||
action #'ivy--switch-buffer-other-window-action
|
||||
filter #'+ivy--is-workspace-buffer-p))
|
||||
(current
|
||||
(setq prompt "Switch to buffer: "
|
||||
action #'ivy--switch-buffer-action))
|
||||
((setq prompt "Switch to buffer in other window: "
|
||||
action #'ivy--switch-buffer-other-window-action)))
|
||||
(when +ivy-buffer-preview
|
||||
(cond ((not (and ivy-use-virtual-buffers
|
||||
(eq +ivy-buffer-preview 'everything)))
|
||||
(setq update #'+ivy--switch-buffer-preview
|
||||
unwind #'+ivy--switch-buffer-unwind))
|
||||
((setq update #'+ivy--switch-buffer-preview-all
|
||||
unwind #'+ivy--switch-buffer-unwind))))
|
||||
(ivy-read prompt 'internal-complete-buffer
|
||||
:action action
|
||||
:predicate filter
|
||||
:update-fn update
|
||||
:unwind unwind
|
||||
:preselect (buffer-name (other-buffer (current-buffer)))
|
||||
:matcher #'ivy--switch-buffer-matcher
|
||||
:keymap ivy-switch-buffer-map
|
||||
;; NOTE A clever disguise, needed for virtual buffers.
|
||||
:caller #'ivy-switch-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-workspace-buffer (&optional arg)
|
||||
"Switch to another buffer within the current workspace.
|
||||
|
||||
If ARG (universal argument), open selection in other-window."
|
||||
(interactive "P")
|
||||
(+ivy--switch-buffer t arg))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-workspace-buffer-other-window ()
|
||||
"Switch another window to a buffer within the current workspace."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer t t))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-buffer ()
|
||||
"Switch to another buffer."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer nil nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/switch-buffer-other-window ()
|
||||
"Switch to another buffer in another window."
|
||||
(interactive)
|
||||
(+ivy--switch-buffer nil t))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/woccur ()
|
||||
"Invoke a wgrep buffer on the current ivy results, if supported."
|
||||
(interactive)
|
||||
(unless (window-minibuffer-p)
|
||||
(user-error "No completion session is active"))
|
||||
(require 'wgrep)
|
||||
(let ((caller (ivy-state-caller ivy-last)))
|
||||
(if-let (occur-fn (plist-get +ivy-edit-functions caller))
|
||||
(ivy-exit-with-action
|
||||
(lambda (_) (funcall occur-fn)))
|
||||
(if-let (occur-fn (plist-get ivy--occurs-list caller))
|
||||
(let ((buffer (generate-new-buffer
|
||||
(format "*ivy-occur%s \"%s\"*"
|
||||
(if caller (concat " " (prin1-to-string caller)) "")
|
||||
ivy-text))))
|
||||
(with-current-buffer buffer
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(funcall occur-fn))
|
||||
(setf (ivy-state-text ivy-last) ivy-text)
|
||||
(setq ivy-occur-last ivy-last)
|
||||
(setq-local ivy--directory ivy--directory))
|
||||
(ivy-exit-with-action
|
||||
`(lambda (_)
|
||||
(pop-to-buffer ,buffer)
|
||||
(ivy-wgrep-change-to-wgrep-mode))))
|
||||
(user-error "%S doesn't support wgrep" caller)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-yas-prompt (prompt choices &optional display-fn)
|
||||
(yas-completing-prompt prompt choices display-fn #'ivy-completing-read))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-git-grep-other-window-action (x)
|
||||
"Opens the current candidate in another window."
|
||||
(when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x)
|
||||
(select-window
|
||||
(with-ivy-window
|
||||
(let ((file-name (match-string-no-properties 1 x))
|
||||
(line-number (match-string-no-properties 2 x)))
|
||||
(find-file-other-window (expand-file-name file-name (ivy-state-directory ivy-last)))
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (string-to-number line-number)))
|
||||
(re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
|
||||
(run-hooks 'counsel-grep-post-action-hook)
|
||||
(selected-window))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-confirm-delete-file (x)
|
||||
(dired-delete-file x 'confirm-each-subdirectory))
|
||||
|
||||
|
||||
;;
|
||||
;;; File searching
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/projectile-find-file ()
|
||||
"A more sensible `counsel-projectile-find-file', which will revert to
|
||||
`counsel-find-file' if invoked from $HOME, `counsel-file-jump' if invoked from a
|
||||
non-project, `projectile-find-file' if in a big project (more than
|
||||
`ivy-sort-max-size' files), or `counsel-projectile-find-file' otherwise.
|
||||
|
||||
The point of this is to avoid Emacs locking up indexing massive file trees."
|
||||
(interactive)
|
||||
(call-interactively
|
||||
(cond ((or (file-equal-p default-directory "~")
|
||||
(when-let (proot (doom-project-root))
|
||||
(file-equal-p proot "~")))
|
||||
#'counsel-find-file)
|
||||
|
||||
((doom-project-p)
|
||||
(let ((files (projectile-current-project-files)))
|
||||
(if (<= (length files) ivy-sort-max-size)
|
||||
#'counsel-projectile-find-file
|
||||
#'projectile-find-file)))
|
||||
|
||||
(#'counsel-file-jump))))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun +ivy-file-search (&key query in all-files (recursive t))
|
||||
"Conduct a file search using ripgrep.
|
||||
|
||||
:query STRING
|
||||
Determines the initial input to search for.
|
||||
:in PATH
|
||||
Sets what directory to base the search out of. Defaults to the current
|
||||
project's root.
|
||||
:recursive BOOL
|
||||
Whether or not to search files recursively from the base directory."
|
||||
(declare (indent defun))
|
||||
(unless (executable-find "rg")
|
||||
(user-error "Couldn't find ripgrep in your PATH"))
|
||||
(require 'counsel)
|
||||
(let* ((ivy-more-chars-alist '((t . 1)))
|
||||
(project-root (or (doom-project-root) default-directory))
|
||||
(directory (or in project-root))
|
||||
(default-directory directory)
|
||||
(args (concat (if all-files " -uu")
|
||||
(unless recursive " --maxdepth 1"))))
|
||||
(counsel-rg
|
||||
(or (if query query)
|
||||
(when (use-region-p)
|
||||
(let ((beg (or (bound-and-true-p evil-visual-beginning) (region-beginning)))
|
||||
(end (or (bound-and-true-p evil-visual-end) (region-end))))
|
||||
(when (> (abs (- end beg)) 1)
|
||||
(let ((query (buffer-substring-no-properties beg end)))
|
||||
;; Escape characters that are special to ivy searches
|
||||
(replace-regexp-in-string "[! |]" (lambda (substr)
|
||||
(cond ((and (string= substr " ")
|
||||
(not (featurep! +fuzzy)))
|
||||
" ")
|
||||
((string= substr "|")
|
||||
"\\\\\\\\|")
|
||||
((concat "\\\\" substr))))
|
||||
(rxt-quote-pcre query)))))))
|
||||
directory args
|
||||
(format "rg%s %s"
|
||||
args
|
||||
(cond ((equal directory default-directory)
|
||||
"./")
|
||||
((equal directory project-root)
|
||||
(projectile-project-name))
|
||||
((file-relative-name directory project-root)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/project-search (&optional arg initial-query directory)
|
||||
"Performs a live project search from the project root using ripgrep.
|
||||
|
||||
If ARG (universal argument), include all files, even hidden or compressed ones,
|
||||
in the search."
|
||||
(interactive "P")
|
||||
(+ivy-file-search :query initial-query :in directory :all-files arg))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/project-search-from-cwd (&optional arg initial-query)
|
||||
"Performs a project search recursively from the current directory.
|
||||
|
||||
If ARG (universal argument), include all files, even hidden or compressed ones."
|
||||
(interactive "P")
|
||||
(+ivy/project-search arg initial-query default-directory))
|
||||
|
||||
|
||||
;;
|
||||
;;; Wrappers around `counsel-compile'
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/compile ()
|
||||
"Execute a compile command from the current buffer's directory."
|
||||
(interactive)
|
||||
(counsel-compile default-directory))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/project-compile ()
|
||||
"Execute a compile command from the current project's root."
|
||||
(interactive)
|
||||
(counsel-compile (projectile-project-root)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/jump-list ()
|
||||
"Go to an entry in evil's (or better-jumper's) jumplist."
|
||||
(interactive)
|
||||
;; REVIEW Refactor me
|
||||
(let (buffers)
|
||||
(unwind-protect
|
||||
(ivy-read "jumplist: "
|
||||
(nreverse
|
||||
(delete-dups
|
||||
(delq
|
||||
nil
|
||||
(mapcar (lambda (mark)
|
||||
(when mark
|
||||
(cl-destructuring-bind (path pt _id) mark
|
||||
(let ((buf (get-file-buffer path)))
|
||||
(unless buf
|
||||
(push (setq buf (find-file-noselect path t))
|
||||
buffers))
|
||||
(with-current-buffer buf
|
||||
(goto-char pt)
|
||||
(font-lock-fontify-region (line-beginning-position) (line-end-position))
|
||||
(cons (format "%s:%d: %s"
|
||||
(buffer-name)
|
||||
(line-number-at-pos)
|
||||
(string-trim-right (or (thing-at-point 'line) "")))
|
||||
(point-marker)))))))
|
||||
(cddr (better-jumper-jump-list-struct-ring
|
||||
(better-jumper-get-jumps (better-jumper--get-current-context))))))))
|
||||
:sort nil
|
||||
:require-match t
|
||||
:action (lambda (cand)
|
||||
(let ((mark (cdr cand)))
|
||||
(delq! (marker-buffer mark) buffers)
|
||||
(mapc #'kill-buffer buffers)
|
||||
(setq buffers nil)
|
||||
(with-current-buffer (switch-to-buffer (marker-buffer mark))
|
||||
(goto-char (marker-position mark)))))
|
||||
:caller '+ivy/jump-list)
|
||||
(mapc #'kill-buffer buffers))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy/git-grep-other-window-action ()
|
||||
"Open the current counsel-{ag,rg,git-grep} candidate in other-window."
|
||||
(interactive)
|
||||
(ivy-set-action #'+ivy-git-grep-other-window-action)
|
||||
(setq ivy-exit 'done)
|
||||
(exit-minibuffer))
|
||||
16
.emacs.d/modules/completion/ivy/autoload/posframe.el
Normal file
16
.emacs.d/modules/completion/ivy/autoload/posframe.el
Normal file
@@ -0,0 +1,16 @@
|
||||
;;; completion/ivy/autoload/posframe.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! +childframe)
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-display-at-frame-center-near-bottom-fn (str)
|
||||
"TODO"
|
||||
(ivy-posframe--display str #'+ivy-poshandler-frame-center-near-bottom-fn))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ivy-poshandler-frame-center-near-bottom-fn (info)
|
||||
"TODO"
|
||||
(let ((parent-frame (plist-get info :parent-frame))
|
||||
(pos (posframe-poshandler-frame-center info)))
|
||||
(cons (car pos)
|
||||
(truncate (/ (frame-pixel-height parent-frame) 2)))))
|
||||
|
||||
350
.emacs.d/modules/completion/ivy/config.el
Normal file
350
.emacs.d/modules/completion/ivy/config.el
Normal file
@@ -0,0 +1,350 @@
|
||||
;;; completion/ivy/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +ivy-buffer-preview nil
|
||||
"If non-nil, preview buffers while switching, à la `counsel-switch-buffer'.
|
||||
|
||||
When nil, don't preview anything.
|
||||
When non-nil, preview non-virtual buffers.
|
||||
When 'everything, also preview virtual buffers")
|
||||
|
||||
(defvar +ivy-buffer-unreal-face 'font-lock-comment-face
|
||||
"The face for unreal buffers in `ivy-switch-to-buffer'.")
|
||||
|
||||
(defvar +ivy-edit-functions nil
|
||||
"A plist mapping ivy/counsel commands to commands that generate an editable
|
||||
results buffer.")
|
||||
|
||||
(defvar +ivy-standard-search-fn
|
||||
(if (featurep! +prescient)
|
||||
#'+ivy-prescient-non-fuzzy
|
||||
#'ivy--regex-plus)
|
||||
"Function to use for non-fuzzy search commands.
|
||||
This uses the standard search algorithm ivy uses (or a variant of it).")
|
||||
|
||||
(defvar +ivy-alternative-search-fn
|
||||
(cond ((featurep! +prescient) #'ivy-prescient-re-builder)
|
||||
((featurep! +fuzzy) #'ivy--regex-fuzzy)
|
||||
;; Ignore order for non-fuzzy searches by default
|
||||
(#'ivy--regex-ignore-order))
|
||||
"Function to use for fuzzy search commands.
|
||||
This uses a search algorithm other than ivy's default.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! ivy
|
||||
:after-call pre-command-hook
|
||||
:init
|
||||
(setq ivy-re-builders-alist
|
||||
`((counsel-rg . +ivy-standard-search)
|
||||
(swiper . +ivy-standard-search)
|
||||
(swiper-isearch . +ivy-standard-search)
|
||||
(t . +ivy-alternative-search)))
|
||||
|
||||
(define-key!
|
||||
[remap switch-to-buffer] #'+ivy/switch-buffer
|
||||
[remap switch-to-buffer-other-window] #'+ivy/switch-buffer-other-window
|
||||
[remap persp-switch-to-buffer] #'+ivy/switch-workspace-buffer
|
||||
[remap evil-show-jumps] #'+ivy/jump-list)
|
||||
:config
|
||||
;; Counsel changes a lot of ivy's state at startup; to control for that, we
|
||||
;; need to load it as early as possible. Some packages (like `ivy-prescient')
|
||||
;; require this.
|
||||
(require 'counsel nil t)
|
||||
|
||||
(setq ivy-height 17
|
||||
ivy-wrap t
|
||||
ivy-fixed-height-minibuffer t
|
||||
projectile-completion-system 'ivy
|
||||
;; disable magic slash on non-match
|
||||
ivy-magic-slash-non-match-action nil
|
||||
;; don't show recent files in switch-buffer
|
||||
ivy-use-virtual-buffers nil
|
||||
;; ...but if that ever changes, show their full path
|
||||
ivy-virtual-abbreviate 'full
|
||||
;; don't quit minibuffer on delete-error
|
||||
ivy-on-del-error-function #'ignore
|
||||
;; enable ability to select prompt (alternative to `ivy-immediate-done')
|
||||
ivy-use-selectable-prompt t)
|
||||
|
||||
;; Highlight each ivy candidate including the following newline, so that it
|
||||
;; extends to the right edge of the window
|
||||
(setf (alist-get 't ivy-format-functions-alist)
|
||||
#'ivy-format-function-line)
|
||||
|
||||
;; Integrate `ivy' with `better-jumper'; ensure a jump point is registered
|
||||
;; before jumping to new locations with ivy
|
||||
(setf (alist-get 't ivy-hooks-alist)
|
||||
(lambda ()
|
||||
(with-ivy-window
|
||||
(setq +ivy--origin (point-marker)))))
|
||||
|
||||
(add-hook! 'minibuffer-exit-hook
|
||||
(defun +ivy--set-jump-point-maybe-h ()
|
||||
(and (markerp (bound-and-true-p +ivy--origin))
|
||||
(not (equal (ignore-errors (with-ivy-window (point-marker)))
|
||||
+ivy--origin))
|
||||
(with-current-buffer (marker-buffer +ivy--origin)
|
||||
(better-jumper-set-jump +ivy--origin)))
|
||||
(setq +ivy--origin nil)))
|
||||
|
||||
(after! yasnippet
|
||||
(add-hook 'yas-prompt-functions #'+ivy-yas-prompt))
|
||||
|
||||
(defadvice! +ivy--inhibit-completion-in-region-a (orig-fn &rest args)
|
||||
"`ivy-completion-in-region' struggles with completing certain
|
||||
evil-ex-specific constructs, so we disable it solely in evil-ex."
|
||||
:around #'evil-ex
|
||||
(let ((completion-in-region-function #'completion--in-region))
|
||||
(apply orig-fn args)))
|
||||
|
||||
(define-key ivy-minibuffer-map (kbd "C-c C-e") #'+ivy/woccur)
|
||||
|
||||
(ivy-mode +1)
|
||||
|
||||
(use-package! ivy-hydra
|
||||
:commands (ivy-dispatching-done ivy--matcher-desc ivy-hydra/body)
|
||||
:init
|
||||
(define-key! ivy-minibuffer-map
|
||||
"C-o" #'ivy-dispatching-done
|
||||
"M-o" #'hydra-ivy/body)
|
||||
:config
|
||||
;; ivy-hydra rebinds this, so we have to do so again
|
||||
(define-key ivy-minibuffer-map (kbd "M-o") #'hydra-ivy/body)))
|
||||
|
||||
|
||||
(use-package! ivy-rich
|
||||
:after ivy
|
||||
:config
|
||||
(setq ivy-rich-parse-remote-buffer nil)
|
||||
|
||||
(when (featurep! +icons)
|
||||
(cl-pushnew '(+ivy-rich-buffer-icon)
|
||||
(cadr (plist-get ivy-rich-display-transformers-list
|
||||
'ivy-switch-buffer))))
|
||||
|
||||
;; Include variable value in `counsel-describe-variable'
|
||||
(plist-put! ivy-rich-display-transformers-list
|
||||
'counsel-describe-variable
|
||||
'(:columns
|
||||
((counsel-describe-variable-transformer (:width 40)) ; the original transformer
|
||||
(+ivy-rich-describe-variable-transformer (:width 50))
|
||||
(ivy-rich-counsel-variable-docstring (:face font-lock-doc-face)))))
|
||||
|
||||
;; Remove built-in coloring of buffer list; we do our own
|
||||
(setq ivy-switch-buffer-faces-alist nil)
|
||||
(ivy-set-display-transformer 'internal-complete-buffer nil)
|
||||
|
||||
;; Highlight buffers differently based on whether they're in the same project
|
||||
;; as the current project or not.
|
||||
(let* ((plist (plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
|
||||
(switch-buffer-alist (assq 'ivy-rich-candidate (plist-get plist :columns))))
|
||||
(when switch-buffer-alist
|
||||
(setcar switch-buffer-alist '+ivy-rich-buffer-name)))
|
||||
|
||||
;; Apply switch buffer transformers to `counsel-projectile-switch-to-buffer' as well
|
||||
(plist-put! ivy-rich-display-transformers-list
|
||||
'counsel-projectile-switch-to-buffer
|
||||
(plist-get ivy-rich-display-transformers-list 'ivy-switch-buffer))
|
||||
|
||||
(ivy-rich-mode +1))
|
||||
|
||||
|
||||
(use-package! all-the-icons-ivy
|
||||
:when (featurep! +icons)
|
||||
:after ivy
|
||||
:config
|
||||
;; `all-the-icons-ivy' is incompatible with ivy-rich's switch-buffer
|
||||
;; modifications, so we disable them and merge them ourselves
|
||||
(setq all-the-icons-ivy-buffer-commands nil)
|
||||
|
||||
(all-the-icons-ivy-setup)
|
||||
(after! counsel-projectile
|
||||
(let ((all-the-icons-ivy-file-commands '(counsel-projectile
|
||||
counsel-projectile-find-file
|
||||
counsel-projectile-find-dir)))
|
||||
(all-the-icons-ivy-setup))))
|
||||
|
||||
|
||||
(use-package! counsel
|
||||
:defer t
|
||||
:init
|
||||
(define-key!
|
||||
[remap apropos] #'counsel-apropos
|
||||
[remap bookmark-jump] #'counsel-bookmark
|
||||
[remap describe-face] #'counsel-faces
|
||||
[remap describe-function] #'counsel-describe-function
|
||||
[remap describe-variable] #'counsel-describe-variable
|
||||
[remap describe-bindings] #'counsel-descbinds
|
||||
[remap set-variable] #'counsel-set-variable
|
||||
[remap execute-extended-command] #'counsel-M-x
|
||||
[remap find-file] #'counsel-find-file
|
||||
[remap find-library] #'counsel-find-library
|
||||
[remap info-lookup-symbol] #'counsel-info-lookup-symbol
|
||||
[remap imenu] #'counsel-imenu
|
||||
[remap recentf-open-files] #'counsel-recentf
|
||||
[remap swiper] #'counsel-grep-or-swiper
|
||||
[remap evil-ex-registers] #'counsel-evil-registers
|
||||
[remap evil-show-marks] #'counsel-mark-ring
|
||||
[remap yank-pop] #'counsel-yank-pop
|
||||
[remap load-theme] #'counsel-load-theme
|
||||
[remap locate] #'counsel-locate
|
||||
[remap unicode-chars-list-chars] #'counsel-unicode-char
|
||||
[remap compile] #'+ivy/compile
|
||||
[remap projectile-compile-project] #'+ivy/project-compile)
|
||||
:config
|
||||
(set-popup-rule! "^\\*ivy-occur" :size 0.35 :ttl 0 :quit nil)
|
||||
|
||||
;; Don't use ^ as initial input. Set this here because `counsel' defines more
|
||||
;; of its own, on top of the defaults.
|
||||
(setq ivy-initial-inputs-alist nil)
|
||||
|
||||
;; REVIEW Move this somewhere else and perhaps generalize this so both
|
||||
;; ivy/helm users can enjoy it.
|
||||
(defadvice! +ivy--counsel-file-jump-use-fd-rg-a (args)
|
||||
"Change `counsel-file-jump' to use fd or ripgrep, if they are available."
|
||||
:override #'counsel--find-return-list
|
||||
(cl-destructuring-bind (find-program . args)
|
||||
(cond ((executable-find "fd")
|
||||
(cons "fd" (list "-t" "f" "-E" ".git")))
|
||||
((executable-find "rg")
|
||||
(cons "rg" (list "--files" "--hidden" "--no-messages")))
|
||||
((cons find-program args)))
|
||||
(unless (listp args)
|
||||
(user-error "`counsel-file-jump-args' is a list now, please customize accordingly."))
|
||||
(counsel--call
|
||||
(cons find-program args)
|
||||
(lambda ()
|
||||
(goto-char (point-min))
|
||||
(let ((offset (if (member find-program '("fd" "rg")) 0 2))
|
||||
files)
|
||||
(while (< (point) (point-max))
|
||||
(push (buffer-substring
|
||||
(+ offset (line-beginning-position)) (line-end-position)) files)
|
||||
(forward-line 1))
|
||||
(nreverse files))))))
|
||||
|
||||
;; Integrate with `helpful'
|
||||
(setq counsel-describe-function-function #'helpful-callable
|
||||
counsel-describe-variable-function #'helpful-variable)
|
||||
|
||||
;; Make `counsel-compile' projectile-aware (if you prefer it over
|
||||
;; `+ivy/compile' and `+ivy/project-compile')
|
||||
(add-to-list 'counsel-compile-root-functions #'projectile-project-root)
|
||||
(after! savehist
|
||||
;; Persist `counsel-compile' history
|
||||
(add-to-list 'savehist-additional-variables 'counsel-compile-history))
|
||||
|
||||
;; Use spotlight on mac for `counsel-locate' by default, since it doesn't need
|
||||
;; any additional setup.
|
||||
(when IS-MAC
|
||||
(setq counsel-locate-cmd #'counsel-locate-cmd-mdfind))
|
||||
|
||||
;; Don't mess with font-locking on the dashboard; it causes breakages
|
||||
(add-to-list 'swiper-font-lock-exclude #'+doom-dashboard-mode)
|
||||
|
||||
;; Record in jumplist when opening files via counsel-{ag,rg,pt,git-grep}
|
||||
(add-hook 'counsel-grep-post-action-hook #'better-jumper-set-jump)
|
||||
|
||||
;; Configure `counsel-find-file'
|
||||
(setq counsel-find-file-ignore-regexp "\\(?:^[#.]\\)\\|\\(?:[#~]$\\)\\|\\(?:^Icon?\\)")
|
||||
(ivy-add-actions
|
||||
'counsel-find-file
|
||||
'(("p" (lambda (path) (with-ivy-window (insert (file-relative-name path default-directory))))
|
||||
"insert relative path")
|
||||
("P" (lambda (path) (with-ivy-window (insert path)))
|
||||
"insert absolute path")
|
||||
("l" (lambda (path) (with-ivy-window (insert (format "[[./%s]]" (file-relative-name path default-directory)))))
|
||||
"insert relative org-link")
|
||||
("L" (lambda (path) (with-ivy-window (insert (format "[[%s]]" path))))
|
||||
"Insert absolute org-link")))
|
||||
|
||||
(ivy-add-actions
|
||||
'counsel-ag ; also applies to `counsel-rg'
|
||||
'(("O" +ivy-git-grep-other-window-action "open in other window"))))
|
||||
|
||||
|
||||
(use-package! counsel-projectile
|
||||
:defer t
|
||||
:init
|
||||
(define-key!
|
||||
[remap projectile-find-file] #'+ivy/projectile-find-file
|
||||
[remap projectile-find-dir] #'counsel-projectile-find-dir
|
||||
[remap projectile-switch-to-buffer] #'counsel-projectile-switch-to-buffer
|
||||
[remap projectile-grep] #'counsel-projectile-grep
|
||||
[remap projectile-ag] #'counsel-projectile-ag
|
||||
[remap projectile-switch-project] #'counsel-projectile-switch-project)
|
||||
:config
|
||||
;; A more sensible `counsel-projectile-find-file' that reverts to
|
||||
;; `counsel-find-file' if invoked from $HOME, `counsel-file-jump' if invoked
|
||||
;; from a non-project, `projectile-find-file' if in a big project (more than
|
||||
;; `ivy-sort-max-size' files), or `counsel-projectile-find-file' otherwise.
|
||||
(setf (alist-get 'projectile-find-file counsel-projectile-key-bindings)
|
||||
#'+ivy/projectile-find-file)
|
||||
|
||||
;; no highlighting visited files; slows down the filtering
|
||||
(ivy-set-display-transformer #'counsel-projectile-find-file nil))
|
||||
|
||||
|
||||
(use-package! wgrep
|
||||
:commands wgrep-change-to-wgrep-mode
|
||||
:config (setq wgrep-auto-save-buffer t))
|
||||
|
||||
|
||||
(use-package! ivy-posframe
|
||||
:when (featurep! +childframe)
|
||||
:hook (ivy-mode . ivy-posframe-mode)
|
||||
:config
|
||||
(setq ivy-fixed-height-minibuffer nil
|
||||
ivy-posframe-border-width 10
|
||||
ivy-posframe-parameters
|
||||
`((min-width . 90)
|
||||
(min-height . ,ivy-height)))
|
||||
|
||||
;; default to posframe display function
|
||||
(setf (alist-get t ivy-posframe-display-functions-alist)
|
||||
#'+ivy-display-at-frame-center-near-bottom-fn)
|
||||
|
||||
;; posframe doesn't work well with async sources (the posframe will
|
||||
;; occasionally stop responding/redrawing), and causes violent resizing of the
|
||||
;; posframe.
|
||||
(dolist (fn '(swiper counsel-rg counsel-grep counsel-git-grep))
|
||||
(setf (alist-get fn ivy-posframe-display-functions-alist)
|
||||
#'ivy-display-function-fallback)))
|
||||
|
||||
|
||||
(use-package! flx
|
||||
:when (featurep! +fuzzy)
|
||||
:unless (featurep! +prescient)
|
||||
:defer t ; is loaded by ivy
|
||||
:init (setq ivy-flx-limit 10000))
|
||||
|
||||
|
||||
(use-package! ivy-prescient
|
||||
:hook (ivy-mode . ivy-prescient-mode)
|
||||
:when (featurep! +prescient)
|
||||
:init
|
||||
(setq prescient-filter-method
|
||||
(if (featurep! +fuzzy)
|
||||
'(literal regexp initialism fuzzy)
|
||||
'(literal regexp initialism))
|
||||
ivy-prescient-enable-filtering nil ; we do this ourselves
|
||||
ivy-prescient-retain-classic-highlighting t)
|
||||
|
||||
:config
|
||||
(defun +ivy-prescient-non-fuzzy (str)
|
||||
(let ((prescient-filter-method '(literal regexp)))
|
||||
(ivy-prescient-re-builder str)))
|
||||
|
||||
;; NOTE prescient config duplicated with `company'
|
||||
(setq prescient-save-file (concat doom-cache-dir "prescient-save.el"))
|
||||
(prescient-persist-mode +1))
|
||||
|
||||
|
||||
;;;###package swiper
|
||||
(setq swiper-action-recenter t)
|
||||
|
||||
|
||||
;;;###package amx
|
||||
(setq amx-save-file (concat doom-cache-dir "amx-items")) ; used by `counsel-M-x'
|
||||
3
.emacs.d/modules/completion/ivy/doctor.el
Normal file
3
.emacs.d/modules/completion/ivy/doctor.el
Normal file
@@ -0,0 +1,3 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; completion/ivy/doctor.el
|
||||
|
||||
22
.emacs.d/modules/completion/ivy/packages.el
Normal file
22
.emacs.d/modules/completion/ivy/packages.el
Normal file
@@ -0,0 +1,22 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; completion/ivy/packages.el
|
||||
|
||||
(package! amx)
|
||||
(package! ivy)
|
||||
(package! counsel)
|
||||
(package! counsel-projectile)
|
||||
(package! swiper)
|
||||
(package! ivy-hydra)
|
||||
(package! ivy-rich)
|
||||
(package! wgrep)
|
||||
|
||||
(if (featurep! +prescient)
|
||||
(package! ivy-prescient)
|
||||
(when (featurep! +fuzzy)
|
||||
(package! flx)))
|
||||
|
||||
(when (featurep! +childframe)
|
||||
(package! ivy-posframe))
|
||||
|
||||
(when (featurep! +icons)
|
||||
(package! all-the-icons-ivy))
|
||||
Reference in New Issue
Block a user