ido-mode with eshell, shell, sql and more...

August 7, 2019

ido-mode doesn't provide completion for eshell, shell or sql-mode out of the box, and I wasn't been able to find any package with this option that is lightweight enough (Helm, I'm looking at you). So, after few attempts, here is the code for that:

(defun ido-eshell-comint-history ()
  "eshell & comint history with ido."
  (interactive)
  (if (or (member major-mode '(eshell-mode sql-interactive-mode))
          (derived-mode-p 'comint-mode))
     (let ((ring (if (eq major-mode 'eshell-mode)
                   eshell-history-ring
                   comint-input-ring)))
       (insert
        (ido-completing-read "History: "
                             (delete-dups
                              (ring-elements ring)))))
    (message "Unsupported mode")))

After evaluating the code, in eshell simply execute M-x ido-eshell-comint-history and magic will happen - you will get full eshell history managed by ido-mode. To make it more authentic, map it to C-c C-l, which is default sequence for completion in eshell.

The same can be applied for shell and sql-mode as well.

But, the things gets interesting here: (ido-eshell-comint-history) will pick up history for all modes inherided from comint-mode (shell is using comint-mode), so you will get history completion for python, lua, lisp and other inferior processes for free!

Just to add (commenting above code), although sql-mode is using comint-mode, it doesn't derive it so additional check is necessary. Also to enable history in sql-mode you will need to set variable sql-input-ring-file-name as well.