Closed azzamsa closed 4 years ago
vterm currently doesn't fill helm-comint-input-ring
.
I'm using a custom helm source on a file and modified vterm-send-return
so it appends the input to this file.
(setq term-prompt-regexp "^[^#$%>\\n]*[#$%>] *")
(defvar vterm-history "path/to/vterm_history")
(defun vterm-send-return ()
"Send `C-m' to the libvterm."
(interactive)
(when vterm--term
(let* ((beg (vterm--get-prompt-point))
(end (vterm--get-end-of-line))
(string (buffer-substring-no-properties beg end))
(file vterm-history))
(write-region (concat string "\n") nil file t 0))
(if (vterm--get-icrnl vterm--term)
(process-send-string vterm--process "\C-j")
(process-send-string vterm--process "\C-m"))))
(defun helm-vterm-history ()
(interactive)
(let ((contents (with-temp-buffer
(insert-file-contents vterm-history)
(reverse (split-string (buffer-string) "\n")))))
(helm :sources `((name . "vterm history")
(candidates . contents)
(action . (lambda (candidate)
(vterm-send-string candidate))))
:candidate-number-limit 10000)))
I noticed this still needs some improvements :P
Great!. It works like a charm.
Thank you for vterm.
@brotzeit I've added the check to ignore empty string so that it doesn't get written into the history file.
I've some problem with the code:
So here is my updated version:
I'll updated the code here if I find a bug
(defun get-current-cmd ()
(let* ((beg (vterm--get-prompt-point))
(end (vterm--get-end-of-line)))
(buffer-substring-no-properties beg end)))
(defun vterm-send-return ()
"Send `C-m' to the libvterm."
(interactive)
(when vterm--term
(let* ((current-cmd (get-current-cmd)))
(if (not (string= current-cmd ""))
(add-to-list 'vterm-history current-cmd)))
;; default part from vterm.el
;; (setq cursor-type 'bar)
(if (vterm--get-icrnl vterm--term)
(process-send-string vterm--process "\C-j")
(process-send-string vterm--process "\C-m"))))
(defun helm-vterm-history ()
(interactive)
(let ((histories vterm-history)
(current-cmd (get-current-cmd)))
(helm :sources `((name . "vterm history")
(candidates . histories)
(action . (lambda (candidate)
(vterm-send-string candidate))))
:input current-cmd
:candidate-number-limit 10000))))
Instead of checking if the string is empty, I don't append strings that are too long. For example when you use return on the output of systemctl status, you get the whole output appended to your history every time you press enter.
Maybe somebody finds a better way to handle this. It's really convenient to have a global history.
Instead of checking if the string is empty, I don't append strings that are too long. For example when you use return on the output of systemctl status, you get the whole output appended to your history every time you press enter.
I can't reproduce this behavior with the code above
Oh then I have to try it :+1:
I also looked for something like that. I'm using the completing-read ecosystem though. I implemented something this morning.
I am mostly interested in the history of zsh, so I ended up reading the zsh history directly. Duplicates are already handled by zsh so this is nice. Here is the code maybe it helps someone in the future:
;; this function is from http://xahlee.info/emacs/emacs/elisp_read_file_content.html
(defun read-lines-from-files (filePath)
"Return a list of lines of a file at filePath."
(with-temp-buffer
(insert-file-contents filePath)
(split-string (buffer-string) "\n" t)))
(defun vterm-history (histfile)
(vterm-send-string (completing-read "Commands: " (read-lines-from-files histfile)) t))
(defun vterm-history-zsh ()
(interactive)
(vterm-history "~/.config/zsh/.histfile"))
(define-key vterm-mode-map (kbd "C-c C-q") 'vterm-history-zsh)
As you see this can be easily adapted to read from any history file, even from a combination of history files if needed.
It probably also relates to https://github.com/minad/consult/issues/121
Can we use comint in vterm buffer?
I tried
helm-comint-input-ring
in vterm buffer it doesn't work. But it works in other e/shell/ansi-term buffer.Thank you for vterm.