2

Is there a shortcut key or command in Emacs (25.x under Unbuntu 18.04 LTS) to restart the sql-postgres process?

I need to quit and restart sql-postgres very often (for debugging purposes). Currently, my work flow is to

  1. switch to the sql-postgres window/buffer
  2. type \q
  3. M-x sql-postgres again.

This is OK for occasional use, but I was wondering if there's a faster way to restart the database connection in one key combination.

phils
  • 48,657
  • 3
  • 76
  • 115
tinlyx
  • 1,276
  • 1
  • 12
  • 27

1 Answers1

2

I like to use the following approach in REPLs to make the common "g to refresh the buffer" binding start the process when there isn't one running. This initial simpler code only works when you are in the SQLi buffer, and you have exited the REPL already, and wish to create a new connection.

(with-eval-after-load "sql"
  (define-key sql-interactive-mode-map "g"
    `(menu-item "" my-sqli-restart
                :filter ,(lambda (cmd)
                           (unless (get-buffer-process (current-buffer))
                             cmd)))))

(defun my-sqli-restart (&optional arg)
  "Restart `sql-product-interactive' using existing settings.

With a prefix argument, prompt for the connection settings."
  (interactive "P")
  (if arg
      (call-interactively 'sql-product-interactive)
    (cl-letf (((symbol-function 'sql-get-login) #'ignore))
      (call-interactively 'sql-product-interactive))))

And here's a variant of my-sqli-restart which (a) works from a sql-mode buffer as well (obviously call M-x my-sqli-restart in that instance, or bind it to a key sequence in sql-mode-map), and (b) actively kills the inferior process in the SQLi buffer, if it was running.

(defun my-sqli-restart (&optional arg)
  "Restart `sql-product-interactive' using existing settings.

With a prefix argument, prompt for the connection settings."
  (interactive "P")
  (save-window-excursion
    (with-current-buffer (cond ((derived-mode-p 'sql-interactive-mode)
                                (current-buffer))
                               ((and (derived-mode-p 'sql-mode)
                                     (buffer-live-p (get-buffer sql-buffer)))
                                sql-buffer)
                               (t (prog1 (current-buffer)
                                    (setq arg t))))
      (cond ((sql-buffer-live-p (current-buffer))
             (set-process-sentinel
              (get-buffer-process (current-buffer))
              `(lambda (process signal)
                 (when (memq (process-status process) '(exit signal))
                   (my-sqli-restart ',arg))))
             (kill-process))
            (arg
             (call-interactively 'sql-product-interactive))
            (t
             (cl-letf (((symbol-function 'sql-get-login) #'ignore))
               (call-interactively 'sql-product-interactive)))))))
phils
  • 48,657
  • 3
  • 76
  • 115
  • Thanks. `my-sqli-restart` seems to work; but I am not sure I understand the `"g" to refresh the buffer` method in the first part. I have only very rudimentary experience with Emacs/elisp. I copied and pasted your code in the update into init.el. Don't know how to make "g" work. Is it a shortcut key like 'C-x g`? I thought it was a shortcut key that I can press while in sqli (or sql) mode to kill-and-reload the process. – tinlyx Feb 19 '19 at 01:31
  • In the SQLi buffer (only), if you kill the process (`\q` or `C-d`) then you will be able to type `g` to restart it. If the process is running, then `g` will just do what it normally does. (I hadn't initially understood that you wanted to trigger things from a `sql-mode` buffer, so I was assuming you would be in the SQLi buffer already.) – phils Feb 19 '19 at 02:27
  • I've updated the description; the usage should be clearer now. – phils Feb 19 '19 at 02:39
  • Thanks for the clarification! – tinlyx Feb 19 '19 at 02:47