diff --git a/CHANGELOG.develop b/CHANGELOG.develop index e6807de8d..c97f9c541 100644 --- a/CHANGELOG.develop +++ b/CHANGELOG.develop @@ -3095,6 +3095,8 @@ Other: - Added key binding (thanks to Michael Hauser-Raspe): ~SPC m b c~ connect to a SQLi buffer from your saved buffer list - Added ~SPC m g~ prefix: =goto= (thanks to duianto) +- Added regional ~sqlfmt~ invocation, error handling, and formatting bindings + (thanks to 0x6362) **** Spell-checking - Added spell checking transient state (thanks to Francesc Elies Henar) - Update to flyspell-correct v0.5 (thanks to Boris Buliga) diff --git a/layers/+lang/sql/README.org b/layers/+lang/sql/README.org index 2d0b73379..868054721 100644 --- a/layers/+lang/sql/README.org +++ b/layers/+lang/sql/README.org @@ -8,6 +8,7 @@ - [[#description][Description]] - [[#features][Features:]] - [[#install][Install]] + - [[#external-dependencies][External Dependencies:]] - [[#sql-keywords-capitalization][SQL Keywords Capitalization]] - [[#sql-interactive-mode][SQL Interactive Mode]] - [[#blacklisting-keywords][Blacklisting keywords]] @@ -39,7 +40,7 @@ This layer adds support for a wide range of SQL dialects to Spacemacs. - Sybase - Vertica - Syntax-checking via [[https://github.com/purcell/sqlint][sqlint]] for ANSI SQL. -- Format code with =sqlfmt= +- Format code with [[https://github.com/mjibson/sqlfmt][=sqlfmt=]] - Snippet insertion for the more general SQL constructs. - REPL support via =SQLi= buffer. - Automatic capitalization of keywords. @@ -49,7 +50,10 @@ To use this configuration layer, add it to your =~/.spacemacs=. You will need to add =sql= to the existing =dotspacemacs-configuration-layers= list in this file. -For syntax-checking you also need to install [[https://www.ruby-lang.org/en/about/][ruby]] as well as =sqlint=. +** External Dependencies: + Some functionality, like linting, rely on external binaries: + - *Syntax Checking*: Install [[https://www.ruby-lang.org/en/about/][ruby]] and the =sqlint= gem. + - *Formatting*: Install [[https://github.com/mjibson/sqlfmt][sqlfmt]] and move it into your =$PATH= #+BEGIN_SRC ruby gem install sqlint @@ -140,4 +144,8 @@ auto-indent by setting the variable =sql-auto-indent= to =nil=. ** Code Formatting -| ~SPC m = c~ | capitalize SQL keywords in region (if capitalize is enabled) | +| Key binding | Description | +|--------------+--------------------------------------------------------------| +| ~SPC m = c~ | capitalize SQL keywords in region (if capitalize is enabled) | +| ~SPC m = ==~ | ~sqlfmt~ whole buffer | +| ~SPC m = r=~ | ~sqlfmt~ active region | diff --git a/layers/+lang/sql/local/sqlfmt/sqlfmt.el b/layers/+lang/sql/local/sqlfmt/sqlfmt.el index 63a369cf3..30c72548d 100644 --- a/layers/+lang/sql/local/sqlfmt/sqlfmt.el +++ b/layers/+lang/sql/local/sqlfmt/sqlfmt.el @@ -1,3 +1,7 @@ +(defgroup sqlfmt nil + "Easy sqlfmt invocation in Emacs" + :group 'sql) + (defcustom sqlfmt-executable "sqlfmt" "Location of sqlfmt executable." @@ -8,21 +12,43 @@ "Command line options to pass to sqlfmt." :type '(repeat string)) +(defcustom sqlfmt-reuse-error-buffer + nil + "Reuse the same buffer for sqlfmt errors, replacing content on new invocations, or generate new buffers on each invocation" + :type 'boolean) + (defun sqlfmt-buffer () (interactive) - (let* ((orig-buffer (current-buffer)) + (sqlfmt-region (point-min) (point-max))) + +(defun sqlfmt-region (start end) + "Calls sqlfmt on region" + (interactive (if (use-region-p) + (list (region-beginning) (region-end)) + (list nil nil))) + (if (not (and start end)) + (error "No region active, sqlfmt cancelled")) + (let* ((sqlfmt-buffer-base "*sqlfmt*") + (inhibit-read-only t) + (orig-buffer (current-buffer)) (orig-point (point)) - (tmpbuf (generate-new-buffer "*sqlfmt*")) - (status-code (apply #'call-process-region (point-min) (point-max) - sqlfmt-executable nil tmpbuf nil - sqlfmt-options))) + (tmpbuf (if sqlfmt-reuse-error-buffer + (get-buffer-create sqlfmt-buffer-base) + (generate-new-buffer sqlfmt-buffer-base))) + (status-code (progn + (with-current-buffer tmpbuf + (erase-buffer) + (setq buffer-read-only t)) + (apply #'call-process-region start end + sqlfmt-executable nil tmpbuf nil + sqlfmt-options)))) (deactivate-mark) - (with-current-buffer tmpbuf - (setq buffer-read-only t)) (if (eq status-code 0) (progn - (with-current-buffer tmpbuf - (copy-to-buffer orig-buffer (point-min) (point-max))) - (kill-buffer tmpbuf) - (goto-char orig-point)) + (with-current-buffer orig-buffer + (delete-region start end) + (insert-buffer tmpbuf) + (kill-buffer tmpbuf) + (goto-char orig-point)) + (message "sqlfmt applied")) (error "sqlfmt failed, see %s buffer for details." (buffer-name tmpbuf))))) diff --git a/layers/+lang/sql/packages.el b/layers/+lang/sql/packages.el index 89e1f4aaf..40639767e 100644 --- a/layers/+lang/sql/packages.el +++ b/layers/+lang/sql/packages.el @@ -185,8 +185,11 @@ (use-package sqlfmt :commands sqlfmt-buffer :init - (spacemacs/set-leader-keys-for-major-mode 'sql-mode - "=" 'sqlfmt-buffer))) + (progn + (spacemacs/declare-prefix-for-mode 'sql-mode "mf" "formatting") + (spacemacs/set-leader-keys-for-major-mode 'sql-mode + "=r" 'sqlfmt-region + "==" 'sqlfmt-buffer)))) (defun sql/init-sqlup-mode () (use-package sqlup-mode