Last active
June 24, 2021 14:30
-
-
Save ohpauleez/c9e625dbceab30c3f2e8afe0edcf4c8f to your computer and use it in GitHub Desktop.
Using Clojure SocketREPL with a simple vimscript setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"Clojure stuff | |
let g:paredit_electric_return = 0 | |
let g:clojure_highlight_local_vars = 0 | |
let g:clojure_highlight_references = 0 " Toggle with :ToggleClojureHighlightReferences | |
let g:clojure_srepl_port = 5555 | |
let g:clojure_srepl_host = "127.0.0.1" | |
let g:clojure_require_preamble = "(set! *warn-on-reflection* true)" " These forms will be sent over srepl before a `require` is sent | |
let g:clojure_reload = ":reload" " This option is sent as an arg to `require` | |
let g:clojure_use_jobs = 0 | |
let g:clojure_repl_job = {} | |
function! VisualNC() range | |
let n = @n | |
silent! normal gv"ny | |
"echo "". @n | |
if v:version < 800 || g:clojure_use_jobs == 0 | |
echo "" . system("script=$(cat <<'EOF'\n" . @n . "\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port) | |
else | |
let g:clojure_repl_job = job_start(['/bin/bash', '-c', "script=$(cat <<'EOF'\n" . @n . "\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port], | |
\ {'out_io': 'buffer', 'out_name': 'repl'}) | |
endif | |
let @n = n | |
" bonus: restores the visual selection | |
"normal! gv | |
endfunction | |
" This next function is like `VisualNC` except it attempts to `ns` you into | |
" the namespace found at the very top of the file | |
function! NSVisualNC() range | |
let save_pos = getpos(".") | |
let l:line = search("(ns") | |
let basens = getline(l:line) | |
let ns = "" | |
if matchend(basens,"(ns ") > 0 | |
if matchend(basens,")") == -1 | |
let ns = basens . ")" | |
else | |
let ns = basens | |
endif | |
endif | |
let n = @n | |
silent! normal gv"ny | |
if v:version < 800 || g:clojure_use_jobs == 0 | |
echo "" . system("script=$(cat <<'EOF'\n" . ns . " " .@n . "\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port) | |
else | |
let g:clojure_repl_job = job_start(['/bin/bash', '-c', "script=$(cat <<'EOF'\n" . ns . " " .@n . "\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port], | |
\ {'out_io': 'buffer', 'out_name': 'repl'}) | |
endif | |
let @n = n | |
call setpos(".", save_pos) | |
" bonus: restores the visual selection | |
"normal! gv | |
endfunction | |
" This next functions attempts to grab the ns from the top of the file and | |
" call `require` on it with `:reload` via g:clojure_reload | |
function! NSRequireReload() | |
let save_pos = getpos(".") | |
let l:line = search("(ns") | |
let basens = getline(l:line) | |
let ns = "" | |
if matchend(basens,"(ns ") > 0 | |
let ns = substitute(matchlist(basens,'(ns \(.*\))\?')[1],")","","") | |
endif | |
if strlen(ns) > 0 | |
echo "(require '" . ns . " " . g:clojure_reload . ")" | |
if v:version < 800 || g:clojure_use_jobs == 0 | |
echo "" . system("script=$(cat <<'EOF'\n(do\n" . g:clojure_require_preamble . "\n(require '" . ns . " " . g:clojure_reload . "))\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port) | |
else | |
let g:clojure_repl_job = job_start(['/bin/bash', '-c', "script=$(cat <<'EOF'\n(do\n" . g:clojure_require_preamble . "\n(require '" . ns . " " . g:clojure_reload . "))\nEOF\n); printf '%s' $script | nc -q 0 " . g:clojure_srepl_host . " " . g:clojure_srepl_port], | |
\ {'out_io': 'buffer', 'out_name': 'repl'}) | |
endif | |
endif | |
call setpos(".", save_pos) | |
endfunction | |
function! ClojureTagLookup() | |
let word = expand('<cword>') | |
if word =~ ".*/.*" | |
let sym_words = split(word, "/") | |
let first_tag = taglist(sym_words[0]) | |
if len(first_tag) == 1 | |
let first_tag = first_tag[0] | |
if first_tag['kind'] == 'a' | |
let nsname = matchlist(first_tag['cmd'], '[\(.*\) :as .*')[1] | |
let second_tag = taglist("^".sym_words[1]."$") | |
let criteria = "has_key(v:val, 'namespace') && v:val['namespace'] == '".nsname."'" | |
let x = filter(second_tag, criteria) | |
if len(x) == 1 | |
let t = x[0] | |
" Drop the trailing '/' from the tag's command/regex entry | |
let cmd = strpart((t.cmd),0,strlen((t.cmd))-1) | |
" Are we on a version of Vim that has gettagstack and | |
" settagstack? | |
if exists('*gettagstack') | |
"TODO: Update the tagstack | |
endif | |
"exe 'tag '.(t.name) " This doesn't work as expected, because it doesn't jump to the tag that was just found | |
" So let's 'edit' the file from the tag, and use the regex | |
" to jump to the line | |
exe 'e '. (t.filename) | |
exe ':'. cmd | |
return | |
endif | |
endif | |
endif | |
exe 'tselect' sym_words[1] | |
return | |
else | |
let first_tag = taglist("^".word."$") | |
if len(first_tag) == 1 | |
exe 'tag' word | |
else | |
exe 'tselect' word | |
endif | |
return | |
endif | |
endfunction | |
function! ClojureCtagOmni(findstart, base) | |
"TODO: I have no idea what I'm doing, or what format the results need to | |
"be in. Not sure this is a good idea given ctrl-x ctrl+] gives you tag | |
"completion | |
let word = expand('<cword>') | |
if word =~ ".*/.*" | |
let sym_words = split(word, "/") | |
let first_tag = taglist(sym_words[0]) | |
if len(first_tag) == 1 | |
let first_tag = first_tag[0] | |
if first_tag['kind'] == 'a' | |
let nsname = matchlist(first_tag['cmd'], '[\(.*\) :as .*')[1] | |
let second_tag = taglist(sym_words[1]) | |
let criteria = "has_key(v:val, 'namespace') && v:val['namespace'] == '".nsname."'" | |
let x = filter(second_tag, criteria) | |
return map(x, "{'word': v:val['name'], 'kind':'t', 'info': ''}") | |
endif | |
endif | |
let second_tag = taglist(sym_words[1]) | |
return map(second_tag, "v:val['name']") | |
endif | |
let tl = taglist(word) | |
return map(tl, "v:val['name']") | |
endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment