From 3f4a0d5370ae6c34afe180df96add3b8522f4af1 Mon Sep 17 00:00:00 2001 From: mattkae Date: Wed, 11 May 2022 09:23:58 -0400 Subject: initial commit --- elpa/ac-js2-20190101.933/ac-js2-autoloads.el | 70 +++ elpa/ac-js2-20190101.933/ac-js2-pkg.el | 11 + elpa/ac-js2-20190101.933/ac-js2-tests.el | 76 ++++ elpa/ac-js2-20190101.933/ac-js2-tests.elc | Bin 0 -> 5403 bytes elpa/ac-js2-20190101.933/ac-js2.el | 608 +++++++++++++++++++++++++++ elpa/ac-js2-20190101.933/ac-js2.elc | Bin 0 -> 21918 bytes elpa/ac-js2-20190101.933/skewer-addon.js | 116 +++++ 7 files changed, 881 insertions(+) create mode 100644 elpa/ac-js2-20190101.933/ac-js2-autoloads.el create mode 100644 elpa/ac-js2-20190101.933/ac-js2-pkg.el create mode 100644 elpa/ac-js2-20190101.933/ac-js2-tests.el create mode 100644 elpa/ac-js2-20190101.933/ac-js2-tests.elc create mode 100644 elpa/ac-js2-20190101.933/ac-js2.el create mode 100644 elpa/ac-js2-20190101.933/ac-js2.elc create mode 100644 elpa/ac-js2-20190101.933/skewer-addon.js (limited to 'elpa/ac-js2-20190101.933') diff --git a/elpa/ac-js2-20190101.933/ac-js2-autoloads.el b/elpa/ac-js2-20190101.933/ac-js2-autoloads.el new file mode 100644 index 0000000..f6b19e7 --- /dev/null +++ b/elpa/ac-js2-20190101.933/ac-js2-autoloads.el @@ -0,0 +1,70 @@ +;;; ac-js2-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "ac-js2" "ac-js2.el" (0 0 0 0)) +;;; Generated autoloads from ac-js2.el + +(autoload 'ac-js2-expand-function "ac-js2" "\ +Expand the function definition left of point. +Expansion will only occur for candidates whose documentation +string contain a function prototype." t nil) + +(autoload 'ac-js2-completion-function "ac-js2" "\ +Function for `completions-at-point'." nil nil) + +(autoload 'ac-js2-company "ac-js2" "\ + + +\(fn COMMAND &optional ARG &rest IGNORED)" t nil) + +(autoload 'ac-js2-jump-to-definition "ac-js2" "\ +Jump to the definition of an object's property, variable or function. +Navigation to a property definend in an Object literal isn't +implemented." t nil) + +(autoload 'ac-js2-mode "ac-js2" "\ +A minor mode that provides auto-completion and navigation for Js2-mode. + +This is a minor mode. If called interactively, toggle the +`Ac-Js2 mode' mode. If the prefix argument is positive, enable +the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `ac-js2-mode'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. + +\(fn &optional ARG)" t nil) + +(register-definition-prefixes "ac-js2" '("ac-js2-")) + +;;;*** + +;;;### (autoloads nil "ac-js2-tests" "ac-js2-tests.el" (0 0 0 0)) +;;; Generated autoloads from ac-js2-tests.el + +(register-definition-prefixes "ac-js2-tests" '("completion-frontend-test")) + +;;;*** + +;;;### (autoloads nil nil ("ac-js2-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; ac-js2-autoloads.el ends here diff --git a/elpa/ac-js2-20190101.933/ac-js2-pkg.el b/elpa/ac-js2-20190101.933/ac-js2-pkg.el new file mode 100644 index 0000000..9b42769 --- /dev/null +++ b/elpa/ac-js2-20190101.933/ac-js2-pkg.el @@ -0,0 +1,11 @@ +(define-package "ac-js2" "20190101.933" "Auto-complete source for Js2-mode, with navigation" + '((js2-mode "20090723") + (skewer-mode "1.4")) + :commit "2b56d09a16c1a0ce514cc1b85d64cb1be4502723" :authors + '(("Scott Barnett" . "scott.n.barnett@gmail.com")) + :maintainer + '("Scott Barnett" . "scott.n.barnett@gmail.com") + :url "https://github.com/ScottyB/ac-js2") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/ac-js2-20190101.933/ac-js2-tests.el b/elpa/ac-js2-20190101.933/ac-js2-tests.el new file mode 100644 index 0000000..05514e3 --- /dev/null +++ b/elpa/ac-js2-20190101.933/ac-js2-tests.el @@ -0,0 +1,76 @@ +;;; Tests for ac-js2 + +(require 'ert) +(require 'skewer-mode) +(require 'js2-mode) +(require 'ac-js2) + +;;; Must have a skewer client connected before running the tests +;; Need to call httpd-stop from main Emacs if running tests in batch mode +(unless skewer-clients + (run-skewer)) + +(ert-deftest ac-js2-candidates-test () + "Test the major function that returns candidates for all frontends." + (let (property + property-dot + func-call + var) + (with-temp-buffer + (insert " + var temp = function(param1, param2) { + var localParam = 15; + return param1 + param2; + }; + + var look; + +temp.aFun = function(lolParam) {}; +temp.anotherFunction = function() { return {about: 3};}") + (setq ac-js2-evaluate-calls t) + (setq ac-js2-external-libraries nil) + + (js2-mode) + (ac-js2-mode t) + (js2-parse) + + (insert "tem") + (ac-js2-candidates) + (setq var ac-js2-skewer-candidates) + (delete-char -3) + + (insert "temp.") + (js2-parse) + (ac-js2-candidates) + (setq property-dot ac-js2-skewer-candidates) + (delete-char -5) + + (insert "temp.aF") + (js2-parse) + (ac-js2-candidates) + (setq property ac-js2-skewer-candidates)) + + (should (assoc 'anotherFunction property-dot)) + (print property) + (should (assoc 'aFun property)) + (should (assoc 'temp var)))) + +(defmacro completion-frontend-test (test-name completion-function) + "Utility for testing completion front ends. +TODO: cover more cases" + `(ert-deftest ,test-name () + (let (var) + (with-temp-buffer + (insert "var testComplete = function(param1, param2) {};") + + (js2-mode) + (ac-js2-mode t) + (js2-parse) + + (insert "testComplet") + (funcall ',completion-function) + (setq var (thing-at-point 'word))) + (should (string= var "testComplete"))))) + +(completion-frontend-test auto-complete-test auto-complete) +(completion-frontend-test completion-at-point-test completion-at-point) diff --git a/elpa/ac-js2-20190101.933/ac-js2-tests.elc b/elpa/ac-js2-20190101.933/ac-js2-tests.elc new file mode 100644 index 0000000..030ca04 Binary files /dev/null and b/elpa/ac-js2-20190101.933/ac-js2-tests.elc differ diff --git a/elpa/ac-js2-20190101.933/ac-js2.el b/elpa/ac-js2-20190101.933/ac-js2.el new file mode 100644 index 0000000..1951388 --- /dev/null +++ b/elpa/ac-js2-20190101.933/ac-js2.el @@ -0,0 +1,608 @@ +;;; ac-js2.el --- Auto-complete source for Js2-mode, with navigation + +;; Copyright (C) 2013 Scott Barnett + +;; Author: Scott Barnett +;; 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 . + +;;; 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 diff --git a/elpa/ac-js2-20190101.933/ac-js2.elc b/elpa/ac-js2-20190101.933/ac-js2.elc new file mode 100644 index 0000000..abe484e Binary files /dev/null and b/elpa/ac-js2-20190101.933/ac-js2.elc differ diff --git a/elpa/ac-js2-20190101.933/skewer-addon.js b/elpa/ac-js2-20190101.933/skewer-addon.js new file mode 100644 index 0000000..8e2b5a1 --- /dev/null +++ b/elpa/ac-js2-20190101.933/skewer-addon.js @@ -0,0 +1,116 @@ +/** + * @fileOverview Completion request handler for skewer.js + * @requires skewer + * @version 1.0 + */ + +/** + * Handles a completion request from Emacs. + * @param request The request object sent by Emacs + * @returns The completions and init values to be returned to Emacs + */ +skewer.fn.complete = function(request) { + var result = { + type : request.type, + id : request.id, + strict : request.strict, + status : "success" + }, + + /** + * Methods for generating candidates + */ + METHOD = { + EVAL : 0, + GLOBAL : 1 + }, + + /** + * Add the properties from object to extendObject. Properties + * may be from the prototype but we still want to add them. + */ + extend = function(extendObject, object) { + for(var key in object) { + extendObject[key] = object[key]; + } + }, + + globalCompletion = function() { + var global = Function('return this')(), + keys = Object.keys(global); + candidates = buildCandidates(global, keys); + }, + + evalCompletion = function(evalObject) { + var obj = (eval, eval)(evalObject); + if (typeof obj === "object") { + candidates = buildCandidates(obj) || {}; + while (request.prototypes && (obj = Object.getPrototypeOf(obj)) !== null) { + extend(candidates, buildCandidates(obj)); + } + } else if (typeof obj === "function"){ + candidates = buildCandidates(obj) || {}; + extend(candidates, buildCandidates(Object.getPrototypeOf(obj))); + if (request.prototypes) { + var protoObject = Object.getPrototypeOf(obj.prototype); + if (protoObject !== null) { + extend(candidates, buildCandidates(protoObject)); + } else { + extend(candidates, buildCandidates(obj.prototype)); + } + } + } + }, + + /** + * Completion candidates sent back to Emacs. Keys are + * completion candidates the values are the inital items or + * function interfaces. + */ + candidates = {}, + + /** + * Build the candiates to return to Emacs. + * @param obj The object to get candidates from + * @param items The selected keys from obj to create candidates for + * @return object containing completion candidates and documentation strings + */ + buildCandidates = function(obj, items) { + var keys = items || Object.getOwnPropertyNames(obj), values = {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (key === "callee" || key === "caller" || key === "arguments") continue; + if (Object.prototype.toString.call(obj[key]) === "[object Function]") { + values[key] = obj[key].toString(); + } else if (typeof obj[key] === "object"){ + values[key] = "[object Object]"; + } else if (typeof obj[key] === "number") { + if (!(obj instanceof Array)) { + values[key] = obj[key].toString(); + } + } else if (typeof obj[key] === "string") { + values[key] = obj[key].toString(); + } else if(obj[key] === true) { + values[key] = "true"; + } else if (obj[key] === false) { + values[key] = "false"; + } else { + values[key] = ""; + } + } + return values; + }; + try { + switch (request.method) { + case METHOD.GLOBAL: + globalCompletion(); + break; + default: + evalCompletion(request.eval); + } + result.value = candidates; + } catch (error){ + skewer.errorResult(error, result, request); + } + return result; +}; -- cgit v1.2.1