--- /dev/null
+;;; sqlformat.el --- Reformat SQL using sqlformat or pgformatter -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018 Steve Purcell
+
+;; Author: Steve Purcell <steveNOSPAMsanityinc.com>
+;; Keywords: languages
+;; URL: https://github.com/purcell/sqlformat
+;; Package-Requires: ((emacs "24.3") (reformatter "0.3"))
+;; Package-Version: 20240325.1006
+;; Package-Revision: f1c8f864f11f
+
+;; This program 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 program 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.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides commands and a minor mode for easily reformatting SQL
+;; using external programs such as "sqlformat" and "pg_format".
+
+;; Install the "sqlparse" (Python) package to get "sqlformat",
+;; or "pgformatter" to get "pg_format",
+;; or "sqlfluff" (Python) to get "sqlfluff",
+
+;; Customise the `sqlformat-command' variable as desired. For example,
+;; to use "pgformatter" (i.e., the `pg_format` command) with
+;; two-character indent and no statement grouping,
+
+;; (setq sqlformat-command 'pgformatter)
+;; (setq sqlformat-args '("-s2" "-g"))
+
+;; Then call `sqlformat', `sqlformat-buffer' or `sqlformat-region' as
+;; convenient.
+
+;; Enable `sqlformat-on-save-mode' in SQL buffers like this:
+
+;; (add-hook 'sql-mode-hook 'sqlformat-on-save-mode)
+
+;; or locally to your project with a form in your .dir-locals.el like
+;; this:
+
+;; ((sql-mode
+;; (mode . sqlformat-on-save)))
+
+;; You might like to bind `sqlformat' or `sqlformat-buffer' to a key,
+;; e.g. with:
+
+;; (define-key 'sql-mode-map (kbd "C-c C-f") 'sqlformat)
+
+;;; Code:
+
+;; Minor mode and customisation
+
+(require 'reformatter)
+
+(defgroup sqlformat nil
+ "Reformat SQL using sqlformat, sqlfluff, or pgformatter."
+ :group 'sql)
+
+(defcustom sqlformat-command 'sqlformat
+ "Command used for reformatting.
+This command should receive SQL input via STDIN and output the
+reformatted SQL to STDOUT, returning an appropriate exit code."
+ :type '(choice (const :tag "Use \"sqlformat\"" sqlformat)
+ (const :tag "Use \"sqlfmt\"" sqlfmt)
+ (const :tag "Use \"pgformatter\"" pgformatter)
+ (const :tag "Use \"sqlfluff\"" sqlfluff)
+ (const :tag "Use \"sql-formatter\"" sql-formatter)))
+
+(defcustom sqlformat-args '()
+ "List of command-line args for reformatting command.
+For example, these args may be useful for sqlformat: (\"-k\" \"upper\")"
+ :type '(repeat string))
+
+\f
+;; Commands for reformatting
+
+;;;###autoload (autoload 'sqlformat-buffer "sqlformat" nil t)
+;;;###autoload (autoload 'sqlformat-region "sqlformat" nil t)
+;;;###autoload (autoload 'sqlformat-on-save-mode "sqlformat" nil t)
+(reformatter-define sqlformat
+ :program (pcase sqlformat-command
+ (`sqlformat "sqlformat")
+ (`sqlfmt "sqlfmt")
+ (`pgformatter "pg_format")
+ (`sqlfluff "sqlfluff")
+ (`sql-formatter "sql-formatter"))
+ :args (pcase sqlformat-command
+ (`sqlformat (append sqlformat-args '("-r" "-")))
+ (`sqlfmt (append sqlformat-args '("-")))
+ (`pgformatter (append sqlformat-args '("-")))
+ (`sqlfluff (append '("format") sqlformat-args '("-")))
+ (`sql-formatter sqlformat-args))
+ :lighter " SQLFmt"
+ :group 'sqlformat)
+
+;;;###autoload
+(defun sqlformat (beg end)
+ "Reformat SQL in region from BEG to END using `sqlformat-region'.
+If no region is active, the current statement (paragraph) is reformatted.
+Install the \"sqlparse\" (Python) package to get \"sqlformat\", or
+\"pgformatter\" to get \"pg_format\", or install the \"sqlfluff\" (Python)
+package to get \"sqlfluff\"."
+ (interactive "r")
+ (unless (use-region-p)
+ (setq beg (save-excursion
+ (backward-paragraph)
+ (skip-syntax-forward " >")
+ (point))
+ end (save-excursion
+ (forward-paragraph)
+ (skip-syntax-backward " >")
+ (point))))
+ (sqlformat-region beg end (called-interactively-p 'any)))
+
+
+(provide 'sqlformat)
+;;; sqlformat.el ends here
+++ /dev/null
-;;; string-inflection.el --- underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names -*- lexical-binding: t -*-
-
-;; Copyright (C) 2004,2014,2016,2017,2018,2020,2021,2022,2023,2024 Free Software Foundation, Inc.
-
-;; Author: akicho8 <akicho8NOSPAMgmail.com>
-;; Keywords: elisp
-;; Package-Version: 20240816.523
-;; Package-Revision: 4cc92e1ecd3d
-
-;; 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 2, 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.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; There are three main functions:
-;;
-;; 1. For Ruby -> string-inflection-ruby-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
-;; 2. For Elixir -> string-inflection-elixir-style-cycle (foo_bar => FooBar => foo_bar)
-;; 3. For Python -> string-inflection-python-style-cycle (foo_bar => FOO_BAR => FooBar => foo_bar)
-;; 4. For Java -> string-inflection-java-style-cycle (fooBar => FOO_BAR => FooBar => fooBar)
-;; 5. For All -> string-inflection-all-cycle (foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar)
-;;
-;;
-;; Example 1:
-;;
-;; (require 'string-inflection)
-;; (global-unset-key (kbd "C-q"))
-;; ;; C-q C-u is the key bindings similar to Vz Editor.
-;; (global-set-key (kbd "C-q C-u") 'my-string-inflection-cycle-auto)
-;;
-;; (defun my-string-inflection-cycle-auto ()
-;; "switching by major-mode"
-;; (interactive)
-;; (cond
-;; ;; for emacs-lisp-mode
-;; ((eq major-mode 'emacs-lisp-mode)
-;; (string-inflection-all-cycle))
-;; ;; for java
-;; ((eq major-mode 'java-mode)
-;; (string-inflection-java-style-cycle))
-;; ;; for python
-;; ((eq major-mode 'python-mode)
-;; (string-inflection-python-style-cycle))
-;; ;; for elixir
-;; ((eq major-mode 'elixir-mode)
-;; (string-inflection-elixir-style-cycle))
-;; (t
-;; ;; default
-;; (string-inflection-ruby-style-cycle))))
-;;
-;;
-;; Example 2:
-;;
-;; (require 'string-inflection)
-;;
-;; ;; default
-;; (global-set-key (kbd "C-c C-u") 'string-inflection-all-cycle)
-;;
-;; ;; for ruby
-;; (add-hook 'ruby-mode-hook
-;; '(lambda ()
-;; (local-set-key (kbd "C-c C-u") 'string-inflection-ruby-style-cycle)))
-;;
-;; ;; for elixir
-;; (add-hook 'elixir-mode-hook
-;; '(lambda ()
-;; (local-set-key (kbd "C-c C-u") 'string-inflection-elixir-style-cycle)))
-;;
-;; ;; for python
-;; (add-hook 'python-mode-hook
-;; '(lambda ()
-;; (local-set-key (kbd "C-c C-u") 'string-inflection-python-style-cycle)))
-;;
-;; ;; for java
-;; (add-hook 'java-mode-hook
-;; '(lambda ()
-;; (local-set-key (kbd "C-c C-u") 'string-inflection-java-style-cycle)))
-;;
-;; You can configure where the cursor should end up after the inflection using the
-;; `string-inflection-final-position' option.
-;;
-;; When a region is active during the inflect operation there are two effects:
-;;
-;; * If the region marks a part of a symbol the operation is only performed on that
-;; part.
-;; * If the region contains more than one symbols, the operation is performed on all
-;; the symbols in the region.
-;; * The region is preserved after the operation.
-
-;;; Code:
-
-(defgroup string-inflection nil
- "Change the casing of words."
- :group 'convenience)
-
-(defcustom string-inflection-final-position 'remain
- "Where to finish after the inflection.
-This can be `remain' – remain at the initial position but not beyond the end of the inflected string –,
-`beginning' – jump to the beginning of the inflection – or
-`end' – jump to the end of the inflection."
- :group 'string-inflection
- :type '(choice (const remain) (const beginning) (const end)))
-
-;; --------------------------------------------------------------------------------
-
-;;;###autoload
-(defun string-inflection-ruby-style-cycle ()
- "foo_bar => FOO_BAR => FooBar => foo_bar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-ruby-style-cycle-function))
-
-(fset 'string-inflection-cycle 'string-inflection-ruby-style-cycle)
-
-;;;###autoload
-(defun string-inflection-elixir-style-cycle ()
- "foo_bar => FooBar => foo_bar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-elixir-style-cycle-function))
-
-;;;###autoload
-(defun string-inflection-python-style-cycle ()
- "foo_bar => FOO_BAR => FooBar => foo_bar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-python-style-cycle-function))
-
-;;;###autoload
-(defun string-inflection-java-style-cycle ()
- "fooBar => FOO_BAR => FooBar => fooBar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-java-style-cycle-function))
-
-;;;###autoload
-(defun string-inflection-all-cycle ()
- "foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-all-cycle-function))
-
-;;;###autoload
-(defun string-inflection-toggle ()
- "toggle foo_bar <=> FooBar"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-toggle-function))
-
-;;;###autoload
-(defun string-inflection-camelcase ()
- "FooBar format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-pascal-case-function))
-
-;;;###autoload
-(defun string-inflection-lower-camelcase ()
- "fooBar format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-camelcase-function))
-
-;;;###autoload
-(defun string-inflection-underscore ()
- "foo_bar format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-underscore-function))
-
-;;;###autoload
-(defun string-inflection-capital-underscore ()
- "Foo_Bar format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-capital-underscore-function))
-
-;;;###autoload
-(defun string-inflection-upcase ()
- "FOO_BAR format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-upcase-function))
-
-;;;###autoload
-(defun string-inflection-kebab-case ()
- "foo-bar format"
- (interactive)
- (string-inflection--single-or-region #'string-inflection-kebab-case-function))
-
-(fset 'string-inflection-lisp 'string-inflection-kebab-case)
-
-;; --------------------------------------------------------------------------------
-
-(defun string-inflection--count-symbols-between-start-and-end (start end)
- "Count the symbols between START and END."
- (let ((symbol-num 0))
- (goto-char start)
- (save-excursion
- (while (< (point) end)
- (setq symbol-num (1+ symbol-num))
- (forward-symbol 1)))
- symbol-num))
-
-(defun string-inflection--single-or-region (inflect-func)
- "Perform INFLECT-FUNC depending on if in region or single."
- (if (use-region-p)
- (string-inflection--region inflect-func)
- (string-inflection--single inflect-func)))
-
-(defun string-inflection--single (inflect-func)
- "Perform INFLECT-FUNC for a single occurrence."
- (let ((orig-point (point)))
- (insert (funcall inflect-func (string-inflection-get-current-word)))
- (pcase string-inflection-final-position
- ('remain (goto-char (min orig-point (cdr (bounds-of-thing-at-point 'symbol)))))
- ('beginning (goto-char (car (bounds-of-thing-at-point 'symbol)))))))
-
-(defun string-inflection--region (inflect-func)
- "Perform INFLECT-FUNC for all occurrences in the region."
- (let ((orig-point (point))
- (start (region-beginning))
- (end (region-end)))
- (dotimes (_ (string-inflection--count-symbols-between-start-and-end start end))
- (let ((orig-length (length (symbol-name (symbol-at-point)))))
- (insert (funcall inflect-func (string-inflection-get-current-word-limited-by start end)))
- (setq end (+ end (- (length (symbol-name (symbol-at-point))) orig-length)))
- (forward-symbol 1)
- (if-let* ((bounds (bounds-of-thing-at-point 'symbol)))
- (goto-char (car bounds)))))
- (let ((new-region
- (pcase string-inflection-final-position
- ('remain (if (/= orig-point start) (cons start end) (cons end start)))
- ('beginning (cons end start))
- ('end (cons start end)))))
- (set-mark (car new-region))
- (goto-char (cdr new-region)))
- (activate-mark)
- (setq deactivate-mark nil)))
-
-(defun string-inflection-get-current-word ()
- "Gets the symbol near the cursor"
- (interactive)
- (if-let* ((bounds (bounds-of-thing-at-point 'symbol))
- (start (car bounds))
- (end (cdr bounds))
- (str (buffer-substring start end)))
- (progn
- (delete-region start end)
- str)
- ""))
-
-(defun string-inflection-get-current-word-limited-by (reg-start reg-end)
- "Gets the symbol near the cursor limited by REG-START and REG-END."
- (interactive)
- (if-let* ((bounds (bounds-of-thing-at-point 'symbol))
- (start (max (car bounds) reg-start))
- (end (min (cdr bounds) reg-end))
- (str (buffer-substring start end)))
- (progn
- (delete-region start end)
- str)
- ""))
-
-;; --------------------------------------------------------------------------------
-
-(defun string-inflection-pascal-case-function (str)
- "foo_bar => FooBar"
- (setq str (string-inflection-underscore-function str))
- (mapconcat 'capitalize (split-string str "_") ""))
-
-(fset 'string-inflection-upper-camelcase-function 'string-inflection-pascal-case-function)
-
-(defun string-inflection-camelcase-function (str)
- "foo_bar => fooBar"
- (setq str (split-string (string-inflection-underscore-function str) "_"))
- (concat (downcase (car str))
- (mapconcat 'capitalize (cdr str) "")))
-
-(fset 'string-inflection-lower-camelcase-function 'string-inflection-camelcase-function)
-
-(defun string-inflection-upcase-function (str)
- "FooBar => FOO_BAR"
- (upcase (string-inflection-underscore-function str)))
-
-(defun string-inflection-underscore-function (str)
- "FooBar => foo_bar"
- (let ((case-fold-search nil))
- (setq str (replace-regexp-in-string "\\([[:lower:][:digit:]]\\)\\([[:upper:]]\\)" "\\1_\\2" str))
- (setq str (replace-regexp-in-string "\\([[:upper:]]+\\)\\([[:upper:]][[:lower:]]\\)" "\\1_\\2" str))
- (setq str (replace-regexp-in-string "-" "_" str)) ; FOO-BAR => FOO_BAR
- (setq str (replace-regexp-in-string "_+" "_" str))
- (downcase str)))
-
-(defun string-inflection-capital-underscore-function (str)
- "foo_bar => Foo_Bar"
- (setq str (string-inflection-underscore-function str))
- (mapconcat 'capitalize (split-string str "_") "_"))
-
-(defun string-inflection-kebab-case-function (str)
- "foo_bar => foo-bar"
- (let ((case-fold-search nil))
- (setq str (string-inflection-underscore-function str))
- (setq str (replace-regexp-in-string "_" "-" str))))
-
-(defun string-inflection-all-cycle-function (str)
- "foo_bar => FOO_BAR => FooBar => fooBar => foo-bar => Foo_Bar => foo_bar
- foo => FOO => Foo => foo"
- (cond
- ;; foo => FOO
- ((string-inflection-word-p str)
- (string-inflection-upcase-function str))
- ;; foo_bar => FOO_BAR
- ((string-inflection-underscore-p str)
- (string-inflection-upcase-function str))
- ;; FOO_BAR => FooBar
- ((string-inflection-upcase-p str)
- (string-inflection-pascal-case-function str))
- ;; FooBar => fooBar
- ;; Foo => foo
- ((string-inflection-pascal-case-p str)
- (string-inflection-camelcase-function str))
- ;; fooBar => foo-bar
- ((string-inflection-camelcase-p str)
- (string-inflection-kebab-case-function str))
- ;; foo-bar => Foo_Bar
- ((string-inflection-kebab-case-p str)
- (string-inflection-capital-underscore-function str))
- ;; foo-bar => foo_bar
- (t
- (string-inflection-underscore-function str))))
-
-(defun string-inflection-ruby-style-cycle-function (str)
- "foo_bar => FOO_BAR => FooBar => foo_bar"
- (cond
- ((string-inflection-underscore-p str)
- (string-inflection-upcase-function str))
- ((string-inflection-upcase-p str)
- (string-inflection-pascal-case-function str))
- (t
- (string-inflection-underscore-function str))))
-
-(defalias 'string-inflection-python-style-cycle-function
- 'string-inflection-ruby-style-cycle-function)
-
-(defun string-inflection-elixir-style-cycle-function (str)
- "foo_bar => FooBar => foo_bar"
- (cond
- ((string-inflection-underscore-p str)
- (string-inflection-pascal-case-function str))
- (t
- (string-inflection-underscore-function str))))
-
-(defun string-inflection-java-style-cycle-function (str)
- "fooBar => FOO_BAR => FooBar => fooBar"
- (cond
- ((string-inflection-underscore-p str)
- (string-inflection-upcase-function str))
- ((string-inflection-camelcase-p str)
- (string-inflection-upcase-function str))
- ((string-inflection-upcase-p str)
- (string-inflection-pascal-case-function str))
- (t
- (string-inflection-camelcase-function str))))
-
-;; Toggle function. But cycle function.
-(defun string-inflection-toggle-function (str)
- "Not so much the case that in all caps when using normal foo_bar <--> FooBar"
- (cond
- ((string-inflection-underscore-p str)
- (string-inflection-pascal-case-function str))
- ((string-inflection-pascal-case-p str)
- (string-inflection-camelcase-function str))
- (t
- (string-inflection-underscore-function str))))
-
-;; --------------------------------------------------------------------------------
-
-(defun string-inflection-word-p (str)
- "if foo => t"
- (let ((case-fold-search nil))
- (string-match "\\`[[:lower:][:digit:]]+\\'" str)))
-
-(defun string-inflection-underscore-p (str)
- "if foo_bar => t"
- (let ((case-fold-search nil))
- (string-match "\\`[[:lower:][:digit:]_]+\\'" str)))
-
-(defun string-inflection-upcase-p (str)
- "if FOO_BAR => t"
- (let ((case-fold-search nil))
- (string-match "\\`[[:upper:][:digit:]_]+\\'" str)))
-
-(defun string-inflection-pascal-case-p (str)
- "if FooBar => t"
- (let ((case-fold-search nil))
- (and
- (string-match "[[:lower:]]" str)
- (string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]]+\\'" str))))
-
-(fset 'string-inflection-upper-camelcase-p 'string-inflection-pascal-case-p)
-
-(defun string-inflection-camelcase-p (str)
- "if fooBar => t"
- (let ((case-fold-search nil))
- (and
- (string-match "[[:upper:]]" str)
- (string-match "\\`[[:lower:]][[:lower:][:upper:][:digit:]]+\\'" str))))
-
-(fset 'string-inflection-lower-camelcase-p 'string-inflection-camelcase-p)
-
-(defun string-inflection-kebab-case-p (str)
- "if foo-bar => t"
- (string-match "-" str))
-
-(defun string-inflection-capital-underscore-p (str)
- "if Foo_Bar => t"
- (let ((case-fold-search nil))
- (and
- (string-match "_" str)
- (string-match "\\`[[:upper:]][[:lower:][:upper:][:digit:]_]+\\'" str))))
-
-(provide 'string-inflection)
-;;; string-inflection.el ends here
+++ /dev/null
-;; -*- lexical-binding: t; -*-
-;;; sqlformat.el --- Use sqlformat to make SQL readable in Emacs
-
-;; Copyright 2015, steckerhalter
-;; Copyright 2015, Friedrich Paetzke <paetzkeNOSPAMfastmail.fm>
-
-;; 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.
-;; <http://www.gnu.org/licenses/>.
-
-;;; 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-no-properties 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