On Github Trevoke / sqlup-talk
Or, how Ι stopped worrying and learned to love emacs
Because, why spend five minutes doing something you can spend ten years automating?
I'm Aldric Giacomoni in meatspace
I'm Trevoke in cyberspace
Find me at trevoke@gmail.com
I study martial arts (the relevance will soon dawn upon you)
Because everyone's origin story can be instructive
If you're just reading the slides, you'll see emacs functions. Just use C-h <function-name> in emacs and seize the power.
(define-minor-mode miyagi-mode "Teaches you martial arts without you even knowing it" (if miyagi-mode (message "Wax on") (message "Wax off")))
Oh sure, you just need a keyword list and you look back and see if the word is in the list.
— Eric Jones
At this point, I knew exactly nothing of emacs-lisp.
This version took over the space and open-parens keys, and replaced the last word (emacs symbol, really) with its upcased counterpart if it was found in a list.
It's Ye Olde Friendly Logger
(message "Hello, world!")
It returns the kind of thing… at point… that you specify
(thing-at-point 'symbol)
A cons cell with the buffer position for …
Start and end of… Thing… At point…
(bounds-of-thing-at-point 'symbol)
This function is used to tell emacs that you're writing an extended command (M-x miyagi)
(defun miyagi () (interactive) (message "Show me… Paint the fence!"))
(setq current-word-upcase (upcase (thing-at-point 'symbol))) (setq current-word-boundaries (bounds-of-thing-at-point 'symbol)) (delete-region (car current-word-boundaries) (cdr current-word-boundaries)) (insert current-word-upcase)
(insert "(")
I added a function to capitalize SQL keywords in a region.
(while true (message "Oh good, a `while true` loop."))
With replace-match
(search-forward-regexp "[[:alpha:]_]+" (point-max)) (replace-match "Miyagi!")
;; In Okinawa, belt mean no need rope to hold up pants. (save-excursion (goto-char (point-min)) (while (search-forward-regexp "rope" (point-max) t) (replace-match "belt")))
Now sqlup uses a post-command hook, working directly with emacs' event loop.
;; The fourth argument means "buffer-local" if non-nil (add-hook 'post-command-hook 'do-something nil t)
Arguable choice. Runs ALL THE TIME. So, early guard clauses are imperative.
(defun sqlup-should-do-work-p () (or (sqlup-user-pressed-return-p) (and (sqlup-user-is-typing-p) (sqlup-trigger-self-insert-character-p))))
(defun sqlup-user-pressed-return-p () (equal 13 (elt (this-command-keys-vector) 0)))
(defun sqlup-user-is-typing-p () (string= "self-insert-command" (symbol-name this-command)))
(sql-add-product-keywords 'ansi '())
(defun sqlup-find-correct-keywords () (if (and (boundp 'sql-mode-font-lock-keywords) sql-mode-font-lock-keywords) (mapcar 'car sql-mode-font-lock-keywords) (mapcar 'car (sql-add-product-keywords (or (and (boundp 'sql-product) sql-product) 'ansi) '()))))
This looks so simple NOW.
(defun sqlup-maybe-capitalize-last-symbol () (forward-symbol -1) (sqlup-work-on-symbol-at-point))
Wait, emacs can do WHAT?
(defun sqlup-comment-p (line) (nth 4 (syntax-ppss)))
Trust me. Write down syntax-ppss and look it up.
Okay, so if you've looked up syntax-ppsss...
Its behavior hinges on the current major mode.
So .... V3, coming next ........ Is a hack
Here's the hack.
(defun sqlup-capitalizable-p (point-location) (let ((old-buffer (current-buffer))) (with-temp-buffer (insert-buffer-substring old-buffer) (sql-mode) (goto-char point-location) (and (not (sqlup-commentp)) (not (sqlup-stringp))))))
This is the implementation I'm most ashamed of. Mostly because I've received no feedback from emacs hackers on it yet.
I got a request for redis-mode support.
Luckily, redis-mode provides a list of keywords.
(defun sqlup-find-correct-keywords () (cond ((sqlup-redis-mode-p) (mapcar 'downcase redis-keywords)) ((sqlup-within-sql-buffer-p) (mapcar 'car sql-mode-font-lock-keywords)) (t (mapcar 'car (sql-add-product-keywords (or (and (boundp 'sql-product) sql-product) 'ansi) '()))))) (defun sqlup-redis-mode-p () (string= (with-current-buffer (current-buffer) major-mode) "redis-mode"))
I AM SO EXCITED BECAUSE I GOT SOME TESTS WORKING LAST WEEK!
Yeah, sqlup is two years old, so I'm batting a thousand.