summaryrefslogtreecommitdiff
path: root/elpa/ac-js2-20190101.933/ac-js2.el
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/ac-js2-20190101.933/ac-js2.el')
-rw-r--r--elpa/ac-js2-20190101.933/ac-js2.el608
1 files changed, 0 insertions, 608 deletions
diff --git a/elpa/ac-js2-20190101.933/ac-js2.el b/elpa/ac-js2-20190101.933/ac-js2.el
deleted file mode 100644
index 1951388..0000000
--- a/elpa/ac-js2-20190101.933/ac-js2.el
+++ /dev/null
@@ -1,608 +0,0 @@
-;;; ac-js2.el --- Auto-complete source for Js2-mode, with navigation
-
-;; Copyright (C) 2013 Scott Barnett
-
-;; Author: Scott Barnett <scott.n.barnett@gmail.com>
-;; URL: https://github.com/ScottyB/ac-js2
-;; Version: 1.0
-;; Package-Requires: ((js2-mode "20090723")(skewer-mode "1.4"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; An attempt to get context sensitive Javascript completion in Emacs.
-;; Basic completions are obtained by parsing Javascript code with
-;; Js2-mode's parser.
-;;
-;; Installation
-;;
-;; Easiest way to get ac-js2 is to install it from MELPA. You may need
-;; this snippet
-;;
-;; `(add-to-list 'package-archives
-;; '("melpa" . "http://melpa.milkbox.net/packages/") t)'
-;;
-;; if you don't have it already to fetch packages from MELPA.
-;;
-;; Enable ac-js2 in js2-mode as follows:
-;;
-;; (add-hook 'js2-mode-hook 'ac-js2-mode)
-;;
-;; Ac-js2 does not require auto-complete mode but I suggest you grab
-;; it anyway as ac-js2 is designed to work with a completion frontend.
-;; Support for Company mode is on its way.
-;;
-;; For more comprehensive completions you can opt to evaluate the code
-;; for candidates. A browser needs to be connected to Emacs for the
-;; evaluation completions to work. Put this in your init.el file.
-;;
-;; `(setq ac-js2-evaluate-calls t)'
-;;
-;; To add completions for external libraries add something like this:
-;;
-;; (add-to-list 'ac-js2-external-libraries "path/to/lib/library.js")
-;;
-;; Then connect a browser to Emacs by calling `(run-skewer)'. You may
-;; need to save the buffer for completions to start.
-;;
-;; If auto-complete mode is installed on your system then completions
-;; should start showing up otherwise use `completion-at-point'.
-;;
-;; Note: library completions will only work if `ac-js2-evaluate-calls'
-;; is set and a browser is connected to Emacs.
-;;
-;; Bonus: M-. is bound to `ac-js2-jump-to-definition' which will jump
-;; to Javascript definitions found in the same buffer. Given the
-;; following proprety reference:
-;;
-;; foo.bar.baz();
-;;
-;; placing the cursor on `foo', `bar' or `baz' and executing M-. will
-;; take you straight to their respective definitions. Use M-, to jump
-;; back to where you were. Also works for object literals.
-;;
-;; Recently added `ac-js2-expand-function' that will expand a function's
-;; parameters bound to `C-c C-c`. Expansion will only work if the cursor
-;; is after the function.
-;;
-;; If you have any issues or suggestions please create an issue on Github:
-;; https://github.com/ScottyB/ac-js2
-
-;;; History:
-
-;; Version 1.0
-;; * Navigation within current buffer
-;; * Completion and docstring for objects via Skewer
-;; * External library support
-;; * Basic completions of objects in current buffer
-
-;;; Code:
-
-(require 'js2-mode)
-(require 'skewer-mode)
-(require 'cl-lib)
-(require 'etags)
-
-(defgroup ac-js2 nil
- "Auto-completion for js2-mode."
- :group 'completion
- :prefix "ac-js2-")
-
-;;; Configuration variables
-
-(defcustom ac-js2-add-ecma-262-externs t
- "If non-nil add `js2-ecma-262-externs' to completion candidates.")
-
-(defcustom ac-js2-add-browser-externs t
- "If non-nil add `js2-browser-externs' to completion candidates.")
-
-(defcustom ac-js2-add-keywords t
- "If non-nil add `js2-keywords' to completion candidates.")
-
-(defcustom ac-js2-add-prototype-completions t
- "When non-nil traverse the prototype chain adding to completion candidates.")
-
-(defcustom ac-js2-external-libraries '()
- "List of absolute paths to external Javascript libraries.")
-
-(defcustom ac-js2-evaluate-calls nil
- "Warning. When true function calls will be evaluated in the browser.
-This may cause undesired side effects however it will
- provide better completions. Use at your own risk.")
-
-(defcustom ac-js2-force-reparse t
- "Force Js2-mode to reparse buffer before fetching completion candidates.")
-
-;;; Internal variables
-
-(defvar ac-js2-keywords '()
- "Cached string version of `js2-keywords'.")
-
-(defvar ac-js2-candidates '())
-
-;; Types of skewer completion methods available
-(defconst ac-js2-method-eval 0)
-(defconst ac-js2-method-global 1
- "Return candidates for the global object.
-Only keys of the object are returned as the other properties come
- from js2-mode's externs.")
-
-(defvar ac-js2-data-root (file-name-directory load-file-name)
- "Location of data files needed for `ac-js2-on-skewer-load'.")
-
-;;; Skewer integration
-
-(defvar ac-js2-skewer-candidates '()
- "Cadidates obtained from skewering.")
-
-(defun ac-js2-on-skewer-load ()
- "Inject skewer addon and evaluate external libraries in browser."
- (insert-file-contents (expand-file-name "skewer-addon.js" ac-js2-data-root))
- (and ac-js2-evaluate-calls
- (mapcar (lambda (library)
- (with-temp-buffer
- (insert-file-contents (expand-file-name library))
- (skewer-eval (buffer-string)
- nil
- :type "complete"))) ac-js2-external-libraries)))
-
-(defun ac-js2-skewer-completion-candidates ()
- "Get completions returned from skewer."
- (mapcar (lambda (candidate) (symbol-name (car candidate))) ac-js2-skewer-candidates))
-
-(defun ac-js2-skewer-document-candidates (name)
- "Return document string for NAME from skewer."
- (let ((doc (cdr (assoc-string name ac-js2-skewer-candidates))))
- (or (ac-js2-format-function doc) doc)))
-
-(defun ac-js2-get-object-properties (name)
- "Find properties of NAME for completion."
- (ac-js2-skewer-eval-wrapper name `((prototypes . ,ac-js2-add-prototype-completions))))
-
-(defun ac-js2-skewer-result-callback (result)
- "Process the RESULT passed from the browser."
- (let ((value (cdr (assoc 'value result))))
- (if (and (skewer-success-p result) value)
- (setq ac-js2-skewer-candidates (append value nil)))))
-
-(defun ac-js2-skewer-eval-wrapper (str &optional extras)
- "Wrap `skewer-eval-synchronously' to check if a skewer-client is avilable.
-STR is the text to send to the browser for evaluation. Extra
-parameters can be passed to the browser using EXTRAS. EXTRAS must
-be of the form (param-string . value) where param-string is the
-reference and value is the value that can be retrieved from the
-request object in Javacript."
- (setq ac-js2-skewer-candidates nil)
- (if skewer-clients
- (if (or ac-js2-evaluate-calls
- (not (ac-js2-has-function-calls str)))
- (ac-js2-skewer-result-callback
- (skewer-eval-synchronously str
- :type "complete"
- :extra extras)))
- (setq skewer-queue nil)))
-
-;; Generate candidates
-(defun ac-js2-candidates ()
- "Main function called to gather candidates for auto-completion."
- (if ac-js2-force-reparse (js2-reparse))
- (let ((node (js2-node-parent (js2-node-at-point (1- (point)))))
- beg
- (prop-get-regex "[a-zA-Z)]\\.")
- name)
- (setq ac-js2-candidates nil)
- (cond
- ((looking-back "\\.")
- ;; TODO: Need to come up with a better way to extract object than this regex!!
- (save-excursion
- (setq beg (and (skip-chars-backward "[a-zA-Z_$][0-9a-zA-Z_$#\"())]+\\.") (point))))
- (setq name (buffer-substring-no-properties beg (1- (point))))
- (ac-js2-get-object-properties name)
- (setq node (ac-js2-initialized-node (if (string-match prop-get-regex name)
- (reverse (split-string name prop-get-regex)) name)))
- (if (js2-object-node-p node)
- (setq ac-js2-candidates
- (mapcar (lambda (elem)
- (ac-js2-format-node (js2-node-string (js2-object-prop-node-left elem))
- elem))
- (js2-object-node-elems node))))
- (append (mapcar 'cl-first ac-js2-candidates)
- (ac-js2-skewer-completion-candidates)))
- ((js2-prop-get-node-p node)
- (setq node (js2-prop-get-node-left node))
- (setq name (js2-node-string node))
- (ac-js2-get-object-properties name)
- (ac-js2-skewer-completion-candidates))
- (t
- (ac-js2-skewer-eval-wrapper "" `((method . ,ac-js2-method-global)))
- (append (ac-js2-skewer-completion-candidates)
- (ac-js2-add-extra-completions
- (mapcar 'cl-first (ac-js2-get-names-in-scope))))))))
-
-(defun ac-js2-document (name)
- "Show documentation for NAME from local buffer if present
-otherwise use documentation obtained from skewer."
- (let* ((docs (cdr (assoc name ac-js2-candidates)))
- (doc (if (listp docs) (cl-first docs) docs)))
- (if doc doc (ac-js2-skewer-document-candidates name))))
-
-;; Auto-complete settings
-
-(defun ac-js2-ac-candidates ()
- "Completion candidates for auto-complete mode."
- (ac-js2-candidates))
-
-(defun ac-js2-ac-document (name)
- "Documentation to be shown for auto-complete mode."
- (ac-js2-document name))
-
-(defun ac-js2-ac-prefix()
- (or (ac-prefix-default) (ac-prefix-c-dot)))
-
-(defun ac-js2-save ()
- "Called on `before-save-hook' to evaluate buffer."
- (interactive)
- (when (string= major-mode "js2-mode")
- (ac-js2-skewer-eval-wrapper (buffer-string)))
- t)
-
-;;;###autoload
-(defun ac-js2-expand-function()
- "Expand the function definition left of point.
-Expansion will only occur for candidates whose documentation
-string contain a function prototype."
- (interactive)
- (let* ((word (progn
- (if (featurep 'auto-complete) (ac-complete))
- (substring-no-properties (or (thing-at-point 'word) ""))))
- (candidate (ac-js2-ac-document word)))
- (if (and (looking-back word) (stringp candidate))
- (when (string-match "^function" candidate)
- (cond ((featurep 'yasnippet)
- (yas-expand-snippet
- (concat "("
- (replace-regexp-in-string "\\([a-zA-Z0-9]+\\)"
- (lambda (txt) (concat "${" txt "}"))
- (cl-second (split-string candidate "[()]")))
- ")$0"))))))))
-
-(defun ac-js2-setup-auto-complete-mode ()
- "Setup ac-js2 to be used with auto-complete-mode."
- (add-to-list 'ac-sources 'ac-source-js2)
- (auto-complete-mode)
- (ac-define-source "js2"
- '((candidates . ac-js2-ac-candidates)
- (document . ac-js2-ac-document)
- (prefix . ac-js2-ac-prefix)
- (requires . -1))))
-
-;;; Completion at point function
-
-;;;###autoload
-(defun ac-js2-completion-function ()
- "Function for `completions-at-point'."
- (save-excursion
- (let ((bounds (if (looking-back "\\.")
- (cons (point) (point))
- (bounds-of-thing-at-point 'word))))
- (list (car bounds) (cdr bounds) (ac-js2-candidates)))))
-
-;;; Company
-
-;;;###autoload
-(defun ac-js2-company (command &optional arg &rest ignored)
- (interactive (list 'interactive))
- (if (not (featurep 'company))
- (message "Company is not installed")
- (cl-case command
- (interactive (company-begin-backend 'ac-js2-company))
- (prefix (when ac-js2-mode
- (or (company-grab-symbol)
- 'stop)))
- (candidates (all-completions arg (ac-js2-candidates)))
- (duplicates t)
- (meta (let ((doc (ac-js2-document arg)))
- (when doc
- (with-temp-buffer
- (insert doc)
- (js-mode)
- (if (fboundp 'font-lock-ensure)
- (font-lock-ensure)
- (with-no-warnings
- (font-lock-fontify-buffer)))
- (buffer-string))))))))
-
-;;; Helper functions
-
-(defun ac-js2-build-prop-name-list (prop-node)
- "Build a list of names from a PROP-NODE."
- (let* (names
- left
- left-node)
- (unless (js2-prop-get-node-p prop-node)
- (error "Node is not a property prop-node"))
- (while (js2-prop-get-node-p prop-node)
- (push (js2-name-node-name (js2-prop-get-node-right prop-node)) names)
- (setq left-node (js2-prop-get-node-left prop-node))
- (when (js2-name-node-p left-node)
- (setq left (js2-name-node-name left-node)))
- (setq prop-node (js2-node-parent prop-node)))
- (append names `(,left))))
-
-(defun ac-js2-prop-names-left (name-node)
- "Create a list of all of the names in the property NAME-NODE.
-NAME-NODE must have a js2-prop-get-node as parent. Only adds
-properties to the left of point. This is so individual jump
-points can be found for each property in the chain."
- (let* (name
- (parent (js2-node-parent name-node))
- left
- names)
- (unless (or (js2-prop-get-node-p parent) (js2-name-node-p name-node))
- (error "Not a name node or doesn't have a prop-get-node as parent"))
- (setq name (js2-name-node-name name-node)
- left (js2-prop-get-node-left parent))
- (if (and (js2-name-node-p left)
- (string= name (js2-name-node-name left)))
- (setq names name)
- (js2-visit-ast
- parent
- (lambda (node endp)
- (unless endp
- (if (js2-name-node-p node)
- (push (js2-name-node-name node) names)
- t))))
- names)))
-
-(defun ac-js2-has-function-calls (string)
- "Check if the Javascript code in STRING has a Js2-call-node."
- (with-temp-buffer
- (insert string)
- (let* ((ast (js2-parse)))
- (catch 'call-node
- (js2-visit-ast-root
- ast
- (lambda (node end-p)
- (unless end-p
- (if (js2-call-node-p node)
- (throw 'call-node t)
- t))))))))
-
-(defun ac-js2-add-extra-completions (completions)
- "Add extra candidates to COMPLETIONS."
- (append completions
- (if ac-js2-add-keywords (or ac-js2-keywords (setq ac-js2-keywords (mapcar 'symbol-name js2-keywords))))
- (if ac-js2-add-ecma-262-externs js2-ecma-262-externs)
- (if ac-js2-add-browser-externs js2-browser-externs)))
-
-(defun ac-js2-root-or-node ()
- "Return the current node or js2-ast-root node."
- (let ((node (js2-node-at-point)))
- (if (js2-ast-root-p node)
- node
- (js2-node-get-enclosing-scope node))))
-
-(defun ac-js2-get-names-in-scope ()
- "Fetches all symbols in scope and formats them for completion."
- (let* ((scope (ac-js2-root-or-node))
- result)
- (while scope
- (setq result (append result
- (cl-loop for item in (js2-scope-symbol-table scope)
- if (not (assoc (car item) result))
- collect item)))
- (setq scope (js2-scope-parent-scope scope)))
- (setq ac-js2-candidates
- (mapcar #'(lambda (x)
- (let* ((name (symbol-name (car x)))
- (init (ac-js2-initialized-node name)))
- (ac-js2-format-node name init)))
- result))))
-
-(defun ac-js2-initialized-node (name)
- "Return initial value assigned to NAME.
-NAME may be either a variable, a function or a variable that
-holds a function. NAME may also be a list of names that make up a
-object property. Returns nil if no initial value can be found."
- (let* ((node (if (listp name) (ac-js2-find-property name)
- (ac-js2-name-declaration name)))
- (parent (if node (js2-node-parent node)))
- (init (cond
- ((js2-function-node-p parent)
- parent)
- ((js2-function-node-p node)
- node)
- ((js2-var-init-node-p parent)
- (js2-var-init-node-initializer parent))
- ((js2-assign-node-p parent)
- (js2-assign-node-right parent))
- (t
- nil))))
- init))
-
-(defun ac-js2-name-declaration (name)
- "Return the declaration node for node named NAME."
- (let* ((node (ac-js2-root-or-node))
- (scope-def (js2-get-defining-scope node name))
- (scope (if scope-def (js2-scope-get-symbol scope-def name) nil))
- (symbol (if scope (js2-symbol-ast-node scope) nil)))
- (if (not symbol)
- (ac-js2-get-function-node name scope-def)
- symbol)))
-
-;;; Completion candidate formatting
-
-(defun ac-js2-format-node (name node)
- "Format NAME and NODE for completion.
-Returned format is a list where the first element is the NAME of
-the node (shown in completion candidate list) and the last
-element is the text to show as documentation."
- (let ((node (if (js2-object-prop-node-p node) (js2-object-prop-node-right node) node))
- (name-format (replace-regexp-in-string "\"" "" name))
- (doc (if (and (js2-function-node-p node)
- (cl-find name (js2-function-node-params node)
- :test '(lambda (name param) (string= name (js2-name-node-name param)))))
- "Function parameter"
- (ac-js2-format-node-doc node))))
- `(,name-format . ,doc)))
-
-(defun ac-js2-format-object-node-doc (obj-node)
- "Format OBJ-NODE to display as documentation."
- (let (elems)
- (unless (js2-object-node-p obj-node)
- (error "Node is not an object node"))
- (setq elems (js2-object-node-elems obj-node))
- (if (not elems)
- "{}"
- (mapconcat #'(lambda (x) (ac-js2-format-js2-object-prop-doc x)) elems "\n"))))
-
-(defun ac-js2-format-node-doc (node)
- "Format NODE for displaying in a document string."
- (let* ((node-above (and node (js2-node-at-point
- (save-excursion
- (goto-char (js2-node-abs-pos node))
- (forward-line -1)
- (point)))))
- (comment (if (js2-comment-node-p node-above)
- (ac-js2-format-comment (js2-node-string node-above))))
- (doc (cond
- ((js2-function-node-p node)
- (ac-js2-format-function node))
- ((js2-object-node-p node)
- (ac-js2-format-object-node-doc node))
- ((js2-object-prop-node-p node)
- (ac-js2-format-node-doc (js2-object-prop-node-right node)))
- (t
- (if (js2-node-p node) (js2-node-string node) "")))))
- (if comment (concat comment "\n" doc) doc)))
-
-(defun ac-js2-format-js2-object-prop-doc (obj-prop)
- "Format an OBJ-PROP for displaying as a document string."
- (unless (js2-object-prop-node-p obj-prop)
- (error "Node is not an object property node"))
- (let* ((left (js2-object-prop-node-left obj-prop))
- (right (js2-object-prop-node-right obj-prop)))
- (concat (js2-node-string left) " : "
- (ac-js2-format-node-doc right))))
-
-(defun ac-js2-format-function (func)
- "Formats a function for a document string.
-FUNC can be either a function node or a string starting with
-'function'. Returns nil if neither."
- (let ((str (or (and (js2-function-node-p func) (js2-node-string func))
- (and (stringp func) (eq 0 (string-match "function" func)) func))))
- (if str (substring str 0 (1+ (string-match ")" str))))))
-
-(defun ac-js2-format-comment (comment)
- "Prepare a COMMENT node for displaying in a popup."
- (let* ((node-string (if (js2-comment-node-p comment)
- (js2-node-string comment)
- comment))
- (string (replace-regexp-in-string "[ \t]$" ""
- (replace-regexp-in-string "^[ \t\n*/*]+" "" node-string))))
- string))
-
-;;; Navigation commands for js2-mode
-
-(defun ac-js2-find-property (list-names)
- "Find the property definition that consists of LIST-NAMES.
-Supports navigation to 'foo.bar = 3' and 'foo = {bar: 3}'."
- (catch 'prop-found
- (js2-visit-ast-root
- js2-mode-ast
- (lambda (node endp)
- (let ((parent (js2-node-parent node)))
- (unless endp
- (if (or (and (js2-prop-get-node-p node)
- (not (or (js2-elem-get-node-p parent) (js2-call-node-p parent)))
- (equal list-names (ac-js2-build-prop-name-list node)))
- (and (js2-name-node-p node)
- (js2-object-prop-node-p parent)
- (string= (js2-name-node-name node)
- (cl-first list-names))))
- (throw 'prop-found node))
- t))))))
-
-(defun ac-js2-get-function-node (name scope)
- "Return node of function named NAME in SCOPE."
- (catch 'function-found
- (js2-visit-ast
- scope
- (lambda (node end-p)
- (when (and (not end-p)
- (string= name (ac-js2-get-function-name node)))
- (throw 'function-found node))
- t))
- nil))
-
-;;;###autoload
-(defun ac-js2-jump-to-definition ()
- "Jump to the definition of an object's property, variable or function.
-Navigation to a property definend in an Object literal isn't
-implemented."
- (interactive)
- (ring-insert find-tag-marker-ring (point-marker))
- (let* ((node (js2-node-at-point))
- (parent (js2-node-parent node))
- (prop-names (if (js2-prop-get-node-p parent)
- (ac-js2-prop-names-left node)))
- (name (if (and (js2-name-node-p node)
- (not (js2-object-prop-node-p parent)))
- (js2-name-node-name node)
- (error "Node is not a supported jump node")))
- (node-init (if (and prop-names (listp prop-names))
- (ac-js2-find-property prop-names)
- (ac-js2-name-declaration name))))
- (unless node-init
- (pop-tag-mark)
- (error "No jump location found"))
- (goto-char (js2-node-abs-pos node-init))))
-
-(defun ac-js2-get-function-name (fn-node)
- "Return the name of the function FN-NODE.
-Value may be either function name or the variable name that holds
-the function."
- (let ((parent (js2-node-parent fn-node)))
- (if (js2-function-node-p fn-node)
- (or (js2-function-name fn-node)
- (if (js2-var-init-node-p parent)
- (js2-name-node-name (js2-var-init-node-target parent)))))))
-
-(defvar ac-js2-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "M-.") 'ac-js2-jump-to-definition)
- (define-key map (kbd "M-,") 'pop-tag-mark)
- (define-key map (kbd "C-c C-c") 'ac-js2-expand-function)
- map)
- "Keymap for `ac-js2-mode'.")
-
-;;; Minor mode
-
-;;;###autoload
-(define-minor-mode ac-js2-mode
- "A minor mode that provides auto-completion and navigation for Js2-mode."
- :keymap ac-js2-mode-map
- (if (featurep 'auto-complete)
- (ac-js2-setup-auto-complete-mode))
- (set (make-local-variable 'completion-at-point-functions)
- (cons 'ac-js2-completion-function completion-at-point-functions))
- (ac-js2-skewer-eval-wrapper (buffer-string))
- (add-hook 'before-save-hook 'ac-js2-save nil t)
- (add-hook 'skewer-js-hook 'ac-js2-on-skewer-load))
-
-
-(provide 'ac-js2)
-
-;;; ac-js2.el ends here