Patches are welcome via the usual mechanisms (pull requests, email, posting to the project issue tracker etc).
For more details, see the "command-t-development" section in the documentation.
- Update "command-t-history" section in
doc/command-t.txt. - Edit metadata in
lua/wincent/commandt/version.luato reflect new$VERSION(removeprelease = 'main'). - Commit using
git commit -p -m "chore: prepare for $VERSION release". - Create tag with
git tag -s $VERSION -m "$VERSION release". - Fast-forward the
releasebranch to match the tag. - Check release readiness with
make check. - Push with
git push --follow-tags. - Update release notes on GitHub.
- Start a new entry under "command-t-history" in
doc/command-t.txtfor subsequent development. - Edit metadata in
lua/wincent/commandt/version.luato showprelease = 'main'andversion = 'x.y.z-main.
Sometimes user bug reports depend on characteristics of their local setup. Reproducing this may require copying configuration and installing dependencies, something I'd rather not do to my own development system. So, here are some notes about setting up a disposable Tart VM on macOS (Apple Silicon) to try things out in a controlled environment.
brew install cirruslabs/cli/tarttart clone ghcr.io/cirruslabs/ubuntu:latest command-t-sandbox
tart run --no-graphics command-t-sandboxIn a separate terminal, SSH in (default credentials are admin/admin):
ssh admin@$(tart ip command-t-sandbox)The current Ubuntu image (at the time of writing, that's 24.04) ships Neovim 0.9.5 via apt, which is relatively ancient:
sudo apt-get update
sudo apt-get install -y neovim build-essentialIf a newer version is needed, build from source:
sudo apt-get install -y ninja-build gettext cmake curl build-essential
git clone --depth=1 https://github.com/neovim/neovim
cd neovim
make CMAKE_BUILD_TYPE=RelWithDebInfo
sudo make installBUNDLE=$HOME/.config/nvim/pack/bundle/start
mkdir -p $BUNDLE
git clone --depth 1 https://github.com/wincent/command-t $BUNDLE/command-t
echo "require('wincent.commandt').setup()" > ~/.config/nvim/init.lua
(cd $BUNDLE/command-t && make)
# Also install any other plug-ins that might be needed to reproduce a problem; eg:
git clone --depth 1 https://github.com/jiangmiao/auto-pairs $BUNDLE/auto-pairsFor reproducing reports that involve a plugin manager:
# Note we need `--filter=blob:none` here instead of `--depth=1` because lazy.nvim
# needs the metadata about the Git history for its lockfile implementation.
git clone --filter=blob:none --branch=stable \
https://github.com/folke/lazy.nvim ~/.local/share/nvim/lazy/lazy.nvimThen, in ~/.config/nvim/init.lua:
vim.opt.rtp:prepend(vim.fn.stdpath('data') .. '/lazy/lazy.nvim')
require('lazy').setup({
{
'wincent/command-t',
build = 'make',
config = function()
require('wincent.commandt').setup()
end,
},
})exit # Leave the SSH session.
tart stop command-t-sandbox # Stop the VM.
tart delete command-t-sandbox # Delete the VM image.In order to get intelligible stack traces, compile with debug symbols with:
make PROFILE=1
I didn't have any success the last time I tried xctrace, but including the notes here for reference anyway:
xctrace record --launch bin/benchmarks/matcher.lua --template "CPU Profiler" # Instruments.app hangs while opening this.
xctrace record --launch bin/benchmarks/matcher.lua --template "Time Profiler" # Instruments.app hangs while opening this.
xctrace record --launch bin/benchmarks/matcher.lua --template "Activity Monitor" # Produces not very useful system-wide stats.
xctrace record --launch bin/benchmarks/matcher.lua --template "Allocations" # Completes with an error and produces no useful info.
In theory, should be able to run the following, but it hangs:
xctrace symbolicate --input some.trace --dsym lua/wincent/commandt/lib/commandt.so.dSYM
I also attempted using the /usr/bin/sample tool, which produces results, albeit not particularly easy ones to parse:
(sleep 1 && luajit bin/benchmarks/matcher.lua) &
sample -wait luajit -mayDie
dtrace, however, produced a useful result, albeit with some hoop-jumping required:
sudo -v
luajit bin/benchmarks/matcher.lua & ; DTRACE_PID=$! ; sudo vmmap $DTRACE_PID | grep commandt.so ; sudo dtrace -x ustackframes=100 -p $DTRACE_PID -n \
'profile-100 /pid == '$DTRACE_PID'/ { @[ustack()] = count(); }' -o dtrace.stacks
ie. refresh sudo credentials, kick off luajit, grab the base address of the commandt.so library so that we can symbolicate later on, run dtrace for 60s, sample 100 times per second (ie. every 10ms), grab user stack (not kernel frames), then exit.
I tried a few tricks1 to get dtrace to symbolicate for us automatically but eventually had to do it manually with atos. Grab the base address of the __TEXT segment (printed by vmmap); in this example, 0x104ac0000:
__TEXT 104ac0000-104ac8000 [ 32K 32K 0K 0K] r-x/rwx SM=COW /Users/USER/*/commandt.so
__DATA_CONST 104ac8000-104acc000 [ 16K 16K 16K 0K] r--/rwx SM=COW /Users/USER/*/commandt.so
__LINKEDIT 104acc000-104ad0000 [ 16K 16K 0K 0K] r--/rwx SM=COW /Users/USER/*/commandt.so
Then run this hacky script:
cat dtrace.stacks | bin/symbolicate-dtrace 0x104ac0000 > dtrace.symbolicated
Which produces output that can then be visualized with:
git clone https://github.com/brendangregg/FlameGraph
cd FlameGraph
./stackcollapse.pl dtrace.symbolicated > dtrace.collapsed
./flamegraph.pl dtrace.collapsed > dtrace.svg
I also had success straightforwardly with Samply:
cargo install --locked samply
TIMES=1 ~/.cargo/bin/samply record luajit bin/benchmarks/matcher.lua
Note: Using TIMES=1 because otherwise the generated profile.json is too big and crashes Chrome (but not Safari).
Make a build that collects profiling data:
make CFLAGS=-fprofile-generate
Run the program to generate the profiling data:
TIMES=1 bin/benchmarks/matcher.lua
Prepare the data:
xcrun llvm-profdata merge -output=lua/wincent/commandt/lib/default.profdata *.profraw
Make a build using the profiling data:
make CFLAGS=-fprofile-use
Footnotes
-
Tricks which didn't work included running from inside
lua/wincent/commandt/lib(where the dSYM bundle is), and moving the dSYM bundle up to the root and running from there.The probable reason why automatic symbol discovery doesn't work is the UUID mismatch between the library and the process that
dtraceis executing:
↩dwarfdump --uuid lua/wincent/commandt/lib/commandt.so # This matches... dwarfdump --uuid lua/wincent/commandt/lib/commandt.so.dSYM # ... with this; dwarfdump --uuid /opt/homebrew/bin/luajit # but not with this.