I've got kind of deja vu from How align tabs inside block of string?. ;-)
Almost everything you need is already mentioned there.
The only thing left to say is that you can combine indentation and alignment by setting
indent-line-function to a function that does both.
Just press tab for indentation and you get the current line not only indented but also the current section/group aligned.
I am using
sql-indent-line from the package
sql-indent again. So the
AND is indented relative to
(defun ReneFroger-indent-relative-and-align ()
"Like `sql-indent-line' but also calls `align'."
(prog1 ;; variable `indent-line-function' wants `noindent' when indentation is not possible
(align nil nil)))
'((space (regexp . "^\\s-*[[:alnum:]]+\\(\\s-+\\)[^[:space:]]")) ;; alignment of the first second word on line
(equal-sign (regexp . "\\(\\s-*\\)=") (separate . group))) ;; alignment of assignment groups
"Alignment rules for `sql-mode'."
(defun ReneFroger-sql-mode-hook-function ()
"All your add-ons to `sql-mode'."
(setq indent-tabs-mode nil) ;; Do as you like. When set to t the distance of = is rather large (depending on `tab-width' or `tab-to-tab-stop').
(setq align-mode-rules-list align-sql-indent-rules-list) ;; HERE we say how to align in `sql-mode'
(setq indent-line-function #'ReneFroger-indent-relative-and-align))
(add-hook 'sql-mode-hook #'ReneFroger-sql-mode-hook-function)
Ah yes, before you ask: You can also add
(sqlup-mode 1) to
ReneFroger-sql-mode-hook-function to get SQL keywords capitalized.
Note, that you can also add the alignment rules to
align-rules-list instead of
align-mode-rules-list. The difference is that
align-rules-list is global while
align-mode-rules-list is buffer local (set when the major mode is activated).
In the case that you use
align-rules-list you should add the
modes attribute to the alignment rule, e.g.,
I think adding the alignment rules to
align-rules-list is the official way. But, it makes the customization a bit more cumbersome.