tern icon indicating copy to clipboard operation
tern copied to clipboard

tern-autocomplete makes emacs unresponsive

Open tejasbubane opened this issue 7 years ago • 2 comments

Using tern-autocomplete on dot leaves emacs in an unresponsive state forever. I have to kill emacs from command line.

Scenario:

  • Using latest emacs 25.2 from here: https://emacsformacosx.com/
  • OSX Version: 10.12.4 (Sierra)
  • tern repo cloned in home directory and ran yarn install.
  • bin/tests run successfuly.
⇒  time bin/test
Ran 597 tests from 100 files.
All passed.
bin/test  4.79s user 0.27s system 93% cpu 5.425 total
  • This is in my emacs config:
;; Config for JS2 mode

(setq js2-basic-offset 2)

;; Tern.JS
(add-to-list 'load-path "~/tern/emacs/")
(autoload 'tern-mode "tern.el" nil t)
(add-hook 'js2-mode-hook (lambda () (tern-mode t)))
(eval-after-load 'tern
  '(progn
     (require 'tern-auto-complete)
     (tern-ac-setup)))
  • Since my emacs went responsive every single time I tried to autocomplete, I did this for debugging:
⇒  bin/tern server --verbose --persistent
Listening on port 53888
  • When I do M-x js2-mode in a js file buffer, I get this message:
Making url-show-status local to  *http 127.0.0.1:53889* while let-bound!

Notice the different port.

  • There are two tern processes running now, emacs does not connect to running tern by default:
⇒  ps aux | grep tern
tejas            23790   0.0  0.0  2450212    804 s002  S+   11:33PM   0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn tern
tejas            23763   0.0  0.5  3043236  20244 s001  Ss+  11:30PM   0:00.34 node /Users/tejas/tern/bin/tern --strip-crs
tejas            23735   0.0  0.6  3045696  24876 s000  S+   11:29PM   0:00.41 node bin/tern server --verbose --persistent

When I press . after any variable, this error appears and emacs hangs indefinitely.

Error running timer 'ac-quick-help': (error "Attempt to shape unibyte text")

Did I misconfigure something? Let me know if you need more info.

tejasbubane avatar May 03 '17 18:05 tejasbubane

Tern runs a process per project, so if you want emacs to connect to the server you started, start it from the project directory. Maybe at that point --verbose provides something useful.

But in principle the requests to the server should be asynchronous, and even if Tern gets stuck (which isn't unheard of, unfortunately), emacs should remain responsive. So this is an issue I haven't seen before, and might be a bug in the elisp code.

marijnh avatar May 03 '17 19:05 marijnh

@marijnh - I'm also seeing this on GNU Emacs 26.0.50 installed on OSX. I've taken a look at the verbose output on tern-ac-complete and tern-ac-dot-complete, and the output looks the same.

Both functions cause Emacs to blow up with:

Error running timer 'ac-quick-help': (error "Attempt to shape unibyte text")

But tern-ac-complete is happy when used over a word.

Example 1:

Emacs (| indicating point):

JS|ON.

Execute tern-ac-complete

tern --verbose output:

Request: {
  "query": {
    "end": 95,
    "file": "exercism/javascript/saddle-points/saddle-points.js",
    "type": "completions",
    "types": true,
    "docs": true,
    "caseInsensitive": true
  }
}
Response: {
  "start": 93,
  "end": 97,
  "isProperty": false,
  "isObjectKey": false,
  "completions": [
    {
      "name": "JSON",
      "type": "JSON",
      "doc": "JSON (JavaScript Object Notation) is a data-interchange format.  It closely resembles a subset of JavaScript syntax, although it is not a strict subset. (See JSON in the Ja
vaScript Reference for full details.)  It is useful when writing any kind of JavaScript-based application, including websites and browser extensions.  For example, you might store user i
nformation in JSON format in a cookie, or you might store extension preferences in JSON in a string-valued browser preference."
    }
  ]
}

and the quick-help window appears.

Example 2

Emacs (| indicating point):

JSON.|

Execute tern-ac-complete

tern --verbose output:

Request: {
  "files": [
    {
      "type": "full",
      "text": "class Matrix {\n  constructor (matrixString) {\n    this.rows = buildRows(matrixString)\n  }\n}\n\nJSON.\n\nfunction buildRows (matrixString) {\n  return matrixString\n        .split('\\n')\n        .map(buildRow)\n}\n\nfunction buildRow (rowString) {\n  return rowString.split(' ')\n        .map(Number)\n}\n\nmodule.exports = Matrix\n",
      "name": "exercism/javascript/saddle-points/saddle-points.js"
    }
  ],
  "query": {
    "end": 98,
    "file": "exercism/javascript/saddle-points/saddle-points.js",
    "type": "completions",
    "types": true,
    "docs": true,
    "caseInsensitive": true
  }
}
Response: {
  "start": 98,
  "end": 98,
  "isProperty": true,
  "isObjectKey": false,
  "completions": [
    {
      "name": "parse",
      "type": "fn(json: string, reviver?: fn(key: string, value: ?))",
      "doc": "Parse a string as JSON, optionally transforming the value produced by parsing."
    },
    {
      "name": "stringify",
      "type": "fn(value: ?, replacer?: fn(key: string, value: ?), space?: string|number) -> string",
      "doc": "Convert a value to JSON, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified."
    }
  ]
}

Emacs freezes with the last error being:

Error running timer 'ac-quick-help': (error "Attempt to shape unibyte text")

So I think you're right about it being an elisp problem.

gypsydave5 avatar Aug 25 '17 13:08 gypsydave5