Background
I am working with prolog in emacs and using prolog-inferior-mode
which has comint-mode
as a parent mode.
The default completion in comint-mode
s is rather terrible, and I was hoping to be able to use helm to do tab completion on the history. I discovered tab-always-indent
and set it to complete
, which triggers completion when appropriate upon hitting the tab key. I also discovered completion-at-point-functions
and wrote a helm source that grabs the previous comint history, which is stored in comint-input-ring
. This variable only exists locally in comint buffers, it seems.
I wrote the following code:
(defun get-comint-candidates ()
(interactive)
(let ((start (car comint-input-ring))
(end (car (cdr comint-input-ring)))
(completed (append (nthcdr 2 comint-input-ring) nil)))
(butlast (nthcdr start completed) (- (length completed) end)))
)
(defun comint-completion-source ()
(interactive)
(helm :sources '((name . "helm comint-mode")
(candidates . get-comint-candidates)
(action . (lambda (cand) (insert cand)))
)
:input (thing-at-point 'word)
)
)
(add-hook 'comint-mode-hook (lambda () (setq completion-at-point-functions 'comint-completion-source)))
(setq tab-always-indent 'complete)
The problem
If I am inside the prolog comint buffer and call get-comint-candidates
, it returns the candidates as it should. However, whenever I call comint-completion-source
either manually or using the tab key, the completion buffer is empty. Moreover, I'm not sure if this is the right solution. I would prefer to be able to basically tell helm that it's supposed to complete from my source and use the default helm completion-at-point
functionality, such that I don't have to manually take care of inserting only the parts of the chosen completion that I haven't already typed(that is to say, if I have typed fo
and complete foobar
, I want it to result in foobar
, not fofoobar
).
I would be very grateful for any hints or tips on how to solve this, as well as any on working with comint-mode
and its children modes in general.