Many development environments require running things in a terminal window. npm run start
, or whatever. I know my biggest project requires me to be running a big fancy Docker-based thing in one terminal, Ruby on Rails in another, and webpack in another. I’ve worked on other projects that require multiple terminal windows as well, and I don’t feel like I’m that unusual. I’ve heard from several others in this situation. It’s not a bad situation, it’s just a little cumbersome and annoying. I’ve got to remember all the commands and set up my command line app in a way that feels comfortable. For me, splitting panels is nicer than tabs, although tabs for separate projects seems OK.
I asked the question on Twitter, of course. I figured I’d compile the options here.
- tmux was the most popular answer. I’m very sure I don’t understand all it can do, but I think I understand that it makes “fake” panes within one terminal session that emulates multiple panes. So, those multiple panes can be configured to open and run different commands simultaneously. I found this interesting because it came literally days later my CodePen co-founder let us all know the new dev environment he’s been working on will use tmux.
- Here’s an example configuration for tmux.
- tmuxinator gives it better configuration, I guess?
- I was pointed to kitty by a fella who told me it feels like a grown-up tmux to him. It can be configured into layouts with commands that run at startup.
- There are native apps for all the platforms that can run multiple panels.
- macOS: I’ve long used iTerm which does split panels nicely. It can also remember window arrangements, which I’ve used, but I don’t see any built-in option for triggering commands in that arrangement. The native terminal can do tabs and splitting, too, but it feels very limited.
- Linux: Terminator
- Windows: The default terminal has panes.
- There are npm things for running multiple scripts, like concurrently and npm-run-all, but (I think?) they are limited to running only npm scripts, rather than any terminal command. Maybe you can make npm scripts for those other commands? But even then, I don’t think you’d see the output in different panels, so it’s probably best for scripts that are run-and-done instead of run-forever.
Being a Mac guy, I was most interested in solutions that would work with iTerm since I’ve used that anyway. In lieu of a built-in iTerm solution, I did learn it was “scriptable.” Apparently, they are sunsetting AppleScript support in favor of Python but, hey, for now it seems to work fine.
It’s basically this:
The Code
tell application "iTerm"
tell current window
create window with default profile
tell current session of current tab
set name to "run.sh"
write text "cd '/Users/chriscoyier/GitHub/CPOR'"
write text "./run.sh"
end tell
create tab with default profile
tell current session of current tab
set name to "Rails"
write text "cd '/Users/chriscoyier/GitHub/CPOR'"
write text "nvm use"
write text "yarn"
write text "bundle install"
write text "yarn run rails"
end tell
create tab with default profile
tell current session of current tab
set name to "webpack"
write text "cd '/Users/chriscoyier/GitHub/CPOR'"
write text "nvm use"
write text "yarn"
write text "yarn run dev"
end tell
# split vertically
# tell application "System Events" to keystroke "d" using command down
# delay 1
# split horizontally
# tell application "System Events" to keystroke "d" using {shift down, command down}
# delay 1
# moving... (requires permission)
# tell application "System Events" to keystroke "]" using command down
end tell
end tell
I just open that script, hit run, and it does the job. I left the comments in there because I’d like to figure out how to get it to do split screen the way I like, rather than tabs, but I got this working and then got lazy again. It felt weird to have to use keystrokes to have to do it, so I figured if I was going to dig in, I’d figure out if their newer Python stuff supports it more directly or what. It’s also funny I can’t like compile it into a little mini app or something. Can’t Automator do that? Shrug.
The other popular answer I got for Mac folks is that they have Alfred do the work. I never got into Alfred, but there clearly is fancy stuff you can do with it.
I think the ttab package (https://www.npmjs.com/package/ttab) someone else mentioned is much closer to what you were asking for, using the tools you already know.
I’d encourage you to give it a look if you didn’t.
In MacOS I started using iTemocil do setup various configs for iTerm layout.
https://github.com/TomAnthony/itermocil
I have a 3 vertical pane setup for an Angular/Rails app. Top pane holds
ng serve
, middle panerails s
, bottom pagerails c
or a plain terminal for rails unit tests.Useful post!
Note that Windows Terminal is not the Default Terminal. It is made by Microsoft but not installed by default and has to be downloaded from the Microsoft Store:
https://www.microsoft.com/en-gb/p/windows-terminal/9n0dx20hk701
Just to add some more ways to manage multiple concurrent terminal running if you are using VS Code as your IDE.
You can set up Tasks to run simultaneously by declaring the
dependsOn
property and put the task you want to run concurrently in the list the trick to the a split terminal is to set the propertypresentation
on each dependent task to utilize the samegroup
propertyHere’s an example that open up two terminal and run in each its command
I have iTerm set up with a set of panes side by side that start a command that prints a message what’s it opening if I press enter. When I start iterm, it reloads the setup and waits for me to press enter on the panes.
I had it run the code initially, but I felt that I’d rather trigger the commands myself than run them every time automatically.
I think I followed this guide to have it running: https://webstudiya.com/develop-faster-with-iterm-profiles-and-window-arrangements/
I think it’s pretty much what you’re asking for.
The Python API for iTerm is pretty simple (even for a novice, like me).
I saved an arrangement which I load via the API. I then run a command in each pane:
docker-compose up
in the firstnpm start
in the secondLoad a Python virtual environment in a third
Took some learning, as APIs do, but it works great and is a very low amount of code.
Here’s my script:
If you don’t actually need separate terminals, I have found that foreman http://blog.daviddollar.org/2011/05/06/introducing-foreman.html works great. It is also very simple to set up as it requires a single text file that lists the commands you want to run.