]> git.wincent.com - wincent.git/log
12 months agochore: bump node version from 14.17.0 to 16.8.0
Greg Hurrell [Mon, 6 Sep 2021 15:55:22 +0000 (17:55 +0200)] 
chore: bump node version from 14.17.0 to 16.8.0

Via the releases page:


v14 is the "Active LTS" release, and came out on 2020-04-21. It will hit
end-of-life on 2023-04-30, so no hurry to get off it.

v16 is the "Current" release, and came out on 2021-04-20. It will hit
end-of-life on 2024-04-30.

So yeah, no hurry to move, but I may as well update about once a year
and stay on whatever is "Current". (This partly prompted because I just
opened a PR to a project that wants me to use Node v16, and if I can
just have that version hanging around on my system already it makes life
easier for me).

Test plan: `./install` and see that things still seem to be working.

12 months agofeat(dotfiles): teach `gg` to run `gg test` if first arg starts with `test/`
Greg Hurrell [Mon, 6 Sep 2021 09:00:00 +0000 (11:00 +0200)] 
feat(dotfiles): teach `gg` to run `gg test` if first arg starts with `test/`

Just a convenience to save some typing, and because on a few occasions I
have typed this unthinkingly anyway, expecting it to work.

13 months agofeat(apt): install par on Debian
Greg Hurrell [Tue, 31 Aug 2021 16:51:15 +0000 (18:51 +0200)] 
feat(apt): install par on Debian

Because I need to wrap in Vim. (I could also make my wrapping keybinding
degrade gracefully in the absence of `par`, but I find it so darn useful
I just prefer to install it everywhere I use Vim.)

Luckily, it is only an `apt-get install par` away:


13 months agorefactor(nvim): apply post-update tweaks for LuaSnip
Greg Hurrell [Tue, 31 Aug 2021 15:53:12 +0000 (17:53 +0200)] 
refactor(nvim): apply post-update tweaks for LuaSnip

I _think_ the docblock snippet works close to how the old UltiSnips one
did now, and the rest seem to still be working.

13 months agochore(nvim): update LuaSnip
Greg Hurrell [Tue, 31 Aug 2021 15:24:07 +0000 (17:24 +0200)] 
chore(nvim): update LuaSnip

Motivation; get this fix:


But it turns out that there have been a _lot_ of changes since I last
updated; if anything breaks, I will follow up:

