It's definitely possible. Here is my initial attempt at creating the 3 window split with a jest test runner, a source file, and it's associated spec file. You can put this code in your config and try it out via M-x jest-open.
(defun jest-spec-for-file (file)
"Given a file, return its matching spec file."
(let* ((dirname (file-name-directory file))
(filename (file-name-nondirectory file))
(ext (file-name-extension file))
(replace-regexp-in-string (concat "." ext "$") "" filename)))
(concat dirname basename ".spec." ext)))
(defvar jest-command "jest --watch"
"This is the shell command used to run jest.")
(defun jest-run (&optional term)
"Switch to the jest buffer if it exists or create a new one."
(if (get-buffer "jest") (switch-to-buffer "jest")
(cond ((equal term 'vterm)
(vterm-send-string (concat jest-command "\n"))))
(term-send-raw-string (concat jest-command "\n"))
(defun jest-open (file)
"Create a 3 window layout containing jest|source|spec."
(let* ((spec (jest-spec-for-file file)))
(jest-run) ; change this to (jest-run 'vterm)
How It Works
We have 3 functions and a variable.
Return the spec file associated with
This is just pure string manipulation that takes a string like
/tmp/index.js and returns
This variable contains the shell command used to invoke jest. Feel free to adapt it to your needs.
(jest-run &optional term)
If a buffer named "jest" exists, switch to it. Otherwise, create a term (or vterm) buffer and run
jest-command inside of it. I have it default to use
term since it's included with stock emacs, but I highly recommend giving vterm a try. Anything that's even slightly animated will look better in vterm. When you're ready to make the switch, change the line that says:
Also, keep in mind that if you hit q to stop jest, this function won't try to restart it. Once the jest buffer is created, all control is deferred to you.
Finally, we have the function that creates the 3 window split and sets up the buffers such that you have a jest test runner on the left, the source in the middle, and a spec file on the right. It will also place the focus on the middle window, because I think that's what would be most intuitive.
You can give it a try by hitting M-x jest-open and selecting a file when prompted. If you end up wanting to use this frequently, you can bind it to a key. You can do it the doom way too.
I tried to write this in a way that works in any Emacs configuration. It should work just fine in Doom. As you explore this code (or any other elisp), I encourage you to use C-h f look up the docs for functions. I also like using M-x ielm to start up an interactive elisp repl to feel how things work. Doing this really accelerated my elisp self-education.