caas works satisfactory now with the latest version of nimrod

modified buffers are handled properly now
nimrod threads are terminated at program exit
added commands for service shutdown/restart
This commit is contained in:
Zahary Karadjov 2013-05-05 19:39:04 +03:00
commit fa9bd5972b
2 changed files with 66 additions and 40 deletions

View file

@ -5,21 +5,21 @@ if !exists("g:nimrod_caas_enabled")
let g:nimrod_caas_enabled = 1 let g:nimrod_caas_enabled = 1
endif endif
exe 'pyfile ' . fnameescape(s:plugin_path) . '/nimrod_vim.py'
if !executable('nimrod') if !executable('nimrod')
echoerr "the nimrod compiler must be in your system's PATH" echoerr "the nimrod compiler must be in your system's PATH"
endif endif
exe 'pyfile ' . fnameescape(s:plugin_path) . '/nimrod_vim.py'
fun! nimrod#init() fun! nimrod#init()
let cmd = printf("nimrod --dump.format:json --verbosity:0 dump %s", s:CurrentNimrodFile()) let cmd = printf("nimrod --dump.format:json --verbosity:0 dump %s", s:CurrentNimrodFile())
let raw_dumpdata = system(cmd) let raw_dumpdata = system(cmd)
if !v:shell_error if !v:shell_error
" the silent bit is to ignore a warning about trailing characters
let dumpdata = eval(substitute(raw_dumpdata, "\n", "", "g")) let dumpdata = eval(substitute(raw_dumpdata, "\n", "", "g"))
let b:nimrod_project_root = dumpdata['project_path'] let b:nimrod_project_root = dumpdata['project_path']
let b:nimrod_caas_enabled = g:nimrod_caas_enabled let b:nimrod_defined_symbols = dumpdata['defined_symbols']
let b:nimrod_caas_enabled = g:nimrod_caas_enabled || index(dumpdata['defined_symbols'], 'forcecaas') != -1
for path in dumpdata['lib_paths'] for path in dumpdata['lib_paths']
if finddir(path) == path if finddir(path) == path
@ -42,16 +42,24 @@ fun! s:UpdateNimLog()
let g:nimrod_log = [] let g:nimrod_log = []
match Search /^nimrod\ idetools.*/ match Search /^nimrod\ .*/
endf endf
augroup NimLog augroup NimrodVim
au! au!
au BufEnter log://nimrod call s:UpdateNimLog() au BufEnter log://nimrod call s:UpdateNimLog()
au QuitPre * :py nimTerminateAll()
au VimLeavePre * :py nimTerminateAll()
augroup END augroup END
command! NimLog :e log://nimrod command! NimLog :e log://nimrod
command! NimTerminateService
\ :exe printf("py nimTerminateService('%s')", b:nimrod_project_root)
command! NimRestartService
\ :exe printf("py nimRestartService('%s')", b:nimrod_project_root)
fun! s:CurrentNimrodFile() fun! s:CurrentNimrodFile()
let save_cur = getpos('.') let save_cur = getpos('.')
call cursor(0, 0, 0) call cursor(0, 0, 0)
@ -91,19 +99,26 @@ let g:nimrod_symbol_types = {
\ } \ }
fun! NimExec(op) fun! NimExec(op)
let isDirty = getbufvar(bufnr('%'), "&modified")
if isDirty
let tmp = tempname() . bufname("%") . "_dirty.nim"
silent! exe ":w " . tmp
let cmd = printf("idetools %s --trackDirty:\"%s,%s,%d,%d\" \"%s\"",
\ a:op, tmp, expand('%:p'), line('.'), col('.')-1, s:CurrentNimrodFile())
else
let cmd = printf("idetools %s --track:\"%s,%d,%d\" \"%s\"", let cmd = printf("idetools %s --track:\"%s,%d,%d\" \"%s\"",
\ a:op, expand('%:p'), line('.'), col('.')-1, s:CurrentNimrodFile()) \ a:op, expand('%:p'), line('.'), col('.')-1, s:CurrentNimrodFile())
if b:nimrod_caas_enabled
exe printf("py execNimCmd('%s', '%s', False)", b:nimrod_project_root, cmd)
let output = l:py_res
else
let syscmd = "nimrod " . cmd
call add(g:nimrod_log, syscmd)
let output = system(syscmd)
endif endif
call add(g:nimrod_log, output) if b:nimrod_caas_enabled
exe printf("py nimExecCmd('%s', '%s', False)", b:nimrod_project_root, cmd)
let output = l:py_res
else
let output = system("nimrod " . cmd)
endif
call add(g:nimrod_log, "nimrod " . cmd . "\n" . output)
return output return output
endf endf
@ -113,6 +128,10 @@ fun! NimExecAsync(op, Handler)
endf endf
fun! NimComplete(findstart, base) fun! NimComplete(findstart, base)
if b:nimrod_caas_enabled == 0
return -1
endif
if a:findstart if a:findstart
if synIDattr(synIDtrans(synID(line("."),col("."),1)), "name") == 'Comment' if synIDattr(synIDtrans(synID(line("."),col("."),1)), "name") == 'Comment'
return -1 return -1
@ -123,7 +142,7 @@ fun! NimComplete(findstart, base)
let sugOut = NimExec("--suggest") let sugOut = NimExec("--suggest")
for line in split(sugOut, '\n') for line in split(sugOut, '\n')
let lineData = split(line, '\t') let lineData = split(line, '\t')
if lineData[0] == "sug" if len(lineData) > 0 && lineData[0] == "sug"
let kind = get(g:nimrod_symbol_types, lineData[1], '') let kind = get(g:nimrod_symbol_types, lineData[1], '')
let c = { 'word': lineData[2], 'kind': kind, 'menu': lineData[3], 'dup': 1 } let c = { 'word': lineData[2], 'kind': kind, 'menu': lineData[3], 'dup': 1 }
call add(result, c) call add(result, c)
@ -137,11 +156,7 @@ if !exists("g:neocomplcache_omni_patterns")
let g:neocomplcache_omni_patterns = {} let g:neocomplcache_omni_patterns = {}
endif endif
" let g:neocomplcache_omni_patterns['nimrod'] = '[^. *\t]\.\w*' let g:neocomplcache_omni_patterns['nimrod'] = '[^. *\t]\.\w*'
fun! StartNimrodThread()
endf
let g:nimrod_completion_callbacks = {} let g:nimrod_completion_callbacks = {}
fun! NimrodAsyncCmdComplete(cmd, output) fun! NimrodAsyncCmdComplete(cmd, output)

