aboutsummaryrefslogtreecommitdiff
path: root/plugin/haredoc.vim
blob: 256ac9ffce8615bffa4533c7765014582438c4df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
" Haredoc plugin -- Hare documentation in vim
" Maintainer: Byron Torres <b@torresjrjr.com>
" Maintainer: Polesznyák Márk <contact@pml68.dev>
" Last Updated: 2025-12-06
" License: Vim License

command -nargs=? Haredoc  :call Haredoc(<q-args>)

function Haredoc(symbol)
	let symbol = a:symbol
	let popup = symbol == '.'
	let goto = symbol == ';'

	if (symbol == '.' || symbol == ',' || symbol == ';')
		let oldiskeyword = &iskeyword
		setlocal iskeyword+=:
		let symbol = expand('<cword>')
		let &iskeyword = oldiskeyword

		" resolve possibly non-complete symbols (chrono::moment)
		if match(symbol, "::") != -1 && &buftype == ''
			let [submodule, ident] = split(symbol, "::")[-2:-1]

			" try joining symbol with a use statement.
			" example: 'use time::chrono' -> 'time::chrono::moment'
			let use = getline(search('^use *.*::'..submodule, 'bnw'))
			if use != ''
				let symbol = substitute(
				\	use,
				\	'\(use *\|;\)',
				\	'',
				\	'g'
				\ )..'::'..ident
			endif
		endif
	endif

	if goto
		let line = search('^fn '..symbol, 'bnw')

		if line != 0
			execute line
		else
			let haredoc_output = system('haredoc -N '..symbol)

			if match(haredoc_output, ":") != 1
				let [filepath, line] = split(haredoc_output, ":")[-2:-1]

				execute 'edit +'..line..' '..filepath
			else
				execute "echo '"..haredoc_output.."'"
			endif
		endif
	elseif popup && has('popupwin') && has('terminal')
		let buf = term_start(
		\	[
		\		'sh', '-c',
		\		"haredoc -Ftty '"..symbol.."' | LESS= less -RKX",
		\	],
		\	#{
		\		term_name: '[haredoc] '..symbol,
		\		hidden: 1,
		\		term_finish: 'close',
		\	},
		\ )
		call setbufvar(buf, "&bufhidden", 'wipe')
		let minheight = 1 + system(
		\	"haredoc -Ftty '"..symbol.."' 2>&1 | wc -l"
		\ )
		let winid = popup_atcursor(
		\	buf,
		\	#{
		\		title: "[haredoc] "..symbol,
		\		col: 'cursor-'..virtcol('.'),
		\		minwidth: 84,
		\		minheight: minheight,
		\		fixed: v:false,
		\		wrap: v:false,
		\		border: [1, 1, 1, 1],
		\	},
		\ )
	elseif has('terminal')
		call term_start(
		\	[
		\		'sh', '-c',
		\		"haredoc -Ftty '"..symbol.."' | less -RKX",
		\	],
		\	#{
		\		term_name: '[haredoc] '..symbol,
		\	},
		\ )
		set nonumber filetype=hare bufhidden=wipe
		nnoremap <buffer> q  :close<CR>
		nnoremap <buffer> <nowait> u  <C-U>
		nnoremap <buffer> <nowait> d  <C-D>
	elseif has('nvim')
		let buf = nvim_create_buf(0, 1)
		let win = nvim_open_win(buf, 1, #{
		\	relative: 'cursor',
		\	width: 80,
		\	height: 20,
		\	bufpos: [0, 0],
		\ })
		hi NormalFloat ctermbg=Black
		execute 'terminal haredoc '..symbol
		tnoremap <buffer> q  <C-\><C-N>
		nnoremap <buffer> q  :close<CR>
		nnoremap <buffer> <nowait> u  <C-U>
		nnoremap <buffer> <nowait> d  <C-D>
		startinsert
	else
		execute '!haredoc '..symbol
	endif
endfunction