diff options
Diffstat (limited to 'custom/jao-custom-completion.el')
-rw-r--r-- | custom/jao-custom-completion.el | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/custom/jao-custom-completion.el b/custom/jao-custom-completion.el new file mode 100644 index 0000000..b44f9b6 --- /dev/null +++ b/custom/jao-custom-completion.el @@ -0,0 +1,425 @@ +;; -*- lexical-binding: t; -*- + +;;; builtin completion +(setq tab-always-indent 'complete + read-extended-command-predicate #'command-completion-default-include-p + completion-auto-select 'second-tab + completion-auto-help 'always + completion-category-defaults nil + completion-cycle-threshold 4 + completions-detailed t + completions-header-format nil + completion-ignore-case t + completion-show-help nil + completion-show-inline-help t + completions-format 'one-column + completion-styles '(basic substring partial-completion emacs22) + completion-category-overrides + '((file (styles partial-completion)) + (command (styles initials substring partial-completion)) + (symbol (styles initials substring partial-completion)) + (variable (styles initials substring partial-completion))) + completion-wrap-movement t) + +;;; crm indicator +(defun jao-completion--crm-indicator (args) + "Add prompt indicator to `completing-read-multiple' filter ARGS." + (cons (concat "[CRM] " (car args)) (cdr args))) + +(advice-add #'completing-read-multiple + :filter-args #'jao-completion--crm-indicator) + +;;; orderless +(use-package orderless + :ensure t + :demand t + :config + (orderless-define-completion-style orderless+initialism + (orderless-matching-styles '(orderless-initialism + orderless-prefixes + orderless-literal + orderless-regexp))) + (defvar jao-orderless-overrides + '((file (styles partial-completion orderless)) + (command (styles orderless+initialism)))) + + (setq orderless-matching-styles + '(orderless-literal orderless-regexp orderless-prefixes))) + +;;; marginalia +(use-package marginalia + :ensure t + :bind (:map minibuffer-local-map ("C-M-a" . marginalia-cycle)) + + :custom ((marginalia-align 'left) + (marginalia-align-offset 1) + (marginalia-field-width 200) + (marginalia-annotators + '(marginalia-annotators-heavy marginalia-annotators-light nil)) + (marginalia-separator " "))) + +(marginalia-mode 1) + +;;; vertico +(use-package vertico + :ensure t + :init + (defvar jao-vertico-reverse t) + + (setq vertico-count 20 + vertico-cycle t + vertico-resize t + vertico-multiform-categories nil + vertico-multiform-commands + `((".*" + (completion-styles orderless basic) + (completion-category-overrides . ,jao-orderless-overrides))) + vertico-buffer-display-action + `(display-buffer-below-selected (window-height . 0.5))) + + (dolist (c '(completion-at-point complete-symbol indent-for-tab-command)) + (let ((s `(,c buffer (vertico-resize) (jao-vertico-reverse)))) + (add-to-list 'vertico-multiform-commands s))) + + :config + (defun jao-vertico--display (fun lines) + (if (not jao-vertico-reverse) + (funcall fun lines) + (move-overlay vertico--candidates-ov (point-min) (point-min)) + (overlay-put vertico--candidates-ov 'after-string (apply #'concat lines)) + (vertico--resize-window (length lines)))) + + (advice-add 'vertico--display-candidates :around #'jao-vertico--display)) + +(use-package vertico-directory + :after vertico + :bind (:map vertico-map (("RET" . vertico-directory-enter) + ("M-<backspace>" . vertico-directory-delete-word) + ("<backspace>" . vertico-directory-delete-char) + ("DEL" . vertico-directory-delete-char)))) + +(vertico-mode) +(vertico-multiform-mode) + +;;; consult +;;;; package +(use-package consult + :ensure t + :bind (("C-x M-:" . consult-complex-command) + ("C-x b" . consult-buffer) + ("C-x C-b" . consult-buffer) + ("C-x 4 b" . consult-buffer-other-window) + ("C-c b" . project-find-file) + ("C-c h" . nil) + ("C-c i" . consult-imenu) + ("C-c I" . consult-project-imenu) + ("C-h I" . consult-info) + ;; ("C-c o" . consult-outline) + ("C-c k" . consult-ripgrep) + ("C-c L" . consult-locate) + ("C-c s" . consult-line) + ("C-x r x" . consult-register) + ("C-x r b" . consult-bookmark) + ("C-x C-f" . jao-find-file) + ("M-g b" . consult-bookmark) + ("M-g m" . consult-mark) + ("M-g e" . consult-error) + ("M-s m" . consult-multi-occur) + ("M-y" . consult-yank-pop) + ("C-s" . isearch-forward) + ("<help> a" . consult-apropos)) + + :custom ((consult-preview-key (kbd "`"))) + + :init + (fset 'multi-occur #'consult-multi-occur) + (setq org-refile-use-outline-path t + org-imenu-depth 7) + + :config + (defun jao-consult--completion-in-region (&rest args) + (apply (if (and (not (bound-and-true-p corfu-mode)) + (not (bound-and-true-p company-mode)) + (bound-and-true-p vertico-mode)) + #'consult-completion-in-region + #'completion--in-region) + args)) + + (setq completion-in-region-function #'jao-consult--completion-in-region) + + (defun jao-find-file (arg) + (interactive "P") + (call-interactively (if arg 'consult-file-externally 'find-file))) + + (define-key consult-narrow-map (vconcat consult-narrow-key "?") + #'consult-narrow-help) + + (with-eval-after-load "esh-mode" + (define-key eshell-mode-map (kbd "C-c h") #'consult-history)) + + (with-eval-after-load "comint" + (define-key comint-mode-map (kbd "C-c h") #'consult-history)) + + (consult-customize consult-mark :preview-key 'any) + (add-hook 'completion-list-mode-hook #'consult-preview-at-point-mode)) + +;;;; consult-dir +;; (use-package consult-dir +;; :ensure t +;; :bind (("C-x C-d" . consult-dir) +;; :map minibuffer-local-completion-map +;; (("C-x C-d" . consult-dir) +;; ("C-x C-j" . consult-dir-jump-file)))) + +;;;; narrow helpers +(defvar jao-consult-narrow nil) + +(defun jao-consult-initial-narrow () + (when-let (c (cond ((eq this-command #'consult-buffer) + (cdr (assoc (jao-afio-frame-name) jao-consult-narrow))) + ((eq this-command #'consult-mode-command) ?m))) + (setq unread-command-events (append unread-command-events `(,c 32))))) + +(add-hook 'minibuffer-setup-hook #'jao-consult-initial-narrow) + +(defmacro jao-consult--mode-buffers (&rest modes) + `(lambda () + (seq-map #'buffer-name + (seq-filter (lambda (b) + (with-current-buffer b + (derived-mode-p ,@modes))) + (buffer-list))))) + +(defun jao-consult-add-buffer-source (src &optional aframe key) + (add-to-list 'consult-buffer-sources src t) + (when (and aframe key) + (add-to-list 'jao-consult-narrow (cons aframe key)))) + +;;; embark +;;;; package +(use-package embark + :ensure t + :demand t + :init + (setq embark-quit-after-action nil + embark-indicators '(embark-mixed-indicator + ;; embark-minimal-indicator + embark-highlight-indicator + embark-isearch-highlight-indicator) + embark-mixed-indicator-both t + embark-mixed-indicator-delay 1 + embark-verbose-indicator-buffer-sections '(bindings) + embark-verbose-indicator-excluded-commands + '(embark-become embark-export embark-collect) + embark-verbose-indicator-nested t + embark-verbose-indicator-display-action + '((display-buffer-at-bottom) + (window-parameters (mode-line-format . none)) + (window-height . fit-window-to-buffer))) + + ;; (setq prefix-help-command #'describe-prefix-bindings) + ;; (add-to-list 'vertico-multiform-categories '(embark-keybinding grid)) + + :bind (("C-;" . embark-act) + ("C-c ;" . embark-act) + ("C-'" . embark-dwim) + ("C-c '" . embark-dwim) + (:map minibuffer-local-map + (("C-'" . embark-dwim) + ("C-c '" . embark-dwim) + ("C-," . embark-become) + ("C-c ," . embark-become) + ("C-o" . embark-export))))) + +(use-package embark-consult + :ensure t + :after (embark consult)) + +(with-eval-after-load 'consult + (with-eval-after-load 'embark + (require 'embark-consult))) + +;;;; randomsig +(defun jao-random-sig-read (_ignored) + "Import region as signature and edit it." + (randomsig-message-read-sig t)) + +(define-key embark-region-map "m" #'jao-random-sig-read) +(define-key embark-region-map "M" #'apply-macro-to-region-lines) + +;;;; dict/say +(defun jao-say (&optional word) + "Isn't it nice to have a computer that can talk to you?" + (interactive "sWhat? ") + (shell-command-to-string (format "say %s" word)) + "") + +(define-key embark-identifier-map "D" #'dictionary-search) +(define-key embark-identifier-map "S" #'jao-say) + +;;;; org targets +(declare-function org-link-any-re "ol") +(declare-function org-open-link-from-string "ol") +(declare-function org-in-regexp "org-macs") + +(defun jao-embark-targets--org-link () + (when (derived-mode-p 'org-mode) + (let ((lnk (org-element-property :raw-link (org-element-context)))) + (and lnk (cons 'org-link lnk))))) + +(defun jao-embark-targets--gl-org-link () + (when (org-in-regexp org-link-bracket-re) + (cons 'gl-org-link (match-string-no-properties 0)))) + +(defvar jao-embark-targets-gl-org-link-map + (define-keymap "RET" #'org-open-at-point-global)) + +(defvar jao-embark-targets-org-link-map + (define-keymap "RET" #'org-open-link-from-string)) + +(add-to-list 'embark-target-finders #'jao-embark-targets--gl-org-link) +(add-to-list 'embark-keymap-alist + '(gl-org-link . jao-embark-targets-gl-org-link-map)) + +(add-to-list 'embark-target-finders #'jao-embark-targets--org-link) +(add-to-list 'embark-keymap-alist + '(org-link . jao-embark-targets-org-link-map)) + +;;;; url targets +(declare-function w3m-anchor "w3m") + +(defun jao-embark-targets--w3m-anchor () + (when (not (region-active-p)) + (when-let ((url (or (jao-url-around-point) + (thing-at-point 'url) + (and (derived-mode-p 'w3m-mode) + (or (w3m-anchor) w3m-current-url)) + (and (derived-mode-p 'eww-mode) + (eww-current-url))))) + (when (string-match-p "^https?.*" url) + (cons 'url url))))) + +(add-to-list 'embark-target-finders #'jao-embark-targets--w3m-anchor) + +(defun jao-embark-url (url) + "Browse URL, externally if we're already in an emacs browser." + (if (derived-mode-p 'w3m-mode 'eww-mode) + (jao-browse-with-external-browser url) + (browse-url url))) + +(define-key embark-url-map (kbd "RET") #'jao-embark-url) +(define-key embark-url-map (kbd "f") #'browse-url-firefox) +(define-key embark-url-map (kbd "x") #'jao-rss-subscribe) +(define-key embark-url-map (kbd "m") 'jao-browse-with-external-browser) +(define-key embark-url-map (kbd "p") 'jao-mpc-add-or-play-url) + +;;;; video url targets +(defvar jao-embark-targets-video-sites + '("youtu.be" "youtube.com" "blip.tv" "vimeo.com" "infoq.com")) + +(defun jao-embark--video-url-rx (&optional sites) + (format "^https?://\\(?:www\\.\\)?%s/.+" + (regexp-opt (or sites jao-embark-targets-video-sites) t))) + +(defvar jao-embark-targets-video-url-rx (jao-embark--video-url-rx) + "A regular expression matching URLs that point to video streams") + +(defun jao-embark-targets--refine-url (_ url) + (if (string-match-p jao-embark-targets-video-url-rx url) + (cons 'video-url url) + (cons 'url url))) + +(defun jao-embark-targets--play-video (player url) + (interactive "sURL: ") + (let ((cmd (format "%s %s" player (shell-quote-argument url)))) + (jao-afio-goto-www) + (start-process-shell-command player nil cmd))) + +(defun jao-embark-targets-mpv (&optional url) + "Play video stream with mpv" + (interactive "sURL: ") + (jao-embark-targets--play-video "mpv" url)) + +(defun jao-embark-targets-vlc (&optional url) + "Play video stream with vlc" + (interactive "sURL: ") + (jao-embark-targets--play-video "vlc" url)) + +(defvar jao-embark-targets-video-url-map + (define-keymap "v" #'jao-embark-targets-mpv "RET" #'jao-embark-targets-mpv) + "Actions on URLs pointing to remote video streams.") + +(add-to-list 'embark-transformer-alist '(url . jao-embark-targets--refine-url)) +(add-to-list 'embark-keymap-alist '(video-url . jao-embark-targets-video-url-map)) +(define-key embark-url-map "v" #'jao-embark-targets-vlc) +(define-key embark-url-map "V" #'jao-embark-targets-vlc) + +;;;; vc targets + + +;;; avy +(use-package avy + :ensure t + :init (setq avy-style 'pre + avy-background t + avy-timeout-seconds 0.6 + avy-single-candidate-jump t) + + :config + + (defun avy-embark-act (pt) + "Use Embark to act on the completion at PT." + (save-excursion + (goto-char pt) + (embark-act))) + (add-to-list 'avy-dispatch-alist '(?\; . avy-embark-act)) + + :bind (("s-j" . avy-goto-char-timer) + ("C-M-j" . avy-goto-char-timer))) + +;;; link-hint +(use-package link-hint + :ensure t + :init (setq link-hint-avy-style 'pre + link-hint-message nil) + + :config + (defun jao-link-hint-open-link-ext () + (interactive) + (let ((jao-browse-url-function jao-browse-url-external-function)) + (link-hint-open-link))) + + :bind (("C-l" . link-hint-open-link) + ("C-M-l" . jao-link-hint-open-link-ext) + ("C-S-l" . jao-link-hint-open-link-ext) + ("C-x C-l" . recenter-top-bottom))) + +(with-eval-after-load "notmuch" + (defun jao-link-hint--notmuch-next-part (&optional bound) + (when-let (p (next-single-property-change (point) :notmuch-part nil bound)) + (and (< p (or bound (point-max))) p))) + + (defun jao-link-hint--notmuch-part-p () + (and (get-text-property (point) :notmuch-part) + (when-let (b (button-at (point))) (button-label b)))) + + (link-hint-define-type 'notmuch-part + :next #'jao-link-hint--notmuch-next-part + :at-point-p #'jao-link-hint--notmuch-part-p + :vars '(notmuch-show-mode) + :open #'push-button + :open-message "Toggled" + :open-multiple t) + + (push 'link-hint-notmuch-part link-hint-types)) + +;;; xref +(setq xref-show-definitions-function #'xref-show-definitions-completing-read) + +;; (use-package dumb-jump +;; :ensure t +;; :after xref +;; :config (add-hook 'xref-backend-functions #'dumb-jump-xref-activate)) + +;;; . +(provide 'jao-custom-completion) |