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

在Emacs中以另一种主要模式缩进SQL,sql,emacs,elisp,indentation,Sql,Emacs,Elisp,Indentation,我经常写一些脚本来做一些事情,通常涉及SQL,以不同的主要模式。可能是这样的: sql = """ SELECT * FROM table WHERE row_awesomeness > 1000 """ 我希望能够对SQL进行属性缩进,因此它看起来像: sql = """ SELECT * FROM table WHERE row_awesomeness > 1000 """ 我对所使用的SQL缩进算法并不挑剔,但我根本无法让任何东西工作。我不是一个超级粉丝,但我甚至不能

我经常写一些脚本来做一些事情,通常涉及SQL,以不同的主要模式。可能是这样的:

sql = """
SELECT * FROM table WHERE row_awesomeness > 1000
"""
我希望能够对SQL进行属性缩进,因此它看起来像:

sql = """
SELECT *
  FROM table
 WHERE row_awesomeness > 1000
"""
我对所使用的SQL缩进算法并不挑剔,但我根本无法让任何东西工作。我不是一个超级粉丝,但我甚至不能在一个新的缓冲区中使用它。函数sql indent buffer与我的第一个描述没有任何改变,我绝对希望SELECT、from和WHERE子句在单独的行上,我认为这是相当标准的


理想情况下,我会突出显示包含SQL的区域,并执行类似于M-x SQL缩进区域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我的sql缩进区域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;
")
我使用polymode

(defun python/init-polymode ()
  (use-package polymode
    :ensure t
    :mode ("\.py$" . poly-python-sql-mode)
    :config
    (setq polymode-prefix-key (kbd "C-c n"))
    (define-hostmode poly-python-hostmode :mode 'python-mode)
    (add-hook 'python-mode-hook 'poly-python-sql-mode)
    (add-hook 'python-mode-hook 'define-python-keybindings))

  (define-innermode poly-sql-expr-python-innermode
    :mode 'sql-mode
    :head-matcher (rx "r" (= 3 (char "\"'")) (* (any space)))
    :tail-matcher (rx (= 3 (char "\"'")))
    :head-mode 'host
    :tail-mode 'host
    )
然后我定义了两个可以应用于当前块的函数

(defun python-indent-sql-chunk ()
  (interactive)
  (let* ((chunk (pm-chunk-range))
         (beg (car chunk))
         (end (cdr chunk)))
    (sqlformat-region beg end)
    (indent-region-line-by-line beg end)
    (delete-trailing-whitespace beg end)
    (sqlup-capitalize-keywords-in-region beg end)))

为了使每次按enter键时都发生这种情况:

defun sql-format-chunk ()
  (interactive)
  (newline-and-indent)
  (python-indent-sql-chunk)

(define-key sql-mode-map (kbd "RET") 'sql-format-chunk)

您应该检查mumamo,它支持多种主要模式。因为我不用,所以我不能给你更多的指导
defun sql-format-chunk ()
  (interactive)
  (newline-and-indent)
  (python-indent-sql-chunk)

(define-key sql-mode-map (kbd "RET") 'sql-format-chunk)