From d76353122ec563eb2d3ca23f96ea67a6843974c5 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Tue, 16 Jan 2024 14:32:21 -0500 Subject: [PATCH] Make elisp-cap region cover a symbol, not lists or strings elisp-completion-at-point calculates the completion region by running backward-sexp from (point) and storing that position as the beginning, then running forward-sexp from the beginning and storing that position as the end. elisp-completion-at-point does symbol completion, so the completion region should only cover a symbol. Therefore, elisp-completion-at-point checks whether the beginning of the completion region (the result from backward-sexp) is a quotation mark or open paren, which would indicate that the region covers a string or list, and returns nil in that case. If point is already at the start of a sexp (e.g. immediately after an open paren) then backward-sexp will not move point and the beginning of the completion region would (correctly) be the original point. forward-sexp, in this case, will move over the next sexp after point and include it in the completion region, even if it's a string or list. That has several bad effects: - An unrelated next sexp can be deleted by doing completion at the start of some earlier sexp (bug#64903, bug#68514) - The completion region can be very large, breaking some completion styles; if the next sexp is large enough, completion will fail with:: (invalid-regexp "Regular expression too big") - External completion packages can be broken by this, including corfu: https://github.com/minad/corfu/issues/350 We fix this by mirroring the check on the character at start of the region. We now also check if the character at the end of the completion region is a quotation mark or close paren, and set the end of the region equal to the beginning in that case. This way, we avoid including a string or list in the completion region, but still allow completion to proceed. * lisp/progmodes/elisp-mode.el (elisp-completion-at-point): Avoid returning a completion region which includes a string or list. (bug#64903) --- lisp/progmodes/elisp-mode.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 0ce98ee471c..c9ae92b5680 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -668,6 +668,9 @@ elisp-completion-at-point (goto-char beg) (forward-sexp 1) (skip-chars-backward "'’") + (when (member (char-syntax (char-before (point))) + '(?\" ?\))) + (goto-char beg)) (when (>= (point) pos) (point))) (scan-error pos)))) -- 2.39.3