From b014bafaf423ffb7c39e5e5bae3366cd03e4e5de Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Thu, 6 Oct 2016 18:26:58 +0200 Subject: [PATCH 01/11] Fix tests --- autoload/ghcmod.vim | 2 +- test/test_build_command.vim | 8 ++++---- test/test_lint.vim | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 145c614..aa9326a 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -183,7 +183,7 @@ function! ghcmod#expand(path) "{{{ let l:dir = fnamemodify(a:path, ':h') let l:qflist = [] - let l:cmd = ghcmod#build_command(['expand', "-b '\n'", a:path]) + let l:cmd = ghcmod#build_command(["-b '\n'", 'expand', a:path]) for l:line in split(ghcmod#system(l:cmd), '\n') let l:line = s:remove_dummy_prefix(l:line) diff --git a/test/test_build_command.vim b/test/test_build_command.vim index d94e416..f6cb017 100644 --- a/test/test_build_command.vim +++ b/test/test_build_command.vim @@ -10,14 +10,14 @@ endfunction function! s:unit.test_build() edit test/data/without-cabal/Foo/Bar.hs - call self.assert.equal(['ghc-mod', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', 'do'], s:build()) endfunction function! s:unit.test_build_with_dist_dir() try call system('cd test/data/with-cabal; cabal configure; cabal build') edit test/data/with-cabal/src/Foo/Bar.hs - call self.assert.equal(['ghc-mod', + call self.assert.equal(['ghc-mod', '--silent', \ '-g', '-i' . fnamemodify('test/data/with-cabal/dist/build/autogen', ':p:h'), \ '-g', '-I' . fnamemodify('test/data/with-cabal/dist/build/autogen', ':p:h'), \ '-g', '-optP-include', @@ -34,7 +34,7 @@ function! s:unit.test_build_global_opt() let g:ghcmod_ghc_options = ['-Wall'] try edit test/data/without-cabal/Main.hs - call self.assert.equal(['ghc-mod', '-g', '-Wall', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', '-g', '-Wall', 'do'], s:build()) finally unlet g:ghcmod_ghc_options endtry @@ -46,7 +46,7 @@ function! s:unit.test_build_buffer_opt() let g:ghcmod_ghc_options = ['-Wall'] try let b:ghcmod_ghc_options = ['-W'] - call self.assert.equal(['ghc-mod', '-g', '-W', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', '-g', '-W', 'do'], s:build()) finally unlet g:ghcmod_ghc_options endtry diff --git a/test/test_lint.vim b/test/test_lint.vim index 099a4de..01aac06 100644 --- a/test/test_lint.vim +++ b/test/test_lint.vim @@ -59,7 +59,7 @@ function! s:unit.test_lint() \ 'lnum': 5, \ 'col': 9, \ 'filename': 'test/data/with-cabal/src/Foo/Bar.hs', - \ 'text': 'Redundant $', + \ 'text': 'Suggestion: Redundant $', \ }), l:qflist) endfunction @@ -76,7 +76,7 @@ function! s:unit.test_lint_whitespace() \ 'lnum': 5, \ 'col': 9, \ 'filename': 'test/data/with whitespace/src/Foo/Bar.hs', - \ 'text': 'Redundant $', + \ 'text': 'Suggestion: Redundant $', \ }), l:qflist) endfunction @@ -95,7 +95,7 @@ function! s:unit.test_lint_async() \ 'lnum': 5, \ 'col': 9, \ 'filename': 'test/data/with-cabal/src/Foo/Bar.hs', - \ 'text': 'Redundant $', + \ 'text': 'Suggestion: Redundant $', \ }), a:qflist) endfunction call s:async(l:callback) @@ -111,7 +111,7 @@ function! s:unit.test_lint_opt() \ 'lnum': 5, \ 'col': 9, \ 'filename': 'test/data/with-cabal/src/Foo/Bar.hs', - \ 'text': 'Redundant $', + \ 'text': 'Suggestion: Redundant $', \ }), l:qflist) finally unlet g:ghcmod_hlint_options @@ -130,7 +130,7 @@ function! s:unit.test_lint_async_opt() \ 'lnum': 5, \ 'col': 9, \ 'filename': 'test/data/with-cabal/src/Foo/Bar.hs', - \ 'text': 'Redundant $', + \ 'text': 'Suggestion: Redundant $', \ }), a:qflist) endfunction call s:async(l:callback) From 338aa5ca8e454c3c3201f1a82533927edccbe199 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Thu, 6 Oct 2016 16:30:26 +0200 Subject: [PATCH 02/11] Unify line separator handling --- autoload/ghcmod.vim | 23 +++++++++++------------ test/test_build_command.vim | 8 ++++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index aa9326a..12fecb6 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -15,8 +15,8 @@ function! ghcmod#getHaskellIdentifier() "{{{ endfunction "}}} function! ghcmod#info(fexp, path, ...) "{{{ - let l:cmd = ghcmod#build_command(["-b \n", 'info', a:path, a:fexp]) - let l:output = ghcmod#system(l:cmd) + let l:cmd = ghcmod#build_command(['info', a:path, a:fexp]) + let l:output = join(split(s:system('info', l:cmd)[0], '\\n'), "\n") " Remove trailing newlines to prevent empty lines let l:output = substitute(l:output, '\n*$', '', '') return s:remove_dummy_prefix(l:output) @@ -29,11 +29,11 @@ function! ghcmod#split(line, col, path, ...) "{{{ if empty(l:lines) return [] endif - let l:parsed = matchlist(l:lines[0], '\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\(.*\)"') + let l:parsed = matchlist(l:lines[0], '^\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\([^"]\+\)"$') if len(l:parsed) < 5 return [] endif - return split(l:parsed[5], '\n') + return split(l:parsed[5], '\\n') endfunction "}}} function! ghcmod#sig(line, col, path, ...) "{{{ @@ -48,10 +48,9 @@ endfunction "}}} function! ghcmod#type(line, col, path, ...) "{{{ let l:cmd = ghcmod#build_command(['type', a:path, a:line, a:col]) - let l:output = ghcmod#system(l:cmd) let l:types = [] - for l:line in split(l:output, '\n') - let l:m = matchlist(l:line, '\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\([^"]\+\)"') + for l:line in s:system('type', l:cmd) + let l:m = matchlist(l:line, '^\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\([^"]\+\)"$') if !empty(l:m) call add(l:types, [map(l:m[1 : 4], 'str2nr(v:val, 10)'), l:m[5]]) endif @@ -114,7 +113,7 @@ function! ghcmod#parse_make(lines, basedir) "{{{ else let l:qf.type = 'E' endif - let l:texts = split(l:rest, '\n') + let l:texts = split(l:rest, '\\n') if len(l:texts) > 0 let l:qf.text = l:texts[0] call add(l:qflist, l:qf) @@ -183,8 +182,8 @@ function! ghcmod#expand(path) "{{{ let l:dir = fnamemodify(a:path, ':h') let l:qflist = [] - let l:cmd = ghcmod#build_command(["-b '\n'", 'expand', a:path]) - for l:line in split(ghcmod#system(l:cmd), '\n') + let l:cmd = ghcmod#build_command(['expand', a:path]) + for l:line in s:system('expand', l:cmd) let l:line = s:remove_dummy_prefix(l:line) " path:line:col1-col2: message @@ -245,7 +244,7 @@ function! ghcmod#add_autogen_dir(path, cmd) "{{{ endfunction "}}} function! ghcmod#build_command(args) "{{{ - let l:cmd = ['ghc-mod', '--silent'] + let l:cmd = ['ghc-mod', '--silent', '-b\\n'] let l:dist_top = s:find_basedir() . '/dist' let l:sandboxes = split(glob(l:dist_top . '/dist-*', 1), '\n') @@ -308,7 +307,7 @@ function! s:system(type, args) "{{{ let [l:cond, l:status] = ghcmod#util#wait(l:proc) let l:tries = 1 while l:cond ==# 'run' - if l:tries >= 50 + if l:tries >= 500 call l:proc.kill(15) " SIGTERM call l:proc.waitpid() throw printf('ghcmod#make: `ghc-mod %s` takes too long time!', a:type) diff --git a/test/test_build_command.vim b/test/test_build_command.vim index f6cb017..ac464e1 100644 --- a/test/test_build_command.vim +++ b/test/test_build_command.vim @@ -10,14 +10,14 @@ endfunction function! s:unit.test_build() edit test/data/without-cabal/Foo/Bar.hs - call self.assert.equal(['ghc-mod', '--silent', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', '-b\\n', 'do'], s:build()) endfunction function! s:unit.test_build_with_dist_dir() try call system('cd test/data/with-cabal; cabal configure; cabal build') edit test/data/with-cabal/src/Foo/Bar.hs - call self.assert.equal(['ghc-mod', '--silent', + call self.assert.equal(['ghc-mod', '--silent', '-b\\n', \ '-g', '-i' . fnamemodify('test/data/with-cabal/dist/build/autogen', ':p:h'), \ '-g', '-I' . fnamemodify('test/data/with-cabal/dist/build/autogen', ':p:h'), \ '-g', '-optP-include', @@ -34,7 +34,7 @@ function! s:unit.test_build_global_opt() let g:ghcmod_ghc_options = ['-Wall'] try edit test/data/without-cabal/Main.hs - call self.assert.equal(['ghc-mod', '--silent', '-g', '-Wall', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', '-b\\n', '-g', '-Wall', 'do'], s:build()) finally unlet g:ghcmod_ghc_options endtry @@ -46,7 +46,7 @@ function! s:unit.test_build_buffer_opt() let g:ghcmod_ghc_options = ['-Wall'] try let b:ghcmod_ghc_options = ['-W'] - call self.assert.equal(['ghc-mod', '--silent', '-g', '-W', 'do'], s:build()) + call self.assert.equal(['ghc-mod', '--silent', '-b\\n', '-g', '-W', 'do'], s:build()) finally unlet g:ghcmod_ghc_options endtry From e6bb405e32775cefec00405a9dc7ee0827720fc4 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Thu, 24 Jul 2014 12:32:43 +0800 Subject: [PATCH 03/11] Add some support for ghc-modi. Right now only the 'type' and 'info' functions are supported. ghc-modi's `make` is still somewhat buggy. --- autoload/ghcmod.vim | 52 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 12fecb6..5b1e4be 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -1,3 +1,9 @@ +if !exists("g:ghcmod_should_use_ghc_modi") + let g:ghcmod_should_use_ghc_modi = 1 +endif + +let s:use_modi = g:ghcmod_should_use_ghc_modi + function! ghcmod#highlight_group() "{{{ return get(g:, 'ghcmod_type_highlight', 'Search') endfunction "}}} @@ -15,8 +21,13 @@ function! ghcmod#getHaskellIdentifier() "{{{ endfunction "}}} function! ghcmod#info(fexp, path, ...) "{{{ - let l:cmd = ghcmod#build_command(['info', a:path, a:fexp]) - let l:output = join(split(s:system('info', l:cmd)[0], '\\n'), "\n") + if s:use_modi + let l:lines = s:modi_command(['info', a:path, a:fexp]) + else + let l:cmd = ghcmod#build_command(['info', a:path, a:fexp]) + let l:lines = s:system('info', l:cmd) + endif + let l:output = join(split(l:lines[0], '\\n'), "\n") " Remove trailing newlines to prevent empty lines let l:output = substitute(l:output, '\n*$', '', '') return s:remove_dummy_prefix(l:output) @@ -47,9 +58,14 @@ function! ghcmod#sig(line, col, path, ...) "{{{ endfunction "}}} function! ghcmod#type(line, col, path, ...) "{{{ - let l:cmd = ghcmod#build_command(['type', a:path, a:line, a:col]) + if s:use_modi + let l:lines = s:modi_command(['type', a:path, a:line, a:col]) + else + let l:cmd = ghcmod#build_command(['type', a:path, a:line, a:col]) + let l:lines = s:system('type', l:cmd) + endif let l:types = [] - for l:line in s:system('type', l:cmd) + for l:line in l:lines let l:m = matchlist(l:line, '^\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\([^"]\+\)"$') if !empty(l:m) call add(l:types, [map(l:m[1 : 4], 'str2nr(v:val, 10)'), l:m[5]]) @@ -278,6 +294,34 @@ function! ghcmod#build_command(args) "{{{ return l:cmd endfunction "}}} +" Cache a handle to the ghc-modi process. +let s:ghc_modi_proc = {} + +function! s:modi_command(args) "{{{ + if s:ghc_modi_proc == {} + let l:ghcmodi_prog = ghcmod#build_command(["legacy-interactive"]) + lcd `=ghcmod#basedir()` + let s:ghc_modi_proc = vimproc#popen2(ghcmodi_prog) + lcd - + endif + + call s:ghc_modi_proc.stdin.write(join(a:args) . "\n") + + let l:res = [] + while 1 + for l:line in s:ghc_modi_proc.stdout.read_lines() + if l:line == "OK" + return l:res + elseif line =~ "^NG " + echoerr "ghc-modi terminated with message: " . join(l:res, "\n") + return '' + elseif len(line) > 0 + let l:res += [l:line] + endif + endfor + endwhile +endfunction "}}} + function! ghcmod#system(...) "{{{ let l:dir = getcwd() try From 33f6f6d6515e6ed4706d22cf11b643ff84cf8d64 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Thu, 24 Jul 2014 23:39:48 +0800 Subject: [PATCH 04/11] Add ability to test the non-ghc-modi cases. --- test.sh | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/test.sh b/test.sh index d409fa3..4cfbfda 100755 --- a/test.sh +++ b/test.sh @@ -2,21 +2,39 @@ shopt -s nullglob +run_tests() { + for f in $1 + do + testname=${f#test/test_} + testname=${testname%.vim} + echo "Running $testname" + rm -f verbose.log + if vim -e -N -u NONE $2 -S test/before.vim -S "$f" < /dev/null; then + cat stdout.log + else + retval=$[retval + 1] + cat stdout.log + cat verbose.log + echo + fi + done +} + retval=0 -for f in test/test_*.vim -do - testname=${f#test/test_} - testname=${testname%.vim} - echo "Running $testname" - rm -f verbose.log - if vim -e -N -u NONE -S test/before.vim -S "$f" < /dev/null; then - cat stdout.log - else - retval=$[retval + 1] - cat stdout.log - cat verbose.log - echo - fi -done + +modonly_tests=(test/test_type.vim test/test_info.vim) + +run_tests "test/test_*.vim" + +# we cannot programmatically set this in our test case vimscripts as the +# variable is fixed once the script is loaded +echo "Setting ghcmod_should_use_ghc_modi=0" + +TMPFILE=`mktemp /tmp/test.XXXXXX` || exit 1 +echo "let g:ghcmod_should_use_ghc_modi=0" >> $TMPFILE + +run_tests "${modonly_tests[*]}" "-S $TMPFILE" + +rm -f $TMPFILE exit $retval From 695ca53a4f7673b4136853c36e2bc2b35faeec21 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Sat, 26 Jul 2014 00:27:05 +0800 Subject: [PATCH 05/11] Add ability to kill ghc-modi. --- after/ftplugin/haskell/ghcmod.vim | 4 +++- autoload/ghcmod.vim | 10 ++++++++++ autoload/ghcmod/command.vim | 12 ++++++++++++ test/test_type.vim | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/after/ftplugin/haskell/ghcmod.vim b/after/ftplugin/haskell/ghcmod.vim index 5492baa..f453713 100644 --- a/after/ftplugin/haskell/ghcmod.vim +++ b/after/ftplugin/haskell/ghcmod.vim @@ -59,6 +59,7 @@ command! -buffer -nargs=0 -bang GhcModCheckAsync call ghcmod#command#async_make( command! -buffer -nargs=0 -bang GhcModLintAsync call ghcmod#command#async_make('lint', 0) command! -buffer -nargs=0 -bang GhcModCheckAndLintAsync call ghcmod#command#check_and_lint_async(0) command! -buffer -nargs=0 -bang GhcModExpand call ghcmod#command#expand(0) +command! -buffer -nargs=0 -bang GhcModKillModi call ghcmod#command#kill_modi(0) let b:undo_ftplugin .= join(map([ \ 'GhcModType', \ 'GhcModTypeInsert', @@ -72,7 +73,8 @@ let b:undo_ftplugin .= join(map([ \ 'GhcModCheckAsync', \ 'GhcModLintAsync', \ 'GhcModCheckAndLintAsync', - \ 'GhcModExpand' + \ 'GhcModExpand', + \ 'GhcModKillModi' \ ], '"delcommand " . v:val'), ' | ') let b:undo_ftplugin .= ' | unlet b:did_ftplugin_ghcmod' diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 5b1e4be..897a8b7 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -322,6 +322,16 @@ function! s:modi_command(args) "{{{ endwhile endfunction "}}} +function! ghcmod#kill_modi(sig) "{{{ + if s:ghc_modi_proc == {} + return + endif + let l:ret = s:ghc_modi_proc.kill(a:sig) + call s:ghc_modi_proc.waitpid() + let s:ghc_modi_proc = {} + return l:ret +endfunction "}}} + function! ghcmod#system(...) "{{{ let l:dir = getcwd() try diff --git a/autoload/ghcmod/command.vim b/autoload/ghcmod/command.vim index d8541a7..42834cf 100644 --- a/autoload/ghcmod/command.vim +++ b/autoload/ghcmod/command.vim @@ -257,6 +257,18 @@ function! ghcmod#command#expand(force) "{{{ call s:open_quickfix() endfunction "}}} +function! ghcmod#command#kill_modi(force) "{{{ + if a:force + let l:sig = g:vimproc#SIGKILL + else + let l:sig = g:vimproc#SIGTERM + endif + let l:ret = ghcmod#kill_modi(l:sig) + if l:ret + echoerr vimproc#get_last_errmsg() + endif +endfunction "}}} + function! s:open_quickfix() "{{{ let l:func = get(g:, 'ghcmod_open_quickfix_function', '') if empty(l:func) diff --git a/test/test_type.vim b/test/test_type.vim index 7e38c05..c6e8547 100644 --- a/test/test_type.vim +++ b/test/test_type.vim @@ -20,4 +20,10 @@ function! s:unit.test_type_compilation_failure() call self.assert.empty(l:types) endfunction +function! s:unit.test_kill_recovery() + call s:unit.test_type() + call ghcmod#kill_modi(9) + call s:unit.test_type() +endfunction + call s:unit.run() From 9a98d324f591bd02a313d1a73f998ab827e04dad Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Fri, 7 Oct 2016 13:28:12 +0200 Subject: [PATCH 06/11] Support multiple packages (multiple ghc-modi instances) Inspired by https://github.com/wuzzeb/syntastic/blob/0c5c68a5c9812e86e3e09d240bd1676d3178aa9c/syntax_checkers/haskell/ghc-modi.vim --- autoload/ghcmod.vim | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 897a8b7..1a41663 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -295,21 +295,26 @@ function! ghcmod#build_command(args) "{{{ endfunction "}}} " Cache a handle to the ghc-modi process. -let s:ghc_modi_proc = {} +let s:ghc_modi_procs = {} function! s:modi_command(args) "{{{ - if s:ghc_modi_proc == {} - let l:ghcmodi_prog = ghcmod#build_command(["legacy-interactive"]) - lcd `=ghcmod#basedir()` - let s:ghc_modi_proc = vimproc#popen2(ghcmodi_prog) + let l:basedir = ghcmod#basedir() + + if has_key(s:ghc_modi_procs, l:basedir) + let l:ghc_modi_proc = s:ghc_modi_procs[l:basedir] + else + let l:ghc_modi_prog = ghcmod#build_command(["legacy-interactive"]) + lcd `=l:basedir` + let l:ghc_modi_proc = vimproc#popen2(l:ghc_modi_prog) lcd - + let s:ghc_modi_procs[l:basedir] = l:ghc_modi_proc endif - call s:ghc_modi_proc.stdin.write(join(a:args) . "\n") + call l:ghc_modi_proc.stdin.write(join(a:args) . "\n") let l:res = [] while 1 - for l:line in s:ghc_modi_proc.stdout.read_lines() + for l:line in l:ghc_modi_proc.stdout.read_lines() if l:line == "OK" return l:res elseif line =~ "^NG " @@ -323,13 +328,15 @@ function! s:modi_command(args) "{{{ endfunction "}}} function! ghcmod#kill_modi(sig) "{{{ - if s:ghc_modi_proc == {} - return + let l:basedir = ghcmod#basedir() + + if has_key(s:ghc_modi_procs, l:basedir) + let l:ghc_modi_proc = s:ghc_modi_procs[l:basedir] + let l:ret = l:ghc_modi_proc.kill(a:sig) + call l:ghc_modi_proc.waitpid() + unlet s:ghc_modi_procs[l:basedir] + return l:ret endif - let l:ret = s:ghc_modi_proc.kill(a:sig) - call s:ghc_modi_proc.waitpid() - let s:ghc_modi_proc = {} - return l:ret endfunction "}}} function! ghcmod#system(...) "{{{ From 2a2598b3e03c021c746eea148692b1f178463d9d Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Sun, 9 Oct 2016 23:59:45 +0200 Subject: [PATCH 07/11] Fix filenames with whitespaces in ghc-modi --- autoload/ghcmod.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 1a41663..592cea3 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -310,7 +310,7 @@ function! s:modi_command(args) "{{{ let s:ghc_modi_procs[l:basedir] = l:ghc_modi_proc endif - call l:ghc_modi_proc.stdin.write(join(a:args) . "\n") + call l:ghc_modi_proc.stdin.write("ascii-escape " . join(map(copy(a:args), '"\2" . v:val . "\3"')) . "\n") let l:res = [] while 1 From 182072fa9457011aafd5797e2d0b12ec6b0dee99 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Sun, 9 Oct 2016 23:29:40 +0200 Subject: [PATCH 08/11] Use ghc-modi for sig/split/expand, too --- autoload/ghcmod.vim | 31 +++++++++++++------------------ test.sh | 2 +- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 592cea3..43058e4 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -21,12 +21,7 @@ function! ghcmod#getHaskellIdentifier() "{{{ endfunction "}}} function! ghcmod#info(fexp, path, ...) "{{{ - if s:use_modi - let l:lines = s:modi_command(['info', a:path, a:fexp]) - else - let l:cmd = ghcmod#build_command(['info', a:path, a:fexp]) - let l:lines = s:system('info', l:cmd) - endif + let l:lines = s:command(['info', a:path, a:fexp]) let l:output = join(split(l:lines[0], '\\n'), "\n") " Remove trailing newlines to prevent empty lines let l:output = substitute(l:output, '\n*$', '', '') @@ -35,8 +30,7 @@ endfunction "}}} function! ghcmod#split(line, col, path, ...) "{{{ " `ghc-mod split` is available since v5.0.0. - let l:cmd = ghcmod#build_command(['split', a:path, a:line, a:col]) - let l:lines = s:system('split', l:cmd) + let l:lines = s:command(['split', a:path, a:line, a:col]) if empty(l:lines) return [] endif @@ -49,8 +43,7 @@ endfunction "}}} function! ghcmod#sig(line, col, path, ...) "{{{ " `ghc-mod sig` is available since v5.0.0. - let l:cmd = ghcmod#build_command(['sig', a:path, a:line, a:col]) - let l:lines = s:system('sig', l:cmd) + let l:lines = s:command(['sig', a:path, a:line, a:col]) if len(l:lines) < 3 return [] endif @@ -58,12 +51,7 @@ function! ghcmod#sig(line, col, path, ...) "{{{ endfunction "}}} function! ghcmod#type(line, col, path, ...) "{{{ - if s:use_modi - let l:lines = s:modi_command(['type', a:path, a:line, a:col]) - else - let l:cmd = ghcmod#build_command(['type', a:path, a:line, a:col]) - let l:lines = s:system('type', l:cmd) - endif + let l:lines = s:command(['type', a:path, a:line, a:col]) let l:types = [] for l:line in l:lines let l:m = matchlist(l:line, '^\(\d\+\) \(\d\+\) \(\d\+\) \(\d\+\) "\([^"]\+\)"$') @@ -198,8 +186,7 @@ function! ghcmod#expand(path) "{{{ let l:dir = fnamemodify(a:path, ':h') let l:qflist = [] - let l:cmd = ghcmod#build_command(['expand', a:path]) - for l:line in s:system('expand', l:cmd) + for l:line in s:command(['expand', a:path]) let l:line = s:remove_dummy_prefix(l:line) " path:line:col1-col2: message @@ -327,6 +314,14 @@ function! s:modi_command(args) "{{{ endwhile endfunction "}}} +function! s:command(args) "{{{ + if s:use_modi + return s:modi_command(a:args) + else + return s:system(a:args[0], ghcmod#build_command(a:args)) + endif +endfunction "}}} + function! ghcmod#kill_modi(sig) "{{{ let l:basedir = ghcmod#basedir() diff --git a/test.sh b/test.sh index 4cfbfda..2142283 100755 --- a/test.sh +++ b/test.sh @@ -22,7 +22,7 @@ run_tests() { retval=0 -modonly_tests=(test/test_type.vim test/test_info.vim) +modonly_tests=(test/test_{expand,info,split,type,command_sig_codegen,command_split,command_type}.vim) run_tests "test/test_*.vim" From ab9f1bc4d2d71bbc4585de19ba1b8360faaa1384 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Mon, 10 Oct 2016 00:54:06 +0200 Subject: [PATCH 09/11] Redirect ghc-modi's stderr to /dev/null popen2 would mix it with stdout and it would mess things up with messages from e.g. cabal. --- autoload/ghcmod.vim | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index 43058e4..d3648ed 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -291,9 +291,7 @@ function! s:modi_command(args) "{{{ let l:ghc_modi_proc = s:ghc_modi_procs[l:basedir] else let l:ghc_modi_prog = ghcmod#build_command(["legacy-interactive"]) - lcd `=l:basedir` - let l:ghc_modi_proc = vimproc#popen2(l:ghc_modi_prog) - lcd - + let l:ghc_modi_proc = s:plineopen3([{'args': l:ghc_modi_prog, 'fd': { 'stdin': '', 'stdout': '', 'stderr': '/dev/null' }}]) let s:ghc_modi_procs[l:basedir] = l:ghc_modi_proc endif From 4135411df44031b4280d2fb0e43f207031551711 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Mon, 10 Oct 2016 00:55:49 +0200 Subject: [PATCH 10/11] Use ghc-modi for check/lint, too --- autoload/ghcmod.vim | 16 ++++++++-------- test.sh | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autoload/ghcmod.vim b/autoload/ghcmod.vim index d3648ed..7df3396 100644 --- a/autoload/ghcmod.vim +++ b/autoload/ghcmod.vim @@ -138,21 +138,21 @@ function! ghcmod#parse_make(lines, basedir) "{{{ return l:qflist endfunction "}}} -function! s:build_make_command(type, path) "{{{ - let l:cmd = ghcmod#build_command([a:type]) +function! s:build_make_args(type, path) "{{{ + let l:args = [a:type] if a:type ==# 'lint' for l:hopt in get(g:, 'ghcmod_hlint_options', []) - call extend(l:cmd, ['-h', l:hopt]) + call extend(l:args, ['-h', l:hopt]) endfor endif - call add(l:cmd, a:path) - return l:cmd + call add(l:args, a:path) + return l:args endfunction "}}} function! ghcmod#make(type, path) "{{{ try - let l:args = s:build_make_command(a:type, a:path) - return ghcmod#parse_make(s:system(a:type, l:args), b:ghcmod_basedir) + let l:lines = s:command(s:build_make_args(a:type, a:path)) + return ghcmod#parse_make(l:lines, b:ghcmod_basedir) catch call ghcmod#util#print_error(printf('%s %s', v:throwpoint, v:exception)) endtry @@ -160,7 +160,7 @@ endfunction "}}} function! ghcmod#async_make(type, path, callback) "{{{ let l:tmpfile = tempname() - let l:args = s:build_make_command(a:type, a:path) + let l:args = ghcmod#build_command(s:build_make_args(a:type, a:path)) let l:proc = s:plineopen3([{'args': l:args, 'fd': { 'stdin': '', 'stdout': l:tmpfile, 'stderr': '' }}]) let l:obj = { \ 'proc': l:proc, diff --git a/test.sh b/test.sh index 2142283..1fd7112 100755 --- a/test.sh +++ b/test.sh @@ -22,7 +22,7 @@ run_tests() { retval=0 -modonly_tests=(test/test_{expand,info,split,type,command_sig_codegen,command_split,command_type}.vim) +modonly_tests=(test/test_{expand,check,info,lint,split,type,command_check,command_sig_codegen,command_split,command_type}.vim) run_tests "test/test_*.vim" From 9f7e9b635a20787e47904db2be5cf4f484b0f579 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Mon, 10 Oct 2016 22:38:54 +0200 Subject: [PATCH 11/11] Fix garbage in tmp after GhcModKillModi --- autoload/ghcmod/command.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/ghcmod/command.vim b/autoload/ghcmod/command.vim index 42834cf..49ac0b9 100644 --- a/autoload/ghcmod/command.vim +++ b/autoload/ghcmod/command.vim @@ -261,7 +261,7 @@ function! ghcmod#command#kill_modi(force) "{{{ if a:force let l:sig = g:vimproc#SIGKILL else - let l:sig = g:vimproc#SIGTERM + let l:sig = g:vimproc#SIGINT endif let l:ret = ghcmod#kill_modi(l:sig) if l:ret