jixiuf / vterm-toggle

toggles between the vterm buffer and whatever buffer you are editing.
GNU General Public License v3.0
188 stars 12 forks source link

Is it possible to include toggling behavior based on if vterm is currently running a foreground process? #23

Closed Dima-369 closed 3 years ago

Dima-369 commented 3 years ago

Is there is a function to check whether the vterm buffer is currently in its prompt state and not running some foreground process?


With this one could do cool things like:

Let's call this new defun (vterm-active-toggle) (just a dummy name) for an demonstration:

  1. Launch Emacs with no open vterm buffers
  2. Invoke (vterm-active-toggle) which would open a new vterm
  3. Run a long running command (let's use sleep 300 as an example)
  4. When vterm is the currently active buffer, (vterm-active-toggle) should check if there is a foreground process running in the current vterm. If yes, it would just hide the buffer. If not, it should kill the vterm because it is idling (to clear up buffer names). In this case because of sleep 300s, it just hides vterm
  5. Invoking (vterm-active-toggle) would see that the first vterm buffer is still busy running something, so it would just create a new vterm buffer
  6. Without anything entered here in this new vterm, invoking (vterm-active-toggle) would just kill this vterm buffer because nothing is running in the foreground

Do you think something like this is realistic to implement? Not sure if it would require changes to emacs-libvterm?

I think if there is such a defun to detect the state of vterm, I could actually code it myself. The toggling is really the easy part here.


I already checked with (vterm-next-prompt) and similar defuns from vterm, but even when a process is already running, it just goes to the bottom of the prompt which is not helpful in detecting this. Not sure if I just missed something.

jixiuf commented 3 years ago

see vterm-cursor-in-command-buffer-p, currently vterm-toggle-cd already check if there is a foreground process running

Dima-369 commented 3 years ago

I tested vterm-cursor-in-command-buffer-p and it always returns t for me, even if there already is a foreground process.

This leads to vterm-toggle-cd incorrectly inserting the cd (notice it being inserted twice in the screenshot below). I also tested with a different commands and it always incorrectly inserted the cd:

image

Any ideas? Does it not behave like this for you?

jixiuf commented 3 years ago

Have you enable Directory tracking and Prompt tracking

Dima-369 commented 3 years ago

Ah, that might be the missing piece. I totally missed that :(

Let me test and report back!

Dima-369 commented 3 years ago

It works, amazing. Thank you a lot :)

Dima-369 commented 3 years ago

In case someone else is interested in the functionality described, I quickly whipped this up.

vterm-send-cd can obviously be improved by using code from this library, but it's fine for me how it is.

(defun vterm-send-cd (dir)
  (vterm-send-C-u) ; clearing the input shell line
  (vterm-send-string (concat "cd " dir))
  (vterm-send-return))

(defun vterm-get-buffer-name (i)
  (if (>= i 2)
      (concat "vterm<" (number-to-string i) ">")
    "vterm"))

;; vterm buffers are named like this:   vterm   vterm<2>   vterm<3>   ...
(defun vterm-seek-idle (i dir)
  (let ((buffer-name (vterm-get-buffer-name i)))
    (if (get-buffer buffer-name)
    (progn
      (switch-to-buffer buffer-name)
      (if (vterm-cursor-in-command-buffer-p)
          (vterm-send-cd dir)
        (bury-buffer)
        (vterm-seek-idle (+ i 1) dir)))
      (vterm)
      (vterm-send-cd dir))))

(defun vterm-toggle-to-idle ()
  (interactive)
  (vterm-seek-idle 1 default-directory))

Thanks again for your help! I really always wanted to have such functionality and now it's here :)