copilot.el
copilot.el copied to clipboard
Dismissing a suggestion at the end of buffer leaves extra empty lines
First of all, thank you for this amazing package!
Steps to reproduce:
- Open an empty file
test.el
with global-copilot-mode enabled - Type something like
(defun test () nil)
and press Enter - You'll see a suggestion like
(defun test2 () nil)
. - Dismiss it by hitting C-g or going back to the first line
- Save the buffer
- You can see the saved file has an empty line at the end.
I understand that you need to add empty lines at the step 3 for a suggestion to be shown, so I'm just wondering if it is possible to remove them when the suggestion is dismissed.
Workaround: use https://github.com/lewang/ws-butler
I will try to fix it later.
It seems that the problem comes from these lines:
(if (= (line-end-position line) (1- (point-max)))
; special case if the last line is empty
(progn
(goto-char (point-max))
(newline)
(forward-char -1))
(forward-line line)
(forward-char col))
Do we actually need this special case? I tested removing it and everything worked fine for me:
@@ -389,14 +389,8 @@ USER-POS is the cursor position (for verification only)."
(save-excursion
(widen)
(goto-char (point-min))
- (if (= (line-end-position line) (1- (point-max)))
- ; special case if the last line is empty
- (progn
- (goto-char (point-max))
- (newline)
- (forward-char -1))
- (forward-line line)
- (forward-char col))
+ (forward-line line)
+ (forward-char col)
; remove common prefix
(let* ((cur-line (s-chop-suffix "\n" (or (thing-at-point 'line) "")))
(my Emacs version is 30.0.50)
@Rogach In the screenshot, my cursor is on the second line while this file has only one line. With the special case, copilot.el can provide completions in this situation, otherwise, you will see an "End of buffer" message.
While creating new lines for users may seem strange, being able to show completions at the ends of files is useful. Any better workaround is welcome.
My apologies, I somehow missed that case (despite the comment talking exactly about that).
Seems that error happens because (thing-at-point 'line)
returns incorrect data at that last line (it returns previous line instead of what we expect). Here's the updated patch, now your example works as expected:
@@ -389,17 +389,11 @@ USER-POS is the cursor position (for verification only)."
(save-excursion
(widen)
(goto-char (point-min))
- (if (= (line-end-position line) (1- (point-max)))
- ; special case if the last line is empty
- (progn
- (goto-char (point-max))
- (newline)
- (forward-char -1))
- (forward-line line)
- (forward-char col))
-
- ; remove common prefix
- (let* ((cur-line (s-chop-suffix "\n" (or (thing-at-point 'line) "")))
+ (forward-line line)
+ (forward-char col)
+
+ ;; remove common prefix
+ (let* ((cur-line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
(common-prefix-len (length (s-shared-start completion cur-line))))
(setq completion (substring completion common-prefix-len))
(forward-char common-prefix-len))
@Rogach Patch applied. Thanks for your elegant solution!