* aspects/nvim/files/.config/nvim/pack/bundle/opt/LuaSnip 72323c1...9a8cf5f (261):
  > Merge pull request #143 from leiserfg/multi-ft
  > Format with stylua
  > fix: account for compound filetypes (closes #142).
  > Update README.md
  > Format with stylua
  > Fix parser, for real now.
  > Format with stylua
  > Fix slight regression with variables in lsp-parsed snippets.
  > Fixup(d2aa43c): BREAKING, parsing has become more strict.
  > Format with stylua
  > Provide option to set better `assemble`-function for nested snippets.
  > Format with stylua
  > Merge branch 'master' of github.com:L3MON4D3/LuaSnip
  > lsp: correctly parse brackets (closes #141) and split iNode-text.
  > fix(parser): remove escape-chars everywhere.
  > Merge pull request #140 from carlitux/patch-2
  > Set pos to nil for better docstring if queried manually.
  > Format with stylua
  > Improve get_docstring().
  > Typo.
  > Format with stylua
  > Account for selecting empty lines (only) (closes #139).
  > Use `rawget` to get position.
  > Merge pull request #138 from leiserfg/handle_emtpy_snippets
  > Parser: ${n:sometext} can also be repetitions of previous insertNodes.
  > Try expanding autosnippets if pum is visible, too.
  > Format with stylua
  > Use tokenizer to create helper-snippet for regex-triggers.
  > Implement tokenizer for patterns.
  > Format with stylua
  > pcall `get_text`, {""} on error. Don't error on `str_utfindex`.
  > Try to prevent jump_from from erroring due to deleted snippets.
  > Auto generate docs
  > Format with stylua
  > Merge branch 'insert_node_event_callbacks'
  > Add <Plug>-mapping for previous choice (Closes #131).
  > Format with stylua
  > Provide setting for delete-check autocommands.
  > Recommend `InsertEnter` for `region_check_events`
  > Make bytecol_to_utfcol behave correctly (used to return three values).
  > Auto generate docs
  > Format with stylua
  > Small changes+improvements for the enter/leave events:
  > Auto generate docs
  > Auto generate docs
  > Format with stylua
  > No need to input_leave the generated snippet in dynamicNode.
  > Trigger autocommands on entering/leaving nodes.
  > Add function to check if the current snippet was deleted+<Plug>-mapping.
  > Merge pull request #126 from leiserfg/generic-package-name
  > Auto generate docs
  > Format with stylua
  > Document indent_snippet_node and some usages for it.
  > Remove prefix_snippet_node, it's really just a specification of ISN.
  > Re-implement changing choice backwards.
  > Prevent region check for autotriggered snippets too.
  > Each choice gets a pointer to the next.
  > Rename choiceNode.inner to choiceNode.active_choice, more expressive.
  > Clear snippets' own marks on exit.
  > Rename vars that store choiceNodes to reflect that.
  > Format with stylua
  > Disable region check while jumping.
  > Make sure node isn't nil before indexing.
  > Check for specific node+also check following snippets.
  > Leave exit node when next snippet is expanded, only compare lines for region.
  > Mention setting in README.
  > Add config for specifying when to do region check, defaults to never.
  > Fix minor bugs with exit_out_of_region_snippet.
  > Fix small issues with exitNode.
  > Fix bug caused by new jump_from/into-behaviour.
  > Add function to leave active snippet if its' region is left.
  > Make no_move actually funcitional.
  > Add snippet.snippet, contains 'outer' (ie. the user-triggered) snippet.
  > Have jump_into/jump_leave return the new active node.
  > Merge pull request #124 from leiserfg/clean_lazy
  > Auto generate docs
  > Fix lazy-loading.
  > Add more details for loading vscode-packaged snippets.
  > Format with stylua
  > Fix/improve update_dependents-behaviour.
  > Clean up a bit.
  > Reset active upon exit()ing, only pop active choice if this was active.
  > Simplify choiceNodes' init-process.
  > Merge pull request #121 from L3MON4D3/static_text_for_snippets
  > Ignore and correctly format lines on which stylua fails.
  > Format with stylua
  > Fix regression: *move_on_mark_*-functions were removed, typo(?) in util.mark.
  > Format with stylua
  > Remove print's.
  > Changes nothing functionally, but clearer.
  > After parsing, the positions of insertNodes are not 'dense', fix it.
  > Inserting a missing `i(0)` is handled by snippet-constructor.
  > Auto generate docs
  > Format with stylua
  > Document expected layout of directories loaded via vscode-loader.
  > Format with stylua
  > Separate expanding tabs in text and indenting; make both more generic.
  > Fix expand_tab-implementation.
  > Always initialize static_text for insert and textNode.
  > Format with stylua
  > Fix unlink_current, correctly set active node.
  > Set Luasnip_active_choice correctly after exit()ing choiceNode.
  > Format with stylua
  > Merge pull request #114 from leiserfg/extra-vars
  > Format with stylua
  > Differentiate between insert and exitNodes(`i(0)`).
  > Call insertNodes' input_leave function for i(0).
  > Auto generate docs
  > Format with stylua
  > Document new behaviour of i(0).
  > Format with stylua
  > Do insertNodes' input_enter for i(0).
  > Fix TM_LINE_INDEX/NUMBER, it should be a string.
  > Format with stylua
  > Explicitly open folds after moving, doesn't seem to happen automatically.
  > Auto generate docs
  > Format with stylua
  > Mention passive extending active and highlight groups in doc.
  > Fix overriding-behaviour.
  > Fix clear_invalid, don't have it override active with passive.
  > Use user-defined Luasnip*Node{Active,Passive} as highlight when defined.
  > Merge default into user-defined table.
  > Format with stylua
  > Replace link to matrix room with icon.
  > Format with stylua
  > Clarify arguments to util.put.
  > Use byte-position of mark to nvim_buf_set_text().
  > Expose function to get byte-position of mark.
  > Format with stylua
  > Default ext_opts-table to {}.
  > Auto generate docs
  > Format with stylua
  > Add example for ext_opts, fix jdoc-snippet.
  > Rename prio_increase to ext_prio_increase.
  > Add documentation for ext_opts.
  > Correctly pass ext_opts with higher prios for inner snippets.
  > Config: include priority+functions to modify.
  > Add appropriate exit()-functions to dynamic and choice.
  > Use copy of passed table.
  > Fix dynNode:set_rgrav, after changing textNode, grav is default-false.
  > Fill missing values in ext_opts.
  > Don't unnecessarily update extmark.
  > Change ext_opts on entering/leaving.
  > Correctly set type and opts for snippet.
  > Rename change_rgravs to update_rgravs.
  > DO change gravities for textNodes, prevents some bug+more uniform.
  > Enter node in both paths.
  > Delete marks on exit.
  > Use two functions to set gravs or other opts.
  > Set snippets' mark from outside also.
  > Format with stylua
  > Mention nvim-cmp and cmp_luasnip in README.
  > Format with stylua
  > Merge pull request #106 from amenonsen/patch-3
  > Format with stylua
  > Merge pull request #105 from amenonsen/patch2
  > Format with stylua
  > Yeeeeeaaaaah no, not really anymore
  > Format with stylua
  > Mention autosnippets in README.
  > Format with stylua
  > Merge branch 'autotrigger'
  > Format with stylua
  > Fix: Adding a i(0) if none was specified.
  > Don't set correctly and then overwrite with old values :/
  > As the mark-id isn't copied anymore, it can be set later in put_initial()
  > Implement clear-function, fix bug with raw_pos.
  > Print gravities in snippet:dump().
  > Store ext_opts in snippet, pass to children; Change marks for dyn/choice
  > Add ext_opts to config.
  > Use raw, not utf-adjusted position for initializing extmarks.
  > Don't set positions in opts.
  > Default-init marks with nil.
  > Fix set_mark_rgrav-function, use default-version everywhere.
  > Actually use new marks in snippets.
  > Most likely, there won't be any updates to pos, and if, then to both.
  > Marks are objects; Simplify extmark_rgrav-setting.
  > Add table for node-names, shift indices to match name.
  > Refactor types to use enum.
  > Auto generate docs
  > Mention mappings in DOC, refer to README.
  > Auto generate docs
  > Merge pull request #104 from amenonsen/patch-1
  > Mention new config-option in README.
  > Auto generate docs
  > Document SELECT-behaviour and lsp-parsing.
  > Provide example mappings for lua and vimscript.
  > Link to lsp-snippet spec.
  > Format with stylua
  > Only remove indent for TM_SELECTED_TEXT.
  > Enable new vars in env.
  > Correctly populate selection.
  > Create all types of indent in store_selection().
  > Modify store_selection to get all lines at once.
  > Allow node.pos to be nil, mimic vscodes' behaviour for $TM_SELECTED_TEXT.
  > Should be an insertNode.
  > Add new snippetNodes prefixSnippetNode and indentSnippetNode
  > Refactor population of args for function/dynamicNodes.
  > Improve autowrapping for snippets, fix it for snippetNodes.
  > Merge pull request #102 from leiserfg/find_vimrc
  > Auto generate docs
  > Specify what the text looks like when executing condition-function.
  > Auto generate docs
  > Maybe also document condition-function.
  > Format with stylua
  > Change snippet:match(...) for regex-triggers, parentheses can mess up patterns.
  > Reuse mark-id if possible.
  > Refactor snippet:indent() slightly.
  > Clean up unneeded args.
  > Indent + populate snippetNodes' env in put_initial().
  > Auto generate docs
  > Format with stylua
  > Explicitly mention text-passing behaviour in docs.
  > BREAKING CHANGE: Pass dedented text to function/dynamicNodes, indent returned text for functionNodes.
  > Merge pull request #94 from leiserfg/fix-of-by-one
  > Merge pull request #93 from leiserfg/use-named-register
  > Format with stylua
  > Reset Visual after use.
  > Return {} instead of "" on empty visual.
  > Prepare for storing prio,hl_group,... in node.mark.
  > Format with stylua
  > Correctly check for empty table ({} != {} in lua);
  > Rewrite extmarks to work more consistently.
  > Update parsed nodes.
  > Fix node-gravities for exitNodes'.
  > Remove prints', fix enter_node.
  > Use only one node to mark beginning and end of node.
  > Merge pull request #92 from leiserfg/select
  > If lambda returns nil, use default of "" to prevent errors.
  > Format with stylua
  > Add dynamic lambdas+examples.
  > Format with stylua
  > Add nonempty-node. Inserts text if arg-node is not empty.
  > Add some examples for `match()`.
  > Adjust default-value for `match()`
  > Merge pull request #86 from leiserfg/match_with_lambda
  > BREAKING CHANGE: Move pseudo-nodes from ls.util.functions to ls.extras.
  > Quickly shuffle around signature of `match()`.
  > Merge pull request #84 from leiserfg/match_with_lambda
  > Auto generate docs
  > Merge pull request #83 from praveendhawan/patch-1
  > Auto generate docs
  > Format with stylua
  > BREAKING CHANGE: Default `wordTrig` to true, not false.
  > Add expand and expandable function+vim-versions (close #79).
  > Luasnip_current_nodes may (somehow) be nil, check before indexing.
  > Format with stylua
  > Add partial function+example (closes #72).
  > Auto generate docs
  > Replace table with list, md2vim doesn't like tables.
  > Auto generate docs
  > Fix table in Doc.
  > Merge pull request #69 from leiserfg/md-doc
  > Alias set_config to setup.
  > Merge pull request #29 from tjdevries/update_config_correctly
  > Initialize function+dynamicNodes when cildren of choiceNode.
  > Format with stylua
  > Add Examples for recently added nodes.
  > Repeat doesn't need lambdas.
  > Merge pull request #67 from leiserfg/lambda-util

13 months agorefactor(nvim): use vim-rails
Greg Hurrell [Tue, 31 Aug 2021 11:31:50 +0000 (13:31 +0200)] 
refactor(nvim): use vim-rails

As mentioned in the previous commit, not sure if I want to go the
heavy-weight plug-in route or not, but am at least going to give it a
try. I did used to use vim-rails waaaaay back; it was vendored in the
very first commit of this repo (61a7e2a830ed, ".vim/.vimrc: initial
import", May 2009), until it finally got removed in in e9a1d032a9f68
("vim: remove vim-{haml,rails}", October 2015).

* aspects/nvim/files/.config/nvim/pack/bundle/opt/vim-rails 0000000...03a5c3e (1612):
  > Ensure we're back in magic mode after embedding `define_pattern()`

13 months agofeat(nvim): set up some projections for Rails-like projects
Greg Hurrell [Tue, 31 Aug 2021 11:28:26 +0000 (13:28 +0200)] 
feat(nvim): set up some projections for Rails-like projects

Not sure whether I want to go with something very minimal like this, or
drag in all of the vim-rails plug-in, which is quite large. I _think_
I'm going to do the latter, but I want at least a simple example in the
Git history to go back to in case I end up changing my mind later on.

13 months agochore(nvim): remove unused vim-soy plugin
Greg Hurrell [Tue, 31 Aug 2021 11:19:04 +0000 (13:19 +0200)] 
chore(nvim): remove unused vim-soy plugin

* aspects/nvim/files/.config/nvim/pack/bundle/opt/vim-soy d103c7c...0000000:

13 months agofeat(nvim): add "cont" and "test" Ruby snippets
Greg Hurrell [Tue, 31 Aug 2021 11:06:02 +0000 (13:06 +0200)] 
feat(nvim): add "cont" and "test" Ruby snippets

Bring back some snippets like the ones I used to have with Ultisnips
(and technically still do over in my .vim files):


AFAICT there is no obvious way to conditionally enable this in files
with compound filetypes, so just adding this for all Ruby files for now.

I asked upstream about whether this is possible:


13 months agorefactor(codespaces): switch to more precise `pkill` mechanism
Greg Hurrell [Mon, 30 Aug 2021 13:10:51 +0000 (15:10 +0200)] 
refactor(codespaces): switch to more precise `pkill` mechanism

Of course, this, too, isn't 100% future-proof, because the file may be
renamed or moved in the future, but it seems better than what I had
before (see parent commit).

13 months agofix(codespaces): tweak `pkill sshd` invocation
Greg Hurrell [Mon, 30 Aug 2021 13:01:24 +0000 (15:01 +0200)] 
fix(codespaces): tweak `pkill sshd` invocation

Something has changed which causes the old command to no longer work.

`pgrep sshd -a` shows these commands running:

    1147 sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
    30372 sshd: root@pts/0

The first (PID 1147) is the main process and the second (PID 30372) is
the subprocess forked to handle my connection. We need to restart the
main process. The old kill command (`pkill -HUP -xf /usr/sbin/sshd`)
would do that (`-f` tells `pkill` to match the entire invocation,
including arguments, and `-x` requires an exact match), because
presumably the old instances were starting `/usr/sbin/sshd` without any
arguments. But now, for some reasons, there is a suffix there that
causes `-fx` to no longer match.

By dropping `-x`, we match against the full string, but less precisely.
This is enough to make the command work again, without killing the
existing connection (the subprocess).

Although as I write this, it still feels too fragile; I think I might
switch to reading `/var/run/sshd.pid` instead.

13 months agofeat(contrib): add /boot/{a,b}.sh scripts on Arch
Greg Hurrell [Thu, 19 Aug 2021 23:21:25 +0000 (01:21 +0200)] 
feat(contrib): add /boot/{a,b}.sh scripts on Arch

Following up on the idea mentioned in the previous commit, we now have
"a.sh" and "b.sh" scripts that can be used to set up EFI boot entries

So, after a BIOS update you can either go through the procedure
mentioned at:


ie. typing some long `efibootmgr` incantations.

Or, you can:

1. Boot off the installation media into a UEFI shell.
2. Boot off the hard drive with `FS1:` followed by `a`.
3. Run `sudo bash /boot/b.sh` (and `sudo bash /boot/a.sh`) to put the
   entries back the way they were before.

Of course, I probably have the names back to front. I mapped "a" to
"linux" because that's the preferred one, and "b" to "linux-lts" because
that's only a fallback, but the way EFI entries are created, you
actually have to run "b before "a", so maybe that's a sign I should just
combine them into a single script. Whatever; I don't do this that often
so it's not probably something I have to agonize over.

13 months agofeat(contrib): add /boot/{a,b}.nsh scripts on Arch
Greg Hurrell [Thu, 19 Aug 2021 23:14:24 +0000 (01:14 +0200)] 
feat(contrib): add /boot/{a,b}.nsh scripts on Arch

Based on:


if my boot entries get blown away (eg. by a BIOS update), I should be
able to boot from the installation medium, get into a UEFI shell, and
run something like:


to boot off the drive, after which I can do the steps described in
"Applying BIOS updates" in:


a little more easily (ie. via copy-paste).

I might also consider dumping the efibootmgr commands themselves into a
script to make running them easier...

13 months agorefactor(systemd): run ssh-agent out of systemd
Greg Hurrell [Thu, 19 Aug 2021 21:53:48 +0000 (23:53 +0200)] 
refactor(systemd): run ssh-agent out of systemd

This is more flexible than running it out of X. For example, I should be
able to log out of X, and ssh into the machine remotely and find that I
still have an agent running.

13 months agostyle: run `yarn format`
Greg Hurrell [Thu, 19 Aug 2021 15:24:34 +0000 (17:24 +0200)] 
style: run `yarn format`

13 months agofix(dotfiles): update for compatibility with new `ghcs` release
Greg Hurrell [Thu, 19 Aug 2021 15:14:02 +0000 (17:14 +0200)] 
fix(dotfiles): update for compatibility with new `ghcs` release

13 months agorefactor: don't use AppleScript in karabiner-kill flow
Greg Hurrell [Thu, 19 Aug 2021 12:40:59 +0000 (14:40 +0200)] 
refactor: don't use AppleScript in karabiner-kill flow

As described in:


just got locked out at the lock screen with SpaceFN jammed on and
couldn't kill Karabiner-Elements because of a permissions dialog that I
couldn't see.

This is the same dialog described here:


Now, I can't remember whether it was specifically
`karabiner_console_user_server` that was mentioned in the dialog I saw,
but in reading the rest of the thread I saw I didn't need to use
AppleScript to run the script in the terminal, and could use `open` and
a `.command` extension instead.

So, that might not prevent the permissions dialog from showing up in the
future, but it still seems like a worthy refactoring to do.

13 months agochore: revert "chore(dotfiles): remove Hammerspoon clipboard-showing binding"
Greg Hurrell [Sun, 15 Aug 2021 20:00:32 +0000 (22:00 +0200)] 
chore: revert "chore(dotfiles): remove Hammerspoon clipboard-showing binding"

Having used the Alfred-powered alternative for a while, I find I
actually like the old way better. For example, with really huge
clipboard contents, the Finder-powered view is better (scrollable). And
it shows non-textual content just fine too.

This reverts commit 5c5c442fd9edef467c5782cefa735b583de0e1cc.

13 months agofeat(vim): [experimental] use OSC-52 in Vim when in Kitty
Greg Hurrell [Sun, 15 Aug 2021 16:41:02 +0000 (18:41 +0200)] 
feat(vim): [experimental] use OSC-52 in Vim when in Kitty

13 months agorefactor(dotfiles): switch back to using OSC 52 for `clip` when in Kitty
Greg Hurrell [Sun, 15 Aug 2021 09:17:03 +0000 (11:17 +0200)] 
refactor(dotfiles): switch back to using OSC 52 for `clip` when in Kitty

Works fine on Kitty's current `master`, as I had hoped it would.

13 months agochore: revert "refactor(dotfiles): [demo] teach `clip` to use OSC 52 escape sequence"
Greg Hurrell [Sun, 15 Aug 2021 09:02:57 +0000 (11:02 +0200)] 
chore: revert "refactor(dotfiles): [demo] teach `clip` to use OSC 52 escape sequence"

As noted in the previous commit, this works, but not for large inputs
(tested in both Kitty and iTerm2). Even `cat /usr/share/dict/words |
kitty +kitten clipboard` doesn't behave well (although I am on a
several-weeks-old Kitty build on this machine, so it is possibly it
works better on current `master`; I'll try that out later), which
inclines me to think this would be a bit of a rabbit hole to go down.

This reverts commit bf75f40bdc2f2f9a0343ac422e4a61c1542e96c6.

13 months agorefactor(dotfiles): [demo] teach `clip` to use OSC 52 escape sequence
Greg Hurrell [Sun, 15 Aug 2021 08:57:49 +0000 (10:57 +0200)] 
refactor(dotfiles): [demo] teach `clip` to use OSC 52 escape sequence

Both Kitty and iTerm2 grok the OCS 52 escape sequence out of the box, so
we can use that instead of Clipper in those terminals. We keep the
Clipper-based code path around as a fallback (for example, would be used
in Terminal.app or other terminals).

Labeling this as a demo though because it probably needs more work. It
works fine with small copies, but not big ones (eg. `cat
/usr/share/dict/words | clip`). Probably need to break it up into chunks
for that to work. I'm committing this so that it can be found in the
history, but I'll revert it in the next commit; will revisit it when I
have time to do a deeper investigation.


- https://github.com/wincent/clipper/issues/26#issuecomment-898799659
- https://www.reddit.com/r/vim/comments/k1ydpn/a_guide_on_how_to_copy_text_from_anywhere/
- https://github.com/roy2220/osc52pty

13 months agofeat(dotfiles): add some aliases to `gg`
Greg Hurrell [Thu, 12 Aug 2021 13:34:40 +0000 (15:34 +0200)] 
feat(dotfiles): add some aliases to `gg`

   gg cs         -> codespace
   gg codespaces -> codespace
   gg db         -> dbconsole
   gg serve      -> server

Note I also renamed "codespaces" to "codespace" because while the
product is called "Codepaces" I generally want to interact with a
singular instance, ie. a "Codespace".

13 months agofeat(dotspaces): add `gg ports`
Greg Hurrell [Thu, 12 Aug 2021 10:01:35 +0000 (12:01 +0200)] 
feat(dotspaces): add `gg ports`

Easier than remembering and typing `gh cs ports forward $NAME 80 80`.

Given a name, does the right thing. If you don't supply a name, shows
usage and prints listing to make it easy to pick out the name and

13 months agorefactor(dotfiles): get rid of silly emoji
Greg Hurrell [Mon, 9 Aug 2021 12:39:43 +0000 (14:39 +0200)] 
refactor(dotfiles): get rid of silly emoji

This didn't have the intended effect anyway... I want a 1-wide character
to make the padding on each side symmetrical, but this one is 2-wide...

13 months agofeat(dotfiles): tweak `git zap` and `git zip` output to have equal width
Greg Hurrell [Mon, 9 Aug 2021 09:49:11 +0000 (11:49 +0200)] 
feat(dotfiles): tweak `git zap` and `git zip` output to have equal width

Because when you run them in sequence with `&&` you get this:

    [  OK   ]: wincent/branch-1
    [  OK   ]: wincent/branch-2
    [  OK   ]: wincent/branch-3
    [  OK   ]: wincent/branch-4
    [  OK   ]: wincent/branch-5
    [   OK   ]: wincent/branch-1
    [   OK   ]: wincent/branch-2
    [   OK   ]: wincent/branch-3
    [   OK   ]: wincent/branch-4
    [   OK   ]: wincent/branch-5

Now, you get this instead:

    [   👍   ]: wincent/branch-1
    [   👍   ]: wincent/branch-2
    [   👍   ]: wincent/branch-3
    [   👍   ]: wincent/branch-4
    [   👍   ]: wincent/branch-5
    [   👍   ]: wincent/branch-1
    [   👍   ]: wincent/branch-2
    [   👍   ]: wincent/branch-3
    [   👍   ]: wincent/branch-4
    [   👍   ]: wincent/branch-5

Pretty obviously these should probably be one command as I almost always
run them together, but I'm still not sure what form that command should
take, so leaving it for now.

13 months agodocs(dotfiles): note how to set hostname on macOS
Greg Hurrell [Mon, 9 Aug 2021 08:57:39 +0000 (10:57 +0200)] 
docs(dotfiles): note how to set hostname on macOS

Not sure if related, but after a kernel panic (and an additional
reboot), my work Mac is coming up without a hostname (ie. `hostname`
prints an IP address, and `hostname -s` is even less helpful than that,
printing "192" 🤦). In the Sharing pref pane the name is there as it
always has been.

Seems mostly people ask about this in the context of public WiFi
networks, but the answer still seems valid:


13 months agochore(nvim): update ferret submodule again
Greg Hurrell [Fri, 6 Aug 2021 09:16:18 +0000 (11:16 +0200)] 
chore(nvim): update ferret submodule again

Just doc updates, but I want to keep things in sync.

* aspects/nvim/files/.config/nvim/pack/bundle/opt/ferret 9ec57fd...a513036 (1):
  > docs: format leader with backticks

13 months agochore(vim): update ferret submodule
Greg Hurrell [Fri, 6 Aug 2021 09:04:25 +0000 (11:04 +0200)] 
chore(vim): update ferret submodule

* aspects/nvim/files/.config/nvim/pack/bundle/opt/ferret 14d8839...9ec57fd (2):
  > docs: fix a minor typo in the docs
  > feat: add `<Plug>(FerretBack)`, `<Plug>(FerretBlack)`, `<Plug>(FerretQuack)`

13 months agofeat(pacman): add some packages useful for contributing to the AUR
Greg Hurrell [Thu, 5 Aug 2021 13:41:42 +0000 (15:41 +0200)] 
feat(pacman): add some packages useful for contributing to the AUR

Just needed these to update some bustage in the clipper-git package:


13 months agofeat(aur): get `par` on this machine
Greg Hurrell [Thu, 5 Aug 2021 13:41:24 +0000 (15:41 +0200)] 
feat(aur): get `par` on this machine

I miss this several times a day in Vim.

14 months agochore(dotfiles): remove Hammerspoon clipboard-showing binding
Greg Hurrell [Wed, 4 Aug 2021 16:00:25 +0000 (18:00 +0200)] 
chore(dotfiles): remove Hammerspoon clipboard-showing binding

Because I can do this with Alfred now, and without the AppleScript:


14 months agofeat(dotfiles): teach `gg codespaces` to delegate to `gh cs ssh`
Greg Hurrell [Tue, 3 Aug 2021 10:10:12 +0000 (12:10 +0200)] 
feat(dotfiles): teach `gg codespaces` to delegate to `gh cs ssh`

Optimize for what is now my most common use case; ie.

    gg codespaces         → gh cs ssh --profile github-codespaces

To get the old behavior, pass `--ssh`:

    gg codespaces --ssh   → ssh github-codespaces

Note the wrinkle that `kitty` can't work via `gh cs ssh` (it needs to
replace the `ssh` command). Sadly, another reason to not use kitty 😢.

14 months agofeat(pacman): install steam
Greg Hurrell [Fri, 30 Jul 2021 09:25:39 +0000 (11:25 +0200)] 
feat(pacman): install steam

Previously, I had manually installed this because you needed to enable
the multilib repo first; but now that I am managing /etc/pacman.conf I
can just include it in the list of packages installed by default.

14 months agorefactor(pacman): manage /etc/pacman.conf by ovewriting
Greg Hurrell [Fri, 30 Jul 2021 09:12:59 +0000 (11:12 +0200)] 
refactor(pacman): manage /etc/pacman.conf by ovewriting

No need to use an ini module for this. Any time the system wants to
update /etc/pacman.conf it will create /etc/pacman.conf.pacnew and I can
easily diff it from there, as I already did a few commits back in

14 months agochore(pacman): remove unused file
Greg Hurrell [Fri, 30 Jul 2021 09:05:44 +0000 (11:05 +0200)] 
chore(pacman): remove unused file

As explained in the parent commit, I don't need this file any more since
starting to use a proper USB hub. (In any case, I still can hit the
Insert key at the lock screen to switch layouts; see the `~/.xinitrc`
config for that trick.)

14 months agorefactor(pacman): bury systemd config files deeper in "files/"
Greg Hurrell [Fri, 30 Jul 2021 09:00:48 +0000 (11:00 +0200)] 
refactor(pacman): bury systemd config files deeper in "files/"

So that I don't have a mix of "top-level files that going to get shoved
into an /etc subdirectory" with "nested files whose paths reflect where
they are going to go under /etc".

Overall, looks like this now:

    └── etc
        ├── pacman.conf
        └── systemd
            └── system
                ├── resume@.service
                └── suspend@.service

Note that "resume" is still unused, as explained in 59290291f45f3c33. I
haven't noticed my keyboard layout getting unset in a while now, and I
think it's because the keyboard is no longer going through the monitor's
incredibly flakey built-in "KVM" USB hub (I'm using an external hub
now). I'll remove the file in the next commit seeing as it will
apparently never be used; I am just including it in this move commit so
that its final resting place in the Git history is next to its cousin.

14 months agochore(pacman): port prior changes to update pacman.conf file
Greg Hurrell [Fri, 30 Jul 2021 08:53:03 +0000 (10:53 +0200)] 
chore(pacman): port prior changes to update pacman.conf file

Re-enabling multilib, and turning on ParallelDownloads for the first
time (exciting).

See the excitement, and changelog etc:


14 months agochore(pacman): update /etc/pacman.conf snapshot
Greg Hurrell [Fri, 30 Jul 2021 08:51:36 +0000 (10:51 +0200)] 
chore(pacman): update /etc/pacman.conf snapshot

This shows the changes add in /etc/pacman.conf.pacnew, which arrived
with the update to Pacman 6.

14 months agochore(pacman): add /etc/pacman.conf snapshot
Greg Hurrell [Fri, 30 Jul 2021 08:49:57 +0000 (10:49 +0200)] 
chore(pacman): add /etc/pacman.conf snapshot

So I can diff it against the latest (Pacman 6) one.

14 months agofeat(aur, dotfiles): set-up Glow on Arch Linux
Greg Hurrell [Fri, 30 Jul 2021 08:43:25 +0000 (10:43 +0200)] 
feat(aur, dotfiles): set-up Glow on Arch Linux

14 months agofeat(dotfiles): set up binding to show clipboard contents
Greg Hurrell [Thu, 29 Jul 2021 17:38:21 +0000 (19:38 +0200)] 
feat(dotfiles): set up binding to show clipboard contents

At times I am paranoid* that I am about to paste the wrong thing in a
public channel. For example I might have tried to grab something out of
a text document, but it silently fails for whatever reason (maybe I
pressed the wrong key), and so I end up pasting the thing that I
previously put in the clipboard, which could be my bank account number,
a confession, or anything.

So, set up Alt (that is Option) + V to preview the clipboard contents.
As far as I can tell, Alt+V's default behavior is not that useful; in my
testing it seems to just insert "√".

[*]: But, if they really _are_ out to get you, is that paranoia?

14 months agofeat(nvim): add "**" again
Greg Hurrell [Wed, 28 Jul 2021 19:42:17 +0000 (21:42 +0200)] 
feat(nvim): add "**" again

As noted, not quite the same as what I had with UltiSnips, but it
delivers 90% of the value.

14 months agofeat: show elapsed time in summary output
Greg Hurrell [Wed, 28 Jul 2021 17:36:15 +0000 (19:36 +0200)] 
feat: show elapsed time in summary output

Doesn't do the per-task times like mentioned as a possibility in the
issue because I think it might be noisy and riddled with edge cases and
I am too lazy.

Closes: https://github.com/wincent/wincent/issues/116
14 months agofeat(pacman): add rust-analyzer
Greg Hurrell [Fri, 23 Jul 2021 07:29:21 +0000 (09:29 +0200)] 
feat(pacman): add rust-analyzer

For LSP goodness in Neovim when editing Rust.

Arch companion to macOS commit 094e348d48146aa15d0102b83b4.

14 months agofix(pacman): remove reference to non-existent pipewire-pulseaudio
Greg Hurrell [Fri, 23 Jul 2021 07:28:31 +0000 (09:28 +0200)] 
fix(pacman): remove reference to non-existent pipewire-pulseaudio

It should be pipewire-pulse. Not sure if the name changed, or I just had
it wrong.

14 months agofeat(nvim): activate rust.vim and set up rust-analyzer
Greg Hurrell [Wed, 21 Jul 2021 19:30:01 +0000 (21:30 +0200)] 
feat(nvim): activate rust.vim and set up rust-analyzer

Should have included this last night in 8b528a75 and 094e348d, but I

14 months agorefactor(nvim): move some Vimscript out of a Lua string
Greg Hurrell [Wed, 21 Jul 2021 16:48:26 +0000 (18:48 +0200)] 
refactor(nvim): move some Vimscript out of a Lua string

Because of the weird way undotree chooses to accommodate overrides, we
still need some Vimscript, to overwrite a global function, but from
there we can call into Lua.

Note that sticking the mappings in an "undotree" `ftplugin` would be the
"right" way to do this, but that doesn't work because undotree sets the
filetype and then overwrites the mappings you set up, then calls the
global function.

14 months agorefactor(nvim): make plugin loading a little more uniform
Greg Hurrell [Wed, 21 Jul 2021 16:24:33 +0000 (18:24 +0200)] 
refactor(nvim): make plugin loading a little more uniform

By channeling all loading through `wincent.plugin` instead of mixing Vim
commands (like `:packadd!`) and calls to `wincent.lazy`.

14 months agofeat(nvim): make help available for lazy-loaded plugins
Greg Hurrell [Wed, 21 Jul 2021 14:18:13 +0000 (16:18 +0200)] 
feat(nvim): make help available for lazy-loaded plugins

To understand what's going on here, you need to know:

1. `packadd!` adds to the 'runtimepath' but it doesn't load anything
2. `packadd` adds to the 'runtimepath' _and_ loads the plugin eagerly
3. As part of the |load-plugins| process, Vim will load all plugins that
   are found in the 'runtimepath'.

So, the net effect of this commit is:

1. `packadd!` in `init.lua` sets up the runtimepath.
2. |load-plugins| happens, so plugins get loaded.
3. |VimEnter| happens, so additional `packadd!` calls are made; this
   adds the plugins to the 'runtimepath', which means we can find their
   help, but the plugins aren't loaded yet.
4. Due to user interaction and `wincent.lazy` mapping/command stubs, the
   lazy plugins may be loaded for real later on, on demand.

Note that for lazy-loaded plugins, we call `packadd`, which will no-op
re-add them to the `runtimepath` again, and then load them, and then we
run the desired mapping/command.

The main gap in this abstraction: once a plugin like "Goyo" is in the
'runtimepath' but not loaded yet, you can invoke an autoloaded function
and that will cause the autoloaded function's file to get loaded. It
_doesn't_ load the rest of the plugin though. ie. I can run `:call
goyo#execute('!', '') and it will fire up Goyo, but it won't source
"plugin/goyo.vim" (which would define the real `:Goyo` command).

All of this suggests that we may want to roll this into a slightly
higher level abstraction to stop it leaking. But I don't think we'll
ever be able to plug the autoload hole.

14 months agochore(nvim): port UltiSnips Markdown snippets to Lua
Greg Hurrell [Wed, 21 Jul 2021 07:56:53 +0000 (09:56 +0200)] 
chore(nvim): port UltiSnips Markdown snippets to Lua

As noted, the table one could be made way smarter but for now I am
keeping it basically the same as it was in the UltiSnips version.

The other thing about LuaSnip is you can't put newlines inside your text
nodes, so instead of writing something like this:

      | First Header  | Second Header |
      | ------------- | ------------- |
      | Content Cell  | Content Cell  |
      | Content Cell  | Content Cell  |

you have to split stuff up into a (list) table of one-line strings:

      '| First Header  | Second Header |',
      '| ------------- | ------------- |',
      '| Content Cell  | Content Cell  |',
      '| Content Cell  | Content Cell  |',

14 months agofeat(homebrew): install rust-analyzer
Greg Hurrell [Tue, 20 Jul 2021 22:35:01 +0000 (00:35 +0200)] 
feat(homebrew): install rust-analyzer

14 months agochore(nvim): add rust.vim
Greg Hurrell [Tue, 20 Jul 2021 22:18:15 +0000 (00:18 +0200)] 
chore(nvim): add rust.vim

Project page:


14 months agoperf(nvim): lazy-load nvim-tree.lua
Greg Hurrell [Tue, 20 Jul 2021 21:21:39 +0000 (23:21 +0200)] 
perf(nvim): lazy-load nvim-tree.lua

Because, as reported here:


it is adding about 40ms to startup time. I'm sure it adds much less
on a faster machine, but on this one (6-year-old, thermal-throttling,
summer-afflicted laptop), it is accounting for about 25% of startup

14 months agorefactor(nvim): port last plugin file to Lua
Greg Hurrell [Tue, 20 Jul 2021 20:45:35 +0000 (22:45 +0200)] 
refactor(nvim): port last plugin file to Lua

14 months agorefactor(nvim): port rest of leader mappings
Greg Hurrell [Tue, 20 Jul 2021 19:52:37 +0000 (21:52 +0200)] 
refactor(nvim): port rest of leader mappings

14 months agochore(homebrew): add `gh`, kind of
Greg Hurrell [Tue, 20 Jul 2021 08:45:54 +0000 (10:45 +0200)] 
chore(homebrew): add `gh`, kind of

Not sure whether I want to include this as part of an automated install
yet, but also want to document that it is installed, so adding it here
commented out.

14 months agorefactor(nvim): port some more things to Lua
Greg Hurrell [Mon, 19 Jul 2021 22:22:51 +0000 (00:22 +0200)] 
refactor(nvim): port some more things to Lua

14 months agofeat(dotfiles): teach `git root` to print root too
Greg Hurrell [Mon, 19 Jul 2021 16:42:17 +0000 (18:42 +0200)] 
feat(dotfiles): teach `git root` to print root too

And show how it can be used.

Specifically, we want to make sure `safe-ruby` is in the `$PATH` if

Sure, I could also have just done a `git root` at the top to `cd` at the
start, but I didn't think of that until too late. In any case, I have a
preference for avoiding `cd` in shell scripts if possible because it can
be hostile to refactoring (ie. any change in order risks breaking things
because lines no longer run from the context they think they're running

14 months agofix(dotfiles): fix one more mistake and make it less likely to recur
Greg Hurrell [Mon, 19 Jul 2021 16:24:15 +0000 (18:24 +0200)] 
fix(dotfiles): fix one more mistake and make it less likely to recur

14 months agofix(dotfiles): really fix the path this time
Greg Hurrell [Mon, 19 Jul 2021 16:17:34 +0000 (18:17 +0200)] 
fix(dotfiles): really fix the path this time

Brought to you by the exclusive clique of the elite "Really Fix" club.

14 months agofix(dotfiles): fix path in `gg serviceowners`
Greg Hurrell [Mon, 19 Jul 2021 16:15:38 +0000 (18:15 +0200)] 
fix(dotfiles): fix path in `gg serviceowners`

14 months agorefactor(dotfiles): pick a better-looking emoji for `gg codespaces`
Greg Hurrell [Mon, 19 Jul 2021 13:05:02 +0000 (15:05 +0200)] 
refactor(dotfiles): pick a better-looking emoji for `gg codespaces`

14 months agofeat(dotfiles): add `gg codespaces`
Greg Hurrell [Mon, 19 Jul 2021 12:23:51 +0000 (14:23 +0200)] 
feat(dotfiles): add `gg codespaces`

Just a convenience shortcut to make connecting from kitty a little

14 months agochore(dotfiles): make kitty tab bar colors match iTerm
Greg Hurrell [Mon, 19 Jul 2021 11:36:36 +0000 (13:36 +0200)] 
chore(dotfiles): make kitty tab bar colors match iTerm

Just grabbed the iTerm ones (approximately, but close enough) using

14 months agofeat(dotfiles): make colorscheme changes sticky for kitty too
Greg Hurrell [Mon, 19 Jul 2021 11:22:32 +0000 (13:22 +0200)] 
feat(dotfiles): make colorscheme changes sticky for kitty too

14 months agofix(dotfiles): make opt-left/right work in kitty on macOS
Greg Hurrell [Mon, 19 Jul 2021 10:08:04 +0000 (12:08 +0200)] 
fix(dotfiles): make opt-left/right work in kitty on macOS

This is a kludge fix. I had these keys working in kitty on Arch with the
existing config. In macOS, however, the keys don't work. Ctrl-V followed
by the key combination shows what actual characters the terminal is
seeing in both platforms.

I'm in a hurry, so I haven't been able to come up with a strategy for
distinguishing between:

1. Being on Darwin (needs 3C/3D).
2. Being in Linux via SSH from Darwin (also needs 3C/3D).
3. Being on Linux (needs 5C/5D).

I'm guessing this is the old "macOS treats Alt differently than other
platforms problem": On macOS, the thing everybody else calls "Alt" is
called "Command" (formerly "Apple"). The thing that everybody else calls
"Super" is called "Alt" or "Option".

With this kluge, _both_ modifiers end up working in Kitty. At least, I
think they do (I'm on macOS right now). I briefly tested on Arch and at
least established that this doesn't break the existing mapping.

14 months agochore(dotfiles): make kitty tabs a little more obvious
Greg Hurrell [Mon, 19 Jul 2021 09:31:58 +0000 (11:31 +0200)] 
chore(dotfiles): make kitty tabs a little more obvious

In the room where I am during the day it's very bright, especially
during summer, so it is hard to see the tabs based on background color
alone. Go for a crisp vertical dividing line instead.

14 months agochore(dotfiles): make cmd+left click on URLs work again in kitty
Greg Hurrell [Mon, 19 Jul 2021 07:53:25 +0000 (09:53 +0200)] 
chore(dotfiles): make cmd+left click on URLs work again in kitty

As noted in the previous commit, this is done using the new way
(replacing `open_url_modifiers`).

14 months agochore(dotfiles): freshen kitty.conf
Greg Hurrell [Mon, 19 Jul 2021 07:38:17 +0000 (09:38 +0200)] 
chore(dotfiles): freshen kitty.conf

1. Move kitty.conf out the way.
2. Select "Preferences..." from the kitty application menu; this creates
   a new kitty.conf.
3. Look at the diff, bringing old customizations back across.

The main differences since last time are:

- kitty now shows default settings as comments. This is nice, because it
  means at a glance you can see what you've actually overridden.
- Some descriptions are longer now.
- Some new options.
- I chose not to carry across the `macos_thicken_font` override; I don't
  really mind the look without it.
- Some features removed; eg. `open_url_modifiers`; as changelog states:

  > Backward incompatibility: The options to control which modifiers
  > keys to press for various mouse actions have been removed, if you used
  > these options, you will need to replace them with configuration using
  > the new :ref:`mouse actions framework <conf-kitty-mouse.mousemap>` as
  > they will be ignored. The options were: terminal_select_modifiers,
  > rectangle_select_modifiers and open_url_modifiers.

  So I'll make that adjustment in the next commit.

14 months agorefactor(nvim): turn down updatecount
Greg Hurrell [Sun, 18 Jul 2021 22:46:37 +0000 (00:46 +0200)] 
refactor(nvim): turn down updatecount

Pointless, now that we're not enabling swap files any more.

14 months agorefactor(nvim): switch tab listchar for benefit of kitty
Greg Hurrell [Sun, 18 Jul 2021 21:42:46 +0000 (23:42 +0200)] 
refactor(nvim): switch tab listchar for benefit of kitty

Works around:


by picking a new glyph that looks almost the same, but which renders
adequately on both iTerm and kitty.

14 months agorefactor(dotfiles): don't bother trying to bounce Dock icon outside of iTerm
Greg Hurrell [Sun, 18 Jul 2021 21:05:09 +0000 (23:05 +0200)] 
refactor(dotfiles): don't bother trying to bounce Dock icon outside of iTerm

Only going to work in iTerm, as described here:


Originally added in 227082e63 and e71a31a25.

14 months agorefactor: prepare to switch to kitty
Greg Hurrell [Sun, 18 Jul 2021 20:45:07 +0000 (22:45 +0200)] 
refactor: prepare to switch to kitty

For profound reasons:


> I think I may have found a compelling (Face with tears of joy) reason
> to use kitty instead of iTerm2 on macOS Big Sur: no unwanted round
> corners and 1-pixel window border. As far as I know, there's no easy
> way to do this in iTerm2:
> https://groups.google.com/g/iterm2-discuss/c/vb0VNo3WM-k/m/GL9Y2TbwAgAJ

Only down-side is that I am going to have to pick a new tab listchar in
Vim, because my current choice doesn't render nicely in Kitty, as
described here:


I'll also lose (for now) some functionality that I'll have to
recreate/adjust, like my "Open in terminal Vim" workflow. I think that
shouldn't be too hard though.

14 months agorefactor: move base16-kitty and base16-iterm2 out of submodules
Greg Hurrell [Sun, 18 Jul 2021 11:50:20 +0000 (13:50 +0200)] 
refactor: move base16-kitty and base16-iterm2 out of submodules

So we can update them at will and keep them fresh.

14 months agofeat: add more validation to base16-builder.rb
Greg Hurrell [Sun, 18 Jul 2021 11:16:15 +0000 (13:16 +0200)] 
feat: add more validation to base16-builder.rb

14 months agorefactor(nvim): switch base16-nvim source to separate repo
Greg Hurrell [Sun, 18 Jul 2021 10:41:42 +0000 (12:41 +0200)] 
refactor(nvim): switch base16-nvim source to separate repo

14 months agochore(nvim): prepare to extract base16-nvim into separate repo
Greg Hurrell [Sun, 18 Jul 2021 10:14:05 +0000 (12:14 +0200)] 
chore(nvim): prepare to extract base16-nvim into separate repo

14 months agorefactor(nvim): avoid repeated calls to :highlight
Greg Hurrell [Sun, 18 Jul 2021 09:56:33 +0000 (11:56 +0200)] 
refactor(nvim): avoid repeated calls to :highlight

14 months agorefactor(nvim): regenerate nvim base16 files as Lua
Greg Hurrell [Sun, 18 Jul 2021 08:33:39 +0000 (10:33 +0200)] 
refactor(nvim): regenerate nvim base16 files as Lua

This is the most straightforward port of the base16-vim files I could
do, to make it easier to see what changed in the move from ".vim" to

14 months agofeat: take control of base16 management
Greg Hurrell [Sun, 18 Jul 2021 01:21:40 +0000 (03:21 +0200)] 
feat: take control of base16 management

Because I want to generate Lua versions of these for Neovim, I may as
well generate the other two versions I need (seeing as I had to figure
out where the sources are, where the templates are etc). This is good
because the upstream template projects are updated exceedingly rarely,
while the upstream-of-upstream scheme projects (maintained by many
individual authors) tend to update much more often; proof of this is in
the number of new themes made available thanks to the changes in this

As my needs here are super minimal (just generating for Vim and the
shell), I am not even using a full featured "builder", just a tiny Ruby
script; that way, I avoid having to deal with dependencies.

This gist:


produced with:

    git diff --no-index \
      vendor/base16-templates/base16-shell/scripts \

shows the differences in the fresh build output relative to the upstream
base16-shell project. Mostly it is new files (total count goes from
131 to 188), but there are some in there with minor changes (eg. see
base16-horizon-dark.sh and some others). Things in here look similar
enough to convince me that my generation code is probably working
correctly (although I do admit it assumes well-formed input for the most
part... I'll add more validations later).

Likewise, this gist:


produced with:

    git diff --no-index \
      vendor/base16-templates/base16-vim/colors \

shows mostly new schemes (again, total count goes from 131 to 188), with
some small number of substantive changes inside some existing themes.

Will continue this tomorrow, replacing the nvim templates with something
that is actually Lua.

14 months agofeat(nvim): generalize improved key generation
Greg Hurrell [Sat, 17 Jul 2021 20:51:27 +0000 (22:51 +0200)] 
feat(nvim): generalize improved key generation

Extracts the function added in the previous commit so that we can
benefit from the same introspectability benefits in autocommands.


:filter /callbacks/ map
:filter /callbacks/ imap
:filter /callbacks/ cmap


s  <C-E>       * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L24_2()
s  <Tab>         v:lua.wincent.g.map_callbacks.plugin_autocomplete_L177_1()
s  <CR>        * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L46_3()
n  j           * v:lua.wincent.g.map_callbacks.plugin_mappings_normal_L38()
n  k           * v:lua.wincent.g.map_callbacks.plugin_mappings_normal_L37()
s  <S-Tab>       v:lua.wincent.g.map_callbacks.plugin_autocomplete_L62_0()
i  <BS>        * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L91()
i  <S-Tab>       v:lua.wincent.g.map_callbacks.plugin_autocomplete_L62()
i  <C-E>       * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L24()
i  <Tab>         v:lua.wincent.g.map_callbacks.plugin_autocomplete_L177()
i  <CR>        * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L46()
i  <C-Y>       * v:lua.wincent.g.map_callbacks.plugin_autocomplete_L38()
c  <S-Tab>     * v:lua.wincent.g.map_callbacks.plugin_mappings_command_L33()
c  <Tab>       * v:lua.wincent.g.map_callbacks.plugin_mappings_command_L21()

Note the duplicates there disambiguated by suffixes: that's because we
end up using the same function (eg. `c_e`) in an `imap` call and an
`snoremap` call etc.

And `:filter` doesn't work with `:autocmd` but we can fake it:

:redir! > /tmp/autocmds.txt
:redir END
:e /tmp/autocmds.txt

Which leaves us with:

    *.js.jsx  lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.jsx     lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.html    lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *.js      lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *.js.jsx  lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.jsx     lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.html    lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *.js      lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L246()
    *         lua wincent.g.autocommand_callbacks.after_plugin_loupe_L4()
    *         lua wincent.g.autocommand_callbacks.plugin_autocomplete_L195()
    *         lua wincent.g.autocommand_callbacks.plugin_autocomplete_L204()
    *         lua wincent.g.autocommand_callbacks.ftdetect_jest_L1()
    *         lua wincent.g.autocommand_callbacks.plugin_par_L31()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
              lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L64()
              lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L69()
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()

Here's the above output again with the headers preserved this time to
make it clear where these are coming from. Note there are no
tie-breaking suffixes this time, but some of the functions _look_ like

filetypedetect  BufNewFile
    *.js.jsx  lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.jsx     lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.html    lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *.js      lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
filetypedetect  BufReadPost
    *.js.jsx  lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.jsx     lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.html    lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
    *.js      lua wincent.g.autocommand_callbacks.ftdetect_jsx_L28()
WincentStatusline  BufWinEnter
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
WincentStatusline  BufWritePost
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
WincentStatusline  ColorScheme
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L246()
WincentLoupe  ColorScheme
    *         lua wincent.g.autocommand_callbacks.after_plugin_loupe_L4()
WincentAutocomplete  CompleteChanged
    *         lua wincent.g.autocommand_callbacks.plugin_autocomplete_L195()
WincentAutocomplete  CompleteDonePre
    *         lua wincent.g.autocommand_callbacks.plugin_autocomplete_L204()
filetypedetect  FileType
    *         lua wincent.g.autocommand_callbacks.ftdetect_jest_L1()
WincentParAutocmds  FileType
    *         lua wincent.g.autocommand_callbacks.plugin_par_L31()
WincentStatusline  FileWritePost
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
WincentStatusline  TextChanged
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
WincentStatusline  TextChangedI
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()
WincentStatusline  User
              lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L64()
              lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L69()
WincentStatusline  WinEnter
    *         lua wincent.g.autocommand_callbacks.lua_wincent_statusline_L87()

However, they're not really duplicates; the two entries like this:

    *.js.jsx  lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()
    *.jsx     lua wincent.g.autocommand_callbacks.ftdetect_jsx_L22()

are fruit of a single call to `autocmd` with a comma-separated pattern:

autocmd('BufNewFile,BufRead', '*.js.jsx,*.jsx', set_jsx)

so the function is stored/registered once, but Vim is reporting it as
two different autocmds, which technically, it is.

14 months agofeat(nvim): improve introspectability of anonymous Lua callbacks
Greg Hurrell [Sat, 17 Jul 2021 20:36:03 +0000 (22:36 +0200)] 
feat(nvim): improve introspectability of anonymous Lua callbacks

Starting with mappings, but I'll apply this to the other places we use
anonymous functions.

Before, running `:nmap j` would print:

n  j           * v:lua.wincent.g.map_callbacks._13()

Now, it prints:

n  j           * v:lua.wincent.g.map_callbacks.plugin_mappings_normal_L38()

The callback key is produced by grabbing the path to the function via
`debug.getinfo`, stripping off the prefix (eg. `~/.config/nvim`),
dropping the extension, turning non-alphanumeric characters (basically
that means slashes) into underscores, appending the line-number, and if
necessary to resolve collisions, appending a monotonically increasing
index number (this can happen if the same anonymous function is added

Closes: https://github.com/wincent/wincent/issues/115
14 months agorefactor(nvim): port normal mode mappings to Lua
Greg Hurrell [Sat, 17 Jul 2021 19:15:32 +0000 (21:15 +0200)] 
refactor(nvim): port normal mode mappings to Lua

14 months agorefactor(nvim): port more stuff to Lua
Greg Hurrell [Sat, 17 Jul 2021 18:55:13 +0000 (20:55 +0200)] 
refactor(nvim): port more stuff to Lua

Of note here is probably how I have to pass in "range" values via an
intermediate command in order to get them from mapping-land to Lua-land.

14 months agorefactor(nvim): port loupe.vim and par.vim to Lua
Greg Hurrell [Sat, 17 Jul 2021 17:46:24 +0000 (19:46 +0200)] 
refactor(nvim): port loupe.vim and par.vim to Lua

The `par` stuff is still crazy edge-casey; it will occasionally complain
about "word too long" for things that don't very obviously qualify for
the definition of a "word". I probably understand it to about 5% of the
possible depth... 🤦

14 months agorefactor(nvim): remove term.vim
Greg Hurrell [Sat, 17 Jul 2021 16:20:10 +0000 (18:20 +0200)] 
refactor(nvim): remove term.vim

Not needed in Neovim, as per `:h t_xx`:

    Nvim does not have special `t_XX` options nor <t_XX> keycodes to configure
    terminal capabilities. Instead Nvim treats the terminal as any other UI,
    e.g. 'guicursor' sets the terminal cursor style if possible.

14 months agorefactor(nvim): port dirvish customizations to Lua
Greg Hurrell [Sat, 17 Jul 2021 16:10:41 +0000 (18:10 +0200)] 
refactor(nvim): port dirvish customizations to Lua

Should always have been an ftplugin; not sure why I didn't do it this
way originally.

14 months agofeat(nvim): let <LocalLeader>f close nvim-tree.lua window
Greg Hurrell [Sat, 17 Jul 2021 16:01:34 +0000 (18:01 +0200)] 
feat(nvim): let <LocalLeader>f  close nvim-tree.lua window

In the same way that you can mash `<LocalLeader>t` repeatedly to toggle
the tree, you should be able to mash `<LocalLeader>f` repeatedly.

Closes: https://github.com/wincent/wincent/issues/114
14 months agorefactor(nvim): prefer `builtin echo` over `/bin/echo`
Greg Hurrell [Sat, 17 Jul 2021 14:19:09 +0000 (16:19 +0200)] 
refactor(nvim): prefer `builtin echo` over `/bin/echo`

In the interests of not leaking the password into the process table,
where others can see it, albeit briefly.

14 months agofeat(nvim): invalidate cached password if sudo call fails
Greg Hurrell [Sat, 17 Jul 2021 13:43:04 +0000 (15:43 +0200)] 
feat(nvim): invalidate cached password if sudo call fails

Seeing as a bad password is the most likely cause of failure.

14 months agofix(nvim): remove code commented out for testing
Greg Hurrell [Sat, 17 Jul 2021 11:51:29 +0000 (13:51 +0200)] 
fix(nvim): remove code commented out for testing

I was testing this with a short delay (5ms) instead of the usual delay
(5m) because I wanted to verify it quickly. Forgot to uncomment before

14 months agofeat(nvim): make :W work in Neovim
Greg Hurrell [Sat, 17 Jul 2021 10:31:21 +0000 (12:31 +0200)] 
feat(nvim): make :W work in Neovim

In porting vim-eunuch.vim to vim-eunuch.lua, I was reminded that the old
trick doesn't work in Neovim. I had barely noticed because the truth is
that I had trained myself to _not_ open root-owned files for writing
from an unprivileged user.

But anyway, we can fix it. I'm doing this "inside" Vim because I want to
have a way of getting the password to `sudo` without having to find a
variant of `SUDO_ASKPASS` that works for each platform I use.

`:W` prompts for password, writes the file, caches the pass for 5

`:W!` will prompt you for a password even if one is already cached
(useful if you entered a wrong pass and it got cached).

Security disclaimer: this asks for your password and stores it in a
variable for 5 minutes. Even after the variable contents are
garbage-collected, the text of the password may be recoverable from
memory using various tricks (debuggers etc). The password is
additionally (briefly) written to disk, where it is only as secure as
filesystem permissions allow (eg. does your OS return a truly private
`tempname()`? is the 700 mode adequately enforced on your filesystem?
are there other privileged users running on the system that would try to
read the pass? once the file is unlinked, when do the actual contents
get truly purged from storage? etc).

As I use this rarely, I am fine with all these trade-offs. But your
mileage may vary.

The other gotcha is that if you enter a wrong pass, Vim will pause while
`sudo` asks two more times for the (same) wrong password. At this point
if you want to retry you should use `:W!`. Again, I'm fine with this
trade-off because I don't think there is an easy workaround.

14 months agorefactor(nvim): port ftdetect files to Lua
Greg Hurrell [Fri, 16 Jul 2021 21:51:38 +0000 (23:51 +0200)] 
refactor(nvim): port ftdetect files to Lua

Two points of interest here:

- While testing this, found and fixed a bug caused by me using a symlink
  to share the "typescriptreact" and "javascriptreact" ftplugin files,
  in d9e91283e3612dffcc5.
- Now I get why `vim.regex` is a thing 😂 — because without real regular
  expressions (Lua string patterns, for example, don't have support for
  `|` alternation), I was forced to use frontier patterns (eg.
  `'%f%[a]thing%f[%A]'`) as a substitute for word boundaries (eg.
  '\v<thing>') and verbose helper functions.

14 months agorefactor(nvim): source with :source
Greg Hurrell [Fri, 16 Jul 2021 20:48:37 +0000 (22:48 +0200)] 
refactor(nvim): source with :source

Because, TIL, it automatically treats ".lua" files as Lua.

14 months agofeat(nvim): allow host-specific overrides to be written in Lua
Greg Hurrell [Fri, 16 Jul 2021 20:42:27 +0000 (22:42 +0200)] 
feat(nvim): allow host-specific overrides to be written in Lua

14 months agochore: update Corpus submodule
Greg Hurrell [Fri, 16 Jul 2021 20:22:27 +0000 (22:22 +0200)] 
chore: update Corpus submodule

* aspects/nvim/files/.config/nvim/pack/bundle/opt/corpus f50c640...1411cb6 (1):
  > refactor: get rid of unnecessary `get_var()` function

14 months agochore(nvim): update Corpus submodule again
Greg Hurrell [Fri, 16 Jul 2021 18:12:57 +0000 (20:12 +0200)] 
chore(nvim): update Corpus submodule again

Just to fix an annoying typo in the docs.

* aspects/nvim/files/.config/nvim/pack/bundle/opt/corpus 6aff854...f50c640 (1):
  > docs: fix sample config

14 months agochore(nvim): update Corpus submodule
Greg Hurrell [Fri, 16 Jul 2021 18:09:34 +0000 (20:09 +0200)] 
chore(nvim): update Corpus submodule

Make use of new `g:CorpusBangCreation` setting, and also do global
config as a Vim global instead of a Lua one.

* aspects/nvim/files/.config/nvim/pack/bundle/opt/corpus d4eaeb8...6aff854 (2):
  > feat: support both Lua global and Vim global for CorpusDirectories
  > feat: add `:Corpus!` and `g:CorpusBangCreation`

14 months agorefactor(nvim): port statusline.vim, tabline.vim to Lua
Greg Hurrell [Thu, 15 Jul 2021 23:00:00 +0000 (01:00 +0200)] 
refactor(nvim): port statusline.vim, tabline.vim to Lua