all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Felix H. Dahlke" <fhd@ubercode.de>
To: Daniel Colascione <dancol@dancol.org>
Cc: 8576@debbugs.gnu.org, 8584@debbugs.gnu.org
Subject: bug#8576: 23.2; js-mode doesn't support multi-line variable declarations
Date: Fri, 01 Jun 2012 09:30:21 +0200	[thread overview]
Message-ID: <4FC86F8D.7010005@ubercode.de> (raw)
In-Reply-To: <033436FB-5DA8-45FF-99CE-93491D1F5116@ubercode.de>


[-- Attachment #1.1.1: Type: text/plain, Size: 1177 bytes --]

Okay, I've prepared a patch for this, based on Dimitriv's work. I've
been using this for a while now and haven't run into any problems.

The attached patch is against the latest revision in the emacs-23
branch. I can provide a patch for emacs-24 or trunk if that's desirable.

Here's the patched version if you'd like to try it out:
https://gist.github.com/2849799

And here's one that should work in Emacs 24:
https://gist.github.com/2849595

There's still one thing that I'd like to behave differently, but I
thought I'd best discuss this first.

The patched js.el will indent the following code like this:

var foo = 5,
      bar = function() {
      };

That's fine. But if a function or an object literal come first, it
indents it like this:

var bar = function() {
},
    foo = 5;

Which I consider somewhat ugly. I'd like to make it indent as follows:

var bar = function() {
    },
    foo = 5;

That should only happen for multi var declarations, single declarations
should indent just like before:

var bar = function() {
};

Would that be acceptable? It'll make the code a bit more complicated,
but I think it's worth it.


[-- Attachment #1.1.2: Type: text/html, Size: 2041 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: indent-multiline-var-statements.patch --]
[-- Type: text/x-patch; name="indent-multiline-var-statements.patch", Size: 8656 bytes --]

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: fhd@ubercode.de-20120601072216-wsfs98ornfd1mugv
# target_branch: file:///home/fhd/Projects/emacs/emacs-23/
# testament_sha1: 101562a7a137d29600bd25ef2b014ca7e5e91ae1
# timestamp: 2012-06-01 09:22:39 +0200
# base_revision_id: handa@m17n.org-20120304120609-saqksj43mnq1tz4n
# 
# Begin patch
=== modified file 'lisp/progmodes/js.el'
--- lisp/progmodes/js.el	2012-01-11 07:52:35 +0000
+++ lisp/progmodes/js.el	2012-06-01 07:22:16 +0000
@@ -418,6 +418,16 @@
    :paren-depth most-negative-fixnum
    :type 'toplevel))
 
+(defconst js--indent-operator-re
+  (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|"
+          (regexp-opt '("in" "instanceof") 'words))
+  "Regular expression matching operators that affect indentation
+of continued expressions.")
+
+(defconst js--declaration-keyword-re
+  (regexp-opt '("var" "let" "const") 'words)
+  "Regular expression matching variable declaration keywords.")
+
 ;;; User Customization
 
 (defgroup js nil
@@ -1758,41 +1768,78 @@
          (list (cons 'c js-comment-lineup-func))))
     (c-get-syntactic-indentation (list (cons symbol anchor)))))
 
+(defun js--multiline-decl-indentation ()
+  "Returns the declaration indentation column if the current line belongs
+to a multiline declaration statement.  All declarations are lined up vertically:
+
+var a = 10,
+    b = 20,
+    c = 30;
+"
+  (let (at-opening-bracket)
+    (save-excursion
+      (back-to-indentation)
+      (when (not (looking-at js--declaration-keyword-re))
+        (when (looking-at js--indent-operator-re)
+          (goto-char (match-end 0)))
+        (while (and (not at-opening-bracket)
+                    (not (bobp))
+                    (let ((pos (point)))
+                      (save-excursion
+                        (js--backward-syntactic-ws)
+                        (or (eq (char-before) ?,)
+                            (and (not (eq (char-before) ?\;))
+                                 (and
+                                  (prog2
+                                      (skip-chars-backward "[[:punct:]]")
+                                      (looking-at js--indent-operator-re)
+                                    (js--backward-syntactic-ws))
+                                  (not (eq (char-before) ?\;))))
+                            (and (>= pos (point-at-bol))
+                                 (<= pos (point-at-eol)))))))
+          (condition-case err
+              (backward-sexp)
+            (scan-error (setq at-opening-bracket t))))
+        (when (looking-at js--declaration-keyword-re)
+          (- (1+ (match-end 0)) (point-at-bol)))))))
+
 (defun js--proper-indentation (parse-status)
   "Return the proper indentation for the current line."
-  (save-excursion
-    (back-to-indentation)
-    (cond ((nth 4 parse-status)
-           (js--get-c-offset 'c (nth 8 parse-status)))
-          ((nth 8 parse-status) 0) ; inside string
-          ((js--ctrl-statement-indentation))
-          ((eq (char-after) ?#) 0)
-          ((save-excursion (js--beginning-of-macro)) 4)
-          ((nth 1 parse-status)
-           (let ((same-indent-p (looking-at
-                                 "[]})]\\|\\_<case\\_>\\|\\_<default\\_>"))
-                 (continued-expr-p (js--continued-expression-p)))
-             (goto-char (nth 1 parse-status))
-             (if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
-                 (progn
-                   (skip-syntax-backward " ")
-		   (when (eq (char-before) ?\)) (backward-list))
-                   (back-to-indentation)
-                   (cond (same-indent-p
-                          (current-column))
-                         (continued-expr-p
-                          (+ (current-column) (* 2 js-indent-level)
-                             js-expr-indent-offset))
-                         (t
-                          (+ (current-column) js-indent-level))))
-               (unless same-indent-p
-                 (forward-char)
-                 (skip-chars-forward " \t"))
-               (current-column))))
+  (or
+   (js--multiline-decl-indentation)
+   (save-excursion
+     (back-to-indentation)
+     (cond ((nth 4 parse-status)
+            (js--get-c-offset 'c (nth 8 parse-status)))
+           ((nth 8 parse-status) 0)     ; inside string
+           ((js--ctrl-statement-indentation))
+           ((eq (char-after) ?#) 0)
+           ((save-excursion (js--beginning-of-macro)) 4)
+           ((nth 1 parse-status)
+            (let ((same-indent-p (looking-at
+                                  "[]})]\\|\\_<case\\_>\\|\\_<default\\_>"))
+                  (continued-expr-p (js--continued-expression-p)))
+              (goto-char (nth 1 parse-status))
+              (if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
+                  (progn
+                    (skip-syntax-backward " ")
+                    (when (eq (char-before) ?\)) (backward-list))
+                    (back-to-indentation)
+                    (cond (same-indent-p
+                           (current-column))
+                          (continued-expr-p
+                           (+ (current-column) (* 2 js-indent-level)
+                              js-expr-indent-offset))
+                          (t
+                           (+ (current-column) js-indent-level))))
+                (unless same-indent-p
+                  (forward-char)
+                  (skip-chars-forward " \t"))
+                (current-column))))
 
-          ((js--continued-expression-p)
-           (+ js-indent-level js-expr-indent-offset))
-          (t 0))))
+           ((js--continued-expression-p)
+            (+ js-indent-level js-expr-indent-offset))
+           (t 0)))))
 
 (defun js-indent-line ()
   "Indent the current line as JavaScript."

# Begin bundle
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
gYVlJFgF5dMCviuHWg0/8XckU4UJDjqFQ+A=

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

  reply	other threads:[~2012-06-01  7:30 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-28  7:22 bug#8576: 23.2; js-mode doesn't support multi-line variable declarations Felix H. Dahlke
2011-06-19 20:38 ` Daniel Colascione
2012-02-15 12:32   ` Felix H. Dahlke
2012-02-15 18:58     ` Stefan Monnier
2012-02-15 19:04       ` Glenn Morris
2012-02-15 19:25       ` Daniel Colascione
2012-02-15 20:41         ` Stefan Monnier
2012-04-04 11:26         ` Felix H. Dahlke
2012-06-01  7:30           ` Felix H. Dahlke [this message]
     [not found]           ` <mailman.2065.1338535901.855.bug-gnu-emacs@gnu.org>
2012-07-05 14:53             ` jaseemabid
2012-02-24  2:16 ` Dmitry Gutov
2012-03-03  1:46 ` bug#8576: " Zeth
2012-03-03  4:51   ` Daniel Colascione
2012-06-07 23:04 ` bug#8576: 23.2; " Dmitry Gutov
2012-06-08  3:13   ` Felix H. Dahlke
2012-07-17  3:16   ` Felix H. Dahlke
2012-07-05 23:02 ` bug#8576: 23.2; , " Dmitry Gutov
2012-07-06  0:52 ` Dmitry Gutov
     [not found] ` <mailman.4157.1341536766.855.bug-gnu-emacs@gnu.org>
2012-07-06  1:23   ` jaseemabid
2012-07-17  4:21 ` bug#8576: 23.2; " Dmitry Gutov
2012-07-17  4:37   ` Felix H. Dahlke
2012-07-17  5:00 ` Dmitry Gutov
2012-07-17  6:32   ` Stefan Monnier
2012-07-17  8:24     ` Felix H. Dahlke
2012-07-17  9:50       ` Stefan Monnier
2012-07-17  9:51         ` Felix H. Dahlke
2012-07-17 17:33         ` Felix H. Dahlke
2013-01-10  3:48           ` Felix H. Dahlke
2013-01-11 23:25             ` Stefan Monnier
2013-01-12  2:59               ` Felix H. Dahlke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4FC86F8D.7010005@ubercode.de \
    --to=fhd@ubercode.de \
    --cc=8576@debbugs.gnu.org \
    --cc=8584@debbugs.gnu.org \
    --cc=dancol@dancol.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.