在Emacs中以另一种主要模式缩进SQL

我经常写一些脚本来做一些事情,通常涉及SQL,在不同的主要模式.也许它看起来像这样:

sql = """
SELECT * FROM table WHERE row_awesomeness > 1000
"""

我希望能够在SQL属性上缩进,所以它看起来像:

sql = """
SELECT *
  FROM table
 WHERE row_awesomeness > 1000
"""

我对使用的SQL缩进算法并不挑剔,但我根本无法工作.我不是sql-indent.el的忠实粉丝,但我甚至无法在新的缓冲区中使用它(函数sql-indent-buffer不会改变我的第一个描述,我绝对想要SELECT ,FROM和WHERE子句在不同的行上,我认为这是非常标准的).

理想情况下,我会突出显示包含SQL的区域并执行类似M-x sql-indent-region RET的操作 – 不需要在换行符上缩进.

最佳答案 这是一种方法(使用您提到的缩进功能进行轻微测试 – 我不使用SQL,但只要它在整个缓冲区上运行,您应该能够插入任何函数):

(defun my-sql-indent-region (beg end)
  "Indent the SQL statement in the region."
  (interactive "*r")
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      ;; http://www.emacswiki.org/emacs/download/sql-indent.el
      (sql-indent-buffer))))

如果我标记以下sql查询(从“SELECT”到“f2.PLAYERID”),则嵌入在elisp中
字符串,并执行M-x my-sql-indent-region RET:

(defvar my-sql-query "
SELECT p1.PLAYERID, 
f1.PLAYERNAME, 
  p2.PLAYERID, 
f2.PLAYERNAME 
FROM PLAYER f1, 
                   PLAYER f2, 
    PLAYS p1 
    FULL OUTER JOIN PLAYS p2 
        ON p1.PLAYERID < p2.PLAYERID 
    AND p1.TEAMID = p2.TEAMID 
GROUP BY p1.PLAYERID, 
    f1.PLAYERID, 
   p2.PLAYERID, 
    f2.PLAYERID 
HAVING Count(p1.PLAYERID) = Count(*) 
  AND Count(p2.PLAYERID) = Count(*) 
    AND p1.PLAYERID = f1.PLAYERID 
AND p2.PLAYERID = f2.PLAYERID;
")

我最终得到:

(defvar my-sql-query "
SELECT p1.PLAYERID, 
    f1.PLAYERNAME, 
    p2.PLAYERID, 
    f2.PLAYERNAME 
FROM PLAYER f1, 
    PLAYER f2, 
    PLAYS p1 
    FULL OUTER JOIN PLAYS p2 
    ON p1.PLAYERID < p2.PLAYERID 
    AND p1.TEAMID = p2.TEAMID 
GROUP BY p1.PLAYERID, 
    f1.PLAYERID, 
    p2.PLAYERID, 
    f2.PLAYERID 
HAVING Count(p1.PLAYERID) = Count(*) 
    AND Count(p2.PLAYERID) = Count(*) 
    AND p1.PLAYERID = f1.PLAYERID 
    AND p2.PLAYERID = f2.PLAYERID;
")
点赞