From 43696ec2e34c8d46ada966d853f7aa908901c4d7 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 29 Apr 2013 09:49:56 +0300 Subject: [PATCH] work-in-progress towards integrating the compiler service --- autoload/nimrod.vim | 70 +++++++++++++++++++++++++-------- autoload/nimrod_vim.py | 87 ++++++++++++++++++++++++++++++++++++++++++ autoload/simulator.py | 18 +++++++++ 3 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 autoload/nimrod_vim.py create mode 100644 autoload/simulator.py diff --git a/autoload/nimrod.vim b/autoload/nimrod.vim index f8d4da5..52f1bb7 100644 --- a/autoload/nimrod.vim +++ b/autoload/nimrod.vim @@ -1,18 +1,23 @@ -fun! nimrod#init() -endf +let g:nimrod_log = [] +let s:plugin_path = escape(expand(':p:h'), ' \') -let g:nim_log = [] +exe 'pyfile ' . fnameescape(s:plugin_path) . '/nimrod_vim.py' + +fun! nimrod#init() + let b:nimrod_project_root = "/foo" + let b:nimrod_caas_enabled = 0 +endf fun! s:UpdateNimLog() setlocal buftype=nofile setlocal bufhidden=hide setlocal noswapfile - for entry in g:nim_log + for entry in g:nimrod_log call append(line('$'), split(entry, "\n")) endfor - let g:nim_log = [] + let g:nimrod_log = [] match Search /^nimrod\ idetools.*/ endf @@ -22,7 +27,7 @@ augroup NimLog au BufEnter log://nimrod call s:UpdateNimLog() augroup END -fun! CurrentNimrodFile() +fun! s:CurrentNimrodFile() let save_cur = getpos('.') call cursor(0, 0, 0) @@ -61,15 +66,27 @@ let g:nimrod_symbol_types = { \ } fun! NimExec(op) - let cmd = printf("nimrod idetools %s --track:\"%s,%d,%d\" \"%s\"", - \ a:op, expand('%:p'), line('.'), col('.')-1, CurrentNimrodFile()) + let cmd = printf("idetools %s --track:\"%s,%d,%d\" \"%s\"", + \ a:op, expand('%:p'), line('.'), col('.')-1, s:CurrentNimrodFile()) - call add(g:nim_log, cmd) - let output = system(cmd) - call add(g:nim_log, output) + 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 + + call add(g:nimrod_log, output) return output endf +fun! NimExecAsync(op, Handler) + let result = NimExec(a:op) + call a:Handler(result) +endf + fun! NimComplete(findstart, base) if a:findstart if synIDattr(synIDtrans(synID(line("."),col("."),1)), "name") == 'Comment' @@ -97,15 +114,32 @@ endif " let g:neocomplcache_omni_patterns['nimrod'] = '[^. *\t]\.\w*' -fun! GotoDefinition_nimrod() - let defOut = NimExec("--def") +fun! StartNimrodThread() +endf + +let g:nimrod_completion_callbacks = {} + +fun! NimrodAsyncCmdComplete(cmd, output) + call add(g:nimrod_log, a:output) + echom g:nimrod_completion_callbacks + if has_key(g:nimrod_completion_callbacks, a:cmd) + let Callback = get(g:nimrod_completion_callbacks, a:cmd) + call Callback(a:output) + " remove(g:nimrod_completion_callbacks, a:cmd) + else + echom "ERROR, Unknown Command: " . a:cmd + endif + return 1 +endf + +fun! GotoDefinition_nimrod_ready(def_output) if v:shell_error echo "nimrod was unable to locate the definition. exit code: " . v:shell_error - " echoerr defOut + " echoerr a:def_output return 0 endif - let rawDef = matchstr(defOut, 'def\t\([^\n]*\)') + let rawDef = matchstr(a:def_output, 'def\t\([^\n]*\)') if rawDef == "" echo "the current cursor position does not match any definitions" return 0 @@ -118,13 +152,17 @@ fun! GotoDefinition_nimrod() return 1 endf +fun! GotoDefinition_nimrod() + call NimExecAsync("--def", function("GotoDefinition_nimrod_ready")) +endf + fun! FindReferences_nimrod() setloclist() endf " Syntastic syntax checking fun! SyntaxCheckers_nimrod_GetLocList() - let makeprg = 'nimrod check ' . CurrentNimrodFile() + let makeprg = 'nimrod check ' . s:CurrentNimrodFile() let errorformat = &errorformat return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) diff --git a/autoload/nimrod_vim.py b/autoload/nimrod_vim.py new file mode 100644 index 0000000..2c7201e --- /dev/null +++ b/autoload/nimrod_vim.py @@ -0,0 +1,87 @@ +import threading, Queue, subprocess, signal, os + +try: + import vim +except ImportError: + class Vim: + def command(self, x): + print("Executing vim command: " + x) + + 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): + def __init__(self): + super(NimrodThread, self).__init__() + self.tasks = Queue.Queue() + self.responses = Queue.Queue() + self.nim = subprocess.Popen( + ["nimrod", "serve", "--server.type:stdin", "nimrod.nim"], + cwd = "/Users/zahary/Projects/nim/compiler", + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.STDOUT, + universal_newlines = True, + preexec_fn = disable_sigint, + bufsize = 1) + + def postNimCmd(self, msg, async = True): + self.tasks.put((msg, async)) + if not async: + return self.responses.get() + + def run(self): + while True: + (msg, async) = self.tasks.get() + + if msg == "quit": + self.nim.terminate() + break + + self.nim.stdin.write(msg + "\n") + result = "" + + while True: + line = self.nim.stdout.readline() + result += line + if line == "\n": + if not async: + self.responses.put(result) + else: + self.asyncOpComplete(msg, result) + break + + +def vimEscapeExpr(expr): + return expr.replace("\\", "\\\\").replace('"', "\\\"").replace("\n", "\\n") + +class NimrodVimThread(NimrodThread): + def asyncOpComplete(self, msg, result): + cmd = "/usr/local/bin/mvim --remote-expr 'NimrodAsyncCmdComplete(1, \"" + vimEscapeExpr(result) + "\")'" + os.system (cmd) + +projects = {} + +log = open("/tmp/nim-log.txt", "w") + +def execNimCmd(project, cmd, async = True): + target = None + if projects.has_key(project): + target = projects[project] + else: + target = NimrodVimThread() + projects[project] = target + target.start() + + result = target.postNimCmd(cmd, async) + if result != None: + log.write(result) + log.flush() + + if not async: + vim.command('let l:py_res = "' + vimEscapeExpr(result) + '"') + diff --git a/autoload/simulator.py b/autoload/simulator.py new file mode 100644 index 0000000..10b244d --- /dev/null +++ b/autoload/simulator.py @@ -0,0 +1,18 @@ +#!/bin/env python + +from nimrod_vim import execNimCmd + +proj = "/foo" + +while True: + line = raw_input("enter command: ") + async = False + + if line == "quit": + async = True + + print execNimCmd(proj, line, async) + + if line == "quit": + break +