From 0adf2da1d62addce56afd5fb8866ecce77147bd5 Mon Sep 17 00:00:00 2001 From: jao Date: Sun, 4 Apr 2021 21:40:15 +0100 Subject: completion.org and minicomp --- attic/counsel.org | 63 +++++++ completion.org | 424 +++++++++++++++++++++++++++++++++++++++++++++++ consult.org | 405 -------------------------------------------- init.org | 87 +--------- lib/themes/jao-themes.el | 2 + readme.org | 2 +- 6 files changed, 494 insertions(+), 489 deletions(-) create mode 100644 completion.org delete mode 100644 consult.org diff --git a/attic/counsel.org b/attic/counsel.org index 6fbd591..f6814ae 100644 --- a/attic/counsel.org +++ b/attic/counsel.org @@ -1,5 +1,68 @@ #+title: Completion configuration using ivy, counsel and friends +* selectrum + #+begin_src emacs-lisp :load no + (use-package selectrum + :ensure t + :init + (defun jao-selectrum--ord-refine (&rest args) + (let ((completion-styles '(orderless))) + (apply #'selectrum-refine-candidates-using-completions-styles args))) + + (defun jao-selectrum-orderless () + (interactive) + (setq selectrum-refine-candidates-function #'jao-selectrum--ord-refine) + (setq selectrum-highlight-candidates-function #'orderless-highlight-matches) + (setq orderless-skip-highlighting (lambda () selectrum-is-active))) + + + :config + ;; https://github.com/raxod502/selectrum/wiki/Ido,-icomplete(fido)-emulation + (defun selectrum-fido-backward-updir () + "Delete char before or go up directory, like `ido-mode'." + (interactive) + (if (and (eq (char-before) ?/) + (eq (selectrum--get-meta 'category) 'file)) + (save-excursion + (goto-char (1- (point))) + (when (search-backward "/" (point-min) t) + (delete-region (1+ (point)) (point-max)))) + (call-interactively 'backward-delete-char))) + + (defun selectrum-fido-delete-char () + "Delete char or maybe call `dired', like `ido-mode'." + (interactive) + (let ((end (point-max))) + (if (or (< (point) end) (not (eq (selectrum--get-meta 'category) 'file))) + (call-interactively 'delete-char) + (dired (file-name-directory (minibuffer-contents))) + (exit-minibuffer)))) + + (defun selectrum-fido-ret () + "Exit minibuffer or enter directory, like `ido-mode'." + (interactive) + (let* ((dir (and (eq (selectrum--get-meta 'category) 'file) + (file-name-directory (minibuffer-contents)))) + (current (selectrum-get-current-candidate)) + (probe (and dir current + (expand-file-name (directory-file-name current) dir)))) + (if (and probe (file-directory-p probe) (not (string= current "./"))) + (selectrum-insert-current-candidate) + (selectrum-select-current-candidate)))) + + ;; (define-key selectrum-minibuffer-map (kbd "RET") 'selectrum-fido-ret) + (define-key selectrum-minibuffer-map (kbd "DEL") 'selectrum-fido-backward-updir) + (define-key selectrum-minibuffer-map (kbd "C-d") 'selectrum-fido-delete-char) + + :custom ((selectrum-complete-in-buffer t) + ;; (selectrum-display-action '(display-buffer-at-bottom)) + (selectrum-extend-current-candidate-highlight t) + (selectrum-fix-vertical-window-height nil) + (selectrum-max-window-height 20) + (selectrum-show-indices nil) + (selectrum-count-style 'current/matches)) + :bind (("C-R" . selectrum-repeat))) + #+end_src * ivy #+begin_src emacs-lisp (use-package ivy diff --git a/completion.org b/completion.org new file mode 100644 index 0000000..37d5bbf --- /dev/null +++ b/completion.org @@ -0,0 +1,424 @@ +#+title: Completion configuration using selectrum, consult and friends + +* company + #+begin_src emacs-lisp + (use-package company + :ensure t + :custom + ((company-global-modes '(clojure-mode + clojurec-mode + emacs-lisp-mode + eshell-mode + lisp-interaction-mode + haskell-mode + message-mode + org-mode + scheme-mode)) + (company-idle-delay 0.15) + (company-lighter "") + (company-lighter-base "") + (company-show-numbers nil) + (company-tooltip-limit 15) + (company-tooltip-align-annotations t) + (company-transformers '(company-sort-by-occurrence))) + + :config + ;; Prevent non-matching input (which will dismiss the completions + ;; menu), but only if the user interacts explicitly with Company. + (setq company-require-match #'company-explicit-action-p) + + (defun jao-complete-at-point () + "Complete using company unless we're in the minibuffer." + (interactive) + (if (window-minibuffer-p) (completion-at-point) (company-manual-begin))) + + :bind (([remap completion-at-point] . #'jao-complete-at-point) + ([remap complete-symbol] . #'jao-complete-at-point) + + ;; The following are keybindings that take effect whenever + ;; the completions menu is visible, even if the user has not + ;; explicitly interacted with Company. + :map company-active-map + + ([remap scroll-up-command] . nil) + ([remap scroll-down-command] . nil) + + ;; Make TAB always complete the current selection, instead of + ;; only completing a common prefix. + ("" . #'company-complete-selection) + ("TAB" . #'company-complete-selection) + + ("C-h" . #'company-show-doc-buffer) + ("M-." . #'company-show-location) + + ;; The following are keybindings that only take effect + ;; if not in eshell. Note that `:map' from above is + ;; "sticky", and applies also below. + ;; Another interesting :filter (company-explicit-action-p) + + :filter (or (not (derived-mode-p 'eshell-mode)) + (company-explicit-action-p)) + ("" . #'company-complete-selection) + ("RET" . #'company-complete-selection)) + + :bind* (;; The default keybinding for `completion-at-point' and + ;; `complete-symbol' is M-TAB or equivalently C-M-i. We + ;; already remapped those bindings to `company-manual-begin' + ;; above. Here we make sure that they definitely invoke + ;; `company-manual-begin' even if a minor mode binds M-TAB + ;; directly. + ("M-TAB" . #'jao-complete-at-point)) + + :diminish) + + (use-package company-math :ensure t :after company) + + (global-company-mode 1) + + #+end_src + +* orderless + #+begin_src emacs-lisp :load no + (use-package orderless + :ensure t + :custom ((orderless-component-separator "[ -/]+") + (orderless-matching-styles + '(orderless-literal orderless-regexp orderless-initialism))) + :bind + ((:map minibuffer-local-completion-map ("SPC" . self-insert-command)))) + #+end_src +* minicomp + #+begin_src emacs-lisp + (jao-load-path "minicomp") + (use-package minicomp + :init (setq minicomp-count 20) + :config + (defun jao-minicomp--orderless (&rest _) + (setq-local completion-styles '(orderless))) + (add-hook 'minibuffer-setup-hook #'jao-minicomp--orderless)) + (minicomp-mode 1) + #+end_src +* marginalia + #+begin_src emacs-lisp + (use-package marginalia + :ensure t + :bind (:map minibuffer-local-map ("C-M-a" . marginalia-cycle)) + + :custom ((marginalia-align-offset 1) + (marginalia-margin-threshold 200) + (marginalia-separator-threshold 120) + (marginalia-truncate-width 80) + (marginalia-annotators + '(marginalia-annotators-heavy marginalia-annotators-light nil)))) + (marginalia-mode 1) + #+end_src +* consult + #+begin_src emacs-lisp + (use-package consult + :ensure t + :bind (("C-x M-:" . consult-complex-command) + ("C-x b" . consult-buffer) + ;; ("C-x 4 b" . consult-buffer-other-window) + ;; ("C-x 5 b" . consult-buffer-other-frame) + ("C-c b" . project-find-file) + ("C-c B" . bookmark-set) + ("C-c h" . consult-history) + ("C-c i" . consult-imenu) + ("C-c k" . consult-ripgrep) + ("C-c K" . consult-git-grep) + ("C-c l" . consult-locate) + ("C-c m" . consult-mode-command) + ("C-c s" . consult-line) + ("C-x r x" . consult-register) + ("C-x r b" . consult-bookmark) + ("M-g b" . consult-bookmark) + ("M-g g" . consult-goto-line) + ("M-g M-g" . consult-goto-line) + ("M-g o" . consult-outline) + ("M-g s" . consult-line) + ("M-g m" . consult-man) + ("M-g M" . consult-mark) + ("M-g K" . consult-git-grep) + ("M-g k" . consult-ripgrep) + ("M-g i" . consult-imenu) + ("M-g I" . consult-project-imenu) + ("M-g e" . consult-error) + ("M-s m" . consult-multi-occur) + ("M-s o" . consult-outline) + ("M-y" . consult-yank-pop) + ("C-s" . isearch-forward) + (" a" . consult-apropos)) + + :custom ((consult-locate-command "locate --ignore-case --regexp ARG OPTS") + (consult-preview-key (kbd "`")) + (consult-config '((consult-mark :preview-key any)))) + + :init + (fset 'multi-occur #'consult-multi-occur) + + :config + (defun jao-consult-project-root () + (expand-file-name (or (jao-compilation-root) (vc-root-dir) ""))) + + (setq consult-project-root-function #'jao-consult-project-root) + + (define-key consult-narrow-map (vconcat consult-narrow-key "?") + #'consult-narrow-help)) + #+end_src +* consultors +*** notmuch + #+begin_src emacs-lisp + (jao-load-path "consult-notmuch") + (use-package consult-notmuch + :config + (add-to-list 'consult-config '(consult-notmuch :preview-key any))) + #+end_src +*** recoll + #+begin_src emacs-lisp + (jao-load-path "consult-recoll") + + (defun jao-recoll-format (title url mtype) + (let* ((u (replace-regexp-in-string "/home/jao/" "" url)) + (u (replace-regexp-in-string "\\(doc\\|org/doc\\|var/mail\\)/" "" u))) + (format "%s (%s, %s)" + title + (propertize u 'face 'jao-themes-f00) + (propertize mtype 'face 'jao-themes-f01)))) + + (use-package consult-recoll + :init (setq consult-recoll-open-fns + '(("application/pdf" . jao-open-doc) + ("message/rfc822" . jao-org-links-open-mail)) + consult-recoll-format-candidate #'jao-recoll-format) + :bind (("C-c R" . #'consult-recoll))) + + #+end_src +*** dh-diff hunks + #+begin_src emacs-lisp + (defun jao-consult--diff-lines (&optional backward) + (let ((candidates) + (width (length (number-to-string + (line-number-at-pos (point-max) + consult-line-numbers-widen))))) + (save-excursion + (while (ignore-errors (diff-hl-next-hunk backward)) + (let* ((str (buffer-substring (line-beginning-position) + (line-end-position))) + (no (line-number-at-pos (point))) + (no (consult--line-number-prefix (point-marker) no width))) + (push (concat no str) candidates)))) + (if backward candidates (nreverse candidates)))) + + (defun jao-consult-hunks () + (interactive) + (let ((candidates (append (jao-consult--diff-lines) + (jao-consult--diff-lines t)))) + (unless candidates (error "No changes!")) + (consult--jump + (consult--read "Go to hunk: " candidates + :category 'consult--encode-location + :sort nil + :require-match t + :lookup #'consult--line-match + :preview (consult--preview-position))))) + + (with-eval-after-load "consult" + (add-to-list 'consult-config '(jao-consult-hunks :preview-key any))) + #+end_src +* embark +*** packages + #+begin_src emacs-lisp + (use-package embark + :ensure t + :custom ((embark-quit-after-action nil) + (prefix-help-command #'embark-prefix-help-command)) + :bind (("C-;" . embark-act) + ("C-'" . embark-default-action) + (:map minibuffer-local-map + (("C-'" . embark-default-action) + ("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))) + (require 'embark) + #+end_src +*** embark action indicator + #+begin_src emacs-lisp + (defvar jao-embark--actions-buffer "*Embark Actions*") + + (defvar jao-embark--default-display + `((,(regexp-quote jao-embark--actions-buffer) + (display-buffer-at-bottom) + (window-parameters (mode-line-format . none)) + (window-height . fit-window-to-buffer)))) + + (setq jao-embark--excluded + '(embark-collect-snapshot embark-collect-live embark-export + embark-keymap-help embark-become embark-isearch nil)) + + (defun jao-embark--key-str (k) + (if (numberp k) (single-key-description k) (key-description k))) + + (defun jao-embark--bind-desc (descs x prefix) + (let ((k (car x)) (c (cdr x))) + (cond ((keymapp c) + (let ((cds (jao-embark--keymap-descs c (jao-embark--key-str k)))) + (cons (max (or (car cds) 0) (or (car descs) 0)) + (cons (max (or (cadr cds) 0) (or (cadr descs) 0)) + (append (cddr descs) (cddr cds)))))) + ((memq c jao-embark--excluded) descs) + ((symbolp c) + (let* ((desc (jao-embark--key-str k)) + (desc (format "%s%s" (or prefix "") desc)) + (doc (car (split-string + (or (ignore-errors (documentation c)) "") + "\n"))) + (fun (symbol-name c))) + (cons (max (length desc) (car descs)) + (cons (max (length fun) (cadr descs)) + (cons (list desc fun doc) (cddr descs)))))) + (t (message "i've skipped %S" x) descs)))) + + (defun jao-embark--keymap-descs (k prefix) + (seq-reduce `(lambda (descs x) (jao-embark--bind-desc descs x ,prefix)) + (cdr (keymap-canonicalize k)) '(0 0))) + + (defun jao-embark--dstr (d) + (let ((s (cadr d))) (if (string-prefix-p "embark" s) "" s))) + + (defun jao-embark--show-keymap (keymap &optional target) + (with-current-buffer (get-buffer-create jao-embark--actions-buffer) + (read-only-mode -1) + (setq-local cursor-type nil) + (delete-region (point-min) (point-max)) + (let* ((descs (jao-embark--keymap-descs keymap "")) + (fmt (format "%%-%ds %%-%ds %%s\n" (cadr descs) (car descs)))) + (seq-each (lambda (desc) + (insert (format fmt + (propertize (cadr desc) 'face 'jao-themes-f00) + (propertize (car desc) 'face 'embark-keybinding) + (propertize (caddr desc) 'face 'italic)))) + (seq-sort-by 'jao-embark--dstr 'string-greaterp (cddr descs)))) + (if target (insert (format "\nAction for '%s'" target)) (delete-char -1)) + (read-only-mode 1) + (let ((display-buffer-alist + (append display-buffer-alist jao-embark--default-display))) + (pop-to-buffer (current-buffer) nil t)) + (lambda () + (embark-kill-buffer-and-window jao-embark--actions-buffer) + (when (or (bound-and-true-p selectrum-is-active) + (and (boundp 'minicomp--input) + (stringp minicomp--input))) + (select-window (minibuffer-window)))))) + + (setq embark-action-indicator #'jao-embark--show-keymap + embark-become-indicator embark-action-indicator) + + #+end_src +*** org targets + #+begin_src emacs-lisp + (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) + (when (org-in-regexp org-link-any-re) + (let ((lnk (match-string-no-properties 2))) + (if (string-match-p "https?://.+" (or lnk "")) + (cons 'url lnk) + (cons 'org-link (match-string-no-properties 0))))))) + + (embark-define-keymap jao-embark-targets-org-link-map + "Actions for org links" + ((kbd "RET") org-open-link-from-string)) + + (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)) + #+end_src +*** url targets + #+begin_src emacs-lisp + (declare-function w3m-anchor "w3m") + + (defun jao-embark-targets--w3m-anchor () + (when (not (region-active-p)) + (when-let ((url (or (and (derived-mode-p 'w3m-mode) + (or (w3m-anchor) w3m-current-url)) + (and (derived-mode-p 'eww-mode) + (or (thing-at-point 'url) (eww-current-url))) + (jao-url-around-point)))) + (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 emacs-w3m" + (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 "e") #'jao-eww-browse-url) + (define-key embark-url-map (kbd "f") #'browse-url-firefox) + (define-key embark-url-map (kbd "m") 'jao-browse-with-external-browser) + #+end_src +*** video url targets + #+begin_src emacs-lisp + (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)))) + (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)) + + (embark-define-keymap jao-embark-targets-video-url-map + "Actions on URLs pointing to remote video streams." + :parent embark-url-map + ("RET" jao-embark-targets-mpv) + ("v" jao-embark-targets-vlc)) + + (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)) + #+end_src +*** spotify + #+begin_src emacs-lisp + (with-eval-after-load "consult-spotify" + (embark-define-keymap spotify-item-keymap + "Actions for Spotify search results" + ("y" espotify-yank-candidate-url) + ("a" espotify-play-candidate-album) + ("h" espotify-show-candidate-info)) + + (add-to-list 'embark-keymap-alist + '(spotify-search-item . spotify-item-keymap))) + #+end_src diff --git a/consult.org b/consult.org deleted file mode 100644 index 76ebee7..0000000 --- a/consult.org +++ /dev/null @@ -1,405 +0,0 @@ -#+title: Completion configuration using selectrum, consult and friends - -* completion styles - #+begin_src emacs-lisp - (setq completion-styles '(basic partial-completion emacs22)) - #+end_src -* orderless - #+begin_src emacs-lisp :load no - (use-package orderless - :ensure t - :custom ((orderless-component-separator "[ -/]+") - (orderless-matching-styles - '(orderless-literal orderless-regexp orderless-initialism))) - :bind - ((:map minibuffer-local-completion-map ("SPC" . self-insert-command)))) - #+end_src -* selectrum - #+begin_src emacs-lisp - (use-package selectrum - :ensure t - :init - (defun jao-selectrum--ord-refine (&rest args) - (let ((completion-styles '(orderless))) - (apply #'selectrum-refine-candidates-using-completions-styles args))) - - (defun jao-selectrum-orderless () - (interactive) - (setq selectrum-refine-candidates-function #'jao-selectrum--ord-refine) - (setq selectrum-highlight-candidates-function #'orderless-highlight-matches) - (setq orderless-skip-highlighting (lambda () selectrum-is-active))) - - - :config - ;; https://github.com/raxod502/selectrum/wiki/Ido,-icomplete(fido)-emulation - (defun selectrum-fido-backward-updir () - "Delete char before or go up directory, like `ido-mode'." - (interactive) - (if (and (eq (char-before) ?/) - (eq (selectrum--get-meta 'category) 'file)) - (save-excursion - (goto-char (1- (point))) - (when (search-backward "/" (point-min) t) - (delete-region (1+ (point)) (point-max)))) - (call-interactively 'backward-delete-char))) - - (defun selectrum-fido-delete-char () - "Delete char or maybe call `dired', like `ido-mode'." - (interactive) - (let ((end (point-max))) - (if (or (< (point) end) (not (eq (selectrum--get-meta 'category) 'file))) - (call-interactively 'delete-char) - (dired (file-name-directory (minibuffer-contents))) - (exit-minibuffer)))) - - (defun selectrum-fido-ret () - "Exit minibuffer or enter directory, like `ido-mode'." - (interactive) - (let* ((dir (and (eq (selectrum--get-meta 'category) 'file) - (file-name-directory (minibuffer-contents)))) - (current (selectrum-get-current-candidate)) - (probe (and dir current - (expand-file-name (directory-file-name current) dir)))) - (if (and probe (file-directory-p probe) (not (string= current "./"))) - (selectrum-insert-current-candidate) - (selectrum-select-current-candidate)))) - - ;; (define-key selectrum-minibuffer-map (kbd "RET") 'selectrum-fido-ret) - (define-key selectrum-minibuffer-map (kbd "DEL") 'selectrum-fido-backward-updir) - (define-key selectrum-minibuffer-map (kbd "C-d") 'selectrum-fido-delete-char) - - :custom ((selectrum-complete-in-buffer t) - ;; (selectrum-display-action '(display-buffer-at-bottom)) - (selectrum-extend-current-candidate-highlight t) - (selectrum-fix-vertical-window-height nil) - (selectrum-max-window-height 20) - (selectrum-show-indices nil) - (selectrum-count-style 'current/matches)) - :bind (("C-R" . selectrum-repeat))) - #+end_src -* marginalia - #+begin_src emacs-lisp - (use-package marginalia - :ensure t - :bind (:map minibuffer-local-map ("C-M-a" . marginalia-cycle)) - - :custom ((marginalia-align-offset 1) - (marginalia-margin-threshold 200) - (marginalia-separator-threshold 120) - (marginalia-truncate-width 80) - (marginalia-annotators - '(marginalia-annotators-heavy marginalia-annotators-light nil)))) - #+end_src -* consult - #+begin_src emacs-lisp - (use-package consult - :ensure t - :bind (("C-x M-:" . consult-complex-command) - ("C-x b" . consult-buffer) - ;; ("C-x 4 b" . consult-buffer-other-window) - ;; ("C-x 5 b" . consult-buffer-other-frame) - ("C-c b" . project-find-file) - ("C-c B" . bookmark-set) - ("C-c h" . consult-history) - ("C-c i" . consult-imenu) - ("C-c k" . consult-ripgrep) - ("C-c K" . consult-git-grep) - ("C-c l" . consult-locate) - ("C-c m" . consult-mode-command) - ("C-c s" . consult-line) - ("C-x r x" . consult-register) - ("C-x r b" . consult-bookmark) - ("M-g b" . consult-bookmark) - ("M-g g" . consult-goto-line) - ("M-g M-g" . consult-goto-line) - ("M-g o" . consult-outline) - ("M-g s" . consult-line) - ("M-g m" . consult-man) - ("M-g M" . consult-mark) - ("M-g K" . consult-git-grep) - ("M-g k" . consult-ripgrep) - ("M-g i" . consult-imenu) - ("M-g I" . consult-project-imenu) - ("M-g e" . consult-error) - ("M-s m" . consult-multi-occur) - ("M-s o" . consult-outline) - ("M-y" . consult-yank-pop) - ("C-s" . isearch-forward) - (" a" . consult-apropos)) - - :custom ((consult-locate-command "locate --ignore-case --regexp ARG OPTS") - (consult-preview-key (kbd "`")) - (consult-config '((consult-mark :preview-key any)))) - - :init - (fset 'multi-occur #'consult-multi-occur) - - :config - (defun jao-consult-project-root () - (expand-file-name (or (jao-compilation-root) (vc-root-dir) ""))) - - (setq consult-project-root-function #'jao-consult-project-root) - - (define-key consult-narrow-map (vconcat consult-narrow-key "?") - #'consult-narrow-help)) - #+end_src -* consultors -*** notmuch - #+begin_src emacs-lisp - (jao-load-path "consult-notmuch") - (use-package consult-notmuch - :config - (add-to-list 'consult-config '(consult-notmuch :preview-key any))) - #+end_src -*** recoll - #+begin_src emacs-lisp - (jao-load-path "consult-recoll") - - (defun jao-recoll-format (title url mtype) - (let* ((u (replace-regexp-in-string "/home/jao/" "" url)) - (u (replace-regexp-in-string "\\(doc\\|org/doc\\|var/mail\\)/" "" u))) - (format "%s (%s, %s)" - title - (propertize u 'face 'jao-themes-f00) - (propertize mtype 'face 'jao-themes-f01)))) - - (use-package consult-recoll - :init (setq consult-recoll-open-fns - '(("application/pdf" . jao-open-doc) - ("message/rfc822" . jao-org-links-open-mail)) - consult-recoll-format-candidate #'jao-recoll-format) - :bind (("C-c R" . #'consult-recoll))) - - #+end_src -*** dh-diff hunks - #+begin_src emacs-lisp - (defun jao-consult--diff-lines (&optional backward) - (let ((candidates) - (width (length (number-to-string - (line-number-at-pos (point-max) - consult-line-numbers-widen))))) - (save-excursion - (while (ignore-errors (diff-hl-next-hunk backward)) - (let* ((str (buffer-substring (line-beginning-position) - (line-end-position))) - (no (line-number-at-pos (point))) - (no (consult--line-number-prefix (point-marker) no width))) - (push (concat no str) candidates)))) - (if backward candidates (nreverse candidates)))) - - (defun jao-consult-hunks () - (interactive) - (let ((candidates (append (jao-consult--diff-lines) - (jao-consult--diff-lines t)))) - (unless candidates (error "No changes!")) - (consult--jump - (consult--read "Go to hunk: " candidates - :category 'consult--encode-location - :sort nil - :require-match t - :lookup #'consult--line-match - :preview (consult--preview-position))))) - - (with-eval-after-load "consult" - (add-to-list 'consult-config '(jao-consult-hunks :preview-key any))) - #+end_src -* embark -*** packages - #+begin_src emacs-lisp - (use-package embark - :ensure t - :custom ((embark-quit-after-action nil) - (prefix-help-command #'embark-prefix-help-command)) - :bind (("C-;" . embark-act) - ("C-'" . embark-default-action) - (:map minibuffer-local-map - (("C-'" . embark-default-action) - ("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))) - (require 'embark) - #+end_src -*** embark action indicator - #+begin_src emacs-lisp - (defvar jao-embark--actions-buffer "*Embark Actions*") - - (defvar jao-embark--default-display - `((,(regexp-quote jao-embark--actions-buffer) - (display-buffer-at-bottom) - (window-parameters (mode-line-format . none)) - (window-height . fit-window-to-buffer)))) - - (setq jao-embark--excluded - '(embark-collect-snapshot embark-collect-live embark-export - embark-keymap-help embark-become embark-isearch nil)) - - (defun jao-embark--key-str (k) - (if (numberp k) (single-key-description k) (key-description k))) - - (defun jao-embark--bind-desc (descs x prefix) - (let ((k (car x)) (c (cdr x))) - (cond ((keymapp c) - (let ((cds (jao-embark--keymap-descs c (jao-embark--key-str k)))) - (cons (max (or (car cds) 0) (or (car descs) 0)) - (cons (max (or (cadr cds) 0) (or (cadr descs) 0)) - (append (cddr descs) (cddr cds)))))) - ((memq c jao-embark--excluded) descs) - ((symbolp c) - (let* ((desc (jao-embark--key-str k)) - (desc (format "%s%s" (or prefix "") desc)) - (doc (car (split-string - (or (ignore-errors (documentation c)) "") - "\n"))) - (fun (symbol-name c))) - (cons (max (length desc) (car descs)) - (cons (max (length fun) (cadr descs)) - (cons (list desc fun doc) (cddr descs)))))) - (t (message "i've skipped %S" x) descs)))) - - (defun jao-embark--keymap-descs (k prefix) - (seq-reduce `(lambda (descs x) (jao-embark--bind-desc descs x ,prefix)) - (cdr (keymap-canonicalize k)) '(0 0))) - - (defun jao-embark--dstr (d) - (let ((s (cadr d))) (if (string-prefix-p "embark" s) "" s))) - - (defun jao-embark--show-keymap (keymap &optional target) - (with-current-buffer (get-buffer-create jao-embark--actions-buffer) - (read-only-mode -1) - (setq-local cursor-type nil) - (delete-region (point-min) (point-max)) - (let* ((descs (jao-embark--keymap-descs keymap "")) - (fmt (format "%%-%ds %%-%ds %%s\n" (cadr descs) (car descs)))) - (seq-each (lambda (desc) - (insert (format fmt - (propertize (cadr desc) 'face 'jao-themes-f00) - (propertize (car desc) 'face 'embark-keybinding) - (propertize (caddr desc) 'face 'italic)))) - (seq-sort-by 'jao-embark--dstr 'string-greaterp (cddr descs)))) - (if target (insert (format "\nAction for '%s'" target)) (delete-char -1)) - (read-only-mode 1) - (let ((display-buffer-alist - (append display-buffer-alist jao-embark--default-display))) - (pop-to-buffer (current-buffer) nil t)) - (lambda () - (embark-kill-buffer-and-window jao-embark--actions-buffer) - (when selectrum-is-active (select-window (minibuffer-window)))))) - - (setq embark-action-indicator #'jao-embark--show-keymap - embark-become-indicator embark-action-indicator) - - #+end_src -*** org targets - #+begin_src emacs-lisp - (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) - (when (org-in-regexp org-link-any-re) - (let ((lnk (match-string-no-properties 2))) - (if (string-match-p "https?://.+" (or lnk "")) - (cons 'url lnk) - (cons 'org-link (match-string-no-properties 0))))))) - - (embark-define-keymap jao-embark-targets-org-link-map - "Actions for org links" - ((kbd "RET") org-open-link-from-string)) - - (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)) - #+end_src -*** url targets - #+begin_src emacs-lisp - (declare-function w3m-anchor "w3m") - - (defun jao-embark-targets--w3m-anchor () - (when (not (region-active-p)) - (when-let ((url (or (and (derived-mode-p 'w3m-mode) - (or (w3m-anchor) w3m-current-url)) - (and (derived-mode-p 'eww-mode) - (or (thing-at-point 'url) (eww-current-url))) - (jao-url-around-point)))) - (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 emacs-w3m" - (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 "e") #'jao-eww-browse-url) - (define-key embark-url-map (kbd "f") #'browse-url-firefox) - (define-key embark-url-map (kbd "m") 'jao-browse-with-external-browser) - #+end_src -*** video url targets - #+begin_src emacs-lisp - (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)))) - (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)) - - (embark-define-keymap jao-embark-targets-video-url-map - "Actions on URLs pointing to remote video streams." - :parent embark-url-map - ("RET" jao-embark-targets-mpv) - ("v" jao-embark-targets-vlc)) - - (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)) - #+end_src -*** spotify - #+begin_src emacs-lisp - (with-eval-after-load "consult-spotify" - (embark-define-keymap spotify-item-keymap - "Actions for Spotify search results" - ("y" espotify-yank-candidate-url) - ("a" espotify-play-candidate-album) - ("h" espotify-show-candidate-info)) - - (add-to-list 'embark-keymap-alist - '(spotify-search-item . spotify-item-keymap))) - #+end_src -* startup - #+begin_src emacs-lisp - (marginalia-mode 1) - (selectrum-mode 1) - (jao-selectrum-orderless) - #+end_src diff --git a/init.org b/init.org index dbf4bff..33b718f 100644 --- a/init.org +++ b/init.org @@ -850,89 +850,6 @@ :bind (("s-n" . jao-hydra-ednc/body) ("H-s-n" . jao-hydra-ednc/body))) #+end_src -* Completion -*** company - #+begin_src emacs-lisp - (use-package company - :ensure t - :custom - ((company-global-modes '(clojure-mode - clojurec-mode - emacs-lisp-mode - eshell-mode - lisp-interaction-mode - haskell-mode - message-mode - org-mode - scheme-mode)) - (company-idle-delay 0.15) - (company-lighter "") - (company-lighter-base "") - (company-show-numbers nil) - (company-tooltip-limit 15) - (company-tooltip-align-annotations t) - (company-transformers '(company-sort-by-occurrence))) - - :config - ;; Prevent non-matching input (which will dismiss the completions - ;; menu), but only if the user interacts explicitly with Company. - (setq company-require-match #'company-explicit-action-p) - - (defun jao-complete-at-point () - "Complete using company unless we're in the minibuffer." - (interactive) - (if (window-minibuffer-p) (completion-at-point) (company-manual-begin))) - - :bind (([remap completion-at-point] . #'jao-complete-at-point) - ([remap complete-symbol] . #'jao-complete-at-point) - - ;; The following are keybindings that take effect whenever - ;; the completions menu is visible, even if the user has not - ;; explicitly interacted with Company. - :map company-active-map - - ([remap scroll-up-command] . nil) - ([remap scroll-down-command] . nil) - - ;; Make TAB always complete the current selection, instead of - ;; only completing a common prefix. - ("" . #'company-complete-selection) - ("TAB" . #'company-complete-selection) - - ("C-h" . #'company-show-doc-buffer) - ("M-." . #'company-show-location) - - ;; The following are keybindings that only take effect - ;; if not in eshell. Note that `:map' from above is - ;; "sticky", and applies also below. - ;; Another interesting :filter (company-explicit-action-p) - - :filter (or (not (derived-mode-p 'eshell-mode)) - (company-explicit-action-p)) - ("" . #'company-complete-selection) - ("RET" . #'company-complete-selection)) - - :bind* (;; The default keybinding for `completion-at-point' and - ;; `complete-symbol' is M-TAB or equivalently C-M-i. We - ;; already remapped those bindings to `company-manual-begin' - ;; above. Here we make sure that they definitely invoke - ;; `company-manual-begin' even if a minor mode binds M-TAB - ;; directly. - ("M-TAB" . #'jao-complete-at-point)) - - :diminish) - - (use-package company-math :ensure t :after company) - - (global-company-mode 1) - - #+end_src -*** completion engine - We can load either [[./consult.org][consult.org]] or [[./attic/counsel.org][counsel.org]] to configure - completion engines: - #+begin_src emacs-lisp - (jao-load-org "consult") - #+end_src * Calendar, diary, weather *** Diary #+BEGIN_SRC emacs-lisp @@ -1136,6 +1053,10 @@ #+END_SRC * General editing +*** Completion + #+begin_src emacs-lisp + (jao-load-org "completion") + #+end_src *** Long lines [[https://200ok.ch/posts/2020-09-29_comprehensive_guide_on_handling_long_lines_in_emacs.html][Comprehensive guide on handling long lines in Emacs - 200ok]] #+begin_src emacs-lisp diff --git a/lib/themes/jao-themes.el b/lib/themes/jao-themes.el index a78d890..6fa66c0 100644 --- a/lib/themes/jao-themes.el +++ b/lib/themes/jao-themes.el @@ -822,6 +822,8 @@ (mm-uu-extract (p hilite) ex) (minibuffer-line (p f00)) (minibuffer-prompt (p f00)) + (minicomp-group-title (p dimm)) + (minicomp-group-separator (p dimm) :strike-through "grey80") (mode-line-buffer-id nbf (c nil nil)) (mode-line-emphasis (p warning)) (mode-line-highlight (~ mode-line)) diff --git a/readme.org b/readme.org index 3e621ea..9e2b7fd 100644 --- a/readme.org +++ b/readme.org @@ -62,7 +62,7 @@ - [[./init.org][init.org]]: main configuration as a literate org file; it uses (besides lots of packages), many of my libraries in [[./lib][lib]], and loads on demand the other org files below. -- [[./consult.org][consult.org]]: completion setup using selectrum, consult and friends. +- [[./completion.org][completion.org]]: completion setup using company, consult and friends. - [[./org.org][org.org]] org mode configuration. - [[./blog.org][blog.org]]: blogging using org-static-blog. - [[./gnus.org][gnus.org]]: tangled to gnus.el automatically by init.org, so that it's -- cgit v1.2.3