Liking cljdoc? Tell your friends :D

Carto Flow for Vim

The hive.carto-flow.vim IAddon, MIT. It is the Vim vessel extension of hive.carto-flow: it registers the presenter :vim on the core timeline and shows every Carto operation frame in a Vim buffer.

The addon runs hive-vessel's :vim-channel executor on 127.0.0.1, which speaks Vim's JSON channel protocol (:help channel-commands). Each frame reaches Vim as ["call", "carto_flow#ingest", [message]], and the message already carries the rendered timeline line and detail lines, so Vim only lays them out. A Vim that connects late first receives the whole timeline. The executor holds one Vim connection at a time: a newly connected Vim replaces the previous one.

The listening port is written to $XDG_STATE_HOME/hive/carto-flow/vim.port (~/.local/state/... when XDG_STATE_HOME is unset) and removed on shutdown. Set :carto-flow.vim/port in the addon config for a fixed port; the default 0 picks a free one.

Vim setup

Needs Vim 8.2 or later built with +channel, +timers and +packages.

Automatic, at injection

The manifest declares an :addon/runtime (hive-addon's client-runtime seam). When the host mounts the addon with a runtime provisioner (hive-addon.runtime.boundary/provisioner passed to mount! as :provision), injection installs the plugin into Vim's package path, ~/.vim/pack/hive/start/hive-carto-flow, with a generated loader. Every Vim started afterwards loads it and, once it has entered, connects to this addon's port file and opens the timeline on the first live change. A Vim that is already running is activated through the provisioner's :eval-fn when the host supplies one. Nothing has to be typed. Tearing the addon down with the matching :deprovision removes the install.

Manual

The addon also extracts its plugin to a stable directory, by default ~/.local/state/hive/carto-flow/vim-plugin (the :carto-flow.vim/plugin-dir hook returns the exact path). Add it to your runtime path:

set rtp+=~/.local/state/hive/carto-flow/vim-plugin
syntax on

Then run :CartoFlow, or set g:carto_flow_autoconnect = 1 to connect on VimEnter. It connects using the port file and reconnects on its own when the server restarts.

Using the timeline

Live frames follow the edit: the changed file opens at the first changed line of the frame's diff, in a window that is not the timeline, and focus stays where it was (g:carto_flow_follow_edits, default on; :CartoFlowFollow flips it, :CartoFlowFollow on|off sets it). Relative frame paths resolve against g:carto_flow_roots, then the current directory.

These keys work in the timeline and in the carto-flow://frame detail:

KeyAction
]f / nnext frame (an open detail re-renders in place)
[f / pprevious frame
Glatest frame, and follow new ones
oopen the frame's code at its first changed line
<CR>(timeline) open the frame's detail and diff in a split
qclose the window

Core's cursor drives this one: when anything moves the core timeline cursor (:carto-flow/next!, :carto-flow/previous!, :carto-flow/latest!, from Emacs, a tool call, or another vessel), the connected Vim's cursor moves to the same frame and an open detail re-renders. Moving with n/p inside Vim stays local to that Vim.

Global keys

The timeline keys above only work inside it, so the plugin also maps four actions globally. <leader> is your mapleader.

KeyAction
<leader>cf, <F9>show or hide the timeline (:CartoFlowToggle)
<leader>clopen it on the newest frame and follow from there
<leader>ce, <S-F9>follow live edits into the code, or stop
<leader>cddisconnect, or connect again

Hiding the timeline keeps its buffer and its frames, so the next toggle shows the same view rather than an empty one.

Each key is installed only when it is free and nothing you wrote already reaches that action, so a vimrc binding wins:

nmap <F5> <Plug>(carto-flow-toggle)   " the default <leader>cf and <F9> stand down

The four named mappings are <Plug>(carto-flow-toggle), <Plug>(carto-flow-latest), <Plug>(carto-flow-follow) and <Plug>(carto-flow-connect). g:carto_flow_no_default_maps = 1 refuses the default set entirely and leaves them for you to bind.

Commands: :CartoFlow [port], :CartoFlowConnect [port], :CartoFlowDisconnect, :CartoFlowCode, :CartoFlowFollow [on|off], :CartoFlowToggle, and :CartoFlowClear, which clears only this Vim's view. g:carto_flow_auto_open = 1 opens the timeline on the first live frame without moving focus.

Neovim is not supported, because it has no Vim JSON channels. A separate hive-carto-flow-nvim addon using msgpack-rpc is the intended route.

Hooks

  • :carto-flow.vim/port returns the listening port.
  • :carto-flow.vim/port-file returns the port file path Vim reads.
  • :carto-flow.vim/plugin-dir extracts the Vim plugin and returns its directory. Running it again is safe.
  • :carto-flow.vim/vessel returns the hive-vessel target of the connected Vim.

Development

clojure -Sdeps "$(cat local.deps.edn)" -M:test

local.deps.edn points hive-carto-flow, hive-vessel, hive-addon, hive-events and hive-dsl at sibling checkouts; clojure -M:test runs against the published jars instead, which is what CI does. The integration test drives a real headless /usr/bin/vim, and the provision test drives a real Vim in tmux started after injection; both are skipped when Vim or its features are missing.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close