Booting Acme on macOS
2020-09-13
Starting up Acme, the text editor I use, is non-trivial. It relies on
two supporting processes (fontsrv
and plumber
) and it doesn't work
well if you run more than one instance.
Besides this process management, it is also desirable to modify environment variables, because Acme is also my terminal emulator, and it is a "dumb" one meaning it needs special settings.
The idea of "run only one instance" sounds like a job for macOS launchd but I have come to not like that. I now just use a script that does an old fashioned double fork.
bin/acme
#!/usr/bin/env ruby Dir.chdir(ENV['HOME']) # Send SIGTERM to all running plan9port server processes system(*%w[pkill 9pserve]) log = ['Library/Logs/acme.log', 'a'] # Prevent colorization settings leaking into Acme %w[ CLICOLOR GREP_OPTIONS ].each { |k| ENV.delete(k) } { 'PAGER' => '9 nobs', 'BROWSER' => 'Google Chrome', 'MAILER' => 'browser', 'EDITOR' => '9 E', 'GIT_EDITOR' => '9 E', 'TERM' => 'dumb', 'SHELL' => '/Users/jacobvosmaer/bin/rc-wrap', }.each { |k, v| ENV[k] = v } fork do Process.setsid $stdin.reopen('/dev/null') [ %w[9 plumber], %w[9 fontsrv], %w[9 acme -l acme.dump], ].each { |cmd| spawn(*cmd, err: log, out: log) } end
The pkill
command at the top of the script takes care of the "only
one Acme process" requirement in a very crude way, by terminating all
plan9port server processes. It is a common problem to terminate acme
itself but not its helpers, and sometimes that is bad. Now by running
bin/acme
I get a clean slate on all its processes.
bin/rc-wrap
You may have noticed the SHELL=rc-wrap
bit. This is what rc-wrap
does:
#!/bin/sh exec rc -l "$@"
What is going on here is that I want all my shells inside plan9port to
be rc -l
, not rc
. For whatever reason SHELL=rc -l
is not allowed
so I made this wrapper executable that adds the -l
argument but
avoids the space in SHELL.
What rc -l
does is to enable loading its startup file $HOME/lib/profile
. I like this because it lets me define
rc
functions as shortcuts for when I work in Acme's terminal.
rc functions
I use rc
functions instead of plain scripts so that I can neatly
"shadow" commands that work fine in regular terminal but not-fine in
Acme. Mostly stuff with colorization, such as:
fn rspec { u bundle exec rspec --no-color $* }
u
is a plan9port helper that removes plan9port from the PATH, making
the non-plan9port ls
, sed
, kill
, grep
etc available.
The advantage of having this rspec
shell function is that it is
specific to plan9port and when I run rspec
in a normal terminal I
still get normal rspec
.
Tags: acme