]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
added sqlup for sql-mode
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Fri, 25 Nov 2016 15:59:45 +0000 (16:59 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Fri, 25 Nov 2016 15:59:45 +0000 (16:59 +0100)
- upper-cases keywords in sql.

Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
bba.org
elpa/sqlup-mode-20160911.1911/sqlup-mode-autoloads.el [new file with mode: 0644]
elpa/sqlup-mode-20160911.1911/sqlup-mode-pkg.el [new file with mode: 0644]
elpa/sqlup-mode-20160911.1911/sqlup-mode.el [new file with mode: 0644]
elpa/sqlup-mode-readme.txt [new file with mode: 0644]

diff --git a/bba.org b/bba.org
index 7f7e969060c37b5d3696c10d6435b574d1a948d5..37e29556f235ad58209ec60da1949545bd384021 100644 (file)
--- a/bba.org
+++ b/bba.org
@@ -1957,6 +1957,18 @@ On OS X you might want to run =sudo port install sqlparse= to have
 
 #+END_SRC
 
+* [[https://github.com/Trevoke/sqlup-mode.el][sqlup]]
+[2016-11-24 Thu 13:31]
+
+Takes care of doing upper-case for keywords.
+
+#+BEGIN_SRC emacs-lisp
+  (add-to-list 'load-path "~/.emacs.d/elpa/sqlup-mode-20160911.1911")
+  (require 'sqlup-mode)
+  (add-hook 'sql-mode-hook 'sqlup-mode)
+  (add-hook 'sql-interactive-mode-hook 'sqlup-mode)
+#+END_SRC
+
 * remove trailing whitespace
     [2014-09-24 Wed 16:56]
 
diff --git a/elpa/sqlup-mode-20160911.1911/sqlup-mode-autoloads.el b/elpa/sqlup-mode-20160911.1911/sqlup-mode-autoloads.el
new file mode 100644 (file)
index 0000000..1700eea
--- /dev/null
@@ -0,0 +1,27 @@
+;;; sqlup-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+\f
+;;;### (autoloads nil "sqlup-mode" "sqlup-mode.el" (22582 56274 0
+;;;;;;  0))
+;;; Generated autoloads from sqlup-mode.el
+
+(autoload 'sqlup-mode "sqlup-mode" "\
+Capitalizes SQL keywords for you.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'sqlup-capitalize-keywords-in-region "sqlup-mode" "\
+Call this function on a region to capitalize the SQL keywords therein.
+
+\(fn START-POS END-POS)" t nil)
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; sqlup-mode-autoloads.el ends here
diff --git a/elpa/sqlup-mode-20160911.1911/sqlup-mode-pkg.el b/elpa/sqlup-mode-20160911.1911/sqlup-mode-pkg.el
new file mode 100644 (file)
index 0000000..d55de96
--- /dev/null
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "sqlup-mode" "20160911.1911" "Upcase SQL words for you" 'nil :url "https://github.com/trevoke/sqlup-mode.el" :keywords '("sql" "tools" "redis" "upcase"))
diff --git a/elpa/sqlup-mode-20160911.1911/sqlup-mode.el b/elpa/sqlup-mode-20160911.1911/sqlup-mode.el
new file mode 100644 (file)
index 0000000..02585b5
--- /dev/null
@@ -0,0 +1,274 @@
+;;; sqlup-mode.el --- Upcase SQL words for you
+
+;; Copyright (C) 2014 Aldric Giacomoni
+
+;; Author: Aldric Giacomoni <trevokeNOSPAMgmail.com>
+;; URL: https://github.com/trevoke/sqlup-mode.el
+;; Package-Version: 20160911.1911
+;; Created: Jun 25 2014
+;; Version: 0.7.0
+;; Keywords: sql, tools, redis, upcase
+
+;;; License:
+
+;; This file is not part of GNU Emacs
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `M-x sqlup-mode` and just type.
+;; This mode supports the various built-in SQL modes as well as redis-mode.
+;; The capitalization is triggered when you press the following keys:
+;; * SPC
+;; * RET
+;; * ,
+;; * ;
+;; * (
+;; * '
+;;
+;; This package also provides a function to capitalize SQL keywords inside a
+;; region - always available, no need to activate the minor mode to use it:
+;;
+;; M-x sqlup-capitalize-keywords-in-region
+;;
+;; It is not bound to a keybinding. Here is an example of how you could do it:
+;;
+;; (global-set-key (kbd "C-c u") 'sqlup-capitalize-keywords-in-region)
+;;
+;; Here follows an example setup to activate `sqlup-mode` automatically:
+;;
+;; (add-hook 'sql-mode-hook 'sqlup-mode)
+;; (add-hook 'sql-interactive-mode-hook 'sqlup-mode)
+;; (add-hook 'redis-mode-hook 'sqlup-mode)
+;;
+;; Sqlup can be configured to ignore certain keywords by adding them to the list
+;; `sqlup-blacklist`. For example if you use `name` as a column name it would be
+;; annoying to have it upcased so you can prevent this by adding
+;;
+;; (add-to-list 'sqlup-blacklist "name")
+;;
+;; to your config (or do the equivalent through the `M-x customize` interface).
+
+
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'sql)
+
+
+;;; Customizable variables
+(defcustom sqlup-blacklist
+  '()
+  "List of words which should never be upcased
+
+The words must match the whole symbol. They are interpreted as plain
+strings not regexes."
+  :type '(repeat string)
+  :group 'sqlup)
+
+
+;;; Internal variables
+(defconst sqlup-trigger-characters
+  (mapcar 'string-to-char '(";"
+                            " "
+                            "("
+                            ","
+                            "'"))
+  "When the user types one of these characters,
+this mode's logic will be evaluated.")
+
+(defconst sqlup-eval-keywords
+  '((postgres "EXECUTE" "format("))
+  "List of keywords introducing eval strings, organised by dialect.")
+
+(defvar sqlup-local-keywords nil
+  "Buffer-local variable holding regexps to identify keywords.")
+
+(defvar sqlup-work-buffer nil
+  "Buffer-local variable keeping track of the name of the buffer where sqlup
+figures out what is and isn't a keyword.")
+
+
+;;;###autoload
+(define-minor-mode sqlup-mode
+  "Capitalizes SQL keywords for you."
+  :lighter " SUP"
+  (if sqlup-mode
+      (sqlup-enable-keyword-capitalization)
+    (sqlup-disable-keyword-capitalization)))
+
+(defun sqlup-enable-keyword-capitalization ()
+  "Add buffer-local hook to handle this mode's logic"
+  (set (make-local-variable 'sqlup-work-buffer) nil)
+  (set (make-local-variable 'sqlup-local-keywords) nil)
+  (add-hook 'post-command-hook 'sqlup-capitalize-as-you-type nil t))
+
+(defun sqlup-disable-keyword-capitalization ()
+  "Remove buffer-local hook to handle this mode's logic"
+  (kill-buffer (sqlup-work-buffer))
+  (remove-hook 'post-command-hook 'sqlup-capitalize-as-you-type t))
+
+(defun sqlup-capitalize-as-you-type ()
+  "If the user typed a trigger key, check if we should capitalize
+the previous word."
+  (if (sqlup-should-do-work-p)
+      (save-excursion (sqlup-maybe-capitalize-symbol -1))))
+
+(defun sqlup-should-do-work-p ()
+  "Checks whether the user pressed one of the trigger keys.
+Other than <RET>, characters are in variable sqlup-trigger-characters."
+  (and (sqlup-not-just-initialized-p)
+       (or (sqlup-user-pressed-return-p)
+           (and (sqlup-user-is-typing-p)
+                (sqlup-trigger-self-insert-character-p)))))
+
+(defun sqlup-not-just-initialized-p ()
+  (not (eq this-command 'sqlup-mode)))
+
+(defun sqlup-user-pressed-return-p ()
+  (and (< 0 (length (this-command-keys-vector)))
+       (or (equal 13 last-command-event)
+           (equal 10 last-command-event))))
+
+(defun sqlup-user-is-typing-p ()
+  (eq this-command #'self-insert-command))
+
+(defun sqlup-trigger-self-insert-character-p ()
+  (let ((sqlup-current-char last-command-event))
+    (member sqlup-current-char sqlup-trigger-characters)))
+
+(defun sqlup-maybe-capitalize-symbol (direction)
+  "DIRECTION is either 1 for forward or -1 for backward"
+  (with-syntax-table (make-syntax-table sql-mode-syntax-table)
+    ;; Give \ symbol syntax so that it is included when we get a symbol. This is
+    ;; needed so that \c in postgres is not treated as the keyword C.
+    (modify-syntax-entry ?\\ "_")
+    (forward-symbol direction)
+    (sqlup-work-on-symbol (thing-at-point 'symbol)
+                          (bounds-of-thing-at-point 'symbol))))
+
+(defun sqlup-work-on-symbol (symbol symbol-boundaries)
+  (if (and symbol
+           (sqlup-keyword-p (downcase symbol))
+           (not (sqlup-blacklisted-p (downcase symbol)))
+           (sqlup-capitalizable-p (point)))
+      (upcase-region (car symbol-boundaries)
+                     (cdr symbol-boundaries))))
+
+(defun sqlup-keyword-p (word)
+  (cl-some (lambda (reg) (string-match-p (concat "^" reg "$") word))
+           (sqlup-keywords-regexps)))
+
+(defun sqlup-blacklisted-p (word)
+  (cl-some (lambda (blacklisted) (string-match-p (concat "^" (regexp-quote blacklisted) "$") word))
+           sqlup-blacklist))
+
+(defun sqlup-capitalizable-p (point-location)
+  (let ((dialect (sqlup-valid-sql-product)))
+    (with-current-buffer (sqlup-work-buffer)
+      (goto-char point-location)
+      (and (not (sqlup-comment-p))
+           (not (and (not (sqlup-in-eval-string-p dialect))
+                     (sqlup-string-p)))))))
+
+(defun sqlup-comment-p ()
+  (and (nth 4 (syntax-ppss)) t))
+
+(defun sqlup-in-eval-string-p (dialect)
+  "Return t if we are in an eval string."
+  (save-excursion
+    (if (sqlup-string-p)
+        (progn
+          (goto-char (nth 8 (syntax-ppss)))
+          (sqlup-match-eval-keyword-p dialect)))))
+
+(defun sqlup-match-eval-keyword-p (dialect)
+  "Return t if the code just before point ends with an eval keyword valid in
+the given DIALECT of SQL."
+  (cl-some (lambda (kw) (looking-back (concat kw "\\s-*") 0))
+           (cdr (assoc dialect sqlup-eval-keywords))))
+
+(defun sqlup-string-p ()
+  (and (nth 3 (syntax-ppss)) t))
+
+;;;###autoload
+(defun sqlup-capitalize-keywords-in-region (start-pos end-pos)
+  "Call this function on a region to capitalize the SQL keywords therein."
+  (interactive "r")
+  (save-excursion
+    (goto-char start-pos)
+    (while (< (point) end-pos)
+      (sqlup-maybe-capitalize-symbol 1))))
+
+(defun sqlup-keywords-regexps ()
+  (or sqlup-local-keywords
+      (set (make-local-variable 'sqlup-local-keywords)
+           (sqlup-find-correct-keywords))))
+
+(defun sqlup-find-correct-keywords ()
+  "Depending on the major mode (redis-mode or sql-mode), find the
+correct keywords. If not, create a (hopefully sane) default based on
+ANSI SQL keywords."
+  (cond ((derived-mode-p 'redis-mode) (mapcar 'downcase (sqlup-get-redis-keywords)))
+        ((sqlup-within-sql-buffer-p) (mapcar 'car sql-mode-font-lock-keywords))
+        (t (mapcar 'car (sql-add-product-keywords
+                         (sqlup-valid-sql-product) '())))))
+
+(defun sqlup-get-redis-keywords ()
+  (if (boundp 'redis-keywords)
+      redis-keywords
+    '()))
+
+(defun sqlup-valid-sql-product ()
+  (or (and (boundp 'sql-product)
+           sql-product)
+      'ansi))
+
+(defun sqlup-within-sql-buffer-p ()
+  (and (boundp 'sql-mode-font-lock-keywords) sql-mode-font-lock-keywords))
+
+(defun sqlup-work-buffer ()
+  "Returns and/or creates an indirect buffer based on current buffer and set
+its major mode to sql-mode"
+  (or sqlup-work-buffer
+      (set (make-local-variable 'sqlup-work-buffer)
+           (with-current-buffer (clone-indirect-buffer
+                                 (generate-new-buffer-name
+                                  (format "*sqlup-%s*" (buffer-name)))
+                                 nil)
+             (sql-mode)
+             (current-buffer)))))
+
+(defadvice font-lock-mode (around sqlup-ignore-font-lock-on-indirect-buffer activate)
+  "Do not turn on jit-lock-mode on indirect buffers at all.
+Because we're using indirect buffers, the font face gets shared and when we
+change the major mode in the indirect buffer it messes with the font in the
+base buffer (the one the user cares about). This tells emacs to not enable
+font locking in an indirect buffer for which the primary buffer has
+sqlup-mode enabled."
+  (unless (and (buffer-base-buffer)
+               (with-current-buffer (buffer-base-buffer)
+                 sqlup-mode))
+    ad-do-it))
+
+(defadvice sql-set-product (after sqlup-invalidate-sqlup-keyword-cache activate)
+  "Advice sql-set-product, to invalidate sqlup's keyword cache after changing
+the sql product. We need to advice sql-set-product since sql-mode does not
+provide any hook that runs after changing the product"
+  (setq sqlup-local-keywords nil))
+
+(provide 'sqlup-mode)
+;;; sqlup-mode.el ends here
diff --git a/elpa/sqlup-mode-readme.txt b/elpa/sqlup-mode-readme.txt
new file mode 100644 (file)
index 0000000..556bdec
--- /dev/null
@@ -0,0 +1,32 @@
+`M-x sqlup-mode` and just type.
+This mode supports the various built-in SQL modes as well as redis-mode.
+The capitalization is triggered when you press the following keys:
+* SPC
+* RET
+* ,
+* ;
+* (
+* '
+
+This package also provides a function to capitalize SQL keywords inside a
+region - always available, no need to activate the minor mode to use it:
+
+M-x sqlup-capitalize-keywords-in-region
+
+It is not bound to a keybinding. Here is an example of how you could do it:
+
+(global-set-key (kbd "C-c u") 'sqlup-capitalize-keywords-in-region)
+
+Here follows an example setup to activate `sqlup-mode` automatically:
+
+(add-hook 'sql-mode-hook 'sqlup-mode)
+(add-hook 'sql-interactive-mode-hook 'sqlup-mode)
+(add-hook 'redis-mode-hook 'sqlup-mode)
+
+Sqlup can be configured to ignore certain keywords by adding them to the list
+`sqlup-blacklist`. For example if you use `name` as a column name it would be
+annoying to have it upcased so you can prevent this by adding
+
+(add-to-list 'sqlup-blacklist "name")
+
+to your config (or do the equivalent through the `M-x customize` interface).