From: João Távora Date: Fri, 18 Mar 2022 10:54:21 +0000 (+0000) Subject: Defend against broken move-to-column in recent emacs X-Git-Tag: emacs-29.0.90~1616^2~524^2~4^2~67 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6dba74d8cb7e0172641ac6fdd7dfcd80bd22a1c4;p=emacs.git Defend against broken move-to-column in recent emacs * eglot.el (eglot-lsp-abiding-column): Use (min (point) (point-max)) This is a defensive fix for an Emacs/company-mode problem described below. The problem can be reproduced in Eglot before this commit with: ~/Source/Emacs/emacs/src/emacs -Q -f package-initialize -L \ ~/Source/Emacs/company-mode -l company -f global-company-mode -l \ eglot.el ~/tmp/issue-860/args_out_of_range.c -f eglot -f \ display-line-numbers-mode -f toggle-debug-on-error 1 // args_out_of_range.c 2 struct Book { 3 int id; 4 char title[50] 5 } book = { 1024, "C" }; 6 7 int main(int argc, char *argv[]) 8 { 9 10 // Error when typing the dot to make "book." 11 book 12 return 0; 13 } When one types the dot after the "book" on line 11, company-mode displays a two-line overlay that visually encompasses line 12 after "book", which has the "return 0;" statement. That line happens to also hold a warning about incorrect syntax, one that starts at column 2. Eglot uses 'move-to-column' to go that precise place. In Emacs 27.2, move-to-column is unaffected by previous company-mode overlays, even if the current line is being co-used visually by the overlay. It moves to the right buffer position. In Emacs master, this isn't true. It seems to be confounded by the company-mode overlay and moves to eob, which eventually breaks Eglot with a backtrace such as this one: Debugger entered--Lisp error: (args-out-of-range # 110 124) encode-coding-region(110 124 utf-16 t) (length (encode-coding-region (or lbp (line-beginning-position)) (point) 'utf-16 t)) (- (length (encode-coding-region (or lbp (line-beginning-position)) (point) 'utf-16 t)) 2) (/ (- (length (encode-coding-region (or lbp (line-beginning-position)) (point) 'utf-16 t)) 2) 2) eglot-lsp-abiding-column(110) (- column (eglot-lsp-abiding-column lbp)) (setq diff (- column (eglot-lsp-abiding-column lbp))) (progn (setq diff (- column (eglot-lsp-abiding-column lbp))) (not (= 0 diff))) (while (progn (setq diff (- column (eglot-lsp-abiding-column lbp))) (not (= 0 diff))) (condition-case eob-err (forward-char (/ (if (> diff 0) (1+ diff) (1- diff)) 2)) (end-of-buffer (throw '--cl-block-nil-- eob-err))) (setq --cl-var-- nil)) (let* ((lbp (line-beginning-position)) (diff nil) (--cl-var-- t)) (narrow-to-region lbp (line-end-position)) (move-to-column column) (while (progn (setq diff (- column (eglot-lsp-abiding-column lbp))) (not (= 0 diff))) (condition-case eob-err (forward-char (/ (if (> diff 0) (1+ diff) (1- diff)) 2)) (end-of-buffer (throw '--cl-block-nil-- eob-err))) (setq --cl-var-- nil)) nil) (catch '--cl-block-nil-- (let* ((lbp (line-beginning-position)) (diff nil) (--cl-var-- t)) (narrow-to-region lbp (line-end-position)) (move-to-column column) (while (progn (setq diff (- column (eglot-lsp-abiding-column lbp))) (not (= 0 diff))) (condition-case eob-err (forward-char (/ (if (> diff 0) (1+ diff) (1- diff)) 2)) (end-of-buffer (throw '--cl-block-nil-- eob-err))) (setq --cl-var-- nil)) nil)) (save-restriction (catch '--cl-block-nil-- (let* ((lbp (line-beginning-position)) (diff nil) (--cl-var-- t)) (narrow-to-region lbp (line-end-position)) (move-to-column column) (while (progn (setq diff (- column (eglot-lsp-abiding-column lbp))) (not (= 0 diff))) (condition-case eob-err (forward-char (/ (if ... ... ...) 2)) (end-of-buffer (throw '--cl-block-nil-- eob-err))) (setq --cl-var-- nil)) nil))) eglot-move-to-lsp-abiding-column(2) GitHub-reference: fix https://github.com/joaotavora/eglot/issues/860 --- diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index ea9299ab59e..3bd2d844c8a 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1312,7 +1312,8 @@ fully LSP-compliant servers, this should be set to "Calculate current COLUMN as defined by the LSP spec. LBP defaults to `line-beginning-position'." (/ (- (length (encode-coding-region (or lbp (line-beginning-position)) - (point) 'utf-16 t)) + ;; Fix github#860 + (min (point) (point-max)) 'utf-16 t)) 2) 2))