Skip to content

Draw diagrams

Julien Burkhard edited this page May 3, 2024 · 2 revisions

Why venn with hydra?

venn.nvim offers ascii and utf diagram drawing via virtual edit. Virtual edit (:h virtualedit) offers positioning the cursor anywhere, which is convenient together with virtual replace (:h gR) to write text, drawing or moving selections. Draw actions ought to be fast, meaning 1 key-press, but there are many options:

  • 4 basic directions (hjkl)
  • 4 arrow only draw commands for dense graphics
  • 4 diagonal direction movements with 2 diagonals
  • 2 diagonals without movements
  • box with overwriting or complementing existing content
  • the same for ascii and utf

Covering this amount of combinations becomes only sane with a modal approach, for which hydra is one option.

General

  • Prefer pink hydras for simplicity.
  • Arrows in utf16
default ones
◄, ▼, ▲, ►
0x25C4, 0x25BC, 0x25B2, 0x25BA
closely related ones
◀, ▾, ▴, ▶
0x25C0, 0x25BE, 0x25B4, 0x25B6
  • Lines in utf16
─ │
0x2500, 0x2502
  • Corners in utf16
┌► ─┐  │ ▲
│   ▼ ◄┘ └─
0x250C, 0x2510, 0x2518, 0x2514
◄┐┌─ │  ▲
 │▼  └►─┘
0x2510, 0x250C, 0x2514, 0x2518
  • Catchy keymaps: venn ascii, venn extended

Recommended setup

Usual error handling.

local ok_hydra, Hydra = pcall(require, 'hydra')
if not ok_hydra then
  vim.notify('hydra not installed...', vim.log.ERROR)
  return
end

local M = {}

-- your hydra configuration

return M

Drawing extended

Includes utf and convenient on-cursor arrow head modifications.

local venn_hint_utf = [[
 Arrow^^^^^^  Select region with <C-v>^^^^^^
 ^ ^ _K_ ^ ^  _f_: Surround with box ^ ^ ^ ^
 _H_ ^ ^ _L_  _<C-h>_: ◄, _<C-j>_: ▼
 ^ ^ _J_ ^ ^  _<C-k>_: ▲, _<C-l>_: ► _<C-c>_
]]

-- :setlocal ve=all
-- :setlocal ve=none
M.venn_hydra = Hydra {
  name = 'Draw Utf-8 Venn Diagram',
  hint = venn_hint_utf,
  config = {
    color = 'pink',
    invoke_on_body = true,
    on_enter = function() vim.wo.virtualedit = 'all' end,
  },
  mode = 'n',
  body = '<leader>ve',
  heads = {
    { '<C-h>', 'xi<C-v>u25c4<Esc>' }, -- mode = 'v' somehow breaks
    { '<C-j>', 'xi<C-v>u25bc<Esc>' },
    { '<C-k>', 'xi<C-v>u25b2<Esc>' },
    { '<C-l>', 'xi<C-v>u25ba<Esc>' },
    { 'H', '<C-v>h:VBox<CR>' },
    { 'J', '<C-v>j:VBox<CR>' },
    { 'K', '<C-v>k:VBox<CR>' },
    { 'L', '<C-v>l:VBox<CR>' },
    { 'f', ':VBox<CR>', { mode = 'v' } },
    { '<C-c>', nil, { exit = true } },
  },
}

Drawing ascii

Includes ascii and diagonals, but is missing boxing support.

  • simplified ascii art with hydra
  • symbols (-,|,^,<,>,/,\)
  • capital letters: -| movements
  • C-letters: <v^>
  • leader clockwise (time running): \/ including movements
  • leader anti-clockwise (enough time): \/ without movements
  • leader hjkl: arrow including rectangular movements
local venn_hint_ascii   = [[
 -| moves: _H_ _J_ _K_ _L_
 <v^> arrow: _<C-h>_ _<C-j>_ _<C-k>_ _<C-l>_
 diagnoal + move: leader + clockwise like ◄ ▲
 _<leader>jh_ _<leader>hk_ _<leader>lj_ _<leader>kl_
 diagnoal + nomove: anticlockwise like ▲ + ◄
 _<leader>hj_ _<leader>kh_ _<leader>jl_ _<leader>lk_
 set +: _<leader>n_
 rectangle move + arrow, ie ► with ->
 _<leader>h_ _<leader>j_ _<leader>k_ _<leader>l_
                              _<C-c>_
]]
-- _F_: surround^^   _f_: surround     ^^ ^
-- + corners ^  ^^   overwritten corners

M.ascii_hydra = Hydra {
  name = 'Draw Ascii Diagram',
  hint = venn_hint_ascii,
  config = {
    color = 'pink',
    invoke_on_body = true,
    on_enter = function() vim.wo.virtualedit = 'all' end,
  },
  mode = 'n',
  body = '<leader>va',
  heads = {
    { '<C-h>', 'r<' },
    { '<C-j>', 'rv' },
    { '<C-k>', 'r^' },
    { '<C-l>', 'r>' },
    { 'H', 'r-h' },
    { 'J', 'r|j' },
    { 'K', 'r|k' },
    { 'L', 'r-l' },
    { '<leader>jh', 'r/hj' },
    { '<leader>hj', 'r/' },
    { '<leader>hk', 'r\\hk' },
    { '<leader>kh', 'r\\' },
    { '<leader>lj', 'r\\jl' },
    { '<leader>jl', 'r\\' },
    { '<leader>kl', 'r/kl' },
    { '<leader>lk', 'r/' },
    { '<leader>n', 'r+' },
    { '<leader>h', 'r-hr<' },
    { '<leader>j', 'r|jrv' },
    { '<leader>k', 'r|kr^' },
    { '<leader>l', 'r-lr>' },

    { '<C-c>', nil, { exit = true } },
  },
}
Clone this wiki locally