Skip to content

Instantly share code, notes, and snippets.

@ohpauleez
Last active June 24, 2021 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ohpauleez/c9e625dbceab30c3f2e8afe0edcf4c8f to your computer and use it in GitHub Desktop.
Save ohpauleez/c9e625dbceab30c3f2e8afe0edcf4c8f to your computer and use it in GitHub Desktop.
Using Clojure SocketREPL with a simple vimscript setup
"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