From cb75dd89f6a54fb3dd7d9bb6c9ad147ba6787780 Mon Sep 17 00:00:00 2001 From: Nikita Bloshchanevich Date: Thu, 24 Dec 2020 11:44:20 +0100 Subject: [PATCH 1/3] `evil-ex': eldoc for Elisp expressions Refactor the `evil-ex' Elisp check into a new function, `evil-ex--elisp-p', since it is used twice now. Add an `eldoc' function that calls `elisp-eldoc-documentation-function' if in an Elisp expression and if the former is available. --- evil-ex.el | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/evil-ex.el b/evil-ex.el index 09848b70..798c4878 100644 --- a/evil-ex.el +++ b/evil-ex.el @@ -229,6 +229,24 @@ Otherwise behaves like `delete-backward-char'." (insert result) (exit-minibuffer)) +(defun evil-ex--elisp-p () + "Check if `evil-ex' is executing an elisp expression." + (string-prefix-p "(" (minibuffer-contents-no-properties))) + +(defun evil-ex-elisp-completion-at-point () + "Complete an `evil-ex' Elisp expression." + (when (and (fboundp 'elisp-completion-at-point) + (evil-ex--elisp-p)) + (elisp-completion-at-point))) + +(defun evil-ex-elisp-eldoc-function () + "`eldoc' for `evil-ex' Elisp expressions. +Only provides an `eldoc' hint if the current `evil-ex' command is +an elisp expression." + (when (and (fboundp 'elisp-eldoc-documentation-function) + (evil-ex--elisp-p)) + (elisp-eldoc-documentation-function))) + (defun evil-ex-setup () "Initialize Ex minibuffer. This function registers several hooks that are used for the @@ -242,8 +260,12 @@ interactive actions during ex state." (with-no-warnings (make-variable-buffer-local 'completion-at-point-functions)) (setq completion-at-point-functions - '(evil-ex-command-completion-at-point - evil-ex-argument-completion-at-point))) + '(evil-ex-elisp-completion-at-point + evil-ex-command-completion-at-point + evil-ex-argument-completion-at-point)) + (add-function :before-until (local 'eldoc-documentation-function) + #'evil-ex-elisp-eldoc-function) + (eldoc-mode 1)) (put 'evil-ex-setup 'permanent-local-hook t) (defun evil-ex-setup-and-update () @@ -261,7 +283,9 @@ Clean up everything set up by `evil-ex-setup'." (let ((runner (evil-ex-argument-handler-runner evil-ex-argument-handler))) (when runner - (funcall runner 'stop))))) + (funcall runner 'stop)))) + (remove-function (local 'eldoc-documentation-function) #'evil-ex-elisp-eldoc-function) + (eldoc-mode -1)) (put 'evil-ex-teardown 'permanent-local-hook t) (defun evil-ex-remove-default () From 8b9ccc702d50bb235f29beb5ecbd7d2b2ee237da Mon Sep 17 00:00:00 2001 From: Nikita Bloshchanevich Date: Thu, 24 Dec 2020 11:44:40 +0100 Subject: [PATCH 2/3] Refactor: use `make-local-variable' to set `capf' `make-variable-buffer-local' should not be used in Elisp and makes the argument permanently buffer-local. Use `make-local-variable' + `set' instead, maing `evil-ex-setup' not set `completion-at-point-functions' as permanently buffer-local and allowing to remove `with-no-warnings'. --- evil-ex.el | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/evil-ex.el b/evil-ex.el index 798c4878..fcd51595 100644 --- a/evil-ex.el +++ b/evil-ex.el @@ -257,12 +257,10 @@ interactive actions during ex state." (when evil-ex-previous-command (add-hook 'pre-command-hook #'evil-ex-remove-default)) (remove-hook 'minibuffer-setup-hook #'evil-ex-setup) - (with-no-warnings - (make-variable-buffer-local 'completion-at-point-functions)) - (setq completion-at-point-functions - '(evil-ex-elisp-completion-at-point - evil-ex-command-completion-at-point - evil-ex-argument-completion-at-point)) + (set (make-local-variable 'completion-at-point-functions) + '(evil-ex-elisp-completion-at-point + evil-ex-command-completion-at-point + evil-ex-argument-completion-at-point)) (add-function :before-until (local 'eldoc-documentation-function) #'evil-ex-elisp-eldoc-function) (eldoc-mode 1)) From fa9c54bf8cfbb08f08f690dfccbbd027457d7091 Mon Sep 17 00:00:00 2001 From: Nikita Bloshchanevich Date: Mon, 25 Jan 2021 13:59:47 +0100 Subject: [PATCH 3/3] `evil-ex': `eldoc': support Emacs < 24.4 For Emacs < 24.4, which does not have `add-function' and `remove-function', use `add-to-list' + `eldoc-documentation-functions' instead. --- evil-ex.el | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/evil-ex.el b/evil-ex.el index fcd51595..f9b73746 100644 --- a/evil-ex.el +++ b/evil-ex.el @@ -247,6 +247,21 @@ an elisp expression." (evil-ex--elisp-p)) (elisp-eldoc-documentation-function))) +(defmacro evil-ex--eldoc-add (fn) + "Add FN to `eldoc'. +Handles older Emacsen that don't have `add-function'." + (if (fboundp 'add-function) + `(add-function :before-until (local 'eldoc-documentation-function) ,fn) + `(add-to-list (make-local-variable 'eldoc-documentation-functions) ,fn))) + +(defmacro evil-ex--eldoc-remove (fn) + "Remove FN from `eldoc'. +See `evil-ex--eldoc-add'. FN must be a symbol." + (if (fboundp 'remove-function) + `(remove-function (local 'eldoc-documentation-function) ,fn) + `(set (make-local-variable 'eldoc-documentation-functions) + (delq ,fn eldoc-documentation-functions)))) + (defun evil-ex-setup () "Initialize Ex minibuffer. This function registers several hooks that are used for the @@ -261,8 +276,7 @@ interactive actions during ex state." '(evil-ex-elisp-completion-at-point evil-ex-command-completion-at-point evil-ex-argument-completion-at-point)) - (add-function :before-until (local 'eldoc-documentation-function) - #'evil-ex-elisp-eldoc-function) + (evil-ex--eldoc-add #'evil-ex-elisp-eldoc-function) (eldoc-mode 1)) (put 'evil-ex-setup 'permanent-local-hook t) @@ -282,7 +296,7 @@ Clean up everything set up by `evil-ex-setup'." evil-ex-argument-handler))) (when runner (funcall runner 'stop)))) - (remove-function (local 'eldoc-documentation-function) #'evil-ex-elisp-eldoc-function) + (evil-ex--eldoc-remove #'evil-ex-elisp-eldoc-function) (eldoc-mode -1)) (put 'evil-ex-teardown 'permanent-local-hook t)