Closed ScottyB closed 11 years ago
Interesting. I've been going through your changes here as well as ac-js2. In skewer.complete() you're carefully and very conservatively capturing both keys and values. Currently you're not using the values but do you have plans to do so? If all you need is a list of the enumerable prototype chain properties then skewer.complete()
can be skipped:
(defvar js2ac-skewer-candidates '()
"Cadidates obtained from skewering")
(defun js2ac-skewer-result-callback (result)
(when (skewer-success-p result)
(let ((vector (json-read-from-string (cdr (assoc 'value result)))))
(setq js2ac-skewer-candidates (coerce vector 'list)))))
(defvar js2ac-get-keys-js
"var values = [];
for (var key in %s)
values.push(key);
values;"
"JavaScript template for gathering the prototype chain enumerable
properties of an object.")
;; Using strict mode so the code doesn't need to be wrapped in an IIFE.
(defun js2ac-get-object-keys (object)
(setq js2ac-skewer-candidates nil)
(skewer-eval (format js2ac-get-keys-js object)
#'js2ac-skewer-result-callback :verbose t :strict t))
Testing it,
(js2ac-get-object-keys "$('body')")
;; (sometime later)
js2ac-skewer-candidates
;; => ("0" "length" "prevObject" "context" "selector" "constructor" "init"
;; "jquery" "size" "toArray" "get" "pushStack" "each" "ready" "eq" ...)
To make things simpler, I could provide a skewer.allKeys() function (similar to Object.keys()) to hold that code, so that you don't need to keep that JavaScript expression around in a string ("skewer.allKeys(%s)"
instead). On Emacs' side you probably want to filter out any completions that need to be quoted, like indexes (same as Chrome's autocomplete behavior).
When I wrote before about having another request type I was expecting more of the work to be done in JavaScript. You're basically doing an eval again, so it's not all that different.
If skewer.complete() is discarded as above, I do believe the right approach is a separate project. Skewer can be generically modified, somewhat like you've done here, to accommodate extensions like yours.
Currently the value pops up next to the key at completion time. If the value happens to be a function then only the function interface is displayed. I thought that would be more helpful than showing the code for the whole function. Perhaps later on a short cut key can be used to show the code for the function.
Tonight I have been trying to get the same level of auto completion in Emacs as in Chrome. To do this I needed to expand skewer.complete
. It still may be possible to simplify the code in the manner as you suggested though. In terms of responsiveness in Emacs, I think that it is probably best to get the browser to do as much as possible.
Thanks for the pickup on the indexes. I'll probably remove these before they get sent to Emacs.
Ok, I didn't notice the use of the value. I see it now. That makes sense.
If you're still working out skewer.complete(), what do you want to do about this pull request? If you're still making a lot of changes in skewer.js I'd like to wait until you've got things settled down. The MELPA package draws right from my master branch so I've been trying to keep it somewhat stable.
I can maybe work in a convenient method for injecting your JS code into skewer.js from your package while that script is being served by simple-httpd, like a hook. That way your completion code isn't split across two repositories.
I just pushed some commits that should help you maintain your own package. Make a skewer-js-hook
hook to insert-file-literally
your own skewer.fn.complete() handler.
With your new changes this pull request isn't needed any more. Thanks for your work. I should be able to load other Javascript libraries in the skewer-js-hook
to provide completion for them as well rather than loading them in js-mode-hook
.
If you find yourself in need of any other hooks into skewer to do what you need to do, feel free to ask or even make another pull request with the proposed hook. You've been really helpful in making skewer-mode more flexible and composable.
I'm trying to get auto-complete working in my js2/skewer setup. I have ac-js2 installed, and it is failing because the skewer I have from melpa doesn't define the compete() function, which was in this pull request. ScottyB's last comment indicates that there's some other solution for completion. Would either of you be able to tell me what this is?
@killdash9
The file skewer-addon.js in ac-js2 defines skewer.fn.complete(). When you activate ac-js2-mode, it adds a function to skewer-js-hook that injects this definition into the JavaScript served up under /skewer.
If you have ac-js2 installed with its dependencies, it should Just Work once you activate ac-js2-mode.
Thanks for your fix. Here are the changes that I needed to make to get auto-completion working in ac-js2. Not sure if it was the best idea to create a separate project for the auto completion though.