]> code.delx.au - gnu-emacs/commitdiff
New indentation option for js-mode
authorJackson Ray Hamilton <jackson@jacksonrayhamilton.com>
Sun, 8 Mar 2015 02:01:05 +0000 (18:01 -0800)
committerJackson Ray Hamilton <jackson@jacksonrayhamilton.com>
Tue, 10 Mar 2015 17:19:07 +0000 (10:19 -0700)
* lisp/progmodes/js.el (js--proper-indentation): Add new custom option
`js-indent-first-initialiser' and a function to utilize it,
`js--maybe-goto-declaration-keyword-end'.

* test/indent/js.js: Add local variables.

* test/indent/js-indent-first-initialiser-t.js: New test for
`js-indent-first-initialiser'.

* test/indent/js-indent-first-initialiser-dynamic.js: New test for
`js-indent-first-initialiser'.

lisp/ChangeLog
lisp/progmodes/js.el
test/indent/js-indent-first-initialiser-dynamic.js [new file with mode: 0644]
test/indent/js-indent-first-initialiser-t.js [new file with mode: 0644]
test/indent/js.js

index c25f4efcdd0e93cf6f7c4d9e9da5da29cf7c29cc..c7cf53df5e0d9d782842eafd35c698b28c660115 100644 (file)
@@ -1,3 +1,17 @@
+2015-03-10  Jackson Ray Hamilton  <jackson@jacksonrayhamilton.com>
+
+       * lisp/progmodes/js.el (js--proper-indentation): Add new custom
+       option `js-indent-first-initialiser' and a function to utilize it,
+       `js--maybe-goto-declaration-keyword-end'.
+
+       * test/indent/js.js: Add local variables.
+
+       * test/indent/js-indent-first-initialiser-t.js: New test for
+       `js-indent-first-initialiser'.
+
+       * test/indent/js-indent-first-initialiser-dynamic.js: New test for
+       `js-indent-first-initialiser'.
+
 2015-03-10  Thomas Fitzsimmons  <fitzsim@fitzsim.org>
 
        * net/ldap.el (ldap-attribute-syntaxes-alist): Add LDAP attributes
index d7712e4c49e586eda19af8bf38df72c87459b97c..27e67bb77c17575bd3ef380c4c5323d7fa7f73cc 100644 (file)
@@ -509,6 +509,50 @@ getting timeout messages."
   :type 'integer
   :group 'js)
 
+(defcustom js-indent-first-initialiser nil
+  "Specially indent the first variable declaration's initialiser
+in variable statements.
+
+Normally, the first declaration's initialiser is unindented, and
+subsequent declarations have their identifiers lined up against
+the first:
+
+  var o = {
+      foo: 3
+  };
+
+  var o = {
+      foo: 3
+  },
+      bar = 2;
+
+When t, always indent the first declaration's initialiser by an
+additional level:
+
+  var o = {
+          foo: 3
+      };
+
+  var o = {
+          foo: 3
+      },
+      bar = 2;
+
+When `dynamic', if there is only one declaration, don't indent
+the first one's initialiser; otherwise, indent it.
+
+  var o = {
+      foo: 3
+  };
+
+  var o = {
+          foo: 3
+      },
+      bar = 2;"
+  :type 'boolean
+  :safe 'symbolp
+  :group 'js)
+
 ;;; KeyMap
 
 (defvar js-mode-map
@@ -1858,6 +1902,36 @@ In particular, return the buffer position of the first `for' kwd."
       (goto-char for-kwd)
       (current-column))))
 
+(defun js--maybe-goto-declaration-keyword-end (parse-status)
+  "Helper function for `js--proper-indentation'.
+Depending on the value of `js-indent-first-initialiser', move
+point to the end of a variable declaration keyword so that
+indentation is aligned to that column."
+  (cond
+   ((eq js-indent-first-initialiser t)
+    (when (looking-at js--declaration-keyword-re)
+      (goto-char (1+ (match-end 0)))))
+   ((eq js-indent-first-initialiser 'dynamic)
+    (let ((bracket (nth 1 parse-status))
+          declaration-keyword-end
+          at-closing-bracket-p
+          comma-p)
+      (when (looking-at js--declaration-keyword-re)
+        (setq declaration-keyword-end (match-end 0))
+        (save-excursion
+          (goto-char bracket)
+          (setq at-closing-bracket-p
+                (condition-case nil
+                    (progn
+                      (forward-sexp)
+                      t)
+                  (error nil)))
+          (when at-closing-bracket-p
+            (while (forward-comment 1))
+            (setq comma-p (looking-at-p ","))))
+        (when comma-p
+          (goto-char (1+ declaration-keyword-end))))))))
+
 (defun js--proper-indentation (parse-status)
   "Return the proper indentation for the current line."
   (save-excursion
@@ -1891,6 +1965,7 @@ In particular, return the buffer position of the first `for' kwd."
                    (skip-syntax-backward " ")
                    (when (eq (char-before) ?\)) (backward-list))
                    (back-to-indentation)
+                   (js--maybe-goto-declaration-keyword-end parse-status)
                    (let* ((in-switch-p (unless same-indent-p
                                          (looking-at "\\_<switch\\_>")))
                           (same-indent-p (or same-indent-p
diff --git a/test/indent/js-indent-first-initialiser-dynamic.js b/test/indent/js-indent-first-initialiser-dynamic.js
new file mode 100644 (file)
index 0000000..9c705db
--- /dev/null
@@ -0,0 +1,30 @@
+var foo = function() {
+  return 7;
+};
+
+var foo = function() {
+      return 7;
+    },
+    bar = 8;
+
+var foo = function() {
+      return 7;
+    },
+    bar = function() {
+      return 8;
+    };
+
+// Local Variables:
+// indent-tabs-mode: nil
+// js-indent-level: 2
+// js-indent-first-initialiser: dynamic
+// End:
+
+// The following test intentionally produces a scan error and should
+// be placed below all other tests to prevent awkward indentation.
+// (It still thinks it's within the body of a function.)
+
+var foo = function() {
+  return 7;
+  ,
+  bar = 8;
diff --git a/test/indent/js-indent-first-initialiser-t.js b/test/indent/js-indent-first-initialiser-t.js
new file mode 100644 (file)
index 0000000..2f08527
--- /dev/null
@@ -0,0 +1,21 @@
+var foo = function() {
+      return 7;
+    };
+
+var foo = function() {
+      return 7;
+    },
+    bar = 8;
+
+var foo = function() {
+      return 7;
+    },
+    bar = function() {
+      return 8;
+    };
+
+// Local Variables:
+// indent-tabs-mode: nil
+// js-indent-level: 2
+// js-indent-first-initialiser: t
+// End:
index f41849da2841d5ff539d3e62def3a0673818bfa4..ad7cb56a277efb8ebbb4815d12d56c730a4ff14c 100644 (file)
@@ -1,5 +1,3 @@
-// -*- js-indent-level: 2 -*-
-
 var a = 1;
 b = 2;
 
@@ -65,3 +63,8 @@ b +=
 
 baz(`http://foo.bar/${tee}`)
   .qux();
+
+// Local Variables:
+// indent-tabs-mode: nil
+// js-indent-level: 2
+// End: