Using vterm with emacs project.el

Home | About | Items

3 September 2024

I'm a big fan of emacs' builtin project tools, project.el. C-x p c to initiate a compile, C-x p g to grep, C-x p f to find files, and C-x p s to launch or switch to a shell.

But lately I've started using vterm, a proper terminal emulator, because the zig compiler has pretty output that a simple terminal can't handle, and who doesn't like to see pretty output while they're waiting for something to compile?

So this afternoon's challenge was: how do I make the project.el project-shell command (C-x p s) use vterm instead of the emacs shell? Well, this did the trick, added to my .init.el. It's a direct copy-paste of project-shell from project.el, with the calls to shell replaced with vterm.

Enjoy nice vterm in your project shells.

(defun my-project-shell ()
  "Start an inferior shell in the current project's root directory.
If a buffer already exists for running a shell in the project's root,
switch to it.  Otherwise, create a new shell buffer.
With \\[universal-argument] prefix arg, create a new inferior shell buffer even
if one already exists."
  (interactive)
  (require 'comint)
  (let* ((default-directory (project-root (project-current t)))
         (default-project-shell-name (project-prefixed-buffer-name "shell"))
         (shell-buffer (get-buffer default-project-shell-name)))
    (if (and shell-buffer (not current-prefix-arg))
        (if (comint-check-proc shell-buffer)
            (pop-to-buffer shell-buffer (bound-and-true-p display-comint-buffer-action))
          (vterm shell-buffer))
      (vterm (generate-new-buffer-name default-project-shell-name)))))

(advice-add 'project-shell :override #'my-project-shell)


Contact: @mocom@mastodon.social. Published using C-c C-e P p. If you use this content commercially, kindly make an appropriate donation to Zig Software Foundation in my name.