branch: externals/sql-indent
commit 036bc14a347db12e89a7b51664c16e482ba66530
Author: Alex Harsanyi <[email protected]>
Commit: Alex Harsanyi <[email protected]>

    Separate indentation of AND, OR into a separate rule.
---
 customize-indentation.md | 40 ++++++++++++++++++++++++---------
 sql-indent.el            | 58 ++++++++++++++++++++++++------------------------
 2 files changed, 59 insertions(+), 39 deletions(-)

diff --git a/customize-indentation.md b/customize-indentation.md
index be986b8..aa7b5b3 100644
--- a/customize-indentation.md
+++ b/customize-indentation.md
@@ -26,9 +26,9 @@ them up in your init.el file before loading the package.  For 
example:
         (delete-clause 0)
         (update-clause 0)
         ,@sqlind-default-indentation-offsets-alist))
-        
-    (add-hook 'sql-mode-hook 
-        (lambda () 
+
+    (add-hook 'sql-mode-hook
+        (lambda ()
            (setq sqlind-indentation-offsets-alist
                my-sql-indentation-offsets-alist)))
 
@@ -100,34 +100,55 @@ The following functions are available as part of the 
package:
 
 * `sqlind-use-previous-line-indentation` -- discards the current offset and
   returns the indentation column of the previous line
-  
+
 * `sqlind-lineup-to-anchor` -- discards the current offset and returns the
   column of the anchor point, which may be different than the indentation
   column
-  
+
 * `sqlind-lineup-open-paren-to-anchor` -- if the line starts with an open
   paren, discard the current offset and return the column of the anchor point.
-  
+
 * `sqlind-lineup-close-paren-to-open` -- if the line starts with a close
   paren, discard the current offset and return the column of the corresponding
   open paren.
-  
+
 * `sqlind-adjust-comma` -- if the line starts with a comma, adjust the current
   offset so that the line is indented to the first word character.  For
   example, if added to a 'select-column' syntax indentation rule, it will
   indent as follows:
-  
+
 ```sql
 select col1
    ,   col2 -- align "col2" to "col1"
 from my_table;
 ```
 
+* `sqlind-adjust-and-or` -- line up AND and OR logic operators with the end of
+  the where clause.  This rule needs to be added to the in-select-clause
+  syntax, after the `sqlind-lineup-to-clause-end`.  For example, the following
+  setup:
+
+```elisp
+(defvar my-sql-indentation-offsets-alist
+  `((in-select-clause   sqlind-lineup-to-clause-end
+                        sqlind-adjust-and-or)
+    ,@sqlind-default-indentation-offsets-alist))
+```
+
+Will indent SQL like this:
+
+```sql
+select *
+  from table
+ where a = b
+   and c = d; -- AND clause sits under the where clause
+```
+
 * `sqlind-lineup-into-nested-statement` -- discard the current offset and
   return the column of the first word inside a nested statement.  This rule
   makes sense only for 'nested-statement-continuation' syntax indentation
   rule, it will indent as follows:
-  
+
 ```sql
 (    a,
      b  -- b is aligned with a
@@ -296,4 +317,3 @@ clause (select, from, where, etc) in which the current 
point is.
 
 * `(in-update-clause CLAUSE)` -- line is inside an update CLAUSE, which can be
   "update", "set" or "where"
-
diff --git a/sql-indent.el b/sql-indent.el
index 2df5fe9..d8b82df 100644
--- a/sql-indent.el
+++ b/sql-indent.el
@@ -61,6 +61,7 @@
 ;;; Code:
 
 (require 'sql)
+(require 'align)
 (eval-when-compile (require 'cc-defs))  ; for c-point
 
 ;;;; General setup
@@ -1427,7 +1428,7 @@ clause (select, from, where, etc) in which the current 
point is.
     (select-join-condition          ++)
     (select-table                   sqlind-indent-select-table)
     (select-table-continuation      sqlind-indent-select-table +)
-    (in-select-clause               sqlind-lineup-to-clause-end)
+    (in-select-clause               sqlind-lineup-to-clause-end 
sqlind-adjust-and-or)
     (insert-clause                  sqlind-right-justify-clause)
     (in-insert-clause               sqlind-lineup-to-clause-end)
     (delete-clause                  sqlind-right-justify-clause)
@@ -1672,34 +1673,33 @@ indentation so that:
 If the clause is on a line by itself, the current line is
 indented by `sqlind-basic-offset', otherwise the current line is
 indented so that it starts in next column from where the clause
-keyword ends.
-
-An exception is made for a 'where' clause: if the current line
-starts with an 'and' or an 'or' the line is indented so that the
-and/or is right justified with the 'where' clause."
-  (let ((origin (point)))
-    (destructuring-bind ((_sym clause) . anchor) (car syntax)
-      (save-excursion
-       (goto-char anchor)
-       (forward-char (1+ (length clause)))
-       (skip-syntax-forward " ")
-       (if (or (looking-at sqlind-comment-start-skip)
-               (looking-at "$"))
-           ;; if the clause is on a line by itself, indent this line
-           ;; with a sqlind-basic-offset
-           (+ base-indentation sqlind-basic-offset)
-           ;; otherwise, align to the end of the clause, with a few
-           ;; exceptions
-           (let ((indentation (current-column)))
-             (goto-char origin)
-             (back-to-indentation)
-             ;; when the line starts with an 'and' or an 'or', line
-             ;; it up so that the logic operator sits right under the
-             ;; where clause
-             (when (and (equal clause "where")
-                        (looking-at "and\\|or"))
-               (decf indentation (1+ (- (match-end 0) (match-beginning 0)))))
-             indentation))))))
+keyword ends."
+  (destructuring-bind ((_sym clause) . anchor) (car syntax)
+    (save-excursion
+      (goto-char anchor)
+      (forward-char (1+ (length clause)))
+      (skip-syntax-forward " ")
+      (if (or (looking-at sqlind-comment-start-skip)
+              (looking-at "$"))
+          ;; if the clause is on a line by itself, indent this line with a
+          ;; sqlind-basic-offset
+          (+ base-indentation sqlind-basic-offset)
+        ;; otherwise, align to the end of the clause, with a few exceptions
+        (current-column)))))
+
+(defun sqlind-adjust-and-or (syntax base-indentation)
+  "Align an AND or OR operator with the end of the WHERE clause.
+If this rule is added to the 'in-select-clause syntax after the
+`sqlind-lineup-to-clause-end' rule, it will adjust lines starting
+with AND or OR to be aligned so they sit under the WHERE clause."
+  (save-excursion
+    (back-to-indentation)
+    (destructuring-bind ((sym clause) . anchor) (car syntax)
+      (if (and (eq sym 'in-select-clause)
+               (equal clause "where")
+               (looking-at "and\\|or"))
+          (- base-indentation (1+ (- (match-end 0) (match-beginning 0))))
+        base-indentation))))
 
 (defun sqlind-right-justify-clause (syntax base-indentation)
   "Return an indentation which right-aligns the first word at

Reply via email to