View file

@ -9,11 +9,6 @@ except ImportError:
vim = Vim() vim = Vim()
def disable_sigint():
# Ignore the SIGINT signal by setting the handler to the standard
# signal handler SIG_IGN.
signal.signal(signal.SIGINT, signal.SIG_IGN)
class NimrodThread(threading.Thread): class NimrodThread(threading.Thread):
def __init__(self, project_path): def __init__(self, project_path):
super(NimrodThread, self).__init__() super(NimrodThread, self).__init__()
@ -26,7 +21,6 @@ class NimrodThread(threading.Thread):
stdout = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, stderr = subprocess.STDOUT,
universal_newlines = True, universal_newlines = True,
preexec_fn = disable_sigint,
bufsize = 1) bufsize = 1)
def postNimCmd(self, msg, async = True): def postNimCmd(self, msg, async = True):
@ -56,32 +50,49 @@ class NimrodThread(threading.Thread):
break break
def vimEscapeExpr(expr): def nimVimEscape(expr):
return expr.replace("\\", "\\\\").replace('"', "\\\"").replace("\n", "\\n") return expr.replace("\\", "\\\\").replace('"', "\\\"").replace("\n", "\\n")
class NimrodVimThread(NimrodThread): class NimrodVimThread(NimrodThread):
def asyncOpComplete(self, msg, result): def asyncOpComplete(self, msg, result):
cmd = "/usr/local/bin/mvim --remote-expr 'NimrodAsyncCmdComplete(1, \"" + vimEscapeExpr(result) + "\")'" cmd = "/usr/local/bin/mvim --remote-expr 'NimrodAsyncCmdComplete(1, \"" + nimVimEscape(result) + "\")'"
os.system (cmd) os.system (cmd)
projects = {} NimProjects = {}
log = open("/tmp/nim-log.txt", "w") def nimStartService(project):
def execNimCmd(project, cmd, async = True):
target = None
if projects.has_key(project):
target = projects[project]
else:
target = NimrodVimThread(project) target = NimrodVimThread(project)
projects[project] = target NimProjects[project] = target
target.start() target.start()
return target
def nimTerminateService(project):
if NimProjects.has_key(project):
NimProjects[project].postNimCmd("quit")
del NimProjects[project]
def nimRestartService(project):
nimTerminateService(project)
nimStartService(project)
NimLog = open("/tmp/nim-log.txt", "w")
def nimExecCmd(project, cmd, async = True):
target = None
if NimProjects.has_key(project):
target = NimProjects[project]
else:
target = nimStartService(project)
result = target.postNimCmd(cmd, async) result = target.postNimCmd(cmd, async)
if result != None: if result != None:
log.write(result) NimLog.write(result)
log.flush() NimLog.flush()
if not async: if not async:
vim.command('let l:py_res = "' + vimEscapeExpr(result) + '"') vim.command('let l:py_res = "' + nimVimEscape(result) + '"')
def nimTerminateAll():
for thread in NimProjects.values():
thread.postNimCmd("quit")