Indenting SQL in another major mode in Emacs

假如想象 提交于 2019-12-05 02:08:55

问题


Oftentimes I'm writing some script to do some stuff, often involving SQL, in a different major mode. Maybe it looks like this:

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

I'd like to be able to indent the SQL propertly, so it looks something like:

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

I'm not picky about the SQL indentation algorithm used, but I can't get anything to work at all. I'm not a huge fan of sql-indent.el, but I can't even get that to work using it in a new buffer (the function sql-indent-buffer doesn't change anything from my first description, and I definitely want the SELECT, FROM and WHERE clauses to be on separate lines which I think is pretty standard).

Ideally, I would highlight the region that contains the SQL and do something like M-x sql-indent-region RET - no need for something that indents upon a newline.


回答1:


This is one way of doing it (lightly tested, using the indenting function you mentioned -- I don't work with SQL but you should be able to plug in any function in its place as long as it operates on the whole buffer):

(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))))

If I mark the following sql query (from "SELECT" through "f2.PLAYERID"), embedded in an elisp string, and do 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;
")

I end up with:

(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;
")


来源:https://stackoverflow.com/questions/19748345/indenting-sql-in-another-major-mode-in-emacs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!