emacs-lsp / lsp-mode

Emacs client/library for the Language Server Protocol
https://emacs-lsp.github.io/lsp-mode
GNU General Public License v3.0
4.75k stars 869 forks source link

`company-capf` error with lsp-mode+clangd when setting `lsp-clients-clangd-args` #3755

Open Cycatz opened 1 year ago

Cycatz commented 1 year ago

Thank you for the bug report

Bug description

Describe the issue

With (setq lsp-clients-clangd-args '("-j=8" "-background-index" "-log=error")), when editing a C++ source file and typing the first three characters ret of the keyword return in a function body, the company window doesn't show the completion and the following error occurs:

Company: frontend company-pseudo-tooltip-unless-just-one-frontend error "Company: backend company-capf error "Wrong type argument: integer-or-marker-p, nil" with args (match •register_t)" on command post-comman

But if I remove the line (setq lsp-clients-clangd-args '("-j=8" "-background-index" "-log=error")) in the config, there will be no error.

Screenshot: image

Here is the video: https://i.imgur.com/CgPw7cb.mp4

Steps to reproduce

Here is the minimal broken config (with lsp and company installed with straight.el):

;; Invoked with emacs -Q -l config.el

;; Load straight initial config
(load-file  "~/.emacs.d/straight/repos/straight.el/bootstrap.el")

;; lsp
(straight-use-package 'lsp-mode)
(setq lsp-clients-clangd-args '("-j=8" "-background-index" "-log=error"))
(add-hook 'c++-mode-hook 'lsp)

;; company
(straight-use-package 'company-mode)
(global-company-mode t)

;; Load an example C++ source
(find-file "~/reproduce.hpp")

And the minimal broken c++ source reproduce.hpp:

#include <cstdlib>

auto operator"" _S(const char *str, std::size_t sz)
{
    return [=](int w) {
        return w ? 0 : 1;
    };
    // Error when typing 'ret' here
}

Invoke Emacs with emacs -Q -l config.el and start typing in the auto operator"" _S() function. Apart from ret, typing other three-character combinations like __b (for __builtin_popcount) or con (for const) also result in the same error.

Expected behavior

The error should not happen and the company window should pop up correctly.

Which Language Server did you use?

lsp-clangd

OS

Linux

Error callstack

Callstack:

Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
  buffer-substring-no-properties(nil 139)
  (downcase (buffer-substring-no-properties (plist-get (text-properties-at 0 candidate) 'lsp-completion-start-point) (point)))
  (let* ((prefix (downcase (buffer-substring-no-properties (plist-get (text-properties-at 0 candidate) 'lsp-completion-start-point) (point)))) (prefix-len (length prefix)) (prefix-pos 0) (label (downcase candidate)) (label-len (length label)) (label-pos 0) matches start) (while (and (not matches) (< prefix-pos prefix-len)) (while (and (< prefix-pos prefix-len) (< label-pos label-len)) (if (equal (aref prefix prefix-pos) (aref label label-pos)) (progn (if start nil (setq start label-pos)) (setq prefix-pos (1+ prefix-pos))) (if start (progn (setq matches (nconc matches ...)) (setq start nil)))) (setq label-pos (1+ label-pos))) (if start (progn (setq matches (nconc matches (list (cons start label-pos)))))) (if (< prefix-pos prefix-len) (progn (setq matches nil))) (if matches nil (setq prefix-pos (1+ prefix-pos)) (setq label-pos 0))) matches)
  lsp-completion--company-match(#("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)))
  company-capf(match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)))
  apply(company-capf (match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>))))
  company-call-backend-raw(match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)))
  apply(company-call-backend-raw (match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>))))
  company--force-sync(company-call-backend-raw (match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>))) company-capf)
  company-call-backend(match #("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)))
  company--common-or-matches(#("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)))
  company-fill-propertize(#("•register_t" 1 2 (lsp-completion-item #<hash-table equal 11/15 0x157e7835401b> lsp-sort-text "40faa292register_t" lsp-completion-start-point 136 lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-prefix "ret" face (completions-first-difference)) 2 12 (lsp-completion-prefix "ret" lsp-completion-markers (136 #<marker (moves after insertion) at 139 in a.hpp>) lsp-completion-start-point 136 lsp-sort-text "40faa292register_t" lsp-completion-item #<hash-table equal 11/15 0x157e7835401b>)) " (Interface)" 29 nil #("  " 0 1 (display (image :file "/home/cycatz/.emacs.d/straight/build/company-mode/..." :type svg :width 16 :height 16 :ascent center :background "cornsilk")) 1 2 (display (space :width (0)))) " ")
  company--create-lines(0 10)
  company-pseudo-tooltip-show(8 4 0)
  company-pseudo-tooltip-show-at-point(139 3)
  company-pseudo-tooltip-frontend(post-command)
  company-pseudo-tooltip-unless-just-one-frontend(post-command)
  company-call-frontends(post-command)
  company-post-command()
  company-idle-begin(#<buffer a.hpp> #<window 3 on a.hpp> 150 139)
  apply(company-idle-begin (#<buffer a.hpp> #<window 3 on a.hpp> 150 139))
  timer-event-handler([t 25410 39093 179724 nil company-idle-begin (#<buffer a.hpp> #<window 3 on a.hpp> 150 139) nil 267000 nil])

Anything else?

https://github.com/company-mode/company-mode/issues/1346

yyoncho commented 1 year ago

I guess adding "--header-insertion-decorators=0" as well will make the issue go away?

yyoncho commented 1 year ago

cc @kiennq

kiennq commented 1 year ago

We're following the discussion in the company-mode's repo now

dgutov commented 10 months ago

I think the ball is in your court now.

necto commented 1 month ago

Hi @dgutov I failed to reproduce the issue following your original instructions with my Emacs 29.4. Does it still reproduce on your side?

dgutov commented 1 month ago

Yep, seems fixed! Not sure what change did it, but I can't reproduce anymore.

It wasn't my instructions, though - the reporter is somebody else.