changeset 374:1099d083a702

Indenting paren-nested SQL expressions
author Adam Chlipala <adamc@hcoop.net>
date Thu, 16 Oct 2008 17:15:21 -0400
parents 008afab3a5ce
children d3de57ce4bca
files src/elisp/urweb-mode.el tests/sql_indent.ur
diffstat 2 files changed, 68 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/elisp/urweb-mode.el	Thu Oct 16 16:24:19 2008 -0400
+++ b/src/elisp/urweb-mode.el	Thu Oct 16 17:15:21 2008 -0400
@@ -175,19 +175,23 @@
             (setq finished t)))
          ((looking-at "}")
           (incf depth))
-         ((save-excursion (backward-char 1) (or (looking-at "=>") (looking-at "->")))
+         ((save-excursion (backward-char 1) (or (looking-at "=>")
+                                                (looking-at "->")
+                                                (looking-at "<>")))
           nil)
          ((looking-at "<")
           (setq finished t))
          ((looking-at ">")
-          (if (> depth 0)
-              (if (not (re-search-backward "<" nil t))
-                  (setq finished t))
+          (cond
+           ((> depth 0)
+            (if (not (re-search-backward "<" nil t))
+                (setq finished t)))
+           (t
             (progn (backward-char 4)
                    (setq answer (not (or
                                       (looking-at "/xml")
                                       (looking-at "xml/"))))
-                   (setq finished t))))))
+                   (setq finished t)))))))
       answer)))
 
 (defun amAttribute (face)
@@ -513,7 +517,7 @@
     (current-indentation)))
 
 (defconst urweb-sql-main-starters
-  '("SELECT" "INSERT" "UPDATE" "DELETE"))
+  '("SQL" "SELECT" "INSERT" "UPDATE" "DELETE"))
 
 (defconst urweb-sql-starters
   (append urweb-sql-main-starters
@@ -525,6 +529,43 @@
 (defconst urweb-sql-starters-re
   (urweb-syms-re urweb-sql-starters))
 
+(defconst urweb-sql-main-starters-paren-re
+  (concat "(" urweb-sql-main-starters-re))
+
+(defun urweb-in-sql ()
+  "Check if the point is in a block of SQL syntax."
+  (save-excursion
+    (let ((depth 0)
+          done)
+      (while (and (not done)
+                  (re-search-backward "[()]" nil t))
+        (cond
+         ((looking-at ")")
+          (decf depth))
+         ((looking-at "(")
+          (if (looking-at urweb-sql-main-starters-paren-re)
+              (setq done t)
+            (incf depth)))))
+      (and (>= depth 0)
+           (looking-at urweb-sql-main-starters-paren-re)))))
+
+(defun urweb-sql-depth ()
+  "Check if the point is in a block of SQL syntax.
+   Returns the paren nesting depth if so, and nil otherwise."
+  (save-excursion
+    (let ((depth 0)
+          done)
+      (while (and (not done)
+                  (re-search-backward "[()]" nil t))
+        (cond
+         ((looking-at ")")
+          (decf depth))
+         ((looking-at "(")
+          (if (looking-at urweb-sql-main-starters-paren-re)
+              (setq done t)
+            (incf depth)))))
+      (max 0 depth))))
+
 (defun urweb-calculate-indentation ()
   (save-excursion
     (beginning-of-line) (skip-chars-forward "\t ")
@@ -579,13 +620,19 @@
 		   (urweb-indent-default 'noindent)
 		 (current-column))))
 
-        (and (looking-at urweb-sql-starters-re)
+        (and (or (looking-at "FROM") (looking-at urweb-sql-starters-re))
              (save-excursion
                (and (re-search-backward urweb-sql-starters-re nil t)
                     (if (looking-at urweb-sql-main-starters-re)
                         (current-column)
                       (current-indentation)))))
 
+        (and (urweb-in-sql)
+             (setq data (urweb-sql-depth))
+             (save-excursion
+               (re-search-backward urweb-sql-starters-re nil t)
+               (+ (current-column) 2 (* 2 data))))
+
 	(and (setq data (assoc sym urweb-close-paren))
 	     (urweb-indent-relative sym data))
 
--- a/tests/sql_indent.ur	Thu Oct 16 16:24:19 2008 -0400
+++ b/tests/sql_indent.ur	Thu Oct 16 17:15:21 2008 -0400
@@ -1,7 +1,7 @@
 table t1 : {A : int, B : string, C : float}
 
 val q1 = (SELECT *
-          FROM t1
+          FROM t1)
           WHERE A = 0)
 
 val a1 = (INSERT INTO t1
@@ -9,6 +9,18 @@
 
 val a2 = (UPDATE t1
           SET A = 3, B = "4", C = 5.0)
-         
+
 val a3 = (DELETE FROM t1
           WHERE B <> "good")
+
+
+val q2 = (SELECT *
+          FROM t1
+          WHERE A = 0
+            OR B = "hi"
+            AND (C <> 10.01
+              OR A = 8)
+            AND (B = B
+              OR B = B
+              AND C = C OR (D =
+                6 AND 8 = 8)))