]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge branch 'master' into emacs24
authorDmitry Gutov <dgutov@yandex.ru>
Sun, 3 Jun 2012 17:37:23 +0000 (21:37 +0400)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 3 Jun 2012 22:46:22 +0000 (02:46 +0400)
Conflicts:
js2-mode.el

1  2 
js2-imenu-extras.el
js2-mode.el

index 0000000000000000000000000000000000000000,50625c934ac5f8002f8d130796c688da96e92587..f9215a4785feffeb06ec79191818179eda66606a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,215 +1,215 @@@
 -    (while (js-re-search-forward re nil t)\r
+ ;;; js2-imenu-extras.el --- Imenu support for additional constructs\r
\r
+ ;; Author:    Dmitry Gutov <dgutov@yandex.ru>\r
+ ;; Keywords:  languages, javascript, imenu\r
\r
+ ;; This file is part of GNU Emacs.\r
\r
+ ;; GNU Emacs is free software: you can redistribute it and/or modify\r
+ ;; it under the terms of the GNU General Public License as published by\r
+ ;; the Free Software Foundation, either version 3 of the License, or\r
+ ;; (at your option) any later version.\r
\r
+ ;; GNU Emacs is distributed in the hope that it will be useful,\r
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ ;; GNU General Public License for more details.\r
\r
+ ;; You should have received a copy of the GNU General Public License\r
+ ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.\r
\r
+ ;;; Commentary:\r
\r
+ ;; This package adds Imenu support for additional framework constructs and\r
+ ;; general patterns to `js2-mode'.\r
\r
+ ;; Usage:\r
\r
+ ;; (eval-after-load 'js2-mode\r
+ ;;   '(progn\r
+ ;;      (require 'js2-imenu-extras)\r
+ ;;      (js2-imenu-extras-setup)))\r
\r
+ ;; To customize how it works:\r
+ ;;   M-x customize-group RET js2-imenu RET\r
\r
+ (eval-when-compile\r
+   (require 'cl))\r
\r
+ (require 'js2-mode)\r
\r
+ (defconst js2-imenu-extension-styles\r
+   `((:framework jquery\r
+      :call-re   "\\_<\\(?:jQuery\\|\\$\\|_\\)\\.extend\\s-*("\r
+      :recorder  js2-imenu-record-jquery-extend)\r
\r
+     (:framework jquery-ui\r
+      :call-re   "^\\s-*\\(?:jQuery\\|\\$\\)\\.widget\\s-*("\r
+      :recorder  js2-imenu-record-string-declare)\r
\r
+     (:framework dojo\r
+      :call-re   "^\\s-*dojo.declare\\s-*("\r
+      :recorder  js2-imenu-record-string-declare)\r
\r
+     (:framework backbone\r
+      :call-re   ,(concat "\\_<" js2-mode-identifier-re "\\.extend\\s-*(")\r
+      :recorder  js2-imenu-record-backbone-extend))\r
+   "List of JavaScript class definition or extension styles.\r
\r
+ :framework is a valid value in `js2-imenu-enabled-frameworks'.\r
\r
+ :call-re is a regular expression that has no capturing groups.\r
\r
+ :recorder is a function name that will be called when the regular\r
+ expression matches some text in the buffer.  When it's called, point will be\r
+ at the end of the match.  The function must keep the point position.")\r
\r
+ (defconst js2-imenu-available-frameworks\r
+   (mapcar (lambda (style) (plist-get style :framework)) js2-imenu-extension-styles)\r
+   "List of available JavaScript framework symbols.")\r
\r
+ (defcustom js2-imenu-enabled-frameworks js2-imenu-available-frameworks\r
+   "Frameworks to be recognized by `js2-mode'."\r
+   :type (cons 'set (mapcar (lambda (x) (list 'const x))\r
+                            js2-imenu-available-frameworks))\r
+   :group 'js2-imenu)\r
\r
+ (defcustom js2-imenu-show-other-functions t\r
+   "Non-nil to show functions not recognized by other mechanisms,\r
+ in a shared namespace."\r
+   :type 'boolean\r
+   :group 'js2-imenu)\r
\r
+ (defcustom js2-imenu-other-functions-ns "?"\r
+   "Namespace name to use for other functions."\r
+   :type 'string\r
+   :group 'js2-imenu)\r
\r
+ (defcustom js2-imenu-show-module-pattern t\r
+   "Non-nil to recognize the module pattern:\r
\r
+ var foobs = (function(a) {\r
+   return {fib: function() {}, fub: function() {}};\r
+ })(b);\r
\r
+ We record the returned hash as belonging to the named module, and\r
+ prefix any functions defined inside the IIFE with the module name."\r
+   :type 'boolean\r
+   :group 'js2-imenu)\r
\r
+ ;;;###autoload\r
+ (defun js2-imenu-extras-setup ()\r
+   (when js2-imenu-enabled-frameworks\r
+     (add-to-list 'js2-post-parse-callbacks 'js2-imenu-record-declarations t))\r
+   (when (or js2-imenu-show-other-functions js2-imenu-show-module-pattern)\r
+     (add-to-list 'js2-post-parse-callbacks 'js2-imenu-walk-ast t)))\r
\r
+ (declare (special root))\r
\r
+ (defun js2-imenu-record-declarations ()\r
+   (let* ((styles (loop for style in js2-imenu-extension-styles\r
+                        when (memq (plist-get style :framework)\r
+                                   js2-imenu-enabled-frameworks)\r
+                        collect style))\r
+          (re (mapconcat (lambda (style)\r
+                           (concat "\\(" (plist-get style :call-re) "\\)"))\r
+                         styles "\\|"))\r
+          ;; Dynamic scoping. Ew.\r
+          (js2-mode-ast root))\r
+     (goto-char (point-min))\r
++    (while (js2-re-search-forward re nil t)\r
+       (loop for i from 0 to (1- (length styles))\r
+             when (match-beginning (1+ i))\r
+             return (funcall (plist-get (nth i styles) :recorder))))))\r
\r
+ (defun js2-imenu-record-jquery-extend ()\r
+   (let ((pred (lambda (subject)\r
+                 (and\r
+                  (js2-prop-get-node-p subject)\r
+                  (string= (js2-name-node-name (js2-prop-get-node-right subject))\r
+                           "prototype")))))\r
+     (js2-imenu-record-extend-first-arg (1- (point)) pred\r
+                                        'js2-compute-nested-prop-get)))\r
\r
+ (defun js2-imenu-record-string-declare ()\r
+   (js2-imenu-record-extend-first-arg\r
+    (1- (point)) 'js2-string-node-p\r
+    (lambda (node) (split-string (js2-string-node-value node) "\\." t))))\r
\r
+ (defun js2-imenu-record-extend-first-arg (point pred qname-fn)\r
+   (let* ((node (js2-node-at-point point))\r
+          (args (js2-call-node-args node))\r
+          (subject (first args)))\r
+     (when (funcall pred subject)\r
+       (loop for arg in (cdr args)\r
+             when (js2-object-node-p arg)\r
+             do (js2-record-object-literal\r
+                 arg (funcall qname-fn subject) (js2-node-abs-pos arg))))))\r
\r
+ (defun js2-imenu-record-backbone-extend ()\r
+   (let* ((node (js2-node-at-point (1- (point))))\r
+          (args (js2-call-node-args node))\r
+          (methods (first args))\r
+          (parent (js2-node-parent node)))\r
+     (when (js2-object-node-p methods)\r
+       (let ((subject (cond ((js2-var-init-node-p parent)\r
+                             (js2-var-init-node-target parent))\r
+                            ((js2-assign-node-p parent)\r
+                             (js2-assign-node-left parent)))))\r
+         (when subject\r
+           (js2-record-object-literal methods\r
+                                      (js2-compute-nested-prop-get subject)\r
+                                      (js2-node-abs-pos methods)))))))\r
\r
+ (defun js2-imenu-walk-ast ()\r
+   (js2-visit-ast\r
+    root\r
+    (lambda (node end-p)\r
+      (unless end-p\r
+        (cond\r
+         ((and js2-imenu-show-other-functions\r
+               (js2-object-prop-node-p node))\r
+          (js2-imenu-record-orphan-function node))\r
+         ((and js2-imenu-show-module-pattern\r
+               (js2-assign-node-p node))\r
+          (js2-imenu-record-module-pattern node)))\r
+        t))))\r
\r
+ (defun js2-imenu-record-orphan-function (node)\r
+   "Record orphan function when it's the value of NODE.\r
+ NODE must be `js2-object-prop-node'."\r
+   (when (js2-function-node-p (js2-object-prop-node-right node))\r
+     (let ((fn-node (js2-object-prop-node-right node)))\r
+       (unless (and js2-imenu-function-map\r
+                    (gethash fn-node js2-imenu-function-map))\r
+         (let ((key-node (js2-object-prop-node-left node)))\r
+           (js2-record-imenu-entry fn-node\r
+                                   (list js2-imenu-other-functions-ns\r
+                                         (js2-prop-node-name key-node))\r
+                                   (js2-node-abs-pos key-node)))))))\r
\r
+ (defun js2-imenu-record-module-pattern (node)\r
+   "Recognize and record module pattern use instance.\r
+ NODE must be `js2-assign-node'."\r
+   (let ((init (js2-assign-node-right node)))\r
+     (when (js2-call-node-p init)\r
+       (let ((target (js2-assign-node-left node))\r
+             (callt (js2-call-node-target init)))\r
+         ;; Just basic call form: (function() {...})();\r
+         ;; TODO: Handle variations without duplicating `js2-wrapper-function-p'?\r
+         (when (and (js2-paren-node-p callt)\r
+                    (js2-function-node-p (js2-paren-node-expr callt)))\r
+           (let* ((fn (js2-paren-node-expr callt))\r
+                  (blk (js2-function-node-body fn))\r
+                  (ret (car (last (js2-block-node-kids blk)))))\r
+             (when (and (js2-return-node-p ret)\r
+                        (js2-object-node-p (js2-return-node-retval ret)))\r
+               ;; TODO: Map function names when revealing module pattern is used.\r
+               (let ((retval (js2-return-node-retval ret))\r
+                     (target-qname (js2-compute-nested-prop-get target)))\r
+                 (js2-record-object-literal retval target-qname\r
+                                            (js2-node-abs-pos retval))\r
+                 (js2-record-imenu-entry fn target-qname\r
+                                         (js2-node-abs-pos target))))))))))\r
\r
+ (provide 'js2-imenu-extras)\r
diff --cc js2-mode.el
index 974bcddd05f8e99602a92abf680613d84cf37ea0,c9decde9dd9714eeafe94be36dab206bba42dedb..64ad3a5b6bbdaa554a52f9b79d64a032e8fed008
@@@ -10559,14 -10746,19 +10556,16 @@@ This ensures that the counts and `next-
  
  (defalias #'js2-echo-help #'js2-echo-error)
  
 -(defun js2-enter-key ()
 -  "Handle user pressing the Enter key."
 -  (interactive)
 -  (let ((parse-status (save-excursion
 -                        (syntax-ppss (point))))
 -        (js2-bounce-indent-p nil))
 +(defun js2-line-break (&optional soft)
 +  "Break line at point."
 +  (let ((parse-status (syntax-ppss)))
      (cond
 -     ;; check if we're inside a string
 +     ;; Check if we're inside a string.
       ((nth 3 parse-status)
-       (js2-mode-split-string parse-status))
+       (if js2-concat-multiline-strings
+           (js2-mode-split-string parse-status)
+         (insert "\n")))
 -     ;; check if inside a block comment
 +     ;; Check if inside a block comment.
       ((nth 4 parse-status)
        (js2-mode-extend-comment))
       (t
@@@ -10579,19 -10776,27 +10578,26 @@@ PARSE-STATUS is as documented in `parse
           (quote-char (nth 3 parse-status))
           (quote-string (string quote-char))
           (string-beg (nth 8 parse-status))
 -         (indent (save-match-data
 -                   (or
 -                    (save-excursion
 -                      (back-to-indentation)
 -                      (if (looking-at "\\+")
 -                          (current-column)))
 -                    (save-excursion
 -                      (goto-char string-beg)
 -                      (if (looking-back "\\+\\s-+")
 -                          (goto-char (match-beginning 0)))
 -                      (current-column))))))
+          (at-eol (eq js2-concat-multiline-strings 'eol))
-     (insert quote-char "\n")
 +         (indent (or
 +                  (save-excursion
 +                    (back-to-indentation)
 +                    (if (looking-at "\\+")
 +                        (current-column)))
 +                  (save-excursion
 +                    (goto-char string-beg)
 +                    (if (looking-back "\\+\\s-+")
 +                        (goto-char (match-beginning 0)))
 +                    (current-column)))))
+     (insert quote-char)
+     (if at-eol
+         (insert " +\n")
+       (insert "\n"))
+     ;; FIXME: This does not match the behavior of `js2-indent-line'.
      (indent-to indent)
-     (insert "+ " quote-string)
+     (unless at-eol
+       (insert "+ "))
+     (insert quote-string)
      (when (eolp)
        (insert quote-string)
        (backward-char 1))))