Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 44 additions & 11 deletions autoload/nim.vim
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,37 @@ elseif has("python")
exe 'pyfile ' . fnameescape(s:plugin_path) . '/nim_vim.py'
endif

if !exists('g:nim_use_nimsuggest')
if executable('nimsuggest')
let g:nim_use_nimsuggest = 1
else
let g:nim_use_nimsuggest = 0
endif
endif

if g:nim_use_nimsuggest
let g:nim_server_cmd = ['nimsuggest', '--stdin', '--v2']
let s:nim_cmd_template = 'echo %s | nimsuggest --stdin --v2 %s'
let s:nim_suggestions_option = 'sug'
let s:nim_definitions_option = 'def'
let s:nim_dirty_cmd_generator = 'printf(''%s "%s";"%s":%d:%d'', a:op, s:CurrentNimFile(), tmp, line("."), col(".")-1)'
let s:nim_cmd_generator = 'printf(''%s "%s":%d:%d'', a:op, s:CurrentNimFile(), line("."), col(".")-1)'
else
let g:nim_server_cmd = ['nim', 'serve', '--server.type:stdin']
let s:nim_cmd_template = 'nim %s "%s"'
let s:nim_suggestions_option = '--suggest'
let s:nim_definitions_option = '--def'
let s:nim_dirty_cmd_generator = 'printf(''idetools %s --trackDirty:"%s,%s,%d,%d"'', a:op, tmp, substitute(expand(''%:p''), ''\\'', "/", "g"), line("."), col(".") - 1)'
let s:nim_cmd_generator = 'printf(''idetools %s --track:"%s,%d,%d"'', a:op, substitute(expand(''%:p''), ''\\'', "/", "g"), line("."), col(".") - 1)'
endif

fun! nim#init()
let cmd = printf("nim --dump.format:json --verbosity:0 dump %s", s:CurrentNimFile())
let raw_dumpdata = system(cmd)
if !v:shell_error && expand("%:e") == "nim"
let dumpdata = eval(substitute(raw_dumpdata, "\n", "", "g"))
let b:nim_project_root = dumpdata['project_path']

let b:nim_project_root = substitute(dumpdata['project_path'], '\\', '/', 'g')
let b:nim_defined_symbols = dumpdata['defined_symbols']
let b:nim_caas_enabled = g:nim_caas_enabled || index(dumpdata['defined_symbols'], 'forcecaas') != -1

Expand Down Expand Up @@ -79,7 +103,7 @@ fun! s:CurrentNimFile()
endif

call setpos('.', save_cur)
return l:to_check
return substitute(fnamemodify(l:to_check, ':p'), '\\', '/', 'g')
endf

let g:nim_symbol_types = {
Expand All @@ -103,26 +127,35 @@ let g:nim_symbol_types = {
\ }

fun! NimExec(op)

" This is the "projectfile.nim that nimsuggest wants. It defaluts to
" the file we're operating on and only set to a real project file if the
" appropriate global configuration is set.
let project_file = s:CurrentNimFile()
if g:nim_use_nimsuggest && exists("g:nim_project_file")
let project_file = g:nim_project_file
endif

let isDirty = getbufvar(bufnr('%'), "&modified")
if isDirty
let tmp = tempname() . bufname("%") . "_dirty.nim"
silent! exe ":w " . tmp
let tmp = substitute(tmp, '\\', '/', 'g')

let cmd = printf("idetools %s --trackDirty:\"%s,%s,%d,%d\" \"%s\"",
\ a:op, tmp, expand('%:p'), line('.'), col('.')-1, s:CurrentNimFile())
let cmd = eval(s:nim_dirty_cmd_generator)
else
let cmd = printf("idetools %s --track:\"%s,%d,%d\" \"%s\"",
\ a:op, expand('%:p'), line('.'), col('.')-1, s:CurrentNimFile())
let cmd = eval(s:nim_cmd_generator)
endif

if b:nim_caas_enabled
exe printf("py nimExecCmd('%s', '%s', False)", b:nim_project_root, cmd)
let output = l:py_res
else
let output = system("nim " . cmd)
let output = system(printf(s:nim_cmd_template, cmd, project_file))
endif
let output = substitute(output, '.\{-}>\s\+', '', '')

call add(g:nim_log, "nim " . cmd . "\n" . output)
call add(g:nim_log, cmd . "\n" . output)
return output
endf

Expand All @@ -143,7 +176,7 @@ fun! NimComplete(findstart, base)
return col('.')
else
let result = []
let sugOut = NimExec("--suggest")
let sugOut = NimExec(s:nim_suggestions_option)
for line in split(sugOut, '\n')
let lineData = split(line, '\t')
if len(lineData) > 0 && lineData[0] == "sug"
Expand Down Expand Up @@ -202,7 +235,7 @@ fun! GotoDefinition_nim_ready(def_output)
endf

fun! GotoDefinition_nim()
call NimExecAsync("--def", function("GotoDefinition_nim_ready"))
call NimExecAsync(s:nim_definitions_option, function("GotoDefinition_nim_ready"))
endf

fun! FindReferences_nim()
Expand Down
34 changes: 26 additions & 8 deletions autoload/nim_vim.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sys import version_info
import threading, subprocess, signal, os, platform, getpass
from os import name
import threading, subprocess, signal, os, platform, getpass, re, copy

if version_info[0] == 3:
import queue as Queue
Expand All @@ -16,17 +17,25 @@ def command(self, x):
vim = Vim()

class NimThread(threading.Thread):
def __init__(self, project_path):
def __init__(self, cmd, project_path):
super(NimThread, self).__init__()
self.tasks = Queue.Queue()
self.responses = Queue.Queue()
if name == 'nt':
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
si.wShowWindow = subprocess.SW_HIDE
else:
si = None
cmd.append(project_path)
self.nim = subprocess.Popen(
["nim", "serve", "--server.type:stdin", project_path],
cmd,
cwd = os.path.dirname(project_path),
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
universal_newlines = True,
startupinfo = si,
bufsize = 1)

def postNimCmd(self, msg, async = True):
Expand All @@ -43,12 +52,13 @@ def run(self):
break

self.nim.stdin.write(msg + "\n")
self.nim.stdin.flush()
result = ""

while True:
line = self.nim.stdout.readline()
result += line
if line == "\n":
if re.match('^(?:\n|>\s*)$', line) is not None:
if not async:
self.responses.put(result)
else:
Expand All @@ -66,8 +76,8 @@ def asyncOpComplete(self, msg, result):

NimProjects = {}

def nimStartService(project):
target = NimVimThread(project)
def nimStartService(cmd, project):
target = NimVimThread(cmd, project)
NimProjects[project] = target
target.start()
return target
Expand All @@ -79,14 +89,22 @@ def nimTerminateService(project):

def nimRestartService(project):
nimTerminateService(project)
nimStartService(project)
server = copy.copy(vim.vars['nim_server_cmd'][0:])
if version_info[0] == 3:
for i in range(len(server)):
server[i] = server[i].decode()
nimStartService(server, project)

def nimExecCmd(project, cmd, async = True):
target = None
if NimProjects.has_key(project):
target = NimProjects[project]
else:
target = nimStartService(project)
server = copy.copy(vim.vars['nim_server_cmd'][0:])
if version_info[0] == 3:
for i in range(len(server)):
server[i] = server[i].decode()
target = nimStartService(server, project)

result = target.postNimCmd(cmd, async)

Expand Down