From: Andreas Gerler Date: Fri, 19 Aug 2016 14:32:08 +0000 (+0200) Subject: added sqlformat X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=d94ce0d6bbac2bcd668d69d93a991a6849eca1c8;p=emacsconfig.git added sqlformat - to make SQL more readable. --- diff --git a/bba.org b/bba.org index ab0d5693..8348ec8b 100644 --- a/bba.org +++ b/bba.org @@ -1702,6 +1702,24 @@ Combine abbrev with Ispell: #+END_SRC +* [[https://github.com/steckerhalter/sqlformat.el][sqlformat]] +[2016-08-19 Fri 16:20] + +Provides the sqlformat command, which uses the external Python tool +sqlformat to format SQL in the current buffer. + +Be aware that if the buffer is mixed code/SQL then you need to select +the SQL so that sqlformat only operates on the region, otherwise it +acts on the whole buffer. + +On OS X you might want to run =sudo port install sqlparse= to have +=sqlformat= available. + +#+BEGIN_SRC emacs-lisp + (load-file (expand-file-name "~/.emacs.d/lisp/sqlformat.el")) + +#+END_SRC + * remove trailing whitespace [2014-09-24 Wed 16:56] diff --git a/lisp/sqlformat.el b/lisp/sqlformat.el new file mode 100644 index 00000000..bd058e39 --- /dev/null +++ b/lisp/sqlformat.el @@ -0,0 +1,126 @@ +;;; sqlformat.el --- Use sqlformat to make SQL readable in Emacs + +;; Copyright 2015, steckerhalter +;; Copyright 2015, Friedrich Paetzke + +;; Author: steckerhalter +;; URL: https://github.com/steckerhalter/sqlformat.el +;; Keywords: sql format region buffer + +;; This file is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; . + +;;; Commentary: + +;; Provides the `sqlformat' commmand, which use the external +;; "sqlformat" tool to format SQL in the current region or buffer. + +;; it is based on `format-sql.el' by Friedrich Paetzke, see: +;; https://github.com/paetzke/format-sql.el +;; but uses the sqlformat command instead of format-sql + +;;; Code: + +(defgroup sqlformat nil + "Use sqlformat to sort the imports in a Python buffer." + :group 'convenience + :prefix "sqlformat-") + +(defcustom sqlformat-options '("--reindent" + "--keywords" "upper" + "--identifiers" "lower") + "Options used for sqlformat." + :group 'sqlformat + :type '(repeat (string :tag "option"))) + +(defun sqlformat-apply-rcs-patch (patch-buffer) + "Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer." + (let ((target-buffer (current-buffer)) + (line-offset 0)) + (save-excursion + (with-current-buffer patch-buffer + (goto-char (point-min)) + (while (not (eobp)) + (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)") + (error "invalid rcs patch or internal error in sqlformat-apply-rcs-patch")) + (forward-line) + (let ((action (match-string 1)) + (from (string-to-number (match-string 2))) + (len (string-to-number (match-string 3)))) + (cond + ((equal action "a") + (let ((start (point))) + (forward-line len) + (let ((text (buffer-substring start (point)))) + (with-current-buffer target-buffer + (setq line-offset (- line-offset len)) + (goto-char (point-min)) + (forward-line (- from len line-offset)) + (insert text))))) + ((equal action "d") + (with-current-buffer target-buffer + (goto-char (point-min)) + (forward-line (- from line-offset 1)) + (setq line-offset (+ line-offset len)) + (kill-whole-line len))) + (t + (error "invalid rcs patch or internal error in sqlformat-apply-rcs-patch"))))))))) + +(defun sqlformat-replace-region (filename) + (delete-region (region-beginning) (region-end)) + (insert-file-contents filename)) + +;;;###autoload +(defun sqlformat (&optional start end) + "Uses the `sqlformat' tool to reformat the current buffer or region. +If a region is active it operates on that, otherwise on the buffer." + (interactive "r") + (when (not (executable-find "sqlformat")) + (error "\"sqlformat\" command not found. Install sqlformat with \"pip install sqlparse\"")) + + (let* ((tmpfile (make-temp-file "sqlformat" nil ".sql")) + (patchbuf (get-buffer-create "*sqlformat patch*")) + (resultbuf (get-buffer-create "*sqlformat result*")) + (coding-system-for-read 'utf-8) + (coding-system-for-write 'utf-8)) + + (with-current-buffer resultbuf + (setq buffer-read-only nil) + (erase-buffer)) + (with-current-buffer patchbuf + (erase-buffer)) + + (if (use-region-p) + (write-region start end tmpfile) + (write-region nil nil tmpfile)) + + (if (zerop (eval `(call-process "sqlformat" nil resultbuf nil ,@sqlformat-options tmpfile))) + (progn + (with-current-buffer resultbuf + (write-region nil nil tmpfile)) + (if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile)) + (progn + (kill-buffer resultbuf) + (message "Buffer is already sqlformated")) + (if (use-region-p) + (progn + (delete-region start end) + (insert-file-contents tmpfile)) + (sqlformat-apply-rcs-patch patchbuf)) + (kill-buffer resultbuf) + (message "Applied sqlformat."))) + (error "Could not apply sqlformat. Check *sqlformat result* for details")) + (kill-buffer patchbuf) + (delete-file tmpfile))) + +(provide 'sqlformat) + +;;; sqlformat.el ends here