summaryrefslogtreecommitdiff
path: root/.vim/feat/code_terminal.vim
blob: 5db87977eeb32856f50c46ea3fcef6838a87bb15 (plain) (blame)
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
" Program in which build actions are executed. If no value, build commands are executes as bash commands.
" This is only really useful in languages with interpreters
let g:codeenvs = {
\	'scheme' : 'racket',
\	'lisp'   : 'rlwrap sbcl --noinform',
\ }

" The following two dictionaries support certain substitutions:
" %F - location of current file (relative path)
" %D - directory of current file (full path)

" Building the current file only
let g:codebuildsingle = {
\	'scheme'  : '(enter! "%F")',
\	'cpp'     : "g++ -g -pedantic '%F' && ./a.out",
\	'c'       : "gcc -g '%F' && ./a.out",
\	'yacc'    : 'bison -t -d %F',
\	'lex'     : 'flex %F',
\	'haskell' : 'runhaskell "%F"',
\	'lisp'    : '(load "%F")',
\ }
" Building all files in the directory (and subdirectories) of the current file
let g:codebuildproject = {
\	'cpp' : "g++ -g -pedantic '%D/'**/*.cpp && ./a.out"
\ }
let g:codebuildinproject = 0

 noremap <F3> :call CodeTerminal()<CR>
 noremap <F4> :call RepeatLastCommand()<CR>
inoremap <F3> <C-O>:call CodeTerminal()<CR>
inoremap <F4> <C-O>:call RepeatLastCommand()<CR>
" We assume that the last accessed window is the one with the source code, otherwise it gets complicated
tnoremap <F3> <C-W><C-P>:call CodeTerminal()<CR><C-W><C-P>
tnoremap <F4> <C-W><C-P>:call RepeatLastCommand()<CR><C-W><C-P>

au TabNew * call CTCreateTabVars()

function! CTCreateTabVars()
	let t:codetermbufnr  = -1
	let t:codetermft     = ""
	let t:codetermhadenv = 0
endfunction
call CTCreateTabVars()

function! OpenCodeTerminal()
	if !bufexists(t:codetermbufnr)
		topleft term
		" Latest buffer is the terminal buffer we just opened
		let t:codetermbufnr = bufnr("$")
		" We go back to the file from which this was called
		wincmd p
		let t:codetermft = ""
		let t:codetermhadenv = 0
	endif

	if &filetype != t:codetermft
		if t:codetermhadenv
			" This is kinda bad, since certain environments might not close with this only
			call term_sendkeys(t:codetermbufnr, "\<C-D>")
			" The sleep is kinda bad, but it fixes the next term_sendkeys not working properly
			sleep 500m
		endif

		let t:codetermft = &filetype
		if has_key(g:codeenvs, &filetype)
			call term_sendkeys(t:codetermbufnr, g:codeenvs[&filetype] . "\<CR>")
			let t:codetermhadenv = 1
		else
			let t:codetermhadenv = 0
		endif
	endif
endfunction

function! RepeatLastCommand()
	call term_sendkeys(t:codetermbufnr, "\<Up>\<CR>")
endfunction

let s:ran = 0

function! CodeTerminal()
	call OpenCodeTerminal()

	let builddict = (g:codebuildinproject == 1 ? g:codebuildproject : g:codebuildsingle)
	if has_key(builddict, &filetype)
		let buildcomm = builddict[&filetype] . "\<CR>"
		let buildcomm = substitute(buildcomm, "%F", @%, "")
		let buildcomm = substitute(buildcomm, "%D", expand('%:p:h'), "")
		call term_sendkeys(t:codetermbufnr, buildcomm)
		echo "[CodeTerminal] Sent build command!"
	else
		if s:ran == 0
			let s:ran = 1
		else
			call RepeatLastCommand()
		endif
		echo "[CodeTerminal] No value in build dictionary!"
	endif
endfunction