Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when auto-completion fires: wrong-type-argument arrayp nil #31

Open
shackra opened this issue Apr 6, 2018 · 11 comments
Open

Error when auto-completion fires: wrong-type-argument arrayp nil #31

shackra opened this issue Apr 6, 2018 · 11 comments

Comments

@shackra
Copy link

shackra commented Apr 6, 2018

I experienced the bug reported on #17

This has happen on Go and Python, and I expect to happen on other languages too.

After inserting the dot to fire auto completion with Company, it fails: nothing happens.

toggling debugging on error on reveals the following (python-mode running on the *scratch* buffer):

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  company-lsp(prefix)
  apply(company-lsp prefix)
  company--force-sync(company-lsp (prefix) company-lsp)
  company--multi-backend-adapter((company-lsp :with company-yasnippet) prefix)
  company--begin-new()
  company--perform()
  company-auto-begin()
  company-idle-begin(#<buffer *scratch*> #<window 3 on *scratch*> 29 55)
  apply(company-idle-begin (#<buffer *scratch*> #<window 3 on *scratch*> 29 55))
  timer-event-handler([t 23239 7758 98423 nil company-idle-begin (#<buffer *scratch*> #<window 3 on *scratch*> 29 55) nil 197000])

This is my current configuration:

(use-package lsp-mode
  :init
  (add-hook 'prog-mode-hook 'lsp-mode))

(use-package lsp-ui
  :init (add-hook 'lsp-mode-hook 'lsp-ui-mode)
  :config
  (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
  (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references))

(use-package company
  :diminish company-mode
  :init
  (setf company-backends '((company-files
                            company-keywords
                            company-capf
                            company-yasnippet)
                           (company-abbrev company-dabbrev)))
  (setf company-idle-delay 0.5)
  (setf company-tooltip-limit 10)
  (setf company-minimum-prefix-length 1)
  (setf company-echo-delay 0)
  (setf company-auto-complete nil)
  (add-hook 'after-init-hook #'global-company-mode))

(use-package company-lsp
  :init
  (push 'company-lsp company-backends)
  (setf company-lsp-async t))

(use-package company-statistics
  :after (company)
  :init
  (setf company-statistics-file "~/.company-statistics-cache.el")
  (add-hook 'after-init-hook 'company-statistics-mode))

(use-package company-quickhelp
  :after (company)
  :config (company-quickhelp-mode 1))

(use-package lsp-python
  :after (lsp-mode)
  :init (add-hook 'python-mode-hook #'lsp-python-enable))

(use-package lsp-go
  :after go-mode
  :init
  (add-hook 'go-mode-hook #'lsp-go-enable)
  (setf lsp-go-go-command '("go-langserver" "-mode=stdio" "-gocodecompletion")))

;; http://emacs.stackexchange.com/questions/10431/get-company-to-show-suggestions-for-yasnippet-names
;; Add yasnippet support for all company backends
;; https://github.com/syl20bnr/spacemacs/pull/179

(defun company-mode/backend-with-yas (backend)
  (if (or (and (listp backend) (member 'company-yasnippet backend)))
      backend
    (append (if (consp backend) backend (list backend))
            '(:with company-yasnippet))))

(add-hook 'after-init-hook (lambda () (setf company-backends (mapcar #'company-mode/backend-with-yas company-backends))) t)
@shackra
Copy link
Author

shackra commented Apr 6, 2018

@xianghx I fixed that with (setf lsp-go-go-command '("go-langserver" "-mode=stdio" "-gocodecompletion") but I don't know if it is related to my bug

@shackra
Copy link
Author

shackra commented Apr 6, 2018

That is covered by use-package or I don't know what you are referring to.

@shackra
Copy link
Author

shackra commented Apr 6, 2018

Which is the problem I'm reporting :)

shackra added a commit to shackra/emacs that referenced this issue Apr 6, 2018
Lenguajes de programación afectados:

- Python
- Golang
- Java
- JavaScript
- TypeScript
- PHP
- C++
- Rust

Existe una falla en company-lsp que previene el uso de lsp por el momento, hay que esperar hasta que
la falla company-lsp#31 sea arreglada.

- https://christian.kellner.me/2017/05/31/language-server-protocol-lsp-rust-and-emacs/
- https://code.visualstudio.com/blogs/2016/06/27/common-language-protocol
- tigersoldier/company-lsp#31
@tigersoldier
Copy link
Owner

Sorry for late response.

For lsp-go: The go language server doesn't provide completion support. You can confirm it by M-x lsp-capabilities.

For lsp-python: It's unclear what went wrong. It's likely a bug in the code. I tried on my machine and it works well. Can you provide the following information for further debugging?

  1. Before opening any python file, M-x set-variable RET lsp-print-io RET t
  2. Open the problematic Python file, try completion
  3. Paste the content of the *Messages* buffer here
  4. Run M-x copmany-diag in the Python file with cursor after a dot, and paste the content of company-diag output here.

@tigersoldier
Copy link
Owner

Sorry I missed comment about emacs-lsp/lsp-go#6

With that patched I was able to trigger completion for Go.

I managed to trigger the error wrong-type-argument arrayp nil once. The lsp client was corrupted and lsp--cur-workspace local variable was somehow set to nil.

Are you constantly triggering this issue? There may be a bug on the lsp-mode side or go/python language server side. company-lsp can provide better messaging but cannot help with the root cause.

@shackra
Copy link
Author

shackra commented Apr 9, 2018

Well, I think this is something related to lsp-mode because I was able to reproduce the exact same error in php-mode and js2-mode (both switched on *scratch* buffer).

Vue-lsp works fine, the auto-completion suggestion seems not related to what you write (It may be a thing of the server) and other features of lsp works too:

captura de pantalla de 2018-04-09 01-19-36
captura de pantalla de 2018-04-09 01-18-09

When I open a Javascript file, the auto-completion works fine in js2-mode:

captura de pantalla de 2018-04-09 01-23-00

The error still happens for python-mode in a project that had no setup.py, I added the file and try again but the error stills kicks in. Then I tried with a project that I built as a Python package (with a formal setup.py and everything and stills the issue happens).

Isn't there a way to spy the communications between lsp-mode and the servers? that would help a lot for bug reporting.

@shackra
Copy link
Author

shackra commented Apr 9, 2018

Note this: Another unrelated package called importmagic experiences the exact same error:

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  epc:call-deferred(nil get_unresolved_symbols "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport os\n\nimport tqdm\n\nPRICE = float(os.getenv(\"SPOYDERMAN_PRICE\", 0.012))\n\n\ndef listDB(client):\n    \"\"\" Lista todas las bases de datos relacionadas a proyecto spoyderman\n    \"\"\"\n    dbs = client.database_names()\n    for db in dbs:\n        if \"spoyderman_\" in db:\n            print(db.replace(\"spoyderman_\", \"📕 \"))\n\n\ndef countDB(client, db, beg, end):\n    \"\"\"Cuenta los documentos en la base de datos\n\n    db: nombre de la base de datos de interes\n    beg: inicio de la colección\n    end: cuanto recoger, -1 equivale a todo lo que hay en la base de datos\n\n    Por motivos de conveniencia retorna una cadena formateada con el precio de\n    la acotación de records, la cantidad de records y la misma colección\n\n    \"\"\"\n    tdb = client[\"spoyderman_\" + db]\n\n    if beg < 0:\n        beg = 0\n\n    if end <= 0:\n        collections = tdb.records.find()[beg:]\n    else:\n        collections = tdb.records.find()[beg:end]\n\n    count = collections.count()\n    return (\"\\n💸 USD$ {:.3f} ({} records)\".format(count * PRICE, count),\n            count, collections)\n\n\ndef exportDB(client, db, exporter, beg=0, end=0):\n    \"\"\" Exporta los documentos a un formato especificado por `exporter`\n\n    db: nombre de la base de datos de interes\n    exporter: una clase que se encarga del formateo\n    beg: inicio de la colección\n    end: cuanto recoger, `all` equivale a todo lo que hay en la base de datos\n    \"\"\"\n    money, count, collections = countDB(client, db, beg, end)\n\n    # Nombra el archivo al cual se hará la exportación de records\n    exporter.filename(db + \"_{}records_.\".format(count) +\n                      exporter.extension().lower())\n\n    for collection in tqdm.tqdm(\n            collections,\n            total=count,\n            desc=\"to {}\".format(exporter.extension())):\n        exporter.insert(collection)\n\n    exporter.close()\n    print(money)\n")
  epc:call-sync(nil get_unresolved_symbols "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport os\n\nimport tqdm\n\nPRICE = float(os.getenv(\"SPOYDERMAN_PRICE\", 0.012))\n\n\ndef listDB(client):\n    \"\"\" Lista todas las bases de datos relacionadas a proyecto spoyderman\n    \"\"\"\n    dbs = client.database_names()\n    for db in dbs:\n        if \"spoyderman_\" in db:\n            print(db.replace(\"spoyderman_\", \"📕 \"))\n\n\ndef countDB(client, db, beg, end):\n    \"\"\"Cuenta los documentos en la base de datos\n\n    db: nombre de la base de datos de interes\n    beg: inicio de la colección\n    end: cuanto recoger, -1 equivale a todo lo que hay en la base de datos\n\n    Por motivos de conveniencia retorna una cadena formateada con el precio de\n    la acotación de records, la cantidad de records y la misma colección\n\n    \"\"\"\n    tdb = client[\"spoyderman_\" + db]\n\n    if beg < 0:\n        beg = 0\n\n    if end <= 0:\n        collections = tdb.records.find()[beg:]\n    else:\n        collections = tdb.records.find()[beg:end]\n\n    count = collections.count()\n    return (\"\\n💸 USD$ {:.3f} ({} records)\".format(count * PRICE, count),\n            count, collections)\n\n\ndef exportDB(client, db, exporter, beg=0, end=0):\n    \"\"\" Exporta los documentos a un formato especificado por `exporter`\n\n    db: nombre de la base de datos de interes\n    exporter: una clase que se encarga del formateo\n    beg: inicio de la colección\n    end: cuanto recoger, `all` equivale a todo lo que hay en la base de datos\n    \"\"\"\n    money, count, collections = countDB(client, db, beg, end)\n\n    # Nombra el archivo al cual se hará la exportación de records\n    exporter.filename(db + \"_{}records_.\".format(count) +\n                      exporter.extension().lower())\n\n    for collection in tqdm.tqdm(\n            collections,\n            total=count,\n            desc=\"to {}\".format(exporter.extension())):\n        exporter.insert(collection)\n\n    exporter.close()\n    print(money)\n")
  importmagic--get-unresolved-symbols()
  importmagic-fix-imports()
  (progn (importmagic-fix-imports))
  (if (eq major-mode (quote python-mode)) (progn (importmagic-fix-imports)))
  shackra-before-save-py-importmagic-fix()
  run-hooks(before-save-hook)
  basic-save-buffer(t)
  save-buffer(1)
  funcall-interactively(save-buffer 1)
  call-interactively(save-buffer nil nil)
  command-execute(save-buffer)

@shackra
Copy link
Author

shackra commented Apr 9, 2018 via email

@shackra
Copy link
Author

shackra commented Apr 14, 2018

Here is the information you requested. With lsp-print-io as t I open a Python file from one of my projects.

Can’t guess python-indent-offset, using defaults: 4
Switched to virtualenv: mcrc
next-line: End of buffer
Company: An error occurred in auto-begin
Wrong type argument: arrayp, nil

Then I position the cursor after the dot and call to company-diag.

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  company-lsp(prefix)
  apply(company-lsp prefix)
  company--force-sync(company-lsp (prefix) company-lsp)
  company--multi-backend-adapter((company-lsp :with company-yasnippet) prefix)
  apply(company--multi-backend-adapter (company-lsp :with company-yasnippet) prefix)
  company-call-backend-raw(prefix)
  apply(company-call-backend-raw prefix)
  company--force-sync(company-call-backend-raw (prefix) (company-lsp :with company-yasnippet))
  company-call-backend(prefix)
  company-diag()
  funcall-interactively(company-diag)
  call-interactively(company-diag record nil)
  command-execute(company-diag record)
  #[257 "\304\305!\203\f�\306\307�!!\210��\307�!\211��\310\307�!\311\")\207" [current-prefix-arg prefix-arg this-command real-this-command featurep smex smex-rank intern command-execute record] 4 "\n\n(fn CMD)"]("company-diag")
  ivy-call()
  ivy-read("M-x " [pulse-delete crux corral comment-dwim-2 delim-kill smartrep-original-position basic-c-compile debugger-previous-window realgud:gdb-frame-file-regexp c-chain-logic hl-indent smartrep-mode-line-string gnus-remove-header gold-mode helm-ack linear-subseq company-edbi fixmee-this-buffer-not-pristine-hook ac-emmet yaml-mode-map wl-highlight-summary-thread-top-face ahk-mode Serto\ Batnan DejaVu\ Sans\ Mono daemons all-the-icons-gnus no-tail fixmee-mode-major-mode save-delay add-node-modules-path Generate\ Source haskell-snippets hamburg-theme aria2 calt eldoc-overlay god-mode Insert\ try record-separator vimish-fold--vimish-overlay-p FUNC fixmee-reload M-wheel-up fixmee-last-good-hit py-yapf align-large-region STIX\ MathJax\ Monospace monokai-256-red-lc grep-a-lot Span\ a\ Cell\ to ...] :predicate commandp :require-match t :history counsel-M-x-history :action #[257 "\304\305!\203\f�\306\307�!!\210��\307�!\211��\310\307�!\311\")\207" [current-prefix-arg prefix-arg this-command real-this-command featurep smex smex-rank intern command-execute record] 4 "\n\n(fn CMD)"] :sort t :keymap (keymap (67108908 . counsel--info-lookup-symbol) (67108910 . counsel-find-symbol)) :initial-input nil :caller counsel-M-x)
  counsel-M-x()
  funcall-interactively(counsel-M-x)
  call-interactively(counsel-M-x nil nil)
  command-execute(counsel-M-x)

Despite lsp-print-io set as t before visiting the Python file, *messages* has no messages coming from lsp-mode

@shackra
Copy link
Author

shackra commented Apr 14, 2018

I said before that js2-mode worked fine with lsp-mode, it turns out tide-mode was providing the auto-completion at that time. If I turn off tide-mode and restart Emacs and try again auto-completion in js2-mode fails as well as in Python and the other programming languages.

shackra added a commit to shackra/emacs that referenced this issue Apr 29, 2018
Lenguajes de programación afectados:

- Python
- Golang
- Java
- JavaScript
- TypeScript
- PHP
- C++
- Rust

Existe una falla en company-lsp que previene el uso de lsp por el momento, hay que esperar hasta que
la falla company-lsp#31 sea arreglada.

- https://christian.kellner.me/2017/05/31/language-server-protocol-lsp-rust-and-emacs/
- https://code.visualstudio.com/blogs/2016/06/27/common-language-protocol
- tigersoldier/company-lsp#31
@shackra
Copy link
Author

shackra commented Apr 29, 2018

I ran bug-hunter in my configuration, and this was the result:

Initial tests done. Hunting for the cause...
"/home/jorge/puntoarchivos/emacs/.emacs.d/tmp-init.el", line 848 pos 0:
  The assertion returned the following value here:
    t
  Caused by the following expression:
    (use-package company-lsp :init
      (push 'company-lsp company-backends)
      (setf company-lsp-async t))

I decided to bisect further by setting company-lsp-async to nil, but it had no impact over the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants