ternjs / tern

A JavaScript code analyzer for deep, cross-editor language support
https://ternjs.net/
MIT License
4.25k stars 378 forks source link

tern-autocomplete makes emacs unresponsive #903

Open tejasbubane opened 7 years ago

tejasbubane commented 7 years ago

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

Scenario:

⇒  time bin/test
Ran 597 tests from 100 files.
All passed.
bin/test  4.79s user 0.27s system 93% cpu 5.425 total

(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.
marijnh commented 7 years ago

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.

gypsydave5 commented 7 years ago

@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.