From 6f65a57391ad93e17435cd9a421e7c63e4d645bc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 02:31:23 +0000 Subject: [PATCH 001/111] use vim-jobs in s:callPsciIde --- ftplugin/purescript_pscide.vim | 224 +++++++++++++++++++++------------ 1 file changed, 144 insertions(+), 80 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 3d48e16..1131c87 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -174,12 +174,19 @@ function! PSCIDEload(silent) let input = {'command': 'load'} - let resp = s:callPscIde(input, "Failed to load", 0) + call s:callPscIde( + \ input, + \ "Failed to load", + \ 0, + \ {msg -> s:PSCIDEloadCallback(loglevel, msg)} + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# "success" - call s:log("PSCIDEload: Succesfully loaded modules: " . string(resp["result"]), loglevel) +function! s:PSCIDEloadCallback(loglevel, resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" + call s:log("PSCIDEload: Succesfully loaded modules: " . string(a:resp["result"]), a:loglevel) else - call s:log("PSCIDEload: Failed to load. Error: " . string(resp["result"]), loglevel) + call s:log("PSCIDEload: Failed to load. Error: " . string(a:resp["result"]), a:loglevel) endif endfunction @@ -216,9 +223,7 @@ function! s:importIdentifier(id, module) return endif - let oldlines = getline(1, '$') - - call writefile(oldlines, s:tempfile) + call writefile(getline(1, '$'), s:tempfile) let input = { \ 'command': 'import' , @@ -233,21 +238,29 @@ function! s:importIdentifier(id, module) let input.params.filters = [{'filter': 'modules', 'params': {'modules': [a:module]}}] endif - let resp = s:callPscIde(input, "Failed to import identifier " . ident, 0) + call s:callPscIde( + \ input, + \ "Failed to import identifier " . ident, + \ 0, + \ {resp -> s:PSCIDEimportIdentifierCallback(ident, a:id, a:module, resp)} + \ ) +endfunction +function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) "multiple possibilities - if type(resp) == type({}) && resp.resultType ==# "success" && type(resp.result[0]) == type({}) - let choice = s:pickOption("Multiple possibilities to import " . ident, resp.result, "module") + call s:log("s:PSCIDEimportIndetifierCallback", 3) + if type(a:resp) == type({}) && a:resp.resultType ==# "success" && type(a:resp.result[0]) == type({}) + let choice = s:pickOption("Multiple possibilities to import " . a:ident, a:resp.result, "module") if choice.picked - call s:importIdentifier(ident, choice.option.module) + call s:importIdentifier(a:ident, choice.option.module) endif return endif - if type(resp) == type({}) && resp['resultType'] ==# "success" - let newlines = resp.result + if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" + let newlines = a:resp.result - let linesdiff = len(newlines) - len(oldlines) + let linesdiff = len(newlines) - line("$") let nrOfOldlinesUnderLine = line(".") - 1 let nrOfNewlinesUnderLine = nrOfOldlinesUnderLine + linesdiff let nrOfLinesToReplace = min([nrOfNewlinesUnderLine, nrOfOldlinesUnderLine]) @@ -280,7 +293,7 @@ function! s:importIdentifier(id, module) call s:log("PSCIDEimportIdentifier: Succesfully imported identifier: " . a:module . " ".a:id, 3) else - call s:log("PSCIDEimportIdentifier: Failed to import identifier " . ident . ". Error: " . string(resp["result"]), 0) + call s:log("PSCIDEimportIdentifier: Failed to import identifier " . a:ident . ". Error: " . string(a:resp["result"]), 0) endif endfunction @@ -351,23 +364,30 @@ function! PSCIDErebuild(stuff) let filename = expand("%:p") let input = {'command': 'rebuild', 'params': {'file': filename}} - let resp = s:callPscIde(input, 0, 0) + call s:callPscIde( + \ input, + \ 0, + \ 0, + \ { msg -> s:PSCIDErebuild(filename, msg) } + \ ) +endfunction - if type(resp) == type({}) && has_key(resp, "resultType") - \ && has_key (resp, "result") && type(resp.result) == type([]) - if resp.resultType == "error" - let out = ParsePscJsonOutput(resp.result, []) +function! s:PSCIDErebuild(filename, resp) + if type(a:resp) == type({}) && has_key(a:resp, "resultType") + \ && has_key (a:resp, "result") && type(a:resp.result) == type([]) + if a:resp.resultType == "error" + let out = ParsePscJsonOutput(a:resp.result, []) else - let out = ParsePscJsonOutput([], resp.result) + let out = ParsePscJsonOutput([], a:resp.result) endif if out.error != "" - call s:log("PSCIDErebuild: Failed to interpret " . string(resp.result), 0) + call s:log("PSCIDErebuild: Failed to interpret " . string(a:resp.result), 0) endif let g:psc_ide_suggestions = out.suggestions return out.llist else - call s:log("PSCIDErebuild: Failed to rebuild " . filename, 0) + call s:log("PSCIDErebuild: Failed to rebuild " . a:filename, 0) return [] endif endfunction @@ -377,13 +397,18 @@ command! PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation() function! PSCIDEaddTypeAnnotation() let identifier = s:GetWordUnderCursor() - let result = s:getType(identifier) + call s:getType( + \ identifier, + \ { resp -> s:PSCIDEaddTypeAnnotationCallback(identifier, resp) } + \ ) +endfunction - if type(result) == type([]) +function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) + if type(a:result) == type([]) let lnr = line(".") call append(lnr - 1, s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) else - echom "PSC-IDE: No type information found for " . identifier + echom "PSC-IDE: No type information found for " . a:identifier endif endfunction @@ -453,26 +478,38 @@ command! PSCIDEtype call PSCIDEtype() function! PSCIDEtype() let identifier = s:GetWordUnderCursor() - let result = s:getType(identifier) + call s:getType( + \ identifier, + \ { resp -> s:PSCIDEtypeCallback(identifier, resp) } + \ ) +endfunction - if type(result) == type([]) - for e in result +function s:PSCIDEtypeCallback(identifier, result) + if type(a:result) == type([]) + for e in a:result echom s:formattype(e) endfor else - echom "PSC-IDE: No type information found for " . identifier + echom "PSC-IDE: No type information found for " . a:identifier endif endfunction -function! s:getType(identifier) +function! s:getType(identifier, cb) let currentModule = s:ExtractModule() call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) - let resp = s:callPscIde({'command': 'type', 'params': {'search': a:identifier, 'filters': []}, 'currentModule': currentModule}, 'Failed to get type info for: ' . a:identifier, 0) + call s:callPscIde( + \ {'command': 'type', 'params': {'search': a:identifier, 'filters': []}, 'currentModule': currentModule}, + \ 'Failed to get type info for: ' . a:identifier, + \ 0, + \ { resp -> s:getTypeCallback(resp, a:cb)} + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' - if len(resp["result"]) > 0 - return resp["result"] +function! s:getTypeCallback(resp, cb) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + if len(a:resp["result"]) > 0 + call a:cb(a:resp["result"]) endif endif endfunction @@ -489,6 +526,7 @@ function! PSCIDEapplySuggestion() let filename = expand("%:p") call PSCIDEapplySuggestionPrime(lnr, filename, 0) endfunction + function! PSCIDEapplySuggestionPrime(lnr, filename, silent) "let llist = getloclist(0) @@ -709,7 +747,7 @@ endfunction " Is responsible for keeping track of whether or not we have a running server " and (re)starting it if not " Also serializes and deserializes from/to JSON -function! s:callPscIde(input, errorm, isRetry) +function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: start: Executing command: " . string(a:input), 3) if s:projectvalid == 0 @@ -722,53 +760,80 @@ function! s:callPscIde(input, errorm, isRetry) let cwdcommand = {'command': 'cwd'} call s:log("callPscIde: No server found, looking for external server", 1) - let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(cwdcommand)) - call s:log("callPscIde: Raw response of trying to reach external server: " . cwdresp, 1) - let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(cwdresp)) - call s:log("callPscIde: Decoded response of trying to reach external server: " - \ . string(cwdrespDecoded), 1) - - if type(cwdrespDecoded) == type({}) && cwdrespDecoded.resultType ==# 'success' - call s:log("callPscIde: Found external server with cwd: " . string(cwdrespDecoded.result), 1) - call s:log("callPscIde: Expecting CWD: " . expectedCWD, 1) - - if expectedCWD != cwdrespDecoded.result - call s:log("callPscIde: External server on incorrect CWD, closing", 1) - PSCIDEend - call s:log("callPscIde: Starting new server", 1) - call PSCIDEstart(1) - else - call s:log("callPscIde: External server CWD matches with what we need", 1) - let s:pscidestarted = 1 - let s:pscideexternal = 1 - endif - else - call s:log("callPscIde: No external server found, starting new server", 1) - call PSCIDEstart(1) - endif + call job_start( + \ ["psc-ide-client", "-p", g:psc_ide_server_port, s:jsonEncode(cwdcommand)], + \ { "out_cb": function("s:PscIdeCallback") + \ }) + return + endif - call s:log("callPscIde: Trying to reach server again", 1) - let cwdresp2 = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(cwdcommand)) - call s:log("callPscIde: Raw response of trying to reach server again: " . cwdresp2, 1) - let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(cwdresp2)) - call s:log("callPscIde: Decoded response of trying to reach server again: " - \ . string(cwdresp2Decoded), 1) - - if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' - \ && cwdresp2Decoded.result == expectedCWD - call s:log("callPscIde: Server successfully contacted! Loading current module.", 1) - call PSCIDEload(1) + let enc = s:jsonEncode(a:input) + let tempfile = tempname() + call writefile([enc], tempfile, "b") + call s:log("callPscIde: psc-ide-client: " . enc, 3) + call job_start( + \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback3(a:input, a:errorm, msg))} + \ , "in_io": "file" + \ , "in_name": tempfile + \ , "err_cb": {ch, msg -> s:log("ups..." . msg, 3)} + \ }) + call delete(tempfile) +endfunction + +" UTILITY FUNCTIONS ---------------------------------------------------------- +function! s:PscIdeCallback(channel, cwdresp) + let expectedCWD = s:findFileRecur('bower.json') + call s:log("callPscIde: Raw response of trying to reach external server: " . a:cwdresp, 1) + let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp)) + call s:log("callPscIde: Decoded response of trying to reach external server: " + \ . string(cwdrespDecoded), 1) + + if type(cwdrespDecoded) == type({}) && cwdrespDecoded.resultType ==# 'success' + call s:log("callPscIde: Found external server with cwd: " . string(cwdrespDecoded.result), 1) + call s:log("callPscIde: Expecting CWD: " . expectedCWD, 1) + + if expectedCWD != cwdrespDecoded.result + call s:log("callPscIde: External server on incorrect CWD, closing", 1) + PSCIDEend + call s:log("callPscIde: Starting new server", 1) + call PSCIDEstart(1) else - call s:log("callPscIde: Server still can't be contacted, aborting...", 1) - return + call s:log("callPscIde: External server CWD matches with what we need", 1) + let s:pscidestarted = 1 + let s:pscideexternal = 1 endif + else + call s:log("callPscIde: No external server found, starting new server", 1) + call PSCIDEstart(1) endif + call s:log("callPscIde: Trying to reach server again", 1) + call job_start( + \ ["psc-ide-client", "-p", g:psc_ide_server_port, s:jsonEncode(cwdcommand)] + \ { "out_cb": function("s:PscIdeCallback2") + \ }) +endfunction - let enc = s:jsonEncode(a:input) - let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) - call s:log("callPscIde: Raw response: " . resp, 3) +function! s:PscIdeCallback2(channel, cwdresp2) + call s:log("callPscIde: Raw response of trying to reach server again: " . a:cwdresp2, 1) + let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp2)) + call s:log("callPscIde: Decoded response of trying to reach server again: " + \ . string(cwdresp2Decoded), 1) - if resp =~? "connection refused" "TODO: This check is probably not crossplatform + if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' + \ && cwdresp2Decoded.result == expectedCWD + call s:log("callPscIde: Server successfully contacted! Loading current module.", 1) + call PSCIDEload(1) + else + call s:log("callPscIde: Server still can't be contacted, aborting...", 1) + return + endif +endfunction + +function! s:PscIdeCallback3(input, errorm, resp) + call s:log("callPscIde: Raw response: " . a:resp, 3) + + if a:resp =~? "connection refused" "TODO: This check is probably not crossplatform let s:pscidestarted = 0 let s:pscideexternal = 0 @@ -783,7 +848,7 @@ function! s:callPscIde(input, errorm, isRetry) endif endif - let decoded = PscIdeDecodeJson(s:CleanEnd(s:StripNewlines(resp))) + let decoded = PscIdeDecodeJson(s:CleanEnd(s:StripNewlines(a:resp))) call s:log("callPscIde: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') @@ -793,7 +858,6 @@ function! s:callPscIde(input, errorm, isRetry) return decoded endfunction -" UTILITY FUNCTIONS ---------------------------------------------------------- function! s:StripNewlines(s) return substitute(a:s, '\s*\n\s*', ' ', 'g') endfunction @@ -983,7 +1047,7 @@ function! PscIdeDecodeJson(json) abort let null = '' try - let object = eval(a:json) + let object = json_decode(a:json) catch " malformed JSON let object = '' From cf701da31a111d3e95b1301272eb34505e4f6a3f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 02:58:16 +0000 Subject: [PATCH 002/111] callPscIde callbacks --- ftplugin/purescript_pscide.vim | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 1131c87..a72c5e3 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -758,12 +758,17 @@ function! s:callPscIde(input, errorm, isRetry, cb) let expectedCWD = s:findFileRecur('bower.json') let cwdcommand = {'command': 'cwd'} + let tempfile = tempname() + call writefile([s:jsonEncode(cwdcommand)], tempfile) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port, s:jsonEncode(cwdcommand)], - \ { "out_cb": function("s:PscIdeCallback") + \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ { "out_cb": { msg -> s:PscIdeCallback(cwdcommand, msg) } + \ , "in_io": "file" + \ , "in_name": tempfile \ }) + call delete(tempfile) return endif @@ -782,7 +787,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- -function! s:PscIdeCallback(channel, cwdresp) +function! s:PscIdeCallback(cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') call s:log("callPscIde: Raw response of trying to reach external server: " . a:cwdresp, 1) let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp)) @@ -808,20 +813,26 @@ function! s:PscIdeCallback(channel, cwdresp) call PSCIDEstart(1) endif call s:log("callPscIde: Trying to reach server again", 1) + let tempfile = tempname() + call writefile([s:jsonEncode(a:cwdcommand)], tempfile) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port, s:jsonEncode(cwdcommand)] - \ { "out_cb": function("s:PscIdeCallback2") - \ }) + \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ { "out_cb": { ch, resp -> s:PscIdeCallback2(expectedCWD, resp) } + \ , "in_io": "file" + \ , "in_name": tempfile + \ , "err_cb": { ch, msg -> s:log("ups..." . msg, 3) } + \ }) + call delete(tempfile) endfunction -function! s:PscIdeCallback2(channel, cwdresp2) +function! s:PscIdeCallback2(expectedCWD, cwdresp2) call s:log("callPscIde: Raw response of trying to reach server again: " . a:cwdresp2, 1) let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp2)) call s:log("callPscIde: Decoded response of trying to reach server again: " \ . string(cwdresp2Decoded), 1) if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' - \ && cwdresp2Decoded.result == expectedCWD + \ && cwdresp2Decoded.result == a:expectedCWD call s:log("callPscIde: Server successfully contacted! Loading current module.", 1) call PSCIDEload(1) else From 2e3aa9bf257f9a503b69f1e4d0b6ae81ae1d225b Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:17:01 +0000 Subject: [PATCH 003/111] PSCIDErebuid --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a72c5e3..96bb690 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -368,11 +368,11 @@ function! PSCIDErebuild(stuff) \ input, \ 0, \ 0, - \ { msg -> s:PSCIDErebuild(filename, msg) } + \ { msg -> s:PSCIDErebuildCallback(filename, msg) } \ ) endfunction -function! s:PSCIDErebuild(filename, resp) +function! s:PSCIDErebuildCallback(filename, resp) if type(a:resp) == type({}) && has_key(a:resp, "resultType") \ && has_key (a:resp, "result") && type(a:resp.result) == type([]) if a:resp.resultType == "error" From d161ca8f0bc4b828811b604ff2decf9661150b4c Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:17:17 +0000 Subject: [PATCH 004/111] PSCIDEcwd --- ftplugin/purescript_pscide.vim | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 96bb690..331ee86 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -416,10 +416,17 @@ endfunction " Get current working directory of psc-ide-server command! PSCIDEcwd call PSCIDEcwd() function! PSCIDEcwd() - let resp = s:callPscIde({'command': 'cwd'}, "Failed to get current working directory", 0) + call s:callPscIde( + \ {'command': 'cwd'}, + \ "Failed to get current working directory", + \ 0, + \ function("s:PSCIDEcwdCallback") + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' - echom "PSC-IDE: Current working directory: " . resp["result"] +function s:PSCIDEcwdCallback(resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + echom "PSC-IDE: Current working directory: " . a:resp["result"] endif endfunction From 95c115c64cf220298200a86156e9befdca903d39 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:17:42 +0000 Subject: [PATCH 005/111] PSCIDEaddClause --- ftplugin/purescript_pscide.vim | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 331ee86..4d62bf2 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -439,12 +439,19 @@ function! PSCIDEaddClause() let command = {'command': 'addClause', 'params': {'line': line, 'annotations': s:jsonFalse()}} - let resp = s:callPscIde(command, "Failed to add clause", 0) + call s:callPscIde( + \ command, + \ "Failed to add clause", + \ 0, + \ { resp -> s:PSCIDEaddClauseCallback(lnr, resp) } + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' && type(resp.result) == type([]) - call s:log('PSCIDEaddClause results: ' . string(resp.result), 3) - call append(lnr, resp.result) - :normal dd +function! s:PSCIDEaddClauseCallback(lnr, resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' && type(a:resp.result) == type([]) + call s:log('PSCIDEaddClause results: ' . string(a:resp.result), 3) + call append(a:lnr, a:resp.result) + normal dd endif endfunction From 36ec0da5f4fadec3494aac380d72488f20da7bbf Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:18:07 +0000 Subject: [PATCH 006/111] PSCIDEcaseSplit --- ftplugin/purescript_pscide.vim | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4d62bf2..3077287 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -475,14 +475,24 @@ function! PSCIDEcaseSplit() call s:log('end position: ' . string(e), 3) call s:log('type: ' . t, 3) - let command = {'command': 'caseSplit', 'params': {'line': line, 'begin': b, 'end': e, 'annotations': s:jsonFalse(), 'type': t}} + let command = { + \ 'command': 'caseSplit', + \ 'params': { 'line': line, 'begin': b, 'end': e, 'annotations': s:jsonFalse(), 'type': t} + \ } - let resp = s:callPscIde(command, 'Failed to split case for: ' . word, 0) + call s:callPscIde( + \ command, + \ 'Failed to split case for: ' . word, + \ 0, + \ { resp -> s:PSCIDEcaseSplitCallback(lnr, resp) } + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' && type(resp.result) == type([]) - call s:log('PSCIDEcaseSplit results: ' . string(resp.result), 3) - call append(lnr, resp.result) - :normal dd +function! s:PSCIDEcaseSplitCallback(lnr, resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' && type(a:resp.result) == type([]) + call s:log('PSCIDEcaseSplit results: ' . string(a:resp.result), 3) + call append(a:lnr, a:resp.result) + normal dd endif endfunction From afca3f0aff150e7d253b887cb019169963a2b6ed Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:18:52 +0000 Subject: [PATCH 007/111] PSCIDEpursuit --- ftplugin/purescript_pscide.vim | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 3077287..0b7690d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -637,11 +637,18 @@ command! PSCIDEpursuit call PSCIDEpursuit() function! PSCIDEpursuit() let identifier = s:GetWordUnderCursor() - let resp = s:callPscIde({'command': 'pursuit', 'params': {'query': identifier, 'type': "completion"}}, 'Failed to get pursuit info for: ' . identifier, 0) + call s:callPscIde( + \ {'command': 'pursuit', 'params': {'query': identifier, 'type': "completion"}}, + \ 'Failed to get pursuit info for: ' . identifier, + \ 0, + \ { resp -> s:PSCIDEpursuitCallback(resp) } + \ ) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' - if len(resp["result"]) > 0 - for e in resp["result"] +function! s:PSCIDEpuresuitCallback(resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + if len(a:resp["result"]) > 0 + for e in a:resp["result"] echom s:formatpursuit(e) endfor else @@ -649,6 +656,7 @@ function! PSCIDEpursuit() endif endif endfunction + function! s:formatpursuit(record) return "In " . s:CleanEnd(s:StripNewlines(a:record["package"])) . " " . s:CleanEnd(s:StripNewlines(a:record['module']) . '.' . s:StripNewlines(a:record['ident']) . ' :: ' . s:StripNewlines(a:record['type'])) endfunction From ca63df4608b3bc0090eba5126036da6795c23f80 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:19:22 +0000 Subject: [PATCH 008/111] PSCIDElist --- ftplugin/purescript_pscide.vim | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 0b7690d..f1efe0d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -678,11 +678,18 @@ endfunction " LIST ----------------------------------------------------------------------- command! PSCIDElist call PSCIDElist() function! PSCIDElist() - let resp = s:callPscIde({'command': 'list', 'params': {'type': 'loadedModules'}}, 'Failed to get loaded modules', 0) + s:callPscIde( + \ {'command': 'list', 'params': {'type': 'loadedModules'}}, + \ 'Failed to get loaded modules', + \ 0 + \ ) + call s:PSCIDElistCallback(resp) +endfunction - if type(resp) == type({}) && resp['resultType'] ==# 'success' - if len(resp["result"]) > 0 - for m in resp["result"] +function s:PSCIDElistCallback(resp) + if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + if len(a:resp["result"]) > 0 + for m in a:resp["result"] echom m endfor else @@ -691,7 +698,6 @@ function! PSCIDElist() endif endfunction - " SET UP OMNICOMPLETION ------------------------------------------------------ set omnifunc=PSCIDEomni From bdd2923d46afdf04a831cf650261b9e03e622d56 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:37:11 +0000 Subject: [PATCH 009/111] s:callPsciIde callbacks --- ftplugin/purescript_pscide.vim | 46 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f1efe0d..412b474 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -802,7 +802,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": { msg -> s:PscIdeCallback(cwdcommand, msg) } + \ { "out_cb": { msg -> s:PscIdeStartCallback(cwdcommand, msg) } \ , "in_io": "file" \ , "in_name": tempfile \ }) @@ -816,7 +816,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: psc-ide-client: " . enc, 3) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback3(a:input, a:errorm, msg))} + \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, msg))} \ , "in_io": "file" \ , "in_name": tempfile \ , "err_cb": {ch, msg -> s:log("ups..." . msg, 3)} @@ -825,37 +825,37 @@ function! s:callPscIde(input, errorm, isRetry, cb) endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- -function! s:PscIdeCallback(cwdcommand, cwdresp) +function! s:PscIdeStartCallback(cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') - call s:log("callPscIde: Raw response of trying to reach external server: " . a:cwdresp, 1) + call s:log("s:PscIdeStartCallback: Raw response of trying to reach external server: " . a:cwdresp, 1) let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp)) - call s:log("callPscIde: Decoded response of trying to reach external server: " + call s:log("s:PscIdeStartCallback: Decoded response of trying to reach external server: " \ . string(cwdrespDecoded), 1) if type(cwdrespDecoded) == type({}) && cwdrespDecoded.resultType ==# 'success' - call s:log("callPscIde: Found external server with cwd: " . string(cwdrespDecoded.result), 1) - call s:log("callPscIde: Expecting CWD: " . expectedCWD, 1) + call s:log("s:PscIdeStartCallback: Found external server with cwd: " . string(cwdrespDecoded.result), 1) + call s:log("s:PscIdeStartCallback: Expecting CWD: " . expectedCWD, 1) if expectedCWD != cwdrespDecoded.result - call s:log("callPscIde: External server on incorrect CWD, closing", 1) + call s:log("s:PscIdeStartCallback: External server on incorrect CWD, closing", 1) PSCIDEend - call s:log("callPscIde: Starting new server", 1) + call s:log("s:PscIdeStartCallback: Starting new server", 1) call PSCIDEstart(1) else - call s:log("callPscIde: External server CWD matches with what we need", 1) + call s:log("s:PscIdeStartCallback: External server CWD matches with what we need", 1) let s:pscidestarted = 1 let s:pscideexternal = 1 endif else - call s:log("callPscIde: No external server found, starting new server", 1) + call s:log("s:PscIdeStartCallback: No external server found, starting new server", 1) call PSCIDEstart(1) endif - call s:log("callPscIde: Trying to reach server again", 1) + call s:log("s:PscIdeStartCallback: Trying to reach server again", 1) let tempfile = tempname() call writefile([s:jsonEncode(a:cwdcommand)], tempfile) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": { ch, resp -> s:PscIdeCallback2(expectedCWD, resp) } + \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(expectedCWD, resp) } \ , "in_io": "file" \ , "in_name": tempfile \ , "err_cb": { ch, msg -> s:log("ups..." . msg, 3) } @@ -863,31 +863,31 @@ function! s:PscIdeCallback(cwdcommand, cwdresp) call delete(tempfile) endfunction -function! s:PscIdeCallback2(expectedCWD, cwdresp2) - call s:log("callPscIde: Raw response of trying to reach server again: " . a:cwdresp2, 1) +function! s:PscIdeRetryCallback(expectedCWD, cwdresp2) + call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . a:cwdresp2, 1) let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp2)) - call s:log("callPscIde: Decoded response of trying to reach server again: " + call s:log("s:PscIdeRetryCallback: Decoded response of trying to reach server again: " \ . string(cwdresp2Decoded), 1) if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' \ && cwdresp2Decoded.result == a:expectedCWD - call s:log("callPscIde: Server successfully contacted! Loading current module.", 1) + call s:log("s:PscIdeRetryCallback: Server successfully contacted! Loading current module.", 1) call PSCIDEload(1) else - call s:log("callPscIde: Server still can't be contacted, aborting...", 1) + call s:log("s:PscIdeRetryCallback: Server still can't be contacted, aborting...", 1) return endif endfunction -function! s:PscIdeCallback3(input, errorm, resp) - call s:log("callPscIde: Raw response: " . a:resp, 3) +function! s:PscIdeCallback(input, errorm, isRetry, resp) + call s:log("s:PscIdeCallback: Raw response: " . a:resp, 3) if a:resp =~? "connection refused" "TODO: This check is probably not crossplatform let s:pscidestarted = 0 let s:pscideexternal = 0 if a:isRetry - call s:log("callPscIde: Error: Failed to contact server", 0) + call s:log("s:PscIdeCallback: Error: Failed to contact server", 0) endif if !a:isRetry " Seems saving often causes psc-ide-server to crash. Haven't been able @@ -898,11 +898,11 @@ function! s:PscIdeCallback3(input, errorm, resp) endif let decoded = PscIdeDecodeJson(s:CleanEnd(s:StripNewlines(a:resp))) - call s:log("callPscIde: Decoded response: " . string(decoded), 3) + call s:log("s:PscIdeCallback: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') \ && type(a:errorm) == type("") - call s:log("callPscIde: Error: " . a:errorm, 0) + call s:log("s:PscIdeCallback: Error: " . a:errorm, 0) endif return decoded endfunction From 1f4631ee64f0c0a76f5d8d6e778d3f1ab047b9e5 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:37:57 +0000 Subject: [PATCH 010/111] s:callPsciIdeSync - synchronous call to psc-ide-client --- ftplugin/purescript_pscide.vim | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 412b474..b03de3d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -824,6 +824,29 @@ function! s:callPscIde(input, errorm, isRetry, cb) call delete(tempfile) endfunction +function! s:callPscIdeSync(input, errorm, isRetry) + call s:log("callPscIde: start: Executing command: " . string(a:input), 3) + + if s:projectvalid == 0 + call PSCIDEprojectValidate() + endif + + if s:pscidestarted == 0 + + let expectedCWD = s:findFileRecur('bower.json') + let cwdcommand = {'command': 'cwd'} + + call s:log("callPscIde: No server found, looking for external server", 1) + let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(cwdcommand)) + call s:PscIdeStartCallback(cwdcommand, cwdresp) + endif + + call s:log("callPscIde: Trying to reach server again", 1) + let enc = s:jsonEncode(a:input) + let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) + return s:PscIdeCallback(a:input, a:errorm, a:isRetry, resp) +endfunction + " UTILITY FUNCTIONS ---------------------------------------------------------- function! s:PscIdeStartCallback(cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') From dfe892f096c776fba3eab81270cf9e30c20731d9 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 13:38:44 +0000 Subject: [PATCH 011/111] PSCIDElist and PSCIDEomni - use s:callPscIdeSync --- ftplugin/purescript_pscide.vim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index b03de3d..3d7fb84 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -678,7 +678,7 @@ endfunction " LIST ----------------------------------------------------------------------- command! PSCIDElist call PSCIDElist() function! PSCIDElist() - s:callPscIde( + let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'loadedModules'}}, \ 'Failed to get loaded modules', \ 0 @@ -723,7 +723,10 @@ function! PSCIDEomni(findstart,base) let currentModule = s:ExtractModule() call s:log('PSCIDEOmni currentModule: ' . currentModule, 3) - let resp = s:callPscIde({'command': 'complete', 'params': {'filters': [s:prefixFilter(str)], 'matcher': s:flexMatcher(str), 'currentModule': currentModule}}, 'Failed to get completions for: '. str, 0) + let resp = s:callPscIdeSync( + \ {'command': 'complete', 'params': {'filters': [s:prefixFilter(str)], 'matcher': s:flexMatcher(str), 'currentModule': currentModule}}, + \ 'Failed to get completions for: '. str, + \ 0) if type(resp) == type({}) && resp.resultType ==# 'success' call s:log('PSCIDEOmni: Found Entries: ' . string(resp.result), 3) From 678a3374d98e70ba4145a628f84962797b869ede Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 14:26:42 +0000 Subject: [PATCH 012/111] s:callPscIdeSync and callbacks --- ftplugin/purescript_pscide.vim | 51 ++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 3d7fb84..61ca82a 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -805,7 +805,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": { msg -> s:PscIdeStartCallback(cwdcommand, msg) } + \ { "out_cb": { msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg) } \ , "in_io": "file" \ , "in_name": tempfile \ }) @@ -819,15 +819,15 @@ function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: psc-ide-client: " . enc, 3) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, msg))} + \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": {ch, msg -> s:log("ups..." . msg, 3)} + \ , "err_cb": {ch, msg -> s:log("s:callPscIde error: " . msg, 3)} \ }) call delete(tempfile) endfunction -function! s:callPscIdeSync(input, errorm, isRetry) +function! s:callPscIdeSync(input, errorm, isRetry) call s:log("callPscIde: start: Executing command: " . string(a:input), 3) if s:projectvalid == 0 @@ -841,17 +841,17 @@ function! s:callPscIdeSync(input, errorm, isRetry) call s:log("callPscIde: No server found, looking for external server", 1) let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(cwdcommand)) - call s:PscIdeStartCallback(cwdcommand, cwdresp) + return s:PscIdeStartCallback(a:input, a:errorm, 0, cwdcommand, cwdresp) endif call s:log("callPscIde: Trying to reach server again", 1) let enc = s:jsonEncode(a:input) let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) - return s:PscIdeCallback(a:input, a:errorm, a:isRetry, resp) + return s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, resp) endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- -function! s:PscIdeStartCallback(cwdcommand, cwdresp) +function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') call s:log("s:PscIdeStartCallback: Raw response of trying to reach external server: " . a:cwdresp, 1) let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp)) @@ -877,19 +877,26 @@ function! s:PscIdeStartCallback(cwdcommand, cwdresp) call PSCIDEstart(1) endif call s:log("s:PscIdeStartCallback: Trying to reach server again", 1) + if (type(a:cb) == type(0) && !a:cb) + let cwdresp = s:mysystem( + \ "psc-ide-client -p" . g:psc_ide_server_port, + \ s:jsonEncode(a:cwdcommand) + \ ) + return s:PscIdeRetryCallback(a:input, a:errorm, 0, expectedCWD, cwdresp) + endif let tempfile = tempname() call writefile([s:jsonEncode(a:cwdcommand)], tempfile) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(expectedCWD, resp) } + \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": { ch, msg -> s:log("ups..." . msg, 3) } + \ , "err_cb": { ch, msg -> s:log("s:PscIdeStartCallback error: " . msg, 3) } \ }) call delete(tempfile) endfunction -function! s:PscIdeRetryCallback(expectedCWD, cwdresp2) +function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . a:cwdresp2, 1) let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp2)) call s:log("s:PscIdeRetryCallback: Decoded response of trying to reach server again: " @@ -903,9 +910,29 @@ function! s:PscIdeRetryCallback(expectedCWD, cwdresp2) call s:log("s:PscIdeRetryCallback: Server still can't be contacted, aborting...", 1) return endif + + let enc = s:jsonEncode(a:input) + if (type(a:cb) == type(0)) + let resp = s:mysystem( + \ "psc-ide-client -p" . g:psc_ide_server_port, + \ enc + \ ) + return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) + endif + let tempfile = tempname() + call writefile([enc], tempfile, "b") + call s:log("callPscIde: psc-ide-client: " . enc, 3) + call job_start( + \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, msg))} + \ , "in_io": "file" + \ , "in_name": tempfile + \ , "err_cb": {ch, msg -> s:log("s:PscIdeRetryCallback error: " . msg, 3)} + \ }) + call delete(tempfile) endfunction -function! s:PscIdeCallback(input, errorm, isRetry, resp) +function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) call s:log("s:PscIdeCallback: Raw response: " . a:resp, 3) if a:resp =~? "connection refused" "TODO: This check is probably not crossplatform @@ -919,7 +946,7 @@ function! s:PscIdeCallback(input, errorm, isRetry, resp) " Seems saving often causes psc-ide-server to crash. Haven't been able " to figure out why. It doesn't crash when I run it externally... " retrying is then the next best thing - return s:callPscIde(a:input, a:errorm, 1) " Keeping track of retries so we only retry once + return s:callPscIde(a:input, a:errorm, 1, a:cb) " Keeping track of retries so we only retry once endif endif From 9446316ee6382fc25b4da0025e3748754ea8e0f7 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 14:32:44 +0000 Subject: [PATCH 013/111] s:PscIdeRetryCallback - sync version --- ftplugin/purescript_pscide.vim | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 61ca82a..bb88da5 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -822,7 +822,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": {ch, msg -> s:log("s:callPscIde error: " . msg, 3)} + \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . err, 3)} \ }) call delete(tempfile) endfunction @@ -847,7 +847,7 @@ function! s:callPscIdeSync(input, errorm, isRetry) call s:log("callPscIde: Trying to reach server again", 1) let enc = s:jsonEncode(a:input) let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) - return s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, resp) + return s:PscIdeCallback(a:input, a:errorm, a:isRetry, 0, resp) endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- @@ -891,7 +891,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": { ch, msg -> s:log("s:PscIdeStartCallback error: " . msg, 3) } + \ , "err_cb": { ch, err -> s:log("s:PscIdeStartCallback error: " . err, 3) } \ }) call delete(tempfile) endfunction @@ -919,15 +919,23 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) \ ) return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) endif + + if (type(a:cb) == type(0) && !a:cb) + let resp = s:mysystem( + \ "psc-ide-client -p" . g:psc_ide_server_port + \ enc + \ ) + return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) + endif let tempfile = tempname() call writefile([enc], tempfile, "b") call s:log("callPscIde: psc-ide-client: " . enc, 3) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, msg))} + \ { "out_cb": {ch, resp -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, resp))} \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": {ch, msg -> s:log("s:PscIdeRetryCallback error: " . msg, 3)} + \ , "err_cb": {ch, err -> s:log("s:PscIdeRetryCallback error: " . err, 3)} \ }) call delete(tempfile) endfunction From 07402bb486e07c84e902148764938fc887059d08 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 14:40:03 +0000 Subject: [PATCH 014/111] PSCIDEgoToDefinition --- ftplugin/purescript_pscide.vim | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index bb88da5..2501b8a 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -323,14 +323,22 @@ function! PSCIDEgoToDefinition() let currentModule = s:ExtractModule() call s:log('PSCIDEgoToDefinition currentModule: ' . currentModule, 3) - let resp = s:callPscIde({'command': 'type', 'params': {'search': identifier, 'filters': []}, 'currentModule': currentModule}, 'Failed to get location info for: ' . identifier, 0) + call s:callPscIde( + \ {'command': 'type', 'params': {'search': identifier, 'filters': []}, 'currentModule': currentModule}, + \ 'Failed to get location info for: ' . identifier, + \ 0, + \ { resp -> s:PSCIDEgoToDefinitionCallback(identifier, resp) } + \ ) +endfunction - if type(resp) == type({}) && resp.resultType ==# "success" && len(resp.result) == 1 - call s:goToDefinition(resp.result[0].definedAt) +function! s:PSCIDEgoToDefinitionCallback(identifier, resp) + call s:log("s:PSCIDEgoToDefinitionCallback: " . string(a:resp), 3) + if type(a:resp) == type({}) && a:resp.resultType ==# "success" && len(a:resp.result) == 1 + call s:goToDefinition(a:resp.result[0].definedAt) endif - if type(resp) == type({}) && resp.resultType ==# "success" && len(resp.result) > 1 - let choice = s:pickOption("Multiple possibilities for " . identifier, resp.result, "module") + if type(a:resp) == type({}) && a:resp.resultType ==# "success" && len(a:resp.result) > 1 + let choice = s:pickOption("Multiple possibilities for " . a:identifier, a:resp.result, "module") if choice.picked call s:goToDefinition(choice.option.definedAt) endif From 0b67d957b9ac73a5bfb5bb02a7ad1631327bdf81 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 21:20:20 +0000 Subject: [PATCH 015/111] PSCIDErebuid - use synchronus version in SyntasticMake --- ftplugin/purescript_pscide.vim | 21 ++++++++++++++------- syntax_checkers/purescript/pscide.vim | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2501b8a..2b72c59 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -367,17 +367,24 @@ function! s:goToDefinition(definedAt) endif endfunction -function! PSCIDErebuild(stuff) +function! PSCIDErebuild(async) let g:psc_ide_suggestions = {} let filename = expand("%:p") let input = {'command': 'rebuild', 'params': {'file': filename}} - call s:callPscIde( - \ input, - \ 0, - \ 0, - \ { msg -> s:PSCIDErebuildCallback(filename, msg) } - \ ) + if a:async + call s:callPscIde( + \ input, + \ 0, + \ 0, + \ { msg -> s:PSCIDErebuildCallback(filename, msg) } + \ ) + else + return s:PSCIDErebuildCallback( + \ filename, + \ s:callPscIdeSync(input, 0, 0), + \ ) + endif endfunction function! s:PSCIDErebuildCallback(filename, resp) diff --git a/syntax_checkers/purescript/pscide.vim b/syntax_checkers/purescript/pscide.vim index 26df1fd..2a1a756 100644 --- a/syntax_checkers/purescript/pscide.vim +++ b/syntax_checkers/purescript/pscide.vim @@ -47,7 +47,8 @@ function! SyntaxCheckers_purescript_pscide_GetLocList() dict let loclist = SyntasticMake({ \ 'makeprg': self.makeprgBuild({'exe': 'echo', 'args': 'a'}), \ 'errorformat': '%t:%f:%l:%c:%m', - \ 'Preprocess': function('PSCIDErebuild') }) + \ 'Preprocess': {args -> PSCIDErebuild(0)} + \ }) endif if g:psc_ide_syntastic_mode == 2 From 27fea94cf2b8310f03c396fd7ee4645cf273aa13 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 21:56:31 +0000 Subject: [PATCH 016/111] PSCIDEend - async --- ftplugin/purescript_pscide.vim | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2b72c59..5b84f20 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -142,8 +142,18 @@ function! PSCIDEend() if s:pscideexternal == 1 return endif - let input = {'command': 'quit'} - let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(input)) + let filename = tempname() + call writefile([s:jsonEncode({'command': 'quite'})], filename) + call job_start( + \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ { "out_cb": function("s:PSCIDEendCallback") + \ , "err_cb": {err -> s:log("PSCIDEend error " . string(err), 0)} + \ , "in_io": "file" + \ , "in_name": filename + \ }) +endfunction + +function! s:PSCIDEendCallback() let s:pscidestarted = 0 let s:projectvalid = 0 endfunction From 7e03af73cb284256159640291dadf321a4f1a603 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 22:16:28 +0000 Subject: [PATCH 017/111] PSCIDErebuild - add callback argument That's useful when one wants to setup error (async) handling (syntastic only runs synchronously). --- ftplugin/purescript_pscide.vim | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 5b84f20..4bbae4c 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -377,22 +377,30 @@ function! s:goToDefinition(definedAt) endif endfunction -function! PSCIDErebuild(async) +function! PSCIDErebuild(async, ...) let g:psc_ide_suggestions = {} let filename = expand("%:p") let input = {'command': 'rebuild', 'params': {'file': filename}} + if a:0 > 0 && type(a:1) == v:t_func + let CallBack = a:1 + else + let CallBack = {resp -> resp} + endif + if a:async call s:callPscIde( \ input, \ 0, \ 0, - \ { msg -> s:PSCIDErebuildCallback(filename, msg) } + \ { msg -> CallBack(s:PSCIDErebuildCallback(filename, msg)) } \ ) else - return s:PSCIDErebuildCallback( - \ filename, - \ s:callPscIdeSync(input, 0, 0), + return CallBack( + s:PSCIDErebuildCallback( + \ filename, + \ s:callPscIdeSync(input, 0, 0), + \ ) \ ) endif endfunction From 1a718bf0760f9c2c74b86a962adb5390207e9b7c Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 22:22:07 +0000 Subject: [PATCH 018/111] error fix --- ftplugin/purescript_pscide.vim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4bbae4c..f320762 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -396,12 +396,11 @@ function! PSCIDErebuild(async, ...) \ { msg -> CallBack(s:PSCIDErebuildCallback(filename, msg)) } \ ) else - return CallBack( - s:PSCIDErebuildCallback( + let resp = s:PSCIDErebuildCallback( \ filename, \ s:callPscIdeSync(input, 0, 0), \ ) - \ ) + return CallBack(resp) endif endfunction From b19c5c8b5ea3fb3345da6c2f445f58d919c5bf7f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 13 Mar 2017 22:34:41 +0000 Subject: [PATCH 019/111] s:PSCIDEaddTypeAnnotationCallback - fix error --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f320762..7c6390b 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -436,9 +436,9 @@ function! PSCIDEaddTypeAnnotation() endfunction function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) - if type(a:result) == type([]) + if type(a:resp) == type([]) let lnr = line(".") - call append(lnr - 1, s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) + call append(lnr - 1, s:StripNewlines(a:resp[0]['identifier']) . ' :: ' . s:StripNewlines(a:resp[0]["type"])) else echom "PSC-IDE: No type information found for " . a:identifier endif From 307e564f767cc2a276a84aec2a51d451f9da42bc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 15:39:32 +0000 Subject: [PATCH 020/111] include @chexxor review --- ftplugin/purescript_pscide.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 7c6390b..10a7db0 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -143,7 +143,7 @@ function! PSCIDEend() return endif let filename = tempname() - call writefile([s:jsonEncode({'command': 'quite'})], filename) + call writefile([s:jsonEncode({'command': 'quit'})], filename) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], \ { "out_cb": function("s:PSCIDEendCallback") @@ -194,7 +194,7 @@ endfunction function! s:PSCIDEloadCallback(loglevel, resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" - call s:log("PSCIDEload: Succesfully loaded modules: " . string(a:resp["result"]), a:loglevel) + call s:log("PSCIDEload: Successfully loaded modules: " . string(a:resp["result"]), a:loglevel) else call s:log("PSCIDEload: Failed to load. Error: " . string(a:resp["result"]), a:loglevel) endif @@ -258,7 +258,7 @@ endfunction function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) "multiple possibilities - call s:log("s:PSCIDEimportIndetifierCallback", 3) + call s:log("s:PSCIDEimportIdentifierCallback", 3) if type(a:resp) == type({}) && a:resp.resultType ==# "success" && type(a:resp.result[0]) == type({}) let choice = s:pickOption("Multiple possibilities to import " . a:ident, a:resp.result, "module") if choice.picked From e101d20e7972fddfb86ecde7bdb422579d054bf4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 16:00:14 +0000 Subject: [PATCH 021/111] PSCIDEend - use exit_cb --- ftplugin/purescript_pscide.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 10a7db0..17d2749 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -144,10 +144,10 @@ function! PSCIDEend() endif let filename = tempname() call writefile([s:jsonEncode({'command': 'quit'})], filename) - call job_start( + return job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": function("s:PSCIDEendCallback") - \ , "err_cb": {err -> s:log("PSCIDEend error " . string(err), 0)} + \ { "exit_cb": {job, status -> s:PSCIDEendCallback() } + \ , "err_cb": {err -> s:log("PSCIDEend error: " . string(err), 0)} \ , "in_io": "file" \ , "in_name": filename \ }) From afca8829011c08f252899ba43b2099140b1756bf Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 16:26:36 +0000 Subject: [PATCH 022/111] PSCIDEstart - start psc-ide-server as a job --- ftplugin/purescript_pscide.vim | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 17d2749..fb32c87 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -51,6 +51,7 @@ if !exists('s:projectvalid') let s:projectvalid = 0 endif +let s:psc_ide_server = v:none "Looks for bower.json, assumes that's the root directory, starts "psc-ide-server in the background "Returns Nothing @@ -70,16 +71,25 @@ function! PSCIDEstart(silent) call s:log("PSCIDEstart: Starting psc-ide-server at " . dir . " on port " . g:psc_ide_server_port, loglevel) - if has('win16') || has('win32') || has('win64') - let command = "start /b psc-ide-server " . dir . "/src/**/*.purs " . dir . "/bower_components/**/*.purs -p " . g:psc_ide_server_port . " -d " . dir - else - let command = "psc-ide-server \"src/**/*.purs\" \"bower_components/**/*.purs\" -p " . g:psc_ide_server_port . " -d " . dir . " > /dev/null &" - endif - let resp = system(command) + let command = [ + \ "psc-ide-server", + \ "-p", g:psc_ide_server_port, + \ "-d", dir, + \ "dir", "/src/**/*.purs", + \ "dir", "/bower_components/**/*.purs", + \ ] + let s:psc_ide_server = job_start( + \ command, + \ { "stoponexit": "term" + \ , "err_mode": "raw" + \ , "err_cb": { ch, msg -> s:log("psc-ide-server error: " . string(msg)) } + \ , "in_io": "null" + \ , "out_io": "null" + \ } + \ ) call s:log("PSCIDEstart: Sleeping for 100ms so server can start up", 1) - :exe "sleep 100m" - + sleep 100m let s:pscidestarted = 1 endfunction From e60189b1718b6a7a7e21ea22e6adb4c177e7d4cb Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 16:38:04 +0000 Subject: [PATCH 023/111] use viml json_encode and json_decode functions --- ftplugin/purescript_pscide.vim | 73 +++++----------------------------- 1 file changed, 11 insertions(+), 62 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index fb32c87..bc4db40 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -153,7 +153,7 @@ function! PSCIDEend() return endif let filename = tempname() - call writefile([s:jsonEncode({'command': 'quit'})], filename) + call writefile([json_encode({'command': 'quit'})], filename) return job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], \ { "exit_cb": {job, status -> s:PSCIDEendCallback() } @@ -842,7 +842,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) let expectedCWD = s:findFileRecur('bower.json') let cwdcommand = {'command': 'cwd'} let tempfile = tempname() - call writefile([s:jsonEncode(cwdcommand)], tempfile) + call writefile([json_encode(cwdcommand)], tempfile) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( @@ -855,7 +855,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) return endif - let enc = s:jsonEncode(a:input) + let enc = json_encode(a:input) let tempfile = tempname() call writefile([enc], tempfile, "b") call s:log("callPscIde: psc-ide-client: " . enc, 3) @@ -882,12 +882,12 @@ function! s:callPscIdeSync(input, errorm, isRetry) let cwdcommand = {'command': 'cwd'} call s:log("callPscIde: No server found, looking for external server", 1) - let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, s:jsonEncode(cwdcommand)) + let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, json_encode(cwdcommand)) return s:PscIdeStartCallback(a:input, a:errorm, 0, cwdcommand, cwdresp) endif call s:log("callPscIde: Trying to reach server again", 1) - let enc = s:jsonEncode(a:input) + let enc = json_encode(a:input) let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) return s:PscIdeCallback(a:input, a:errorm, a:isRetry, 0, resp) endfunction @@ -896,7 +896,7 @@ endfunction function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') call s:log("s:PscIdeStartCallback: Raw response of trying to reach external server: " . a:cwdresp, 1) - let cwdrespDecoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp)) + let cwdrespDecoded = json_decode(s:StripNewlines(a:cwdresp)) call s:log("s:PscIdeStartCallback: Decoded response of trying to reach external server: " \ . string(cwdrespDecoded), 1) @@ -922,12 +922,12 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) if (type(a:cb) == type(0) && !a:cb) let cwdresp = s:mysystem( \ "psc-ide-client -p" . g:psc_ide_server_port, - \ s:jsonEncode(a:cwdcommand) + \ json_encode(a:cwdcommand) \ ) return s:PscIdeRetryCallback(a:input, a:errorm, 0, expectedCWD, cwdresp) endif let tempfile = tempname() - call writefile([s:jsonEncode(a:cwdcommand)], tempfile) + call writefile([json_encode(a:cwdcommand)], tempfile) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } @@ -940,7 +940,7 @@ endfunction function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . a:cwdresp2, 1) - let cwdresp2Decoded = PscIdeDecodeJson(s:StripNewlines(a:cwdresp2)) + let cwdresp2Decoded = json_decode(s:StripNewlines(a:cwdresp2)) call s:log("s:PscIdeRetryCallback: Decoded response of trying to reach server again: " \ . string(cwdresp2Decoded), 1) @@ -953,7 +953,7 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) return endif - let enc = s:jsonEncode(a:input) + let enc = json_encode(a:input) if (type(a:cb) == type(0)) let resp = s:mysystem( \ "psc-ide-client -p" . g:psc_ide_server_port, @@ -1000,7 +1000,7 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) endif endif - let decoded = PscIdeDecodeJson(s:CleanEnd(s:StripNewlines(a:resp))) + let decoded = json_decode(s:CleanEnd(s:StripNewlines(a:resp))) call s:log("s:PscIdeCallback: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') @@ -1082,33 +1082,6 @@ fun! s:jsonToJSONBool(i) return a:i ? s:jsonTrue() : s:jsonFalse() endf -fun! s:jsonEncode(thing, ...) - let nl = a:0 > 0 ? (a:1 ? "\n" : "") : "" - if type(a:thing) == type("") - return '"'.escape(a:thing,'"\').'"' - elseif type(a:thing) == type({}) && !has_key(a:thing, 'json_special_value') - let pairs = [] - for [Key, Value] in items(a:thing) - call add(pairs, s:jsonEncode(Key).':'.s:jsonEncode(Value)) - unlet Key | unlet Value - endfor - return "{".nl.join(pairs, ",".nl)."}" - elseif type(a:thing) == type(0) - return a:thing - elseif type(a:thing) == type([]) - return '['.join(map(copy(a:thing), "s:jsonEncode(v:val)"),",").']' - return - elseif string(a:thing) == string(s:jsonNULL()) - return "null" - elseif string(a:thing) == string(s:jsonTrue()) - return "true" - elseif string(a:thing) == string(s:jsonFalse()) - return "false" - else - throw "unexpected new thing: ".string(a:thing) - endif -endf - " Parse Errors & Suggestions ------------------------------------------ " Returns { error :: String, " llist :: Array (String in errorformat), @@ -1187,30 +1160,6 @@ function! s:cleanupMessage(str) return out endfunction -function! PscIdeDecodeJson(json) abort - if a:json ==# '' - return [] - endif - - if substitute(a:json, '\v\"%(\\.|[^"\\])*\"|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g') !~# "[^,:{}[\\] \t]" - " JSON artifacts - let true = 1 - let false = 0 - let null = '' - - try - let object = json_decode(a:json) - catch - " malformed JSON - let object = '' - endtry - else - let object = '' - endif - - return object -endfunction - function! s:mysystem(a, b) return system(a:a, a:b . "\n") endfunction From 59ba4760eb58034476713037b45be434c37277dc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 18:26:31 +0000 Subject: [PATCH 024/111] fix - s:log requires two arguments --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index bc4db40..fbd1999 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -82,7 +82,7 @@ function! PSCIDEstart(silent) \ command, \ { "stoponexit": "term" \ , "err_mode": "raw" - \ , "err_cb": { ch, msg -> s:log("psc-ide-server error: " . string(msg)) } + \ , "err_cb": { ch, msg -> s:log("psc-ide-server error: " . string(msg), 0) } \ , "in_io": "null" \ , "out_io": "null" \ } From adaeb5fb3139a96deb1bc570573579da16687f9b Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 14 Mar 2017 19:36:00 +0000 Subject: [PATCH 025/111] s:PscIdeStartCallback - catch json decoding errors * add err_cb in s:calPscIde * fix how s:PscIdeStartCallback is called --- ftplugin/purescript_pscide.vim | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index fbd1999..e40652e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -847,7 +847,8 @@ function! s:callPscIde(input, errorm, isRetry, cb) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( \ ["psc-ide-client", "-p", g:psc_ide_server_port], - \ { "out_cb": { msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg) } + \ { "out_cb": {ch, msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg)} + \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} \ , "in_io": "file" \ , "in_name": tempfile \ }) @@ -895,8 +896,12 @@ endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let expectedCWD = s:findFileRecur('bower.json') - call s:log("s:PscIdeStartCallback: Raw response of trying to reach external server: " . a:cwdresp, 1) - let cwdrespDecoded = json_decode(s:StripNewlines(a:cwdresp)) + try + let cwdrespDecoded = json_decode(a:cwdresp) + catch /.*/ + let cwdrespDecoded = {"resultType": "failed", "error": a:cwdresp} + endtry + call s:log("s:PscIdeStartCallback: Decoded response of trying to reach external server: " \ . string(cwdrespDecoded), 1) @@ -940,7 +945,11 @@ endfunction function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . a:cwdresp2, 1) - let cwdresp2Decoded = json_decode(s:StripNewlines(a:cwdresp2)) + try + let cwdresp2Decoded = json_decode(a:cwdresp2) + catch /.*/ + let cwdresp2Decoded = {"resultType": "failed", "error": a:cwdresp2} + endtry call s:log("s:PscIdeRetryCallback: Decoded response of trying to reach server again: " \ . string(cwdresp2Decoded), 1) From 877e705092bd13bf779d2b2ada4b06b20586f543 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 05:48:27 +0000 Subject: [PATCH 026/111] PSCIDEstart * use lcd to start psc-ide-server in the right directory * fix src paths --- ftplugin/purescript_pscide.vim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index e40652e..4e281b9 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -75,9 +75,11 @@ function! PSCIDEstart(silent) \ "psc-ide-server", \ "-p", g:psc_ide_server_port, \ "-d", dir, - \ "dir", "/src/**/*.purs", - \ "dir", "/bower_components/**/*.purs", + \ "dir", "src/**/*.purs", + \ "dir", "bower_components/**/*.purs", \ ] + + exe "lcd" dir let s:psc_ide_server = job_start( \ command, \ { "stoponexit": "term" @@ -87,6 +89,7 @@ function! PSCIDEstart(silent) \ , "out_io": "null" \ } \ ) + lcd - call s:log("PSCIDEstart: Sleeping for 100ms so server can start up", 1) sleep 100m From 15cd257c55f9b4fee56761c0ce8fdd41ee99116e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 05:49:19 +0000 Subject: [PATCH 027/111] clean code --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4e281b9..7df6ac3 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -868,7 +868,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} \ , "in_io": "file" \ , "in_name": tempfile - \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . err, 3)} + \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} \ }) call delete(tempfile) endfunction @@ -1012,7 +1012,7 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) endif endif - let decoded = json_decode(s:CleanEnd(s:StripNewlines(a:resp))) + let decoded = json_decode(a:resp) call s:log("s:PscIdeCallback: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') From 8abd2269c5e77f9d092949e70671a737101ccc07 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 11:51:43 +0000 Subject: [PATCH 028/111] use viml filter function instead of s:findInListBy --- ftplugin/purescript_pscide.vim | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4fcd51f..caf6207 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -69,8 +69,7 @@ function! PSCIDEstart(silent) return endif - call s:log("PSCIDEstart: Starting psc-ide-server at " . dir . " on port " . g:psc_ide_server_port, loglevel) - + let g:dir = dir let command = [ \ "psc-ide-server", \ "-p", g:psc_ide_server_port, @@ -777,7 +776,7 @@ function! PSCIDEomni(findstart,base) for entry in entries if entry['identifier'] =~ '^' . str let e = {'word': entry['identifier'], 'menu': s:StripNewlines(entry['type']), 'info': entry['module'], 'dup': 0} - let existing = s:findInListBy(result, 'word', e['word']) + let existing = filter(result, {idx, val -> val["word"] == e["word"]}) if existing != {} let e['menu'] = e['menu'] . ' (' . e['info'] . ')' @@ -796,21 +795,6 @@ function! PSCIDEomni(findstart,base) endif endfunction -function! s:findInListBy(list, key, str) - let i = 0 - let l = len(a:list) - let found = {} - - while found == {} && i < l - if a:list[i][a:key] == a:str - let found = a:list[i] - endif - let i = i + 1 - endwhile - - return found -endfunction - function! s:prefixFilter(s) return {"filter": "prefix", "params": { "search": a:s } } endfunction From f656695fb342427a9f97ad3d8c4376aec7d2b34d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 12:06:19 +0000 Subject: [PATCH 029/111] remove debug variable --- ftplugin/purescript_pscide.vim | 1 - 1 file changed, 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index caf6207..040232d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -69,7 +69,6 @@ function! PSCIDEstart(silent) return endif - let g:dir = dir let command = [ \ "psc-ide-server", \ "-p", g:psc_ide_server_port, From 63bfce2139850d58625f57e478f87274a4e6ad25 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 12:25:30 +0000 Subject: [PATCH 030/111] revert 8abd226 --- ftplugin/purescript_pscide.vim | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 040232d..6ad5906 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -775,7 +775,7 @@ function! PSCIDEomni(findstart,base) for entry in entries if entry['identifier'] =~ '^' . str let e = {'word': entry['identifier'], 'menu': s:StripNewlines(entry['type']), 'info': entry['module'], 'dup': 0} - let existing = filter(result, {idx, val -> val["word"] == e["word"]}) + let existing = s:findInListBy(result, 'word', e['word']) if existing != {} let e['menu'] = e['menu'] . ' (' . e['info'] . ')' @@ -794,6 +794,21 @@ function! PSCIDEomni(findstart,base) endif endfunction +function! s:findInListBy(list, key, str) + let i = 0 + let l = len(a:list) + let found = {} + + while found == {} && i < l + if a:list[i][a:key] == a:str + let found = a:list[i] + endif + let i = i + 1 + endwhile + + return found +endfunction + function! s:prefixFilter(s) return {"filter": "prefix", "params": { "search": a:s } } endfunction From 7b84cbec20abb6ee6aa277129c19469e3fa0a525 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 12:26:17 +0000 Subject: [PATCH 031/111] finish merging upstream master --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 6ad5906..02c1ca8 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -871,7 +871,7 @@ function! s:callPscIdeSync(input, errorm, isRetry) if s:pscidestarted == 0 - let expectedCWD = s:findFileRecur('bower.json') + let expectedCWD = s:findRoot() let cwdcommand = {'command': 'cwd'} call s:log("callPscIde: No server found, looking for external server", 1) @@ -887,7 +887,7 @@ endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) - let expectedCWD = s:findFileRecur('bower.json') + let expectedCWD = s:findRoot() try let cwdrespDecoded = json_decode(a:cwdresp) catch /.*/ From 4100b78cef0e84031a6148fcfa9f58cc9c8183e0 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 12:26:50 +0000 Subject: [PATCH 032/111] use viml filter instead of s:take and s:drop --- ftplugin/purescript_pscide.vim | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 02c1ca8..327d966 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -286,7 +286,7 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) " Adding one at a time with setline + append/delete to keep line symbols and " cursor as intact as possible - call setline(1, s:take(newlines, nrOfLinesToReplace)) + call setline(1, filter(newlines, { idx -> idx < nrOfLinesToReplace })) if (nrOfLinesToDelete > 0) let comm = 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d|0" @@ -294,7 +294,7 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) call cursor(oldCursorPos[1] - nrOfLinesToDelete, oldCursorPos[2]) endif if (nrOfLinesToAppend > 0) - let linesToAppend = s:take(s:drop(newlines, nrOfLinesToReplace), nrOfLinesToAppend) + let linesToAppend = filter(neslines, { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) call s:log('linesToAppend: ' . string(linesToAppend), 3) call append(nrOfOldlinesUnderLine, linesToAppend) endif @@ -305,24 +305,6 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) endif endfunction -function! s:take(list, j) - let newlist = [] - for i in range(0, a:j - 1) - call add(newlist, a:list[i]) - endfor - return newlist -endfunction - -function! s:drop(list, j) - let newlist = [] - for i in range(0, len(a:list) - 1) - if i >= a:j - call add(newlist, a:list[i]) - endif - endfor - return newlist -endfunction - command! PSCIDEgoToDefinition call PSCIDEgoToDefinition() function! PSCIDEgoToDefinition() let identifier = s:GetWordUnderCursor() From 5e422e758bab88455aac2b0db50f787a557d1dbf Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 12:49:32 +0000 Subject: [PATCH 033/111] s:getTypeCallback was masking error message when type was not found --- ftplugin/purescript_pscide.vim | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 327d966..a4d717b 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -420,9 +420,10 @@ function! PSCIDEaddTypeAnnotation() endfunction function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) - if type(a:resp) == type([]) + if type(a:resp) == v:t_dict && a:resp["resultType"] ==# 'success' && !empty(a:resp["result"]) + let result = a:resp["result"] let lnr = line(".") - call append(lnr - 1, s:StripNewlines(a:resp[0]['identifier']) . ' :: ' . s:StripNewlines(a:resp[0]["type"])) + call append(lnr - 1, s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) else echom "PSC-IDE: No type information found for " . a:identifier endif @@ -542,18 +543,10 @@ function! s:getType(identifier, cb) \ {'command': 'type', 'params': {'search': a:identifier, 'filters': []}, 'currentModule': currentModule}, \ 'Failed to get type info for: ' . a:identifier, \ 0, - \ { resp -> s:getTypeCallback(resp, a:cb)} + \ {resp -> a:cb(resp)} \ ) endfunction -function! s:getTypeCallback(resp, cb) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' - if len(a:resp["result"]) > 0 - call a:cb(a:resp["result"]) - endif - endif -endfunction - function! s:formattype(record) return s:CleanEnd(s:StripNewlines(a:record['module']) . '.' . s:StripNewlines(a:record['identifier']) . ' :: ' . s:StripNewlines(a:record['type'])) endfunction From 13551f40fd09b0bd27def383456f732f6f5bbb96 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 15 Mar 2017 23:47:57 +0000 Subject: [PATCH 034/111] PSCIDEgoto * use column * use full path: previously length of current working directory was removed from the path - that does not work if the current working directory is not somewhere outside of a project --- ftplugin/purescript_pscide.vim | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a4d717b..38810fc 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -294,7 +294,7 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) call cursor(oldCursorPos[1] - nrOfLinesToDelete, oldCursorPos[2]) endif if (nrOfLinesToAppend > 0) - let linesToAppend = filter(neslines, { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) + let linesToAppend = filter(newlines, { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) call s:log('linesToAppend: ' . string(linesToAppend), 3) call append(nrOfOldlinesUnderLine, linesToAppend) endif @@ -327,8 +327,12 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) call s:goToDefinition(a:resp.result[0].definedAt) endif - if type(a:resp) == type({}) && a:resp.resultType ==# "success" && len(a:resp.result) > 1 - let choice = s:pickOption("Multiple possibilities for " . a:identifier, a:resp.result, "module") + if type(a:resp) == type({}) && a:resp.resultType ==# "success" + if len(a:resp.result) > 1 + let choice = s:pickOption("Multiple possibilities for " . a:identifier, a:resp.result, "module") + else + let choice = {"picked": v:true, "option": a:resp.result[0]} + endif if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) else @@ -343,21 +347,17 @@ endfunction function! s:goToDefinition(definedAt) let currentfile = expand("%:p") if (currentfile == a:definedAt.name) - let cur = getpos(".") - let cur[1] = a:definedAt.start[0] - call setpos(".", cur) + " set ' mark at the current position + m' + call cursor(a:definedAt.start[0], a:definedAt.start[1]) else - let cwd = getcwd() - call s:log("PSCIDE s:goToDefinition: cwd: " . cwd, 3) - - let lcwd = len(cwd) - let name = strpart(a:definedAt.name, lcwd + 1) " To strip slash + let name = a:definedAt.name call s:log("PSCIDE s:goToDefinition: name: " . name, 3) let command = "e +" . a:definedAt.start[0] . " " . name call s:log("PSCIDE s:goToDefinition: command: " . command, 3) - - :exe command + exe command + exe "normal " . a:definedAt.start[1] . "|" endif endfunction From 5202310d479cc06f26310ceec0aaebd251958a0d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 16 Mar 2017 00:01:08 +0000 Subject: [PATCH 035/111] README.md - add and to suggested nmap definitions --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b179ebd..5686a69 100644 --- a/README.md +++ b/README.md @@ -53,15 +53,15 @@ This plugin provides two kinds of syntax checking with syntastic. Controlling wh No custom mappings are provided, but it's easy to map the above commands to any key mapping you want. My personal setup: ``` -au FileType purescript nmap t :PSCIDEtype -au FileType purescript nmap s :PSCIDEapplySuggestion -au FileType purescript nmap a :PSCIDEaddTypeAnnotation -au FileType purescript nmap i :PSCIDEimportIdentifier -au FileType purescript nmap r :PSCIDEload -au FileType purescript nmap p :PSCIDEpursuit -au FileType purescript nmap c :PSCIDEcaseSplit -au FileType purescript nmap qd :PSCIDEremoveImportQualifications -au FileType purescript nmap qa :PSCIDEaddImportQualifications +au FileType purescript nmap t :PSCIDEtype +au FileType purescript nmap s :PSCIDEapplySuggestion +au FileType purescript nmap a :PSCIDEaddTypeAnnotation +au FileType purescript nmap i :PSCIDEimportIdentifier +au FileType purescript nmap r :PSCIDEload +au FileType purescript nmap p :PSCIDEpursuit +au FileType purescript nmap c :PSCIDEcaseSplit +au FileType purescript nmap qd :PSCIDEremoveImportQualifications +au FileType purescript nmap qa :PSCIDEaddImportQualifications ``` From c6ee3fccc239a92118fb17e81846de3d8a5022cc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 16 Mar 2017 16:52:21 +0000 Subject: [PATCH 036/111] buffer only commands When using commnad-buffer the commands are only defined in the current buffer - this way one does not polute the global name space with filetype only commands. --- ftplugin/purescript_pscide.vim | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 38810fc..8c9946e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -55,7 +55,7 @@ let s:psc_ide_server = v:none "Looks for bower.json, assumes that's the root directory, starts "psc-ide-server in the background "Returns Nothing -command! PSCIDEstart call PSCIDEstart(0) +command! -buffer PSCIDEstart call PSCIDEstart(0) function! PSCIDEstart(silent) if s:pscidestarted == 1 return @@ -135,7 +135,7 @@ endfunction " END ------------------------------------------------------------------------ " Tell the psc-ide-server to quit -command! PSCIDEend call PSCIDEend() +command! -buffer PSCIDEend call PSCIDEend() function! PSCIDEend() if s:pscideexternal == 1 return @@ -176,7 +176,7 @@ endfunction " LOAD ----------------------------------------------------------------------- " Load module of current buffer + its dependencies into psc-ide-server -command! PSCIDEload call PSCIDEload(0) +command! -buffer PSCIDEload call PSCIDEload(0) function! PSCIDEload(silent) let loglevel = a:silent == 1 ? 1 : 0 @@ -216,7 +216,7 @@ function! s:ExtractModule() endfunction " Import given identifier -command! PSCIDEimportIdentifier call PSCIDEimportIdentifier() +command! -buffer PSCIDEimportIdentifier call PSCIDEimportIdentifier() function! PSCIDEimportIdentifier() call s:importIdentifier(s:GetWordUnderCursor(), "") endfunction @@ -305,7 +305,7 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) endif endfunction -command! PSCIDEgoToDefinition call PSCIDEgoToDefinition() +command! -buffer PSCIDEgoToDefinition call PSCIDEgoToDefinition() function! PSCIDEgoToDefinition() let identifier = s:GetWordUnderCursor() call s:log('PSCIDEgoToDefinition identifier: ' . identifier, 3) @@ -409,7 +409,7 @@ function! s:PSCIDErebuildCallback(filename, resp) endfunction " Add type annotation -command! PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation() +command! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation() function! PSCIDEaddTypeAnnotation() let identifier = s:GetWordUnderCursor() @@ -431,7 +431,7 @@ endfunction " CWD ------------------------------------------------------------------------ " Get current working directory of psc-ide-server -command! PSCIDEcwd call PSCIDEcwd() +command! -buffer PSCIDEcwd call PSCIDEcwd() function! PSCIDEcwd() call s:callPscIde( \ {'command': 'cwd'}, @@ -449,7 +449,7 @@ endfunction " ADDCLAUSE " Makes template function implementation from signature -command! PSCIDEaddClause call PSCIDEaddClause() +command! -buffer PSCIDEaddClause call PSCIDEaddClause() function! PSCIDEaddClause() let lnr = line(".") let line = getline(lnr) @@ -475,7 +475,7 @@ endfunction " CASESPLIT " Hover cursor over variable in function declaration -> pattern match on all " different cases of the variable -command! PSCIDEcaseSplit call PSCIDEcaseSplit() +command! -buffer PSCIDEcaseSplit call PSCIDEcaseSplit() function! PSCIDEcaseSplit() let lnr = line(".") let line = getline(lnr) @@ -515,7 +515,7 @@ endfunction " TYPE ----------------------------------------------------------------------- " Get type of word under cursor -command! PSCIDEtype call PSCIDEtype() +command! -buffer PSCIDEtype call PSCIDEtype() function! PSCIDEtype() let identifier = s:GetWordUnderCursor() @@ -553,7 +553,7 @@ endfunction " APPLYSUGGESTION ------------------------------------------------------ " Apply suggestion in loclist to buffer -------------------------------- -command! PSCIDEapplySuggestion call PSCIDEapplySuggestion() +command! -buffer PSCIDEapplySuggestion call PSCIDEapplySuggestion() function! PSCIDEapplySuggestion() let lnr = line(".") let filename = expand("%:p") @@ -608,7 +608,7 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) endfunction " Remove all import qualifications -command! PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() +command! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() function! PSCIDEremoveImportQualifications() let captureregex = "import\\s\\(\\S\\+\\)\\s*(.*)" let replace = "import \\1" @@ -618,7 +618,7 @@ function! PSCIDEremoveImportQualifications() endfunction " Add all import qualifications -command! PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() +command! -buffer PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() function! PSCIDEaddImportQualifications() let foundLines = [] let filename = expand("%:p") @@ -642,7 +642,7 @@ endfunction " PURSUIT -------------------------------------------------------------------- -command! PSCIDEpursuit call PSCIDEpursuit() +command! -buffer PSCIDEpursuit call PSCIDEpursuit() function! PSCIDEpursuit() let identifier = s:GetWordUnderCursor() @@ -671,7 +671,7 @@ function! s:formatpursuit(record) endfunction " VALIDATE ----------------------------------------------------------------------- -command! PSCIDEprojectValidate call PSCIDEprojectValidate() +command! -buffer PSCIDEprojectValidate call PSCIDEprojectValidate() function! PSCIDEprojectValidate() let problems = s:projectProblems() @@ -685,7 +685,7 @@ function! PSCIDEprojectValidate() endfunction " LIST ----------------------------------------------------------------------- -command! PSCIDElist call PSCIDElist() +command! -buffer PSCIDElist call PSCIDElist() function! PSCIDElist() let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'loadedModules'}}, From 5475136efd757d8ab90b5f942da54836bc22a4e6 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 16 Mar 2017 17:06:54 +0000 Subject: [PATCH 037/111] Don't use defined commands, instead call functions directly Some users delete them and define their own set of commmands. --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 8c9946e..e2594b7 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -878,7 +878,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) if expectedCWD != cwdrespDecoded.result call s:log("s:PscIdeStartCallback: External server on incorrect CWD, closing", 1) - PSCIDEend + call PSCIDEend() call s:log("s:PscIdeStartCallback: Starting new server", 1) call PSCIDEstart(1) else From 6692d504394803a34d4a4029ce23f4c53a90ad62 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 16 Mar 2017 19:58:23 +0000 Subject: [PATCH 038/111] filter requires using a copy --- ftplugin/purescript_pscide.vim | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index e2594b7..6a1ed4c 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -286,16 +286,14 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) " Adding one at a time with setline + append/delete to keep line symbols and " cursor as intact as possible - call setline(1, filter(newlines, { idx -> idx < nrOfLinesToReplace })) + call setline(1, filter(copy(newlines), { idx -> idx < nrOfLinesToReplace })) if (nrOfLinesToDelete > 0) - let comm = 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d|0" - :exe comm + exe 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d_|0" call cursor(oldCursorPos[1] - nrOfLinesToDelete, oldCursorPos[2]) endif if (nrOfLinesToAppend > 0) - let linesToAppend = filter(newlines, { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) - call s:log('linesToAppend: ' . string(linesToAppend), 3) + let linesToAppend = filter(copy(newlines), { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) call append(nrOfOldlinesUnderLine, linesToAppend) endif From 03a77865b8c493d078f5669723455f2a8537f55e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sun, 19 Mar 2017 14:05:53 +0000 Subject: [PATCH 039/111] filter results in PSCIDEimportIdentifierCallback & PSCIDEgoToDefinitionCallback --- ftplugin/purescript_pscide.vim | 39 +++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 6a1ed4c..407b05c 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -258,8 +258,19 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) "multiple possibilities call s:log("s:PSCIDEimportIdentifierCallback", 3) if type(a:resp) == type({}) && a:resp.resultType ==# "success" && type(a:resp.result[0]) == type({}) - let choice = s:pickOption("Multiple possibilities to import " . a:ident, a:resp.result, "module") - if choice.picked + " filter results + let results = [] + for res in a:resp.result + if empty(filter(copy(results), { idx, val -> val.module == res.module })) + call add(results, res) + endif + endfor + if (len(results) == 1) + let choice = { option: results[0], picked: v:true } + else + let choice = s:pickOption("Multiple possibilities to import " . a:ident, results, "module") + endif + if choice.picked == v:true call s:importIdentifier(a:ident, choice.option.module) endif return @@ -320,16 +331,24 @@ function! PSCIDEgoToDefinition() endfunction function! s:PSCIDEgoToDefinitionCallback(identifier, resp) - call s:log("s:PSCIDEgoToDefinitionCallback: " . string(a:resp), 3) + call s:log("s:PSCIDEgoToDefinitionCallback", 3) + let results = [] + for res in a:resp.result + if empty(filter(copy(results), { idx, val -> val.definedAt.name == res.definedAt.name && val.definedAt.start[0] == res.definedAt.start[0] && val.definedAt.start[1] == res.definedAt.start[1]})) + call add(results, res) + endif + endfor if type(a:resp) == type({}) && a:resp.resultType ==# "success" && len(a:resp.result) == 1 - call s:goToDefinition(a:resp.result[0].definedAt) + call s:goToDefinition(results[0].definedAt) endif if type(a:resp) == type({}) && a:resp.resultType ==# "success" - if len(a:resp.result) > 1 - let choice = s:pickOption("Multiple possibilities for " . a:identifier, a:resp.result, "module") + if len(results) > 1 + let choice = s:pickOption("Multiple possibilities for " . a:identifier, results, "module") + elseif len(results) == 1 + let choice = {"picked": v:true, "option": results[0]} else - let choice = {"picked": v:true, "option": a:resp.result[0]} + let choice = {"picked": v:false, "option": v:none} endif if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) @@ -439,7 +458,7 @@ function! PSCIDEcwd() \ ) endfunction -function s:PSCIDEcwdCallback(resp) +function! s:PSCIDEcwdCallback(resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' echom "PSC-IDE: Current working directory: " . a:resp["result"] endif @@ -523,7 +542,7 @@ function! PSCIDEtype() \ ) endfunction -function s:PSCIDEtypeCallback(identifier, result) +function! s:PSCIDEtypeCallback(identifier, result) if type(a:result) == type([]) for e in a:result echom s:formattype(e) @@ -693,7 +712,7 @@ function! PSCIDElist() call s:PSCIDElistCallback(resp) endfunction -function s:PSCIDElistCallback(resp) +function! s:PSCIDElistCallback(resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' if len(a:resp["result"]) > 0 for m in a:resp["result"] From c27c092b52567eab0e1b9f7fc6d2460b4632a7d5 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 23 Mar 2017 12:54:38 +0000 Subject: [PATCH 040/111] PSCIDEgoToDefinitionCallback --- ftplugin/purescript_pscide.vim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 407b05c..b087bb5 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -352,8 +352,10 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) endif if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) - else + elseif choice.option echom "PSCIDE: No location information found for: " . a:identifier . " in module " . choice.option.module + else + echom "PSCIDE: No location information found for: " . a:identifier endif return else From cf0e39129ac76b7be9fdf42603ac8a5b199638e8 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 23 Mar 2017 12:54:53 +0000 Subject: [PATCH 041/111] remove not neaded code --- ftplugin/purescript_pscide.vim | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index b087bb5..2e28a16 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1036,15 +1036,6 @@ endfunction "endif "endfunction -" Automatically close the server when leaving vim -augroup PscideShutDown - au! - autocmd VimLeavePre * call s:Shutdown() -augroup END -function! s:Shutdown() - silent PSCIDEend -endfunction - " " Automatic import after completion " function! s:completeDone(item) " if g:psc_ide_auto_imports == 0 From 43bbe0a4bba6b364e928a4aa67f2f3615fd619b4 Mon Sep 17 00:00:00 2001 From: chexxor Date: Tue, 28 Mar 2017 12:58:10 -0500 Subject: [PATCH 042/111] Fix getType command. Quote source file loaded. --- ftplugin/purescript_pscide.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 906477a..c847dd8 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -73,8 +73,8 @@ function! PSCIDEstart(silent) \ "psc-ide-server", \ "-p", g:psc_ide_server_port, \ "-d", dir, - \ "dir", "src/**/*.purs", - \ "dir", "bower_components/**/*.purs", + \ "dir", "'src/**/*.purs'", + \ "dir", "'bower_components/**/*.purs'", \ ] exe "lcd" dir @@ -538,7 +538,7 @@ function! PSCIDEtype() call s:getType( \ identifier, - \ { resp -> s:PSCIDEtypeCallback(identifier, resp) } + \ { resp -> s:PSCIDEtypeCallback(identifier, resp.result) } \ ) endfunction From 674d9615f5f8e96d6c23df64a707ceab4e8fd848 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 29 Mar 2017 22:53:23 +0100 Subject: [PATCH 043/111] do not quote globs for psc-ide-server --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index c847dd8..e238fe4 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -73,8 +73,8 @@ function! PSCIDEstart(silent) \ "psc-ide-server", \ "-p", g:psc_ide_server_port, \ "-d", dir, - \ "dir", "'src/**/*.purs'", - \ "dir", "'bower_components/**/*.purs'", + \ "src/**/*.purs", + \ "bower_components/**/*.purs", \ ] exe "lcd" dir From 74611053deb560864e2aa32b10a7301ddff44dc2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 29 Mar 2017 22:54:39 +0100 Subject: [PATCH 044/111] PSCIDEgoToDefinitionCallback * val.definedAt can be v:null * simplify logic --- ftplugin/purescript_pscide.vim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index e238fe4..3e7ce74 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -332,15 +332,16 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) call s:log("s:PSCIDEgoToDefinitionCallback", 3) let results = [] for res in a:resp.result - if empty(filter(copy(results), { idx, val -> val.definedAt.name == res.definedAt.name && val.definedAt.start[0] == res.definedAt.start[0] && val.definedAt.start[1] == res.definedAt.start[1]})) + if empty(filter(copy(results), { idx, val -> + \ val.definedAt != v:null + \ && res.definedAt != v:null + \ && val.definedAt.name == res.definedAt.name + \ && val.definedAt.start[0] == res.definedAt.start[0] + \ && val.definedAt.start[1] == res.definedAt.start[1]})) call add(results, res) endif endfor - if type(a:resp) == type({}) && a:resp.resultType ==# "success" && len(a:resp.result) == 1 - call s:goToDefinition(results[0].definedAt) - endif - - if type(a:resp) == type({}) && a:resp.resultType ==# "success" + if type(a:resp) == v:t_dict && a:resp.resultType ==# "success" if len(results) > 1 let choice = s:pickOption("Multiple possibilities for " . a:identifier, results, "module") elseif len(results) == 1 @@ -350,12 +351,11 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) endif if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) - elseif choice.option + elseif type(choice.option) == v:t_dict echom "PSCIDE: No location information found for: " . a:identifier . " in module " . choice.option.module else echom "PSCIDE: No location information found for: " . a:identifier endif - return else echom "PSCIDE: No location information found for: " . a:identifier endif From 5119972b4f89c584abf1ac54148152913e075879 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 30 Mar 2017 11:05:48 +0000 Subject: [PATCH 045/111] check type in PSCIDEgoToDefinitionCallback --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 3e7ce74..f4194a3 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -333,8 +333,8 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) let results = [] for res in a:resp.result if empty(filter(copy(results), { idx, val -> - \ val.definedAt != v:null - \ && res.definedAt != v:null + \ type(val.definedAt) == v:t_dict + \ && type(res.definedAt) != v:t_dict \ && val.definedAt.name == res.definedAt.name \ && val.definedAt.start[0] == res.definedAt.start[0] \ && val.definedAt.start[1] == res.definedAt.start[1]})) From 5e6f2f6b3cdbe1057292fb01331db96f540a7a1f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sun, 16 Apr 2017 13:51:05 +0100 Subject: [PATCH 046/111] PureScript 0.11 --- ftplugin/purescript_pscide.vim | 59 ++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f4194a3..54f935e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -53,7 +53,7 @@ endif let s:psc_ide_server = v:none "Looks for bower.json, assumes that's the root directory, starts -"psc-ide-server in the background +"`purs ide server` in the background "Returns Nothing command! -buffer PSCIDEstart call PSCIDEstart(0) function! PSCIDEstart(silent) @@ -63,14 +63,15 @@ function! PSCIDEstart(silent) let loglevel = a:silent == 1 ? 1 : 0 let dir = s:findRoot() + call s:log("PSCIDEstart: cwd " . dir, 3) if empty(dir) - echom "No psc-package.json or bower.json found, couldn't start psc-ide-server" + echom "No psc-package.json or bower.json found, couldn't start `purs ide server`" return endif let command = [ - \ "psc-ide-server", + \ "purs", "ide", "server", \ "-p", g:psc_ide_server_port, \ "-d", dir, \ "src/**/*.purs", @@ -82,7 +83,7 @@ function! PSCIDEstart(silent) \ command, \ { "stoponexit": "term" \ , "err_mode": "raw" - \ , "err_cb": { ch, msg -> s:log("psc-ide-server error: " . string(msg), 0) } + \ , "err_cb": { ch, msg -> s:log("purs ide server error: " . string(msg), 0) } \ , "in_io": "null" \ , "out_io": "null" \ } @@ -134,7 +135,7 @@ function! s:findRoot() endfunction " END ------------------------------------------------------------------------ -" Tell the psc-ide-server to quit +" Tell the `purs ide server` to quit command! -buffer PSCIDEend call PSCIDEend() function! PSCIDEend() if s:pscideexternal == 1 @@ -143,7 +144,7 @@ function! PSCIDEend() let filename = tempname() call writefile([json_encode({'command': 'quit'})], filename) return job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "exit_cb": {job, status -> s:PSCIDEendCallback() } \ , "err_cb": {err -> s:log("PSCIDEend error: " . string(err), 0)} \ , "in_io": "file" @@ -173,7 +174,7 @@ function! s:projectProblems() endfunction " LOAD ----------------------------------------------------------------------- -" Load module of current buffer + its dependencies into psc-ide-server +" Load module of current buffer + its dependencies into `purs ide server` command! -buffer PSCIDEload call PSCIDEload(0) function! PSCIDEload(silent) let loglevel = a:silent == 1 ? 1 : 0 @@ -363,15 +364,17 @@ endfunction function! s:goToDefinition(definedAt) let currentfile = expand("%:p") - if (currentfile == a:definedAt.name) + let fname = a:definedAt.name + let cwd = s:findRoot() + let fname = fnameescape(findfile(fname, cwd)) + if (currentfile == fname) " set ' mark at the current position m' call cursor(a:definedAt.start[0], a:definedAt.start[1]) else - let name = a:definedAt.name - call s:log("PSCIDE s:goToDefinition: name: " . name, 3) + call s:log("PSCIDE s:goToDefinition: fname: " . fname, 3) - let command = "e +" . a:definedAt.start[0] . " " . name + let command = "e +" . a:definedAt.start[0] . " " . fname call s:log("PSCIDE s:goToDefinition: command: " . command, 3) exe command exe "normal " . a:definedAt.start[1] . "|" @@ -447,7 +450,7 @@ function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) endfunction " CWD ------------------------------------------------------------------------ -" Get current working directory of psc-ide-server +" Get current working directory of `pure ide server` command! -buffer PSCIDEcwd call PSCIDEcwd() function! PSCIDEcwd() call s:callPscIde( @@ -578,12 +581,11 @@ function! PSCIDEapplySuggestion() endfunction function! PSCIDEapplySuggestionPrime(lnr, filename, silent) - "let llist = getloclist(0) + let dir = s:findRoot() + let key = fnamemodify(a:filename, ':s?'.dir.'/??') . "|" . string(a:lnr) - call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr, 3) - call s:log('PSCIDEapplySuggestion: filename: ' . a:filename, 3) + call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . "filename: " . a:filename . " key: " . key, 3) - let key = a:filename . "|" . string(a:lnr) if (has_key(g:psc_ide_suggestions, key)) let found = g:psc_ide_suggestions[key] else @@ -824,13 +826,14 @@ function! s:callPscIde(input, errorm, isRetry, cb) if s:pscidestarted == 0 let expectedCWD = fnamemodify(s:findRoot(), ":p:h") + call s:log("callPscIde: cwd " . expectedCWD, 3) let cwdcommand = {'command': 'cwd'} let tempfile = tempname() call writefile([json_encode(cwdcommand)], tempfile) call s:log("callPscIde: No server found, looking for external server", 1) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "out_cb": {ch, msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg)} \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} \ , "in_io": "file" @@ -843,9 +846,9 @@ function! s:callPscIde(input, errorm, isRetry, cb) let enc = json_encode(a:input) let tempfile = tempname() call writefile([enc], tempfile, "b") - call s:log("callPscIde: psc-ide-client: " . enc, 3) + call s:log("callPscIde: purs ide client: " . enc, 3) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} \ , "in_io": "file" \ , "in_name": tempfile @@ -867,13 +870,13 @@ function! s:callPscIdeSync(input, errorm, isRetry) let cwdcommand = {'command': 'cwd'} call s:log("callPscIde: No server found, looking for external server", 1) - let cwdresp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, json_encode(cwdcommand)) + let cwdresp = s:mysystem("purs ide client -p " . g:psc_ide_server_port, json_encode(cwdcommand)) return s:PscIdeStartCallback(a:input, a:errorm, 0, cwdcommand, cwdresp) endif call s:log("callPscIde: Trying to reach server again", 1) let enc = json_encode(a:input) - let resp = s:mysystem("psc-ide-client -p " . g:psc_ide_server_port, enc) + let resp = s:mysystem("purs ide client -p " . g:psc_ide_server_port, enc) return s:PscIdeCallback(a:input, a:errorm, a:isRetry, 0, resp) endfunction @@ -910,7 +913,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) call s:log("s:PscIdeStartCallback: Trying to reach server again", 1) if (type(a:cb) == type(0) && !a:cb) let cwdresp = s:mysystem( - \ "psc-ide-client -p" . g:psc_ide_server_port, + \ "purs ide client -p" . g:psc_ide_server_port, \ json_encode(a:cwdcommand) \ ) return s:PscIdeRetryCallback(a:input, a:errorm, 0, expectedCWD, cwdresp) @@ -918,7 +921,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let tempfile = tempname() call writefile([json_encode(a:cwdcommand)], tempfile) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } \ , "in_io": "file" \ , "in_name": tempfile @@ -949,7 +952,7 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) let enc = json_encode(a:input) if (type(a:cb) == type(0)) let resp = s:mysystem( - \ "psc-ide-client -p" . g:psc_ide_server_port, + \ "purs ide client -p" . g:psc_ide_server_port, \ enc \ ) return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) @@ -957,16 +960,16 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) if (type(a:cb) == type(0) && !a:cb) let resp = s:mysystem( - \ "psc-ide-client -p" . g:psc_ide_server_port + \ "purs ide client -p" . g:psc_ide_server_port \ enc \ ) return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) endif let tempfile = tempname() call writefile([enc], tempfile, "b") - call s:log("callPscIde: psc-ide-client: " . enc, 3) + call s:log("callPscIde: purs ide client: " . enc, 3) call job_start( - \ ["psc-ide-client", "-p", g:psc_ide_server_port], + \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "out_cb": {ch, resp -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, resp))} \ , "in_io": "file" \ , "in_name": tempfile @@ -986,7 +989,7 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) call s:log("s:PscIdeCallback: Error: Failed to contact server", 0) endif if !a:isRetry - " Seems saving often causes psc-ide-server to crash. Haven't been able + " Seems saving often causes `purs ide server` to crash. Haven't been able " to figure out why. It doesn't crash when I run it externally... " retrying is then the next best thing return s:callPscIde(a:input, a:errorm, 1, a:cb) " Keeping track of retries so we only retry once From ed849f1e894ba6faf92183dd8f08306fbf81f9e3 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sun, 16 Apr 2017 20:59:53 +0100 Subject: [PATCH 047/111] PSCIDElistImports * show more identifiers and a qualifier * use highlight colors --- ftplugin/purescript_pscide.vim | 41 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 44bdbf4..6227cc5 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -239,7 +239,7 @@ function! s:importIdentifier(id, module) \ 'importCommand': { \ 'importCommand': 'addImport', \ 'identifier': ident - \ } } } + \ } } } if a:module != "" let input.params.filters = [{'filter': 'modules', 'params': {'modules': [a:module]}}] @@ -296,16 +296,17 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) " Adding one at a time with setline + append/delete to keep line symbols and " cursor as intact as possible + let view = winsaveview() call setline(1, filter(copy(newlines), { idx -> idx < nrOfLinesToReplace })) if (nrOfLinesToDelete > 0) exe 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d_|0" - call cursor(oldCursorPos[1] - nrOfLinesToDelete, oldCursorPos[2]) endif if (nrOfLinesToAppend > 0) + let view = winsaveview() let linesToAppend = filter(copy(newlines), { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) - call append(nrOfOldlinesUnderLine, linesToAppend) endif + call winrestview(view) call s:log("PSCIDEimportIdentifier: Succesfully imported identifier: " . a:module . " ".a:id, 3) else @@ -564,6 +565,36 @@ function! PSCIDElistImports() call s:ListImports(currentModule) endfunction +function! s:EchoImport(import) + echohl Identifier + echon a:import["module"] + echohl Normal + if has_key(a:import, "identifiers") + echon " (" + let len = len(a:import["identifiers"]) + let idx = 0 + for ident in a:import["identifiers"] + echohl Identifier + echon ident + echohl Normal + if (idx < len - 1) + echon ", " + else + echon ")" + endif + let idx += 1 + endfor + endif + if has_key(a:import, "qualifier") + echohl Keyword + echon " as " + echohl Identifier + echon a:import["qualifier"] + echohl Normal + endif + echon "\n" +endfunction + function! s:ListImports(module) let filename = expand("%:p") call s:log('PSCIDE s:ListImports ' . a:module . ' in file ' . filename, 1) @@ -578,8 +609,8 @@ function! s:ListImports(module) " psc-ide >=0.11 returns imports on 'imports' property. let imports = type(resp['result']) == type([]) ? resp['result'] : resp['result']['imports'] if len(imports) > 0 - for module in imports - echom module["module"] + for import in imports + call s:EchoImport(import) endfor else echom "purs ide: No import information found for " . a:module From 9205fe03707719f1c2da553a58874e7e61911b60 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 17 Apr 2017 12:08:14 +0100 Subject: [PATCH 048/111] s:ListImports - is used by getType --- ftplugin/purescript_pscide.vim | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 6227cc5..18f93f2 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -562,7 +562,14 @@ command! PSCIDElistImports call PSCIDElistImports() function! PSCIDElistImports() let currentModule = s:ExtractModule() call s:log('PSCIDElistImports ' . currentModule, 3) - call s:ListImports(currentModule) + let imports = s:ListImports(currentModule) + for import in imports + call s:EchoImport(import) + endfor + if (len(imports) == 0) + echom "PSC-IDE: No import information found for " . currentModule + endif + endfunction function! s:EchoImport(import) @@ -607,20 +614,14 @@ function! s:ListImports(module) " Only need module names right now, so pluck just those. if type(resp) == type({}) && resp['resultType'] ==# 'success' " psc-ide >=0.11 returns imports on 'imports' property. - let imports = type(resp['result']) == type([]) ? resp['result'] : resp['result']['imports'] - if len(imports) > 0 - for import in imports - call s:EchoImport(import) - endfor - else - echom "purs ide: No import information found for " . a:module + return type(resp['result']) == type([]) ? resp['result'] : resp['result']['imports'] endif endif endfunction -function! s:getType(identifier) +function! s:getType(identifier, cb) let currentModule = s:ExtractModule() - let importedModules = s:ListImports(currentModule) + let importedModules = map(s:ListImports(currentModule), {key, val -> val["module"]}) call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( From 3ebd3f1817d0f814edfe50889454c914a53d9fd2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 17 Apr 2017 15:32:39 +0100 Subject: [PATCH 049/111] s:PSCIDEimportIdentifierCallback * fix: append `linesToAppend` * fix: update line number in the value of windsaveview() --- ftplugin/purescript_pscide.vim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 18f93f2..5f4c67c 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -297,14 +297,16 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) " Adding one at a time with setline + append/delete to keep line symbols and " cursor as intact as possible let view = winsaveview() - call setline(1, filter(copy(newlines), { idx -> idx < nrOfLinesToReplace })) + call setline(1, filter(copy(newlines), { idx -> idx < nrOfLinesToReplace + nrOfLinesToAppend })) if (nrOfLinesToDelete > 0) + let view["lnum"] -= nrOfLinesToDelete exe 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d_|0" endif if (nrOfLinesToAppend > 0) - let view = winsaveview() - let linesToAppend = filter(copy(newlines), { idx -> idx >= nrOfLinesToReplace && idx < nrOfLinesToReplace + nrOfLinesToAppend }) + let linesToAppend = filter(copy(newlines), { idx -> idx > nrOfLinesToReplace && idx <= nrOfLinesToReplace + nrOfLinesToAppend }) + let view["lnum"] += nrOfLinesToAppend + call append(line("."), linesToAppend) endif call winrestview(view) From e948b63e248bb7aac3f1cc699eabf67a74b00aaf Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 17 Apr 2017 15:45:55 +0100 Subject: [PATCH 050/111] =?UTF-8?q?s:formattype=20-=20use=20=E2=88=B7=20di?= =?UTF-8?q?graph?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 5f4c67c..ec89151 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -635,7 +635,7 @@ function! s:getType(identifier, cb) endfunction function! s:formattype(record) - return s:CleanEnd(s:StripNewlines(a:record['module']) . '.' . s:StripNewlines(a:record['identifier']) . ' :: ' . s:StripNewlines(a:record['type'])) + return s:CleanEnd(s:StripNewlines(a:record['module']) . '.' . s:StripNewlines(a:record['identifier']) . ' ∷ ' . s:StripNewlines(a:record['type'])) endfunction " APPLYSUGGESTION ------------------------------------------------------ From 586c2356b9673d103e75d940f3f20087fac5e7fc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sun, 30 Apr 2017 11:19:20 +0100 Subject: [PATCH 051/111] s:PSCIDEloadCallback: do not access a:resp on error It might not be a dictionary. --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index ec89151..f889207 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -193,7 +193,7 @@ function! s:PSCIDEloadCallback(loglevel, resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" call s:log("PSCIDEload: Successfully loaded modules: " . string(a:resp["result"]), a:loglevel) else - call s:log("PSCIDEload: Failed to load. Error: " . string(a:resp["result"]), a:loglevel) + call s:log("PSCIDEload: Failed to load. Error.", a:loglevel) endif endfunction From 668fd3527052a641c212bc35ecb3f04b7ceda518 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sun, 30 Apr 2017 11:25:10 +0100 Subject: [PATCH 052/111] s:PscIdeCallback - catch errors when decoding json --- ftplugin/purescript_pscide.vim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f889207..7582420 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1048,7 +1048,9 @@ endfunction function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) call s:log("s:PscIdeCallback: Raw response: " . a:resp, 3) - if a:resp =~? "connection refused" "TODO: This check is probably not crossplatform + try + let decoded = json_decode(a:resp) + catch /.*/ let s:pscidestarted = 0 let s:pscideexternal = 0 @@ -1061,9 +1063,8 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) " retrying is then the next best thing return s:callPscIde(a:input, a:errorm, 1, a:cb) " Keeping track of retries so we only retry once endif - endif + endtry - let decoded = json_decode(a:resp) call s:log("s:PscIdeCallback: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') From e6839664c6a906060058f0561c0e61bcc74c05e3 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 22 May 2017 20:53:33 -0400 Subject: [PATCH 053/111] s:getType - include currentModule when filtering by module --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 9490d65..24d3616 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -653,7 +653,7 @@ endfunction function! s:getType(identifier, cb) let currentModule = s:ExtractModule() - let importedModules = map(s:ListImports(currentModule), {key, val -> val["module"]}) + let importedModules = add(map(s:ListImports(currentModule), {key, val -> val["module"]}), currentModule) call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( From 46af4bd119af0b3fa630252dd2317c33a881bb79 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Mon, 22 May 2017 20:53:33 -0400 Subject: [PATCH 054/111] s:getType - include currentModule when filtering by module --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 9490d65..9b57f1f 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -653,7 +653,7 @@ endfunction function! s:getType(identifier, cb) let currentModule = s:ExtractModule() - let importedModules = map(s:ListImports(currentModule), {key, val -> val["module"]}) + let importedModules = add(map(s:ListImports(currentModule), {key, val -> val["module"]}), currentModule) call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( From 053eeac08b32b19b32299b4ce5fb728f82d566a6 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 24 May 2017 16:20:57 -0600 Subject: [PATCH 055/111] fix: s:getType - put currentModule in params --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 9b57f1f..4df4503 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -657,7 +657,7 @@ function! s:getType(identifier, cb) call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( - \ {'command': 'type', 'params': {'search': a:identifier, 'filters': [{'filter': 'modules' , 'params': {'modules': importedModules } }]}, 'currentModule': currentModule}, + \ {'command': 'type', 'params': {'search': a:identifier, 'filters': [{'filter': 'modules' , 'params': {'modules': importedModules } }], 'currentModule': currentModule}}, \ 'Failed to get type info for: ' . a:identifier, \ 0, \ {resp -> a:cb(resp)} From 66b76fbc54094f1117c59f5b1c89b972fa5947c3 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 00:38:46 +0200 Subject: [PATCH 056/111] PSCIDEaddTypeAnnotation --- ftplugin/purescript_pscide.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4df4503..3f7a901 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -434,7 +434,7 @@ endfunction " Add type annotation command! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation() function! PSCIDEaddTypeAnnotation() - let identifier = s:GetWordUnderCursor() + let identifier = matchstr(getline(line(".")), '^\s*\zs\k\+\ze') call s:getType( \ identifier, @@ -446,7 +446,8 @@ function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) if type(a:resp) == v:t_dict && a:resp["resultType"] ==# 'success' && !empty(a:resp["result"]) let result = a:resp["result"] let lnr = line(".") - call append(lnr - 1, s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) + let indent = matchstr(getline(lnr), '^\s*\ze') + call append(lnr - 1, indent . s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) else echom "PSC-IDE: No type information found for " . a:identifier endif From 4d292df78d9df685172eaee600bf3ebc12fbc998 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 00:42:31 +0200 Subject: [PATCH 057/111] remove duplicated code --- ftplugin/purescript_pscide.vim | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 3f7a901..5d5f5be 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -605,36 +605,6 @@ function! s:EchoImport(import) echon "\n" endfunction -function! s:EchoImport(import) - echohl Identifier - echon a:import["module"] - echohl Normal - if has_key(a:import, "identifiers") - echon " (" - let len = len(a:import["identifiers"]) - let idx = 0 - for ident in a:import["identifiers"] - echohl Identifier - echon ident - echohl Normal - if (idx < len - 1) - echon ", " - else - echon ")" - endif - let idx += 1 - endfor - endif - if has_key(a:import, "qualifier") - echohl Keyword - echon " as " - echohl Identifier - echon a:import["qualifier"] - echohl Normal - endif - echon "\n" -endfunction - function! s:ListImports(module) let filename = expand("%:p") call s:log('PSCIDE s:ListImports ' . a:module . ' in file ' . filename, 1) From df448c01676652e7f95bb656a2521fdf92cdffb2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 00:47:25 +0200 Subject: [PATCH 058/111] remove obsolete functions --- ftplugin/purescript_pscide.vim | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 5d5f5be..c11c35a 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -478,7 +478,7 @@ function! PSCIDEaddClause() let lnr = line(".") let line = getline(lnr) - let command = {'command': 'addClause', 'params': {'line': line, 'annotations': s:jsonFalse()}} + let command = {'command': 'addClause', 'params': {'line': line, 'annotations': v:false}} call s:callPscIde( \ command, @@ -518,7 +518,7 @@ function! PSCIDEcaseSplit() let command = { \ 'command': 'caseSplit', - \ 'params': { 'line': line, 'begin': b, 'end': e, 'annotations': s:jsonFalse(), 'type': t} + \ 'params': { 'line': line, 'begin': b, 'end': e, 'annotations': v:false, 'type': t} \ } call s:callPscIde( @@ -1121,23 +1121,6 @@ endfunction " autocmd CompleteDone * call s:completeDone(v:completed_item) " augroup END - - - - -fun! s:jsonNULL() - return {'json_special_value': 'null'} -endf -fun! s:jsonTrue() - return {'json_special_value': 'true'} -endf -fun! s:jsonFalse() - return {'json_special_value': 'false'} -endf -fun! s:jsonToJSONBool(i) - return a:i ? s:jsonTrue() : s:jsonFalse() -endf - " Parse Errors & Suggestions ------------------------------------------ " Returns { error :: String, " llist :: Array (String in errorformat), From 78ef2a7dc31f85f2e593b93f48c409b46b6eba3d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 01:04:58 +0200 Subject: [PATCH 059/111] remove s:cleanupmessage - vim handles new spaces well in :cli, and :copen commands - this opens up a possibility to properly show long error messages directly accessing quickfix list --- ftplugin/purescript_pscide.vim | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index c11c35a..269ec99 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1170,7 +1170,7 @@ function! s:addEntry(out, suggestions, err, e) \ a:e.filename, \ startL, \ startC, - \ s:cleanupMessage(a:e.message)], ":") + \ a:e.message], ":") call add(a:out, msg) @@ -1190,15 +1190,6 @@ function! s:addSuggestion(suggestions, e) let a:suggestions[a:e.filename . "|" . string(a:e.position.startLine)] = sugg endfunction -function! s:cleanupMessage(str) - let transformations = [ ['\s*\n\+\s*', ' '], ['(\s', '('], ['\s)', ')'], ['\s\,', ','] ] - let out = a:str - for t in transformations - let out = substitute(out, t[0], t[1], 'g') - endfor - return out -endfunction - function! s:mysystem(a, b) return system(a:a, a:b . "\n") endfunction From 8ddfe5402875b7ca0f39c54f558bd13eb47fe616 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 01:45:34 +0200 Subject: [PATCH 060/111] :PSCIDEerr command Useful for inspection long error messages. --- ftplugin/purescript_pscide.vim | 76 +++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 269ec99..a34ece2 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1094,34 +1094,54 @@ function! s:log(str, level) endfunction " INIT ----------------------------------------------------------------------- -" Automatically load the module we just opened -"augroup PscIdeAutoLoad - "au! - "autocmd BufEnter *.purs call s:AutoLoad() - "autocmd BufWritePost *.purs call s:AutoLoad() -"augroup END -"function! s:AutoLoad() - "if s:pscidestarted == 1 - "call PSCIDEload(1) - "endif -"endfunction - -" " Automatic import after completion -" function! s:completeDone(item) -" if g:psc_ide_auto_imports == 0 -" return -" endif -" if (type(a:item) == type({}) -" \ && has_key(a:item, 'word') && type(a:item.word) == type("") -" \ && has_key(a:item, 'info')) && type(a:item.info) == type("") -" call s:importIdentifier(a:item.word, a:item.info) -" endif -" endfunction -" augroup PscideAfterCompletion -" autocmd CompleteDone * call s:completeDone(v:completed_item) -" augroup END - -" Parse Errors & Suggestions ------------------------------------------ +function! PSCIDEerrors(llist) + let qflist = [] + for e in a:llist + let eparts = split(e, ":") + let bufnr = bufnr(eparts[1]) + if bufnr != -1 + call add( + \ qflist + \ , { "bufnr": bufnr(eparts[1]) + \ , "filename": eparts[1] + \ , "lnum": eparts[2] + \ , "col": eparts[3] + \ , "text": join(filter(eparts, {idx -> idx >= 4}), ":") + \ , "type": eparts[0] + \ } + \ ) + endif + endfor + call setqflist(qflist) +endfunction +if g:psc_ide_syntastic_mode == 0 + com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup purescript + au! BufWritePost *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup END +endif + +silent! call PSCIDEstart(0) +silent! call PSCIDEload(0) + +" PSCIDEerr ------------------------------------------------------------------ +fun PSCIDEerr(nr) + let qf = getqflist() + if a:nr > 0 && a:nr < len(qf) + 1 + let e = qf[a:nr - 1] + echo getline(e["lnum"]) + let col = e["col"] + echon "\n" . repeat(" ", col - 1) + echohl Error + echon "^\n\n" + echohl Normal + echo e["text"] + endif +endfun + +command! -buffer -count=1 PSCIDEerr call PSCIDEerr() + +" Parse Errors & Suggestions ------------------------------------------------- " Returns { error :: String, " llist :: Array (String in errorformat), " suggestions :: StrMap { startLine :: Int, From de41a2fa4bfa35f355592edd9d2463b3f4aa6f7b Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 02:28:19 +0200 Subject: [PATCH 061/111] g:psc_ide_notify --- ftplugin/purescript_pscide.vim | 39 +++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a34ece2..d27bd46 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -27,6 +27,10 @@ if !exists('g:psc_ide_check_output_dir') let g:psc_ide_check_output_dir = 1 endif +if !exists('g:psc_ide_notify') + let g:psc_ide_notify = v:true +endif + " Adding iskeyword symbols to improve GetWordUnderCursor --------------------- " 124 = | setlocal iskeyword+=<,>,$,#,+,-,*,/,%,',&,=,!,:,124,^ @@ -1098,20 +1102,29 @@ function! PSCIDEerrors(llist) let qflist = [] for e in a:llist let eparts = split(e, ":") - let bufnr = bufnr(eparts[1]) + let [type, filename, lnum, col, endLnum, endCol] = eparts[0:5] + let bufnr = bufnr(filename) if bufnr != -1 call add( - \ qflist - \ , { "bufnr": bufnr(eparts[1]) - \ , "filename": eparts[1] - \ , "lnum": eparts[2] - \ , "col": eparts[3] - \ , "text": join(filter(eparts, {idx -> idx >= 4}), ":") - \ , "type": eparts[0] + \ qflist + \ , { "bufnr": bufnr + \ , "filename": filename + \ , "lnum": lnum + \ , "col": col + \ , "text": join(filter(eparts, {idx -> idx >= 6}), ":") + \ , "type": type \ } \ ) endif endfor + if g:psc_ide_notify + let errsLen = len(filter(copy(qflist), { n, e -> e["type"] ==# "E" || e["type"] ==# "F" })) + if errsLen + echohl ErrorMsg + echom "purs: " . errsLen . " " . (errsLen == 1 ? "error" : "errors") + echohl Normal + endif + endif call setqflist(qflist) endfunction if g:psc_ide_syntastic_mode == 0 @@ -1183,13 +1196,19 @@ function! s:addEntry(out, suggestions, err, e) let isError = a:err == 1 let letter = isError ? (hasSuggestion ? 'F' : 'E') : (hasSuggestion ? 'V' : 'W') let startL = (exists("a:e.position") && type(a:e.position) == type({})) - \ ? a:e.position.startLine : 1 + \ ? a:e.position.startLine : 1 let startC = (exists("a:e.position") && type(a:e.position) == type({})) - \ ? a:e.position.startColumn : 1 + \ ? a:e.position.startColumn : 1 + let endL = (exists("a:e.position") && type(a:e.position) == type({})) + \ ? a:e.position.endLine : 1 + let endC = (exists("a:e.position") && type(a:e.position) == type({})) + \ ? a:e.position.endColumn : 1 let msg = join([letter, \ a:e.filename, \ startL, \ startC, + \ endL, + \ endC, \ a:e.message], ":") call add(a:out, msg) From 6e636e865d5dfd704951793cc197f5ff5d9431fd Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 02:34:31 +0200 Subject: [PATCH 062/111] notify errors, warnings & success --- ftplugin/purescript_pscide.vim | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index d27bd46..71d0a5e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1119,10 +1119,19 @@ function! PSCIDEerrors(llist) endfor if g:psc_ide_notify let errsLen = len(filter(copy(qflist), { n, e -> e["type"] ==# "E" || e["type"] ==# "F" })) - if errsLen + let wrnLen = len(filter(copy(qflist), { n, e -> e["type"] ==# "W" || e["type"] ==# "V" })) + if errsLen > 0 echohl ErrorMsg echom "purs: " . errsLen . " " . (errsLen == 1 ? "error" : "errors") echohl Normal + elseif wrnLen > 0 + echohl WarningMsg + echom "purs: " . wrnLen . " ". (wrnLen == 1 ? "warnings" : "warning") + echohl Normal + else + echohl Title + echom "purs: ok" + echohl Normal endif endif call setqflist(qflist) From d02a8dc28ba6861fb31e193e90f7f0323198d3b5 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 12:44:05 +0200 Subject: [PATCH 063/111] sort qflist --- ftplugin/purescript_pscide.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 71d0a5e..0ff0c2e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -656,7 +656,7 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) let dir = s:findRoot() let key = fnamemodify(a:filename, ':s?'.dir.'/??') . "|" . string(a:lnr) - call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . "filename: " . a:filename . " key: " . key, 3) + call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . " filename: " . a:filename . " key: " . key, 3) if (has_key(g:psc_ide_suggestions, key)) let found = g:psc_ide_suggestions[key] @@ -1134,6 +1134,7 @@ function! PSCIDEerrors(llist) echohl Normal endif endif + call sort(qflist, { e1, e2 -> e1["lnum"] == e2["lnum"] ? e1["col"] - e2["col"] : e1["lnum"] - e2["lnum"] }) call setqflist(qflist) endfunction if g:psc_ide_syntastic_mode == 0 From cae8579722fa8bbceb5209630a5d0bd3671e4a83 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 14:27:25 +0200 Subject: [PATCH 064/111] PSCIDEapplySuggestions --- ftplugin/purescript_pscide.vim | 89 ++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 0ff0c2e..86a4e33 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -659,7 +659,7 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . " filename: " . a:filename . " key: " . key, 3) if (has_key(g:psc_ide_suggestions, key)) - let found = g:psc_ide_suggestions[key] + let sugg = g:psc_ide_suggestions[key] else if !a:silent call s:log('PSCIDEapplySuggestion: No suggestion found', 0) @@ -667,37 +667,50 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) return endif - call s:log('PSCIDEapplySuggestion: Suggestion found: ' . string(found), 3) - - while found.endColumn == 1 || getline(found.endLine) == '' - call s:log('PSCIDEapplySuggestion: endLine moved from ' . found.endLine . " to " . (found.endLine - 1) , 3) - let found.endLine = found.endLine - 1 - let found.endColumn = len(getline(found.endLine)) + 1 - endwhile - - let lines = getline(found.startLine, found.endLine) - call s:log('PSCIDEapplySuggestion: Lines to replace: ' . string(lines), 3) - - let newl = strpart(lines[0], 0, found.startColumn - 1) . - \ found.replacement . - \ strpart(lines[len(lines) - 1], found.endColumn - 1) - call s:log('PSCIDEapplySuggestion: newl: ' . newl, 3) - - let newlines = split(newl, '\n') - call s:log('PSCIDEapplySuggestion: newlines: ' . string(newlines), 3) - - if len(newlines) == 1 - call s:log('PSCIDEapplySuggestion: setline(' . found.startLine . ", " . newlines[0] .")", 3) - call setline(found.startLine, newlines[0]) + call s:log('PSCIDEapplySuggestion: Suggestion found: ' . string(sugg), 3) + let replacement = sugg.replacement + let range = sugg.replaceRange + let startLine = range.startLine + let startColumn = range.startColumn + let endLine = range.endLine + let endColumn = range.endColumn + if startLine == endLine + let line = getline(startLine) + let replacement = substitute(replacement, '\_s*$', '\n', '') + let cursor = getcurpos() + if startColumn == 1 + let newLines = split(replacement . line[endColumn - 1:], "\n") + else + let newLines = split(line[0:startColumn - 2] . replacement . line[endColumn - 1:], "\n") + endif + exe startLine . "d _" + call append(startLine - 1, newLines) + call cursor(cursor[1], startColumn - 1) + call remove(g:psc_ide_suggestions, key) + let g:psc_ide_suggestions = s:UpdateSuggestions(startLine, len(newLines) - 1) else - let command = string(found.startLine) . "," . string(found.endLine) . "d" - call s:log('PSCIDEapplySuggestion: exe ' . command , 3) - :exe command - call s:log('PSCIDEapplySuggestion: append(' . (found.startLine - 1) . ", " . string(newlines) . ")", 3) - call append(found.startLine - 1, newlines) + echom "PSCIDEapplySuggestion: multiline suggestions are not yet supported" endif endfunction +fun! s:UpdateSuggestions(startLine, newLines) + let suggestions = {} + for key in keys(g:psc_ide_suggestions) + let sug = g:psc_ide_suggestions[key] + if sug.replaceRange.startLine < a:startLine + let suggestions[key] = sug + else + let keyParts = split(key, "|") + let keyParts[len(keyParts) - 1] = sug.replaceRange.startLine + a:newLines + let newKey = join(keyParts, "|") + let sug.replaceRange.startLine = sug.replaceRange.startLine + a:newLines + let sug.replaceRange.endLine = sug.replaceRange.endLine + a:newLines + let suggestions[newKey] = sug + endif + endfor + return suggestions +endfun + " Remove all import qualifications command! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() function! PSCIDEremoveImportQualifications() @@ -1201,17 +1214,16 @@ function! ParsePscJsonOutput(errors, warnings) endfunction function! s:addEntry(out, suggestions, err, e) - let hasSuggestion = exists("a:e.suggestion") && type(a:e.suggestion) == type({}) && - \ exists("a:e.position") && type(a:e.position) == type({}) + let hasSuggestion = type(get(a:e, "suggestion", v:null)) == v:t_dict let isError = a:err == 1 let letter = isError ? (hasSuggestion ? 'F' : 'E') : (hasSuggestion ? 'V' : 'W') - let startL = (exists("a:e.position") && type(a:e.position) == type({})) + let startL = has_key(a:e, "position") && type(a:e.position) == v:t_dict \ ? a:e.position.startLine : 1 - let startC = (exists("a:e.position") && type(a:e.position) == type({})) + let startC = has_key(a:e, "position") && type(a:e.position) == v:t_dict \ ? a:e.position.startColumn : 1 - let endL = (exists("a:e.position") && type(a:e.position) == type({})) + let endL = has_key(a:e, "position") && type(a:e.position) == v:t_dict \ ? a:e.position.endLine : 1 - let endC = (exists("a:e.position") && type(a:e.position) == type({})) + let endC = has_key(a:e, "position") && type(a:e.position) == v:t_dict \ ? a:e.position.endColumn : 1 let msg = join([letter, \ a:e.filename, @@ -1229,14 +1241,7 @@ function! s:addEntry(out, suggestions, err, e) endfunction function! s:addSuggestion(suggestions, e) - let sugg = {'startLine': a:e['position']['startLine'], - \'startColumn': a:e['position']['startColumn'], - \'endLine': a:e['position']['endLine'], - \'endColumn': a:e['position']['endColumn'], - \'filename': a:e['filename'], - \'replacement': a:e['suggestion']['replacement']} - - let a:suggestions[a:e.filename . "|" . string(a:e.position.startLine)] = sugg + let a:suggestions[a:e.filename . "|" . string(a:e.position.startLine)] = a:e.suggestion endfunction function! s:mysystem(a, b) From 42134896c2937dd705e77f9632f7d101b786b0d7 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 15:30:44 +0200 Subject: [PATCH 065/111] psc_ide_filter_prelude_modules Filter prelude modules in :PSCIDEimportIdentifier --- ftplugin/purescript_pscide.vim | 111 +++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 86a4e33..d7d2041 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -31,6 +31,38 @@ if !exists('g:psc_ide_notify') let g:psc_ide_notify = v:true endif +if !exists('g:psc_ide_filter_prelude_modules') + let g:psc_ide_filter_prelude_modules = v:true +endif + +let s:prelude = [ + \ "Control.Applicative", + \ "Control.Apply", + \ "Control.Bind", + \ "Control.Category", + \ "Control.Monad", + \ "Control.Semigroupoid", + \ "Data.Boolean", + \ "Data.BooleanAlgebra", + \ "Data.Bounded", + \ "Data.CommutativeRing", + \ "Data.Eq", + \ "Data.EuclideanRing", + \ "Data.Field", + \ "Data.Function", + \ "Data.Functor", + \ "Data.HeytingAlgebra", + \ "Data.NaturalTransformation", + \ "Data.Ord", + \ "Data.Ordering", + \ "Data.Ring", + \ "Data.Semigroup", + \ "Data.Semiring", + \ "Data.Show", + \ "Data.Unit", + \ "Data.Void", + \ ] + " Adding iskeyword symbols to improve GetWordUnderCursor --------------------- " 124 = | setlocal iskeyword+=<,>,$,#,+,-,*,/,%,',&,=,!,:,124,^ @@ -234,12 +266,13 @@ function! s:importIdentifier(id, module) return endif - call writefile(getline(1, '$'), s:tempfile) + let file = fnamemodify(bufname(""), ":p") let input = { \ 'command': 'import' , \ 'params': { - \ 'file': s:tempfile, + \ 'file': file, + \ 'outfile': file, \ 'importCommand': { \ 'importCommand': 'addImport', \ 'identifier': ident @@ -249,27 +282,42 @@ function! s:importIdentifier(id, module) let input.params.filters = [{'filter': 'modules', 'params': {'modules': [a:module]}}] endif + let view = winsaveview() + let lines = line("$") + call s:callPscIde( \ input, \ "Failed to import identifier " . ident, \ 0, - \ {resp -> s:PSCIDEimportIdentifierCallback(ident, a:id, a:module, resp)} + \ {resp -> s:PSCIDEimportIdentifierCallback(resp, ident, view, lines)} \ ) endfunction -function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) - "multiple possibilities +function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call s:log("s:PSCIDEimportIdentifierCallback", 3) - if type(a:resp) == type({}) && a:resp.resultType ==# "success" && type(a:resp.result[0]) == type({}) - " filter results + if a:resp.resultType !=# "success" + echohl ErrorMsg + echo "purs ide: error" + echohl Normal + return + endif + + if type(a:resp.result) == v:t_list + " multiple possibilities + let respResults = a:resp.result + if g:psc_ide_filter_prelude_modules && len(filter(copy(respResults), { idx, r -> r.module ==# "Prelude" })) + " filter prelude modules (hopefully there are no identifires in prelude + " that clash + call filter(respResults, { idx, r -> index(s:prelude, r.module) == -1 }) + endif let results = [] - for res in a:resp.result + for res in respResults if empty(filter(copy(results), { idx, val -> val.module == res.module })) call add(results, res) endif endfor if (len(results) == 1) - let choice = { option: results[0], picked: v:true } + let choice = { "option": results[0], "picked": v:true } else let choice = s:pickOption("Multiple possibilities to import " . a:ident, results, "module") endif @@ -279,45 +327,12 @@ function! s:PSCIDEimportIdentifierCallback(ident, id, module, resp) return endif - if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" - let newlines = a:resp.result - - let linesdiff = len(newlines) - line("$") - let nrOfOldlinesUnderLine = line(".") - 1 - let nrOfNewlinesUnderLine = nrOfOldlinesUnderLine + linesdiff - let nrOfLinesToReplace = min([nrOfNewlinesUnderLine, nrOfOldlinesUnderLine]) - let nrOfLinesToDelete = -min([0, linesdiff]) - let nrOfLinesToAppend = max([0, linesdiff]) - - call s:log('linesdiff: ' . linesdiff, 3) - call s:log('nrOfOldlinesUnderLine: ' . nrOfOldlinesUnderLine, 3) - call s:log('nrOfNewlinesUnderLine: ' . nrOfNewlinesUnderLine, 3) - call s:log('nrOfLinesToReplace: ' . nrOfLinesToReplace, 3) - call s:log('nrOfLinesToDelete: ' . nrOfLinesToDelete, 3) - call s:log('nrOfLinesToAppend: ' . nrOfLinesToAppend, 3) - - let oldCursorPos = getcurpos() - - " Adding one at a time with setline + append/delete to keep line symbols and - " cursor as intact as possible - let view = winsaveview() - call setline(1, filter(copy(newlines), { idx -> idx < nrOfLinesToReplace + nrOfLinesToAppend })) - - if (nrOfLinesToDelete > 0) - let view["lnum"] -= nrOfLinesToDelete - exe 'silent ' . (nrOfLinesToReplace + 1) . "," . (nrOfLinesToReplace + nrOfLinesToDelete) . "d_|0" - endif - if (nrOfLinesToAppend > 0) - let linesToAppend = filter(copy(newlines), { idx -> idx > nrOfLinesToReplace && idx <= nrOfLinesToReplace + nrOfLinesToAppend }) - let view["lnum"] += nrOfLinesToAppend - call append(line("."), linesToAppend) - endif - call winrestview(view) - - call s:log("PSCIDEimportIdentifier: Succesfully imported identifier: " . a:module . " ".a:id, 3) - else - call s:log("PSCIDEimportIdentifier: Failed to import identifier " . a:ident . ". Error: " . string(a:resp["result"]), 0) - endif + let ar = &l:autoread + let &l:ar = 1 + checktime % + let &l:ar = ar + let a:view.lnum = a:view.lnum + line("$") - a:lines + call winrestview(a:view) endfunction command! -buffer PSCIDEgoToDefinition call PSCIDEgoToDefinition() From 3bce0fb06fc81b1b301d0b82ffad7e31227a9112 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 16:38:01 +0200 Subject: [PATCH 066/111] g:psc_ide_import_from_top Import identifiers from top module. --- ftplugin/purescript_pscide.vim | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index d7d2041..494a560 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -63,6 +63,17 @@ let s:prelude = [ \ "Data.Void", \ ] +if !exists('g:psc_ide_import_from_top') + " this might hide some modules, e.g. React.DOM.Dynamic will be hidden by + " React.DOM module, you can adjust g:psc_ide_import_from_top_do_not_hide + " variable. + let g:psc_ide_import_from_top = v:false +endif + +if !exists("g:psc_ide_import_from_top_do_not_hide") + let g:psc_ide_import_from_top_do_not_hide = [ "React.DOM.Dynamic" ] +endif + " Adding iskeyword symbols to improve GetWordUnderCursor --------------------- " 124 = | setlocal iskeyword+=<,>,$,#,+,-,*,/,%,',&,=,!,:,124,^ @@ -293,6 +304,28 @@ function! s:importIdentifier(id, module) \ ) endfunction +fun! s:TopFilter(module, modules) + " module :: Array String + " modules :: Array (Array String) + let mods = map(copy(g:psc_ide_import_from_top_do_not_hide), { idx, m -> split(m, '\.') }) + return empty(filter(copy(a:modules), { idx, m -> s:IsSubmodule(a:module, m, mods) })) +endfun + +fun! s:IsSubmodule(m1, m2, mods) + " is m1 a submodule of m2 + " m1 :: Array String + " m2 :: Array String + if index(mods, m1) != -1 + return v:false + endif + if len(a:m1) > len(a:m2) + let res = a:m1[0:len(a:m2)-1] == a:m2 ? v:true : v:false + else + let res = v:false + endif + return res +endfun + function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call s:log("s:PSCIDEimportIdentifierCallback", 3) if a:resp.resultType !=# "success" @@ -310,6 +343,10 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) " that clash call filter(respResults, { idx, r -> index(s:prelude, r.module) == -1 }) endif + if g:psc_ide_import_from_top + let modules = map(copy(respResults), { idx, r -> split(r.module, '\.') }) + call filter(respResults, { idx, r -> s:TopFilter(split(r.module, '\.'), modules) }) + endif let results = [] for res in respResults if empty(filter(copy(results), { idx, val -> val.module == res.module })) From e9fb182462d1988a9a3b75db4cad139d0f7c43f4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 2 Jun 2017 21:02:05 +0200 Subject: [PATCH 067/111] log json encoded commands --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 494a560..4c950e9 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -954,7 +954,7 @@ endfunction " and (re)starting it if not " Also serializes and deserializes from/to JSON function! s:callPscIde(input, errorm, isRetry, cb) - call s:log("callPscIde: start: Executing command: " . string(a:input), 3) + call s:log("callPscIde: start: command: " . json_encode(a:input), 3) if s:projectvalid == 0 call PSCIDEprojectValidate() @@ -995,7 +995,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) endfunction function! s:callPscIdeSync(input, errorm, isRetry) - call s:log("callPscIde: start: Executing command: " . string(a:input), 3) + call s:log("callPscIdeSync: command: " . json_encode(a:input), 3) if s:projectvalid == 0 call PSCIDEprojectValidate() From b4868942168a00d0f5ff71ee54b3fa16734601cc Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 3 Jun 2017 11:10:14 +0200 Subject: [PATCH 068/111] PSCIDEomni: filter & sort * filter prelude modules * filter top * sort results by identifier --- ftplugin/purescript_pscide.vim | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4c950e9..2fe790d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -304,7 +304,7 @@ function! s:importIdentifier(id, module) \ ) endfunction -fun! s:TopFilter(module, modules) +fun! s:FilterTopFn(module, modules) " module :: Array String " modules :: Array (Array String) let mods = map(copy(g:psc_ide_import_from_top_do_not_hide), { idx, m -> split(m, '\.') }) @@ -326,6 +326,15 @@ fun! s:IsSubmodule(m1, m2, mods) return res endfun +fun! s:FilterTop(respResults) + let modules = map(copy(respResults), { idx, r -> split(r.module, '\.') }) + call filter(a:respResults, { idx, r -> s:FilterTopFn(split(r.module, '\.'), modules) }) +endfun + +fun! s:FilterPrelude(respResults) + call filter(a:respResults, { idx, r -> index(s:prelude, r.module) == -1 }) +endfun + function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call s:log("s:PSCIDEimportIdentifierCallback", 3) if a:resp.resultType !=# "success" @@ -341,11 +350,10 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) if g:psc_ide_filter_prelude_modules && len(filter(copy(respResults), { idx, r -> r.module ==# "Prelude" })) " filter prelude modules (hopefully there are no identifires in prelude " that clash - call filter(respResults, { idx, r -> index(s:prelude, r.module) == -1 }) + call s:FilterPrelude(respResults) endif if g:psc_ide_import_from_top - let modules = map(copy(respResults), { idx, r -> split(r.module, '\.') }) - call filter(respResults, { idx, r -> s:TopFilter(split(r.module, '\.'), modules) }) + call s:FilterTop(respResults) endif let results = [] for res in respResults @@ -902,6 +910,16 @@ function! PSCIDEomni(findstart,base) "Popuplating the omnicompletion list let result = [] + if g:psc_ide_filter_prelude_modules && len(filter(copy(entries), { idx, r -> r.module ==# "Prelude" })) + " filter prelude modules (hopefully there are no identifires in prelude + " that clash + call s:FilterPrelude(entries) + endif + if g:psc_ide_import_from_top + call s:FilterTop(entries) + endif + " vimL does not have compare function for strings + call sort(entries, { e1, e2 -> sort([e1.identifier, e2.identifier]) == [e2.identifier, e1.identifier]}) if type(entries)==type([]) for entry in entries if entry['identifier'] =~ '^' . str @@ -1194,9 +1212,7 @@ function! PSCIDEerrors(llist) echom "purs: " . wrnLen . " ". (wrnLen == 1 ? "warnings" : "warning") echohl Normal else - echohl Title echom "purs: ok" - echohl Normal endif endif call sort(qflist, { e1, e2 -> e1["lnum"] == e2["lnum"] ? e1["col"] - e2["col"] : e1["lnum"] - e2["lnum"] }) From 0b35a0717920370c21de4c3f22b590c8d00ed285 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 3 Jun 2017 16:46:01 +0200 Subject: [PATCH 069/111] rename g:psc_ide_filter_submodules & g:psc_ide_filter_submodules_do_not_hide --- ftplugin/purescript_pscide.vim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2fe790d..a8538b6 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -63,15 +63,15 @@ let s:prelude = [ \ "Data.Void", \ ] -if !exists('g:psc_ide_import_from_top') +if !exists('g:psc_ide_filter_submodules') " this might hide some modules, e.g. React.DOM.Dynamic will be hidden by - " React.DOM module, you can adjust g:psc_ide_import_from_top_do_not_hide + " React.DOM module, you can adjust g:psc_ide_filter_submodules_do_not_hide " variable. - let g:psc_ide_import_from_top = v:false + let g:psc_ide_filter_submodules = v:false endif -if !exists("g:psc_ide_import_from_top_do_not_hide") - let g:psc_ide_import_from_top_do_not_hide = [ "React.DOM.Dynamic" ] +if !exists("g:psc_ide_filter_submodules_do_not_hide") + let g:psc_ide_filter_submodules_do_not_hide = [ "React.DOM.Dynamic" ] endif " Adding iskeyword symbols to improve GetWordUnderCursor --------------------- @@ -307,7 +307,7 @@ endfunction fun! s:FilterTopFn(module, modules) " module :: Array String " modules :: Array (Array String) - let mods = map(copy(g:psc_ide_import_from_top_do_not_hide), { idx, m -> split(m, '\.') }) + let mods = map(copy(g:psc_ide_filter_submodules_do_not_hide), { idx, m -> split(m, '\.') }) return empty(filter(copy(a:modules), { idx, m -> s:IsSubmodule(a:module, m, mods) })) endfun @@ -352,7 +352,7 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) " that clash call s:FilterPrelude(respResults) endif - if g:psc_ide_import_from_top + if g:psc_ide_filter_submodules call s:FilterTop(respResults) endif let results = [] From 096cb6e817b5e1283da613fffee68c43ee713076 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 3 Jun 2017 16:47:12 +0200 Subject: [PATCH 070/111] s:modulesFilter helper function --- ftplugin/purescript_pscide.vim | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a8538b6..0ddda97 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -290,7 +290,7 @@ function! s:importIdentifier(id, module) \ } } } if a:module != "" - let input.params.filters = [{'filter': 'modules', 'params': {'modules': [a:module]}}] + let input.params.filters = [s:modulesFilter([a:module])] endif let view = winsaveview() @@ -692,7 +692,7 @@ function! s:getType(identifier, cb) call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( - \ {'command': 'type', 'params': {'search': a:identifier, 'filters': [{'filter': 'modules' , 'params': {'modules': importedModules } }], 'currentModule': currentModule}}, + \ {'command': 'type', 'params': {'search': a:identifier, 'filters': [s:modulesFilter(importedModules)], 'currentModule': currentModule}}, \ 'Failed to get type info for: ' . a:identifier, \ 0, \ {resp -> a:cb(resp)} @@ -959,13 +959,17 @@ function! s:findInListBy(list, key, str) endfunction function! s:prefixFilter(s) - return {"filter": "prefix", "params": { "search": a:s } } + return { "filter": "prefix", "params": { "search": a:s } } endfunction function! s:flexMatcher(s) - return {"matcher": "flex", "params": {"search": a:s} } + return { "matcher": "flex", "params": { "search": a:s } } endfunction +fun! s:modulesFilter(modules) + return { "filter": "modules", "params": { "modules": a:modules } } +endfun + " PSCIDE HELPER FUNCTION ----------------------------------------------------- " Issues the commands to the server " Is responsible for keeping track of whether or not we have a running server From 00a386513534250fc5072dac08b5238045da01d6 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 3 Jun 2017 16:50:27 +0200 Subject: [PATCH 071/111] omni completion * support options: - g:psc_ide_omnicompletion_filter_modules find matches only in imported modules - g:psc_ide_filter_prelude_modules do not find matches in submodules of Prelude (unless Prelude is not in the results itself) - g:psc_ide_filter_submodules ignore matches in submodules if it is find in a top level module (you can use g:psc_ide_filter_submodules_do_not_hide to avoid hidding some of submodules) * completion of qualified identifiers --- ftplugin/purescript_pscide.vim | 47 +++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 0ddda97..fd60cab 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -35,6 +35,10 @@ if !exists('g:psc_ide_filter_prelude_modules') let g:psc_ide_filter_prelude_modules = v:true endif +if !exists('g:psc_ide_omnicompletion_filter_modules') + let g:psc_ide_omnicompletion_filter_modules = v:false +endif + let s:prelude = [ \ "Control.Applicative", \ "Control.Apply", @@ -875,29 +879,54 @@ endfunction set omnifunc=PSCIDEomni " OMNICOMPLETION FUNCTION ---------------------------------------------------- -"Omnicompletion function -function! PSCIDEomni(findstart,base) +fun! PSCIDEomni(findstart, base) if a:findstart let col = col(".") let line = getline(".") " search backwards for start of identifier (iskeyword pattern) let start = col - while start>0 && (line[start-2] =~ "\\k" || line[start-2] =~ "\\.") + while start > 0 && (line[start - 2] =~ '\k' || line[start - 2] =~ '\.') let start -= 1 endwhile "Looking for the start of the identifier that we want to complete - return start-1 + return start - 1 else - let str = type(a:base) == type('a') ? a:base : string(a:base) + let str = type(a:base) == v:t_string ? a:base : string(a:base) call s:log('PSCIDEOmni: Looking for completions for: ' . str, 3) let currentModule = s:ExtractModule() call s:log('PSCIDEOmni currentModule: ' . currentModule, 3) + if match(str, '\.') != -1 + let str_ = split(str, '\.') + let qualifier = join(str_[0:len(str_)-2], ".") + let str = str_[len(str_) - 1] + let imports = s:ListImports(currentModule) + let modules = [] + for mod in imports + if get(mod, "qualifier", "") == qualifier || get(mod, "module", "") == qualifier + call add(modules, mod.module) + endif + endfor + + let filters = [s:prefixFilter(str)] + if len(modules) + call add(filters, s:modulesFilter(modules)) + endif + let matcher = s:flexMatcher(str) + else + let qualifier = "" + let filters = [s:prefixFilter(str)] + if g:psc_ide_omnicompletion_filter_modules + call add(filters, s:modulesFilter(map(s:ListImports(currentModule), { n, m -> m.module }))) + endif + let matcher = s:flexMatcher(str) + endif + let resp = s:callPscIdeSync( - \ {'command': 'complete', 'params': {'filters': [s:prefixFilter(str)], 'matcher': s:flexMatcher(str), 'currentModule': currentModule}}, + \ {'command': 'complete', 'params': {'filters': filters, 'matcher': matcher, 'currentModule': currentModule}}, \ 'Failed to get completions for: '. str, \ 0) @@ -915,7 +944,7 @@ function! PSCIDEomni(findstart,base) " that clash call s:FilterPrelude(entries) endif - if g:psc_ide_import_from_top + if g:psc_ide_filter_submodules call s:FilterTop(entries) endif " vimL does not have compare function for strings @@ -923,7 +952,7 @@ function! PSCIDEomni(findstart,base) if type(entries)==type([]) for entry in entries if entry['identifier'] =~ '^' . str - let e = {'word': entry['identifier'], 'menu': s:StripNewlines(entry['type']), 'info': entry['module'], 'dup': 0} + let e = {'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'], 'menu': s:StripNewlines(entry['type']), 'info': entry['module'], 'dup': 0} let existing = s:findInListBy(result, 'word', e['word']) if existing != {} @@ -941,7 +970,7 @@ function! PSCIDEomni(findstart,base) endif return result endif -endfunction +endfun function! s:findInListBy(list, key, str) let i = 0 From 8eca6da33f6c8bdd98ae192ca624c1dda9e1a217 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Sat, 3 Jun 2017 17:53:28 +0200 Subject: [PATCH 072/111] PSCIDEimportIdentifier: use :update --- ftplugin/purescript_pscide.vim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index fd60cab..2abe9b4 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -299,6 +299,8 @@ function! s:importIdentifier(id, module) let view = winsaveview() let lines = line("$") + " updated the file + update call s:callPscIde( \ input, From 585137e3db355dce4be4727e87bc0b105406798e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:24:41 +0200 Subject: [PATCH 073/111] fix s:FilterTop, s:IsSubmodule --- ftplugin/purescript_pscide.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2abe9b4..591ed68 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -314,14 +314,14 @@ fun! s:FilterTopFn(module, modules) " module :: Array String " modules :: Array (Array String) let mods = map(copy(g:psc_ide_filter_submodules_do_not_hide), { idx, m -> split(m, '\.') }) - return empty(filter(copy(a:modules), { idx, m -> s:IsSubmodule(a:module, m, mods) })) + return empty(filter(copy(a:modules), { idx, m -> s:IsSubmodule(a:module, m, a:modules) })) endfun fun! s:IsSubmodule(m1, m2, mods) " is m1 a submodule of m2 " m1 :: Array String " m2 :: Array String - if index(mods, m1) != -1 + if index(a:mods, a:m1) != -1 return v:false endif if len(a:m1) > len(a:m2) @@ -333,7 +333,7 @@ fun! s:IsSubmodule(m1, m2, mods) endfun fun! s:FilterTop(respResults) - let modules = map(copy(respResults), { idx, r -> split(r.module, '\.') }) + let modules = map(copy(a:respResults), { idx, r -> split(r.module, '\.') }) call filter(a:respResults, { idx, r -> s:FilterTopFn(split(r.module, '\.'), modules) }) endfun From 959c5d772ed43ee692abfb21f242b3d2fe64732c Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:25:48 +0200 Subject: [PATCH 074/111] omnicompletion: group reexports (purs 0.11.5) --- ftplugin/purescript_pscide.vim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 591ed68..ba8a42a 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -928,7 +928,14 @@ fun! PSCIDEomni(findstart, base) endif let resp = s:callPscIdeSync( - \ {'command': 'complete', 'params': {'filters': filters, 'matcher': matcher, 'currentModule': currentModule}}, + \ {'command': 'complete' + \ , 'params': + \ { 'filters': filters + \ , 'matcher': matcher + \ , 'currentModule': currentModule + \ , 'options': { 'groupReexports': v:true } + \ } + \ }, \ 'Failed to get completions for: '. str, \ 0) From 926e5ce778549233aa63fe722791d51f3c29187f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:29:42 +0200 Subject: [PATCH 075/111] omnicompletion - g:psc_ide_omnicompletion_sort_by: "identifier" / "module" - change how completion is shown (depending on 'completeop') - review omnicompletion --- ftplugin/purescript_pscide.vim | 69 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index ba8a42a..1598cad 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -956,45 +956,44 @@ fun! PSCIDEomni(findstart, base) if g:psc_ide_filter_submodules call s:FilterTop(entries) endif - " vimL does not have compare function for strings - call sort(entries, { e1, e2 -> sort([e1.identifier, e2.identifier]) == [e2.identifier, e1.identifier]}) - if type(entries)==type([]) - for entry in entries - if entry['identifier'] =~ '^' . str - let e = {'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'], 'menu': s:StripNewlines(entry['type']), 'info': entry['module'], 'dup': 0} - let existing = s:findInListBy(result, 'word', e['word']) - - if existing != {} - let e['menu'] = e['menu'] . ' (' . e['info'] . ')' - let e['dup'] = 1 - if existing['dup'] == 0 - let existing['menu'] = existing['menu'] . ' (' . existing['info'] . ')' - let existing['dup'] = 1 - endif - endif - - call add(result, e) - endif - endfor - endif + let hasPreview = index(split(&l:completeopt, ','), 'preview') != -1 + " vimL does not have compare function for strings, and uniq must run after + " sort. + call uniq( + \ sort(entries, { e1, e2 -> + \ g:psc_ide_omnicompletion_sort_by == "module" + \ ? e1.module == e2.module + \ : sort([e1.identifier, e2.identifier]) == [e2.identifier, e1.identifier]}), + \ { e1, e2 -> !s:compareByDefinedAt(e1, e2) } + \ ) + for entry in entries + + let e = + \ { 'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'] + \ , 'menu': hasPreview ? entry["type"] : printf("\t%-25S\t\t%s", entry['module'], "(" . entry["type"] . ")") + \ , 'info': entry["module"] . "\t\t" . entry['type'] + \ , 'dup': 1 + \ } + call add(result, e) + endfor + echom string(result) return result endif endfun -function! s:findInListBy(list, key, str) - let i = 0 - let l = len(a:list) - let found = {} - - while found == {} && i < l - if a:list[i][a:key] == a:str - let found = a:list[i] - endif - let i = i + 1 - endwhile - - return found -endfunction +fun! s:compareByDefinedAt(e1, e2) + let d1 = a:e1["definedAt"] + let d2 = a:e2["definedAt"] + if d1["name"] != d2["name"] + \ || d1["start"][0] != d2["start"][0] + \ || d1["start"][1] != d2["start"][1] + \ || d1["end"][0] != d2["end"][0] + \ || d1["end"][1] != d2["end"][1] + return v:false + else + return v:true + endif +endfun function! s:prefixFilter(s) return { "filter": "prefix", "params": { "search": a:s } } From a5e5203e29429e9e191083e9625352b6d3e5486d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:54:59 +0200 Subject: [PATCH 076/111] PSCIDEomni - remove topfilter & submodule filter --- ftplugin/purescript_pscide.vim | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 1598cad..553f962 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -948,14 +948,6 @@ fun! PSCIDEomni(findstart, base) "Popuplating the omnicompletion list let result = [] - if g:psc_ide_filter_prelude_modules && len(filter(copy(entries), { idx, r -> r.module ==# "Prelude" })) - " filter prelude modules (hopefully there are no identifires in prelude - " that clash - call s:FilterPrelude(entries) - endif - if g:psc_ide_filter_submodules - call s:FilterTop(entries) - endif let hasPreview = index(split(&l:completeopt, ','), 'preview') != -1 " vimL does not have compare function for strings, and uniq must run after " sort. From 0d5129f41e560eece90b7ea951bb1a975f1c1e1f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:56:32 +0200 Subject: [PATCH 077/111] PSCIDEomni - completion entry --- ftplugin/purescript_pscide.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 553f962..d26d876 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -960,15 +960,15 @@ fun! PSCIDEomni(findstart, base) \ ) for entry in entries + let detail = printf("\t%-25S\t\t%s", entry['module'], entry["type"]) let e = \ { 'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'] - \ , 'menu': hasPreview ? entry["type"] : printf("\t%-25S\t\t%s", entry['module'], "(" . entry["type"] . ")") - \ , 'info': entry["module"] . "\t\t" . entry['type'] + \ , 'menu': hasPreview ? entry["type"] : detail + \ , 'info': detail \ , 'dup': 1 \ } call add(result, e) endfor - echom string(result) return result endif endfun From 4b86b1764d498ddebef7adb96d5fb7fdd522d0d8 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 00:59:55 +0200 Subject: [PATCH 078/111] PSCIDEomni - fix flex matcher - g:psc_ide_omnicompletion_prefix_filter v:true / v:falser disables flex matcher - g:psc_ide_omnicompletion_sort_by: flex / identifier / module --- ftplugin/purescript_pscide.vim | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index d26d876..a285a7e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -39,6 +39,17 @@ if !exists('g:psc_ide_omnicompletion_filter_modules') let g:psc_ide_omnicompletion_filter_modules = v:false endif +if !exists('g:psc_ide_omnicompletion_sort_by') + " flex / identifier / module + let g:psc_ide_omnicompletion_sort_by = "flex" +endif + +if !exists("g:psc_ide_omnicompletion_prefix_filter") + " with this option will let purs ide filter by prefix (this disables flex + " matching) + let g:psc_ide_omnicompletion_prefix_filter = v:false +endif + let s:prelude = [ \ "Control.Applicative", \ "Control.Apply", @@ -901,6 +912,11 @@ fun! PSCIDEomni(findstart, base) let currentModule = s:ExtractModule() call s:log('PSCIDEOmni currentModule: ' . currentModule, 3) + let filters = [] + if g:psc_ide_omnicompletion_prefix_filter + call add(filters, s:prefixFilter(str)) + endif + if match(str, '\.') != -1 let str_ = split(str, '\.') let qualifier = join(str_[0:len(str_)-2], ".") @@ -913,14 +929,12 @@ fun! PSCIDEomni(findstart, base) endif endfor - let filters = [s:prefixFilter(str)] if len(modules) call add(filters, s:modulesFilter(modules)) endif let matcher = s:flexMatcher(str) else let qualifier = "" - let filters = [s:prefixFilter(str)] if g:psc_ide_omnicompletion_filter_modules call add(filters, s:modulesFilter(map(s:ListImports(currentModule), { n, m -> m.module }))) endif @@ -951,13 +965,15 @@ fun! PSCIDEomni(findstart, base) let hasPreview = index(split(&l:completeopt, ','), 'preview') != -1 " vimL does not have compare function for strings, and uniq must run after " sort. - call uniq( - \ sort(entries, { e1, e2 -> - \ g:psc_ide_omnicompletion_sort_by == "module" - \ ? e1.module == e2.module - \ : sort([e1.identifier, e2.identifier]) == [e2.identifier, e1.identifier]}), - \ { e1, e2 -> !s:compareByDefinedAt(e1, e2) } - \ ) + if g:psc_ide_omnicompletion_sort_by != "flex" + call uniq( + \ sort(entries, { e1, e2 -> + \ g:psc_ide_omnicompletion_sort_by == "module" + \ ? e1.module == e2.module + \ : sort([e1.identifier, e2.identifier]) == [e2.identifier, e1.identifier]}), + \ { e1, e2 -> !s:compareByDefinedAt(e1, e2) } + \ ) + endif for entry in entries let detail = printf("\t%-25S\t\t%s", entry['module'], entry["type"]) From 665b4099fec8bc568e6a8bfaf8b1989d2c12b395 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 01:37:08 +0200 Subject: [PATCH 079/111] add bang to PSCIDEload Reset the server and then load modules again. --- ftplugin/purescript_pscide.vim | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a285a7e..40c22d6 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -237,9 +237,17 @@ endfunction " LOAD ----------------------------------------------------------------------- " Load module of current buffer + its dependencies into `purs ide server` -command! -buffer PSCIDEload call PSCIDEload(0) -function! PSCIDEload(silent) - let loglevel = a:silent == 1 ? 1 : 0 +command! -buffer -bang PSCIDEload call PSCIDEload(0, ) +function! PSCIDEload(logLevel, bang) + + if a:bang == "!" + return s:callPscIde( + \ {"command": "reset"}, + \ "Failed to reset", + \ 0, + \ { resp -> resp["resultType"] == "success" ? PSCIDEload(a:logLevel, "") : "" } + \ ) + endif let input = {'command': 'load'} @@ -247,15 +255,15 @@ function! PSCIDEload(silent) \ input, \ "Failed to load", \ 0, - \ {msg -> s:PSCIDEloadCallback(loglevel, msg)} + \ { resp -> s:PSCIDEloadCallback(a:logLevel, resp)} \ ) endfunction -function! s:PSCIDEloadCallback(loglevel, resp) +function! s:PSCIDEloadCallback(logLevel, resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" - call s:log("PSCIDEload: Successfully loaded modules: " . string(a:resp["result"]), a:loglevel) + call s:log("PSCIDEload: Successfully loaded modules: " . string(a:resp["result"]), a:logLevel) else - call s:log("PSCIDEload: Failed to load. Error.", a:loglevel) + call s:log("PSCIDEload: Failed to load. Error.", a:logLevel) endif endfunction @@ -1147,7 +1155,7 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' \ && cwdresp2Decoded.result == a:expectedCWD call s:log("s:PscIdeRetryCallback: Server successfully contacted! Loading current module.", 1) - call PSCIDEload(1) + call PSCIDEload(1, "") else call s:log("s:PscIdeRetryCallback: Server still can't be contacted, aborting...", 1) return @@ -1275,7 +1283,7 @@ if g:psc_ide_syntastic_mode == 0 endif silent! call PSCIDEstart(0) -silent! call PSCIDEload(0) +silent! call PSCIDEload(0, "") " PSCIDEerr ------------------------------------------------------------------ fun PSCIDEerr(nr) From 862d53a95f3b21109500709f22997f70a58b451b Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 01:37:29 +0200 Subject: [PATCH 080/111] add bang to PSCIDEerr function declaration --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 40c22d6..8139d2d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1286,7 +1286,7 @@ silent! call PSCIDEstart(0) silent! call PSCIDEload(0, "") " PSCIDEerr ------------------------------------------------------------------ -fun PSCIDEerr(nr) +fun! PSCIDEerr(nr) let qf = getqflist() if a:nr > 0 && a:nr < len(qf) + 1 let e = qf[a:nr - 1] From 0be8a8479a321ded9ae1d5f3a9df8706dea19809 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 22:14:35 +0200 Subject: [PATCH 081/111] PSCIDEapplySuggestion - use full path --- ftplugin/purescript_pscide.vim | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 8139d2d..31bbb4d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -739,7 +739,7 @@ endfunction function! PSCIDEapplySuggestionPrime(lnr, filename, silent) let dir = s:findRoot() - let key = fnamemodify(a:filename, ':s?'.dir.'/??') . "|" . string(a:lnr) + let key = a:filename . "|" . string(a:lnr) call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . " filename: " . a:filename . " key: " . key, 3) @@ -1023,6 +1023,19 @@ fun! s:modulesFilter(modules) return { "filter": "modules", "params": { "modules": a:modules } } endfun +" SEARCH --------------------------------------------------------------------- +" fun! s:search(ident) + " let resp = s:callPscIdeSync( + " \ {'command': 'complete' + " \ , 'params': + " \ , 'matcher': matcher + " \ , 'options': { 'groupReexports': v:true } + " \ } + " \ }, + " \ 'Failed to get completions for: '. str, + " \ 0) +" endfun + " PSCIDE HELPER FUNCTION ----------------------------------------------------- " Issues the commands to the server " Is responsible for keeping track of whether or not we have a running server From f0591bbf228bff6483ec470df123ef0fd6c9079c Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 22:24:14 +0200 Subject: [PATCH 082/111] PSCIDEapplySugestion! - apply or suggestions --- ftplugin/purescript_pscide.vim | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 31bbb4d..c0dab4f 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -730,21 +730,23 @@ endfunction " APPLYSUGGESTION ------------------------------------------------------ " Apply suggestion in loclist to buffer -------------------------------- -command! -buffer PSCIDEapplySuggestion call PSCIDEapplySuggestion() -function! PSCIDEapplySuggestion() - let lnr = line(".") - let filename = expand("%:p") - call PSCIDEapplySuggestionPrime(lnr, filename, 0) +command! -buffer -bang PSCIDEapplySuggestion call PSCIDEapplySuggestion() +function! PSCIDEapplySuggestion(bang) + if empty(a:bang) + call PSCIDEapplySuggestionPrime(expand("%:p") . "|" . line("."), v:true, 0) + else + for key in keys(g:psc_ide_suggestions) + call PSCIDEapplySuggestionPrime(key, v:true, 0) + endfor + endif endfunction -function! PSCIDEapplySuggestionPrime(lnr, filename, silent) - let dir = s:findRoot() - let key = a:filename . "|" . string(a:lnr) +function! PSCIDEapplySuggestionPrime(key, cursor, silent) - call s:log('PSCIDEapplySuggestion: lineNr: ' . a:lnr . " filename: " . a:filename . " key: " . key, 3) + call s:log('PSCIDEapplySuggestion: a:key: ' . a:key, 3) - if (has_key(g:psc_ide_suggestions, key)) - let sugg = g:psc_ide_suggestions[key] + if (has_key(g:psc_ide_suggestions, a:key)) + let sugg = g:psc_ide_suggestions[a:key] else if !a:silent call s:log('PSCIDEapplySuggestion: No suggestion found', 0) @@ -770,8 +772,10 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) endif exe startLine . "d _" call append(startLine - 1, newLines) - call cursor(cursor[1], startColumn - 1) - call remove(g:psc_ide_suggestions, key) + if a:cursor + call cursor(cursor[1], startColumn - 1) + endif + call remove(g:psc_ide_suggestions, a:key) let g:psc_ide_suggestions = s:UpdateSuggestions(startLine, len(newLines) - 1) else echom "PSCIDEapplySuggestion: multiline suggestions are not yet supported" From a8e1c2daa20956b3d47a4e1693358adda37fc1ae Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 23:17:11 +0200 Subject: [PATCH 083/111] PSCIDEsearch - search & load results into location list --- ftplugin/purescript_pscide.vim | 48 ++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index c0dab4f..b39b59a 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1028,17 +1028,43 @@ fun! s:modulesFilter(modules) endfun " SEARCH --------------------------------------------------------------------- -" fun! s:search(ident) - " let resp = s:callPscIdeSync( - " \ {'command': 'complete' - " \ , 'params': - " \ , 'matcher': matcher - " \ , 'options': { 'groupReexports': v:true } - " \ } - " \ }, - " \ 'Failed to get completions for: '. str, - " \ 0) -" endfun +com! -buffer -nargs=1 PSCIDEsearch call PSCIDEsearch() +fun! PSCIDEsearch(ident) + let matcher = s:flexMatcher(a:ident) + call s:callPscIde( + \ {'command': 'complete' + \ , 'params': + \ { 'matcher': matcher + \ , 'options': { 'groupReexports': v:true } + \ } + \ }, + \ 'Failed to get completions for: '. a:ident, + \ 0, + \ { resp -> s:searchFn(resp) } + \ ) +endfun + +fun! s:searchFn(resp) + if get(a:resp, "resultType", "error") !=# "success" + return + endif + let llist = [] + for res in get(a:resp, "result", []) + let llentry = {} + let bufnr = bufnr(res.definedAt.name) + if bufnr != -1 + let llentry.bufnr = bufnr + endif + let llentry.filename = res.definedAt.name + let llentry.lnum = res.definedAt.start[0] + let llentry.col = res.definedAt.start[1] + let llentry.text = res.type + call add(llist, llentry) + endfor + " echom json_encode(a:resp) + call setloclist(0, llist) + lopen +endfun " PSCIDE HELPER FUNCTION ----------------------------------------------------- " Issues the commands to the server From 7d9387df1d2247c28ff7cfcec2a731261bd429e2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Tue, 6 Jun 2017 23:17:58 +0200 Subject: [PATCH 084/111] use expand("") directly --- ftplugin/purescript_pscide.vim | 92 ++++++++++++++++------------------ 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index b39b59a..f023d78 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -89,7 +89,7 @@ if !exists("g:psc_ide_filter_submodules_do_not_hide") let g:psc_ide_filter_submodules_do_not_hide = [ "React.DOM.Dynamic" ] endif -" Adding iskeyword symbols to improve GetWordUnderCursor --------------------- +" Adding iskeyword symbols to improve expansion- --------------------- " 124 = | setlocal iskeyword+=<,>,$,#,+,-,*,/,%,',&,=,!,:,124,^ @@ -285,18 +285,17 @@ function! s:ExtractModule() endfunction " Import given identifier -command! -buffer PSCIDEimportIdentifier call PSCIDEimportIdentifier() -function! PSCIDEimportIdentifier() - call s:importIdentifier(s:GetWordUnderCursor(), "") +command! -buffer PSCIDEimportIdentifier call PSCIDEimportIdentifier(expand("")) +function! PSCIDEimportIdentifier(ident) + call s:importIdentifier(a:ident, "") endfunction -function! s:importIdentifier(id, module) - let ident = a:id +function! s:importIdentifier(ident, module) call s:log('PSCIDEimportIdentifier', 3) - call s:log('ident: ' . ident, 3) + call s:log('ident: ' . a:ident, 3) call s:log('s:tempfile: ' . s:tempfile, 3) - if (ident == "") + if (a:ident == "") return endif @@ -309,7 +308,7 @@ function! s:importIdentifier(id, module) \ 'outfile': file, \ 'importCommand': { \ 'importCommand': 'addImport', - \ 'identifier': ident + \ 'identifier': a:ident \ } } } if a:module != "" @@ -323,9 +322,9 @@ function! s:importIdentifier(id, module) call s:callPscIde( \ input, - \ "Failed to import identifier " . ident, + \ "Failed to import identifier " . a:ident, \ 0, - \ {resp -> s:PSCIDEimportIdentifierCallback(resp, ident, view, lines)} + \ {resp -> s:PSCIDEimportIdentifierCallback(resp, a:ident, view, lines)} \ ) endfunction @@ -405,23 +404,22 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call winrestview(a:view) endfunction -command! -buffer PSCIDEgoToDefinition call PSCIDEgoToDefinition() -function! PSCIDEgoToDefinition() - let identifier = s:GetWordUnderCursor() - call s:log('PSCIDEgoToDefinition identifier: ' . identifier, 3) +command! -buffer PSCIDEgoToDefinition call PSCIDEgoToDefinition(expand("")) +function! PSCIDEgoToDefinition(ident) + call s:log('PSCIDEgoToDefinition identifier: ' . a:ident, 3) let currentModule = s:ExtractModule() call s:log('PSCIDEgoToDefinition currentModule: ' . currentModule, 3) call s:callPscIde( - \ {'command': 'type', 'params': {'search': identifier, 'filters': []}, 'currentModule': currentModule}, - \ 'Failed to get location info for: ' . identifier, + \ {'command': 'type', 'params': {'search': a:ident, 'filters': []}, 'currentModule': currentModule}, + \ 'Failed to get location info for: ' . a:ident, \ 0, - \ { resp -> s:PSCIDEgoToDefinitionCallback(identifier, resp) } + \ { resp -> s:PSCIDEgoToDefinitionCallback(a:ident, resp) } \ ) endfunction -function! s:PSCIDEgoToDefinitionCallback(identifier, resp) +function! s:PSCIDEgoToDefinitionCallback(ident, resp) call s:log("s:PSCIDEgoToDefinitionCallback", 3) let results = [] for res in a:resp.result @@ -436,7 +434,7 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) endfor if type(a:resp) == v:t_dict && a:resp.resultType ==# "success" if len(results) > 1 - let choice = s:pickOption("Multiple possibilities for " . a:identifier, results, "module") + let choice = s:pickOption("Multiple possibilities for " . a:ident, results, "module") elseif len(results) == 1 let choice = {"picked": v:true, "option": results[0]} else @@ -445,12 +443,12 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) elseif type(choice.option) == v:t_dict - echom "PSCIDE: No location information found for: " . a:identifier . " in module " . choice.option.module + echom "PSCIDE: No location information found for: " . a:ident . " in module " . choice.option.module else - echom "PSCIDE: No location information found for: " . a:identifier + echom "PSCIDE: No location information found for: " . a:ident endif else - echom "PSCIDE: No location information found for: " . a:identifier + echom "PSCIDE: No location information found for: " . a:ident endif endfunction @@ -521,24 +519,22 @@ function! s:PSCIDErebuildCallback(filename, resp) endfunction " Add type annotation -command! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation() -function! PSCIDEaddTypeAnnotation() - let identifier = matchstr(getline(line(".")), '^\s*\zs\k\+\ze') - +command! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation(matchstr(getline(line(".")), '^\s*\zs\k\+\ze')) +function! PSCIDEaddTypeAnnotation(ident) call s:getType( - \ identifier, - \ { resp -> s:PSCIDEaddTypeAnnotationCallback(identifier, resp) } + \ a:ident, + \ { resp -> s:PSCIDEaddTypeAnnotationCallback(a:ident, resp) } \ ) endfunction -function! s:PSCIDEaddTypeAnnotationCallback(identifier, resp) +function! s:PSCIDEaddTypeAnnotationCallback(ident, resp) if type(a:resp) == v:t_dict && a:resp["resultType"] ==# 'success' && !empty(a:resp["result"]) let result = a:resp["result"] let lnr = line(".") let indent = matchstr(getline(lnr), '^\s*\ze') call append(lnr - 1, indent . s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) else - echom "PSC-IDE: No type information found for " . a:identifier + echom "PSC-IDE: No type information found for " . a:ident endif endfunction @@ -593,7 +589,7 @@ function! PSCIDEcaseSplit() let lnr = line(".") let line = getline(lnr) - let word = s:GetWordUnderCursor() + let word = expand("") let b = match(line, word) let e = matchend(line, word) @@ -628,23 +624,22 @@ endfunction " TYPE ----------------------------------------------------------------------- " Get type of word under cursor -command! -buffer PSCIDEtype call PSCIDEtype() -function! PSCIDEtype() - let identifier = s:GetWordUnderCursor() +command! -buffer PSCIDEtype call PSCIDEtype(expand("")) +function! PSCIDEtype(ident) call s:getType( - \ identifier, - \ { resp -> s:PSCIDEtypeCallback(identifier, resp.result) } + \ a:ident, + \ { resp -> s:PSCIDEtypeCallback(a:ident, resp.result) } \ ) endfunction -function! s:PSCIDEtypeCallback(identifier, result) +function! s:PSCIDEtypeCallback(ident, result) if type(a:result) == type([]) for e in a:result echom s:formattype(e) endfor else - echom "PSC-IDE: No type information found for " . a:identifier + echom "PSC-IDE: No type information found for " . a:ident endif endfunction @@ -807,7 +802,7 @@ function! PSCIDEremoveImportQualifications() let replace = "import \\1" let command = "silent %s:" . captureregex . ":" . replace . ":g|norm!``" call s:log('Executing PSCIDEremoveImportQualifications command: ' . command, 3) - :exe command + exe command endfunction " Add all import qualifications @@ -835,19 +830,18 @@ endfunction " PURSUIT -------------------------------------------------------------------- -command! -buffer PSCIDEpursuit call PSCIDEpursuit() -function! PSCIDEpursuit() - let identifier = s:GetWordUnderCursor() +command! -buffer PSCIDEpursuit call PSCIDEpursuit(expand("")) +function! PSCIDEpursuit(ident) call s:callPscIde( - \ {'command': 'pursuit', 'params': {'query': identifier, 'type': "completion"}}, - \ 'Failed to get pursuit info for: ' . identifier, + \ {'command': 'pursuit', 'params': {'query': a:ident, 'type': "completion"}}, + \ 'Failed to get pursuit info for: ' . a:ident, \ 0, \ { resp -> s:PSCIDEpursuitCallback(resp) } \ ) endfunction -function! s:PSCIDEpuresuitCallback(resp) +function! s:PSCIDEpursuitCallback(resp) if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' if len(a:resp["result"]) > 0 for e in a:resp["result"] @@ -1270,10 +1264,6 @@ function! s:CleanEnd(s) return substitute(a:s, '\s*\n*\s*$', '', 'g') endfunction -function! s:GetWordUnderCursor() - return expand("") -endfunction - function! s:log(str, level) if g:psc_ide_log_level >= a:level echom a:str @@ -1318,6 +1308,8 @@ function! PSCIDEerrors(llist) call sort(qflist, { e1, e2 -> e1["lnum"] == e2["lnum"] ? e1["col"] - e2["col"] : e1["lnum"] - e2["lnum"] }) call setqflist(qflist) endfunction + +" AUTOSTART ------------------------------------------------------------------ if g:psc_ide_syntastic_mode == 0 com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) augroup purescript From 07490a098adaf64a089f2a29196669b64f3b56eb Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 08:04:04 +0200 Subject: [PATCH 085/111] PSCIDEsearch - add identifier to results --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f023d78..0e2e22b 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1052,7 +1052,7 @@ fun! s:searchFn(resp) let llentry.filename = res.definedAt.name let llentry.lnum = res.definedAt.start[0] let llentry.col = res.definedAt.start[1] - let llentry.text = res.type + let llentry.text = printf("%-25S\t%s", res.identifier, res.type) call add(llist, llentry) endfor " echom json_encode(a:resp) From 364bb64c8697461d1368efffd7c9b06f5c61b77e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 09:04:06 +0200 Subject: [PATCH 086/111] PSCIDEcomplete - 'completefunc' --- ftplugin/purescript_pscide.vim | 138 ++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 56 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 0e2e22b..d8e532e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -46,8 +46,8 @@ endif if !exists("g:psc_ide_omnicompletion_prefix_filter") " with this option will let purs ide filter by prefix (this disables flex - " matching) - let g:psc_ide_omnicompletion_prefix_filter = v:false + " matching) (tip: use i^xu when searching for a command) + let g:psc_ide_omnicompletion_prefix_filter = v:true endif let s:prelude = [ @@ -857,7 +857,7 @@ function! s:formatpursuit(record) return "In " . s:CleanEnd(s:StripNewlines(a:record["package"])) . " " . s:CleanEnd(s:StripNewlines(a:record['module']) . '.' . s:StripNewlines(a:record['ident']) . ' :: ' . s:StripNewlines(a:record['type'])) endfunction -" VALIDATE ----------------------------------------------------------------------- +" VALIDATE ------------------------------------------------------------------- command! -buffer PSCIDEprojectValidate call PSCIDEprojectValidate() function! PSCIDEprojectValidate() let problems = s:projectProblems() @@ -894,11 +894,8 @@ function! s:PSCIDElistCallback(resp) endif endfunction -" SET UP OMNICOMPLETION ------------------------------------------------------ -set omnifunc=PSCIDEomni - -" OMNICOMPLETION FUNCTION ---------------------------------------------------- -fun! PSCIDEomni(findstart, base) +" COMPLETION FUNCTION -------------------------------------------------------- +fun! s:completeFn(findstart, base, commandFn) if a:findstart let col = col(".") let line = getline(".") @@ -912,62 +909,25 @@ fun! PSCIDEomni(findstart, base) "Looking for the start of the identifier that we want to complete return start - 1 else - let str = type(a:base) == v:t_string ? a:base : string(a:base) - call s:log('PSCIDEOmni: Looking for completions for: ' . str, 3) - - let currentModule = s:ExtractModule() - call s:log('PSCIDEOmni currentModule: ' . currentModule, 3) - - let filters = [] - if g:psc_ide_omnicompletion_prefix_filter - call add(filters, s:prefixFilter(str)) - endif - if match(str, '\.') != -1 - let str_ = split(str, '\.') + if match(a:base, '\.') != -1 + let str_ = split(a:base, '\.') let qualifier = join(str_[0:len(str_)-2], ".") - let str = str_[len(str_) - 1] - let imports = s:ListImports(currentModule) - let modules = [] - for mod in imports - if get(mod, "qualifier", "") == qualifier || get(mod, "module", "") == qualifier - call add(modules, mod.module) - endif - endfor - - if len(modules) - call add(filters, s:modulesFilter(modules)) - endif - let matcher = s:flexMatcher(str) + let ident= str_[len(str_) - 1] else + let ident = a:base let qualifier = "" - if g:psc_ide_omnicompletion_filter_modules - call add(filters, s:modulesFilter(map(s:ListImports(currentModule), { n, m -> m.module }))) - endif - let matcher = s:flexMatcher(str) endif let resp = s:callPscIdeSync( - \ {'command': 'complete' - \ , 'params': - \ { 'filters': filters - \ , 'matcher': matcher - \ , 'currentModule': currentModule - \ , 'options': { 'groupReexports': v:true } - \ } - \ }, - \ 'Failed to get completions for: '. str, + \ a:commandFn(ident, qualifier), + \ 'Failed to get completions for: '. a:base, \ 0) - if type(resp) == type({}) && resp.resultType ==# 'success' - call s:log('PSCIDEOmni: Found Entries: ' . string(resp.result), 3) - let entries = resp["result"] "Entries = list of {module, identifier, type} - else - let entries = [] - endif - + let entries = get(resp, "result", []) "Popuplating the omnicompletion list let result = [] + let hasPreview = index(split(&l:completeopt, ','), 'preview') != -1 " vimL does not have compare function for strings, and uniq must run after " sort. @@ -980,11 +940,10 @@ fun! PSCIDEomni(findstart, base) \ { e1, e2 -> !s:compareByDefinedAt(e1, e2) } \ ) endif - for entry in entries + for entry in entries let detail = printf("\t%-25S\t\t%s", entry['module'], entry["type"]) - let e = - \ { 'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'] + let e = { 'word': (empty(qualifier) ? "" : qualifier . ".") . entry['identifier'] \ , 'menu': hasPreview ? entry["type"] : detail \ , 'info': detail \ , 'dup': 1 @@ -995,6 +954,44 @@ fun! PSCIDEomni(findstart, base) endif endfun +fun! s:omniCommand(ident, qualifier) + let currentModule = s:ExtractModule() + + let filters = [] + if g:psc_ide_omnicompletion_prefix_filter + call add(filters, s:prefixFilter(a:ident)) + endif + + if !empty(a:qualifier) + let imports = s:ListImports(currentModule) + let modules = [] + for mod in imports + if get(mod, "qualifier", "") == a:qualifier || get(mod, "module", "") == a:qualifier + call add(modules, mod.module) + endif + endfor + + if len(modules) + call add(filters, s:modulesFilter(modules)) + endif + let matcher = s:flexMatcher(a:ident) + else + if g:psc_ide_omnicompletion_filter_modules + call add(filters, s:modulesFilter(map(s:ListImports(currentModule), { n, m -> m.module }))) + endif + let matcher = s:flexMatcher(a:ident) + endif + + return {'command': 'complete' + \ , 'params': + \ { 'filters': filters + \ , 'matcher': matcher + \ , 'currentModule': currentModule + \ , 'options': { 'groupReexports': v:true } + \ } + \ } +endfun + fun! s:compareByDefinedAt(e1, e2) let d1 = a:e1["definedAt"] let d2 = a:e2["definedAt"] @@ -1021,6 +1018,35 @@ fun! s:modulesFilter(modules) return { "filter": "modules", "params": { "modules": a:modules } } endfun +" SET UP OMNICOMPLETION ------------------------------------------------------ +fun! PSCIDEomni(findstart, base) + if a:findstart + return s:completeFn(a:findstart, a:base, function("s:omniCommand")) + else + let results = s:completeFn(a:findstart, a:base, function("s:omniCommand")) + if empty(results) + let results = PSCIDEcomplete(a:findstart, a:base) + endif + return results + endif +endfun + +set omnifunc=PSCIDEomni + +" SET UP USERCOMPLETION ------------------------------------------------------ +fun! PSCIDEcomplete(findstart, base) + return s:completeFn(a:findstart, a:base, { ident, qualifier -> + \ {'command': 'complete' + \ , 'params': + \ { 'matcher': s:flexMatcher(a:base) + \ , 'options': { 'groupReexports': v:true } + \ } + \ } + \ }) +endfun + +set completefunc=PSCIDEcomplete + " SEARCH --------------------------------------------------------------------- com! -buffer -nargs=1 PSCIDEsearch call PSCIDEsearch() fun! PSCIDEsearch(ident) From fbada1bd4abf61621792c73f3de40f7340206ea4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 09:04:31 +0200 Subject: [PATCH 087/111] PSCIDEtype - filters --- ftplugin/purescript_pscide.vim | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index d8e532e..5c2c375 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -624,20 +624,22 @@ endfunction " TYPE ----------------------------------------------------------------------- " Get type of word under cursor -command! -buffer PSCIDEtype call PSCIDEtype(expand("")) -function! PSCIDEtype(ident) - +command! -buffer PSCIDEtype call PSCIDEtype(expand(""), v:true) +function! PSCIDEtype(ident, filterModules) call s:getType( \ a:ident, - \ { resp -> s:PSCIDEtypeCallback(a:ident, resp.result) } + \ a:filterModules, + \ { resp -> s:PSCIDEtypeCallback(a:ident, resp.result, a:filterModules) } \ ) endfunction -function! s:PSCIDEtypeCallback(ident, result) - if type(a:result) == type([]) +function! s:PSCIDEtypeCallback(ident, result, filterModules) + if !empty(a:result) && type(a:result) == v:t_list for e in a:result echom s:formattype(e) endfor + elseif a:filterModules + call PSCIDEtype(a:ident, v:false) else echom "PSC-IDE: No type information found for " . a:ident endif @@ -706,14 +708,25 @@ function! s:ListImports(module) endif endfunction -function! s:getType(identifier, cb) +function! s:getType(ident, filterModules, cb) let currentModule = s:ExtractModule() - let importedModules = add(map(s:ListImports(currentModule), {key, val -> val["module"]}), currentModule) + if a:filterModules + let modules = add(map(s:ListImports(currentModule), {key, val -> val["module"]}), currentModule) + let filters = s:modulesFilter(modules) + else + let filters = [] + endif call s:log('PSCIDE s:getType currentModule: ' . currentModule, 3) call s:callPscIde( - \ {'command': 'type', 'params': {'search': a:identifier, 'filters': [s:modulesFilter(importedModules)], 'currentModule': currentModule}}, - \ 'Failed to get type info for: ' . a:identifier, + \ { 'command': 'type' + \ , 'params': + \ { 'search': a:ident + \ , 'filters': filters + \ , 'currentModule': currentModule + \ } + \ }, + \ 'Failed to get type info for: ' . a:ident, \ 0, \ {resp -> a:cb(resp)} \ ) From e5ce1054051491c391bad66c78a2016598964b4f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 10:39:37 +0200 Subject: [PATCH 088/111] use setl for omnifunc and completefunc --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 5c2c375..7d0be9e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1044,7 +1044,7 @@ fun! PSCIDEomni(findstart, base) endif endfun -set omnifunc=PSCIDEomni +setl omnifunc=PSCIDEomni " SET UP USERCOMPLETION ------------------------------------------------------ fun! PSCIDEcomplete(findstart, base) @@ -1058,7 +1058,7 @@ fun! PSCIDEcomplete(findstart, base) \ }) endfun -set completefunc=PSCIDEcomplete +setl completefunc=PSCIDEcomplete " SEARCH --------------------------------------------------------------------- com! -buffer -nargs=1 PSCIDEsearch call PSCIDEsearch() From 3d0346d70041a99a253f9c9b773808910f9c5075 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 14:25:56 +0200 Subject: [PATCH 089/111] use buffer local variable to execute script once --- ftplugin/purescript_pscide.vim | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 7d0be9e..56ebe9f 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1,10 +1,9 @@ " Inits ---------------------------------------------------------------------- -if exists('g:loaded_psc_ide_vim') +if !exists("b:loaded_psc_ide_vim") + let b:loaded_psc_ide_vim = v:true +else finish endif -let g:loaded_psc_ide_vim = 1 - -let s:tempfile = tempname() if !exists('g:psc_ide_suggestions') let g:psc_ide_suggestions = {} @@ -293,7 +292,6 @@ function! s:importIdentifier(ident, module) call s:log('PSCIDEimportIdentifier', 3) call s:log('ident: ' . a:ident, 3) - call s:log('s:tempfile: ' . s:tempfile, 3) if (a:ident == "") return From 4f59aabfbb13c23b8a7a1a65beda48893ffa7a07 Mon Sep 17 00:00:00 2001 From: FrigoEU Date: Wed, 7 Jun 2017 14:36:32 +0200 Subject: [PATCH 090/111] Make async work on vim8 and neovim --- autoload/async/job.vim | 182 +++++++++++++++++++++++++++++++++ ftplugin/purescript_pscide.vim | 109 ++++++++++---------- 2 files changed, 234 insertions(+), 57 deletions(-) create mode 100644 autoload/async/job.vim diff --git a/autoload/async/job.vim b/autoload/async/job.vim new file mode 100644 index 0000000..5848769 --- /dev/null +++ b/autoload/async/job.vim @@ -0,0 +1,182 @@ +" Author: Prabir Shrestha +" License: The MIT License +" Website: https://github.com/prabirshrestha/async.vim + +let s:save_cpo = &cpo +set cpo&vim + +let s:jobidseq = 0 +let s:jobs = {} " { job, opts, type: 'vimjob|nvimjob'} +let s:job_type_nvimjob = 'nvimjob' +let s:job_type_vimjob = 'vimjob' +let s:job_error_unsupported_job_type = -2 " unsupported job type + +function! s:job_supported_types() abort + let l:supported_types = [] + if has('nvim') + let l:supported_types += [s:job_type_nvimjob] + endif + if !has('nvim') && has('job') && has('channel') && has('lambda') + let l:supported_types += [s:job_type_vimjob] + endif + return l:supported_types +endfunction + +function! s:job_supports_type(type) abort + return index(s:job_supported_types(), a:type) >= 0 +endfunction + +function! s:out_cb(job, data, jobid, opts) abort + if has_key(a:opts, 'on_stdout') + call a:opts.on_stdout(a:jobid, split(a:data, "\n", 1), 'stdout') + endif +endfunction + +function! s:err_cb(job, data, jobid, opts) abort + if has_key(a:opts, 'on_stderr') + call a:opts.on_stderr(a:jobid, split(a:data, "\n", 1), 'stderr') + endif +endfunction + +function! s:exit_cb(job, status, jobid, opts) abort + if has_key(a:opts, 'on_exit') + call a:opts.on_exit(a:jobid, a:status, 'exit') + endif + if has_key(s:jobs, a:jobid) + call remove(s:jobs, a:jobid) + endif +endfunction + +function! s:on_stdout(jobid, data, event) abort + if has_key(s:jobs, a:jobid) + let l:jobinfo = s:jobs[a:jobid] + if has_key(l:jobinfo.opts, 'on_stdout') + call l:jobinfo.opts.on_stdout(a:jobid, a:data, a:event) + else + echom "No on_stdout" + endif + endif +endfunction + +function! s:on_stderr(jobid, data, event) abort + if has_key(s:jobs, a:jobid) + let l:jobinfo = s:jobs[a:jobid] + if has_key(l:jobinfo.opts, 'on_stderr') + call l:jobinfo.opts.on_stderr(a:jobid, a:data, a:event) + endif + endif +endfunction + +function! s:on_exit(jobid, status, event) abort + if has_key(s:jobs, a:jobid) + let l:jobinfo = s:jobs[a:jobid] + if has_key(l:jobinfo.opts, 'on_exit') + call l:jobinfo.opts.on_exit(a:jobid, a:status, a:event) + endif + endif +endfunction + +function! s:job_start(cmd, opts) abort + let l:jobtypes = s:job_supported_types() + let l:jobtype = '' + + if has_key(a:opts, 'type') + if type(a:opts.type) == type('') + if !s:job_supports_type(a:opts.type) + return s:job_error_unsupported_job_type + endif + let l:jobtype = a:opts.type + else + let l:jobtypes = a:opts.type + endif + endif + + if empty(l:jobtype) + " find the best jobtype + for l:jobtype2 in l:jobtypes + if s:job_supports_type(l:jobtype2) + let l:jobtype = l:jobtype2 + endif + endfor + endif + + if l:jobtype == '' + return s:job_error_unsupported_job_type + endif + + if l:jobtype == s:job_type_nvimjob + let l:job = jobstart(a:cmd, { + \ 'on_stdout': function('s:on_stdout'), + \ 'on_stderr': function('s:on_stderr'), + \ 'on_exit': function('s:on_exit'), + \}) + if l:job <= 0 + return l:job + endif + let l:jobid = l:job " nvimjobid and internal jobid is same + let s:jobs[l:jobid] = { + \ 'type': s:job_type_nvimjob, + \ 'opts': a:opts, + \ } + let s:jobs[l:jobid].job = l:job + elseif l:jobtype == s:job_type_vimjob + let s:jobidseq = s:jobidseq + 1 + let l:jobid = s:jobidseq + let l:job = job_start(a:cmd, { + \ 'out_cb': {job,data->s:out_cb(job, data, l:jobid, a:opts)}, + \ 'err_cb': {job,data->s:err_cb(job, data, l:jobid, a:opts)}, + \ 'exit_cb': {job,data->s:exit_cb(job, data, l:jobid, a:opts)}, + \ 'mode': 'raw', + \}) + if job_status(l:job) != 'run' + return -1 + endif + let s:jobs[l:jobid] = { + \ 'type': s:job_type_vimjob, + \ 'opts': a:opts, + \ 'job': l:job, + \ 'channel': job_getchannel(l:job) + \ } + else + return s:job_error_unsupported_job_type + endif + + return l:jobid +endfunction + +function! s:job_stop(jobid) abort + if has_key(s:jobs, a:jobid) + let l:jobinfo = s:jobs[a:jobid] + if l:jobinfo.type == s:job_type_nvimjob + call jobstop(a:jobid) + elseif l:jobinfo.type == s:job_type_vimjob + call job_stop(s:jobs[a:jobid].job) + endif + if has_key(s:jobs, a:jobid) + call remove(s:jobs, a:jobid) + endif + endif +endfunction + +function! s:job_send(jobid, data) abort + let l:jobinfo = s:jobs[a:jobid] + if l:jobinfo.type == s:job_type_nvimjob + return jobsend(a:jobid, a:data) + elseif l:jobinfo.type == s:job_type_vimjob + return ch_sendraw(l:jobinfo.channel, a:data) + endif +endfunction + +" public apis {{{ +function! async#job#start(cmd, opts) abort + return s:job_start(a:cmd, a:opts) +endfunction + +function! async#job#stop(jobid) abort + call s:job_stop(a:jobid) +endfunction + +function! async#job#send(jobid, data) abort + return s:job_send(a:jobid, a:data) +endfunction +" }}} diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 4df4503..b7528c5 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -51,7 +51,7 @@ if !exists('s:projectvalid') let s:projectvalid = 0 endif -let s:psc_ide_server = v:none +let s:psc_ide_server = v:null "Looks for bower.json, assumes that's the root directory, starts "`purs ide server` in the background "Returns Nothing @@ -79,14 +79,12 @@ function! PSCIDEstart(silent) \ ] exe "lcd" dir - let s:psc_ide_server = job_start( + let jobid = async#job#start( \ command, - \ { "stoponexit": "term" - \ , "err_mode": "raw" - \ , "err_cb": { ch, msg -> s:log("purs ide server error: " . string(msg), 0) } - \ , "in_io": "null" - \ , "out_io": "null" - \ } + \ { "on_stderr": { ch, msg -> s:log("purs ide server error: " . string(msg), 0) } + \ , "on_stdout": { ch, msg -> s:log("purs ide server got stdout: " . string(msg), 0) } + \ , "on_exit": function("s:onServerExit") + \ } \ ) lcd - @@ -95,6 +93,11 @@ function! PSCIDEstart(silent) let s:pscidestarted = 1 endfunction +function! s:onServerExit(ch, msg, ev) + call s:log("purs ide server exited: " . string(ev), 0) + let s:pscidestarted = 0 +endfunction + if v:version > 704 || (v:version == 704 && has('patch279')) function! s:globpath(dir, pattern) abort return globpath(a:dir, a:pattern, 1, 1) @@ -115,7 +118,7 @@ function! s:pickOption(message, options, labelKey) if choice return {'picked': v:true, 'option': a:options[choice - 1]} else - return {'picked': v:false, 'option': v:none} + return {'picked': v:false, 'option': v:null} endif endfunction @@ -141,15 +144,13 @@ function! PSCIDEend() if s:pscideexternal == 1 return endif - let filename = tempname() - call writefile([json_encode({'command': 'quit'})], filename) - return job_start( + let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "exit_cb": {job, status -> s:PSCIDEendCallback() } - \ , "err_cb": {err -> s:log("PSCIDEend error: " . string(err), 0)} - \ , "in_io": "file" - \ , "in_name": filename + \ { "on_exit": {job, status, ev -> s:PSCIDEendCallback() } + \ , "on_stderr": {err -> s:log("PSCIDEend error: " . string(err), 0)} \ }) + call async#job#send(jobid, json_encode({'command': 'quit'})) + call async#job#stop(jobid) endfunction function! s:PSCIDEendCallback() @@ -351,7 +352,7 @@ function! s:PSCIDEgoToDefinitionCallback(identifier, resp) elseif len(results) == 1 let choice = {"picked": v:true, "option": results[0]} else - let choice = {"picked": v:false, "option": v:none} + let choice = {"picked": v:false, "option": v:null} endif if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) @@ -544,7 +545,7 @@ function! PSCIDEtype() call s:getType( \ identifier, - \ { resp -> s:PSCIDEtypeCallback(identifier, resp.result) } + \ { resp -> s:PSCIDEtypeCallback(identifier, resp["result"]) } \ ) endfunction @@ -587,9 +588,9 @@ function! s:EchoImport(import) echon ident echohl Normal if (idx < len - 1) - echon ", " + echon ", " else - echon ")" + echon ")" endif let idx += 1 endfor @@ -647,7 +648,6 @@ function! s:ListImports(module) if type(resp) == type({}) && resp['resultType'] ==# 'success' " psc-ide >=0.11 returns imports on 'imports' property. return type(resp['result']) == type([]) ? resp['result'] : resp['result']['imports'] - endif endif endfunction @@ -925,33 +925,26 @@ function! s:callPscIde(input, errorm, isRetry, cb) let expectedCWD = fnamemodify(s:findRoot(), ":p:h") call s:log("callPscIde: cwd " . expectedCWD, 3) let cwdcommand = {'command': 'cwd'} - let tempfile = tempname() - call writefile([json_encode(cwdcommand)], tempfile) call s:log("callPscIde: No server found, looking for external server", 1) - call job_start( + let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg)} - \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} - \ , "in_io": "file" - \ , "in_name": tempfile + \ { "on_stdout": {ch, msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg)} + \ , "on_stderr": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} \ }) - call delete(tempfile) + call async#job#stop(jobid) return endif let enc = json_encode(a:input) - let tempfile = tempname() - call writefile([enc], tempfile, "b") call s:log("callPscIde: purs ide client: " . enc, 3) - call job_start( + let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} - \ , "in_io": "file" - \ , "in_name": tempfile - \ , "err_cb": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} + \ { "on_stdout": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} + \ , "on_stderr": {ch, err -> s:log("s:callPscIde error: " . string(err), 0)} \ }) - call delete(tempfile) + call async#job#send(jobid, enc ."\n") + " call async#job#stop(jobid) endfunction function! s:callPscIdeSync(input, errorm, isRetry) @@ -963,7 +956,7 @@ function! s:callPscIdeSync(input, errorm, isRetry) if s:pscidestarted == 0 - let expectedCWD = s:findRoot() + let expectedCWD = fnamemodify(s:findRoot(), ":p:h") let cwdcommand = {'command': 'cwd'} call s:log("callPscIde: No server found, looking for external server", 1) @@ -979,7 +972,7 @@ endfunction " UTILITY FUNCTIONS ---------------------------------------------------------- function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) - let expectedCWD = s:findRoot() + let expectedCWD = fnamemodify(s:findRoot(), ":p:h") try let cwdrespDecoded = json_decode(a:cwdresp) catch /.*/ @@ -1015,16 +1008,13 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) \ ) return s:PscIdeRetryCallback(a:input, a:errorm, 0, expectedCWD, cwdresp) endif - let tempfile = tempname() - call writefile([json_encode(a:cwdcommand)], tempfile) - call job_start( + let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "out_cb": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } - \ , "in_io": "file" - \ , "in_name": tempfile - \ , "err_cb": { ch, err -> s:log("s:PscIdeStartCallback error: " . err, 3) } + \ { "on_stdout": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } + \ , "on_stderr": { ch, err -> s:log("s:PscIdeStartCallback error: " . err, 3) } \ }) - call delete(tempfile) + call async#job#send(jobid, json_encode(a:cwdcommand)) + call async#job#stop(jobid) endfunction function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) @@ -1036,6 +1026,7 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) endtry call s:log("s:PscIdeRetryCallback: Decoded response of trying to reach server again: " \ . string(cwdresp2Decoded), 1) + call s:log("s:PscIdeRetryCallback: Expecting CWD: " . a:expectedCWD, 1) if type(cwdresp2Decoded) == type({}) && cwdresp2Decoded.resultType ==# 'success' \ && cwdresp2Decoded.result == a:expectedCWD @@ -1062,24 +1053,27 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) \ ) return s:PscIdeCallback(a:input, a:errorm, 1, 0, resp) endif - let tempfile = tempname() - call writefile([enc], tempfile, "b") call s:log("callPscIde: purs ide client: " . enc, 3) - call job_start( + let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "out_cb": {ch, resp -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, resp))} - \ , "in_io": "file" - \ , "in_name": tempfile - \ , "err_cb": {ch, err -> s:log("s:PscIdeRetryCallback error: " . err, 3)} + \ { "on_stdout": {ch, resp -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, resp))} + \ , "on_stderr": {ch, err -> s:log("s:PscIdeRetryCallback error: " . err, 3)} \ }) - call delete(tempfile) + call async#job#send(jobid, enc) + call async#job#stop(jobid) endfunction function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) - call s:log("s:PscIdeCallback: Raw response: " . a:resp, 3) + call s:log("s:PscIdeCallback: Raw response: " . string(a:resp), 3) + + if (type(a:resp) == type([])) + let json = a:resp[0] + else + let json = a:resp + endif try - let decoded = json_decode(a:resp) + let decoded = json_decode(json) catch /.*/ let s:pscidestarted = 0 let s:pscideexternal = 0 @@ -1095,6 +1089,7 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) endif endtry + call s:log("s:PscIdeCallback: Input: " . string(a:input), 3) call s:log("s:PscIdeCallback: Decoded response: " . string(decoded), 3) if (type(decoded) != type({}) || decoded['resultType'] !=# 'success') From 9f7ac916970a96b85cbff1bb9e4e33a36125ed4d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 17:36:09 +0200 Subject: [PATCH 091/111] log, warning & error messages --- ftplugin/purescript_pscide.vim | 77 +++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 56ebe9f..07b1bbe 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -259,10 +259,10 @@ function! PSCIDEload(logLevel, bang) endfunction function! s:PSCIDEloadCallback(logLevel, resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# "success" - call s:log("PSCIDEload: Successfully loaded modules: " . string(a:resp["result"]), a:logLevel) + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# "success" + call s:log("purs ide: successfully loaded modules: " . string(a:resp["result"]), a:logLevel) else - call s:log("PSCIDEload: Failed to load. Error.", a:logLevel) + call s:echoError(get(a:resp, "result", "error")) endif endfunction @@ -360,10 +360,7 @@ endfun function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call s:log("s:PSCIDEimportIdentifierCallback", 3) if a:resp.resultType !=# "success" - echohl ErrorMsg - echo "purs ide: error" - echohl Normal - return + return s:echoError(get(a:resp, "result", "error")) endif if type(a:resp.result) == v:t_list @@ -441,12 +438,12 @@ function! s:PSCIDEgoToDefinitionCallback(ident, resp) if choice.picked && type(choice.option.definedAt) == type({}) call s:goToDefinition(choice.option.definedAt) elseif type(choice.option) == v:t_dict - echom "PSCIDE: No location information found for: " . a:ident . " in module " . choice.option.module + call s:echoWarn("no location information found for: " . a:ident . " in module " . choice.option.module) else - echom "PSCIDE: No location information found for: " . a:ident + call s:echoWarn("no location information found for: " . a:ident) endif else - echom "PSCIDE: No location information found for: " . a:ident + call s:echoError(get(a:resp, "result", "error")) endif endfunction @@ -497,21 +494,21 @@ function! PSCIDErebuild(async, ...) endfunction function! s:PSCIDErebuildCallback(filename, resp) - if type(a:resp) == type({}) && has_key(a:resp, "resultType") - \ && has_key (a:resp, "result") && type(a:resp.result) == type([]) + if type(a:resp) == v:t_dict && has_key(a:resp, "resultType") + \ && has_key (a:resp, "result") && type(a:resp.result) == v:t_list if a:resp.resultType == "error" let out = ParsePscJsonOutput(a:resp.result, []) else let out = ParsePscJsonOutput([], a:resp.result) endif if out.error != "" - call s:log("PSCIDErebuild: Failed to interpret " . string(a:resp.result), 0) + call s:echoError("failed to interpret " . string(a:resp.result)) endif let g:psc_ide_suggestions = out.suggestions return out.llist else - call s:log("PSCIDErebuild: Failed to rebuild " . a:filename, 0) + call s:echoError("failed to rebuild") return [] endif endfunction @@ -532,7 +529,7 @@ function! s:PSCIDEaddTypeAnnotationCallback(ident, resp) let indent = matchstr(getline(lnr), '^\s*\ze') call append(lnr - 1, indent . s:StripNewlines(result[0]['identifier']) . ' :: ' . s:StripNewlines(result[0]["type"])) else - echom "PSC-IDE: No type information found for " . a:ident + call s:echoWarn("no type information found for " .a:indent) endif endfunction @@ -549,8 +546,10 @@ function! PSCIDEcwd() endfunction function! s:PSCIDEcwdCallback(resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' - echom "PSC-IDE: Current working directory: " . a:resp["result"] + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' + call s:echoLog("current working directory: " . a:resp.result) + else + call s:echoError(get(a:resp, "result", "error)) endif endfunction @@ -572,10 +571,12 @@ function! PSCIDEaddClause() endfunction function! s:PSCIDEaddClauseCallback(lnr, resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' && type(a:resp.result) == type([]) + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' call s:log('PSCIDEaddClause results: ' . string(a:resp.result), 3) call append(a:lnr, a:resp.result) normal dd + else + call s:echoError(get(a:resp, "result", "error")) endif endfunction @@ -613,10 +614,12 @@ function! PSCIDEcaseSplit() endfunction function! s:PSCIDEcaseSplitCallback(lnr, resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' && type(a:resp.result) == type([]) + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' call s:log('PSCIDEcaseSplit results: ' . string(a:resp.result), 3) call append(a:lnr, a:resp.result) normal dd + else + call s:echoError(get(a:resp, "result", "error")) endif endfunction @@ -691,7 +694,6 @@ endfunction function! s:ListImports(module) let filename = expand("%:p") - call s:log('PSCIDE s:ListImports ' . a:module . ' in file ' . filename, 1) let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'import', 'file': filename}}, \ 'Failed to get imports for: ' . a:module, @@ -699,10 +701,11 @@ function! s:ListImports(module) \ ) call s:log("PSCIDE s:ListImports result: " . string(resp), 3) " Only need module names right now, so pluck just those. - if type(resp) == type({}) && resp['resultType'] ==# 'success' + if type(a:resp) == v:t_dict && resp['resultType'] ==# 'success' " psc-ide >=0.11 returns imports on 'imports' property. - return type(resp['result']) == type([]) ? resp['result'] : resp['result']['imports'] - endif + return type(resp.result) == v:t_list ? resp.result : resp.result.imports + else + call s:echoError(get(resp, "result", "error")) endif endfunction @@ -853,13 +856,13 @@ function! PSCIDEpursuit(ident) endfunction function! s:PSCIDEpursuitCallback(resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' if len(a:resp["result"]) > 0 for e in a:resp["result"] echom s:formatpursuit(e) endfor else - echom "PSC-IDE: No results found on Pursuit" + call s:echoError(get(a:resp, "result", "error")) endif endif endfunction @@ -894,13 +897,13 @@ function! PSCIDElist() endfunction function! s:PSCIDElistCallback(resp) - if type(a:resp) == type({}) && a:resp['resultType'] ==# 'success' + if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' if len(a:resp["result"]) > 0 for m in a:resp["result"] echom m endfor else - echom "PSC-IDE: No loaded modules found" + call s:echoError(get(a:resp, "result", "error")) endif endif endfunction @@ -1077,7 +1080,7 @@ endfun fun! s:searchFn(resp) if get(a:resp, "resultType", "error") !=# "success" - return + return s:echoError(get(a:resp, "result", "error")) endif let llist = [] for res in get(a:resp, "result", []) @@ -1339,7 +1342,7 @@ function! PSCIDEerrors(llist) echom "purs: " . wrnLen . " ". (wrnLen == 1 ? "warnings" : "warning") echohl Normal else - echom "purs: ok" + call s:echoLog("success") endif endif call sort(qflist, { e1, e2 -> e1["lnum"] == e2["lnum"] ? e1["col"] - e2["col"] : e1["lnum"] - e2["lnum"] }) @@ -1444,3 +1447,19 @@ endfunction function! s:mysystem(a, b) return system(a:a, a:b . "\n") endfunction + +fun! s:echoError(msg) + echohl ErrorMsg + echom "purs ide: " . a:msg + echohl Normal +endfun + +fun! s:echoWarn(msg) + echohl WarningMsg + echom "purs ide: " . a:msg + echohl Normal +endfun + +fun! s:echoLog(msg) + echom "purs ide: " .a:msg +endfun From 0d990f69a2b4dcd71ead686cc627eb7e3b8f8d4e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 18:16:18 +0200 Subject: [PATCH 092/111] PSCIDEcaseSplit - fix find identifier --- ftplugin/purescript_pscide.vim | 50 ++++++++++++++++------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 07b1bbe..cfeaf1f 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -583,26 +583,21 @@ endfunction " CASESPLIT " Hover cursor over variable in function declaration -> pattern match on all " different cases of the variable -command! -buffer PSCIDEcaseSplit call PSCIDEcaseSplit() -function! PSCIDEcaseSplit() +command! -buffer -nargs=1 PSCIDEcaseSplit call PSCIDEcaseSplit() +function! PSCIDEcaseSplit(type) + let winview = winsaveview() let lnr = line(".") + let begin = s:findStart() let line = getline(lnr) + let len = len(matchstr(line[begin:], '^\k*')) + let word = line[:len] + echom begin . " " . len . " '" . line . "' word: " . word - let word = expand("") - let b = match(line, word) - let e = matchend(line, word) - - let t = input("Type: ") - - call s:log('PSCIDEcaseSplit: ', 3) - call s:log('line: ' . line, 3) - call s:log('start position: ' . string(b), 3) - call s:log('end position: ' . string(e), 3) - call s:log('type: ' . t, 3) + call winrestview(winview) let command = { \ 'command': 'caseSplit', - \ 'params': { 'line': line, 'begin': b, 'end': e, 'annotations': v:false, 'type': t} + \ 'params': { 'line': line, 'begin': begin, 'end': begin + len, 'annotations': v:false, 'type': a:type} \ } call s:callPscIde( @@ -615,7 +610,6 @@ endfunction function! s:PSCIDEcaseSplitCallback(lnr, resp) if type(a:resp) == v:t_dict && a:resp['resultType'] ==# 'success' - call s:log('PSCIDEcaseSplit results: ' . string(a:resp.result), 3) call append(a:lnr, a:resp.result) normal dd else @@ -908,20 +902,24 @@ function! s:PSCIDElistCallback(resp) endif endfunction +fun! s:findStart() + let col = col(".") + let line = getline(".") + + " search backwards for start of identifier (iskeyword pattern) + let start = col + while start > 0 && (line[start - 2] =~ '\k' || line[start - 2] =~ '\.') + let start -= 1 + endwhile + + "Looking for the start of the identifier that we want to complete + return start - 1 +endfun + " COMPLETION FUNCTION -------------------------------------------------------- fun! s:completeFn(findstart, base, commandFn) if a:findstart - let col = col(".") - let line = getline(".") - - " search backwards for start of identifier (iskeyword pattern) - let start = col - while start > 0 && (line[start - 2] =~ '\k' || line[start - 2] =~ '\.') - let start -= 1 - endwhile - - "Looking for the start of the identifier that we want to complete - return start - 1 + return s:findStart() else if match(a:base, '\.') != -1 From 943f8c28f9b9d8290e4604c87919da4e630e3f3a Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 19:15:30 +0200 Subject: [PATCH 093/111] PSCIDEimportModule --- ftplugin/purescript_pscide.vim | 57 ++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index cfeaf1f..edfd024 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -242,7 +242,7 @@ function! PSCIDEload(logLevel, bang) if a:bang == "!" return s:callPscIde( \ {"command": "reset"}, - \ "Failed to reset", + \ "failed to reset", \ 0, \ { resp -> resp["resultType"] == "success" ? PSCIDEload(a:logLevel, "") : "" } \ ) @@ -591,7 +591,6 @@ function! PSCIDEcaseSplit(type) let line = getline(lnr) let len = len(matchstr(line[begin:], '^\k*')) let word = line[:len] - echom begin . " " . len . " '" . line . "' word: " . word call winrestview(winview) @@ -1167,6 +1166,60 @@ function! s:callPscIdeSync(input, errorm, isRetry) return s:PscIdeCallback(a:input, a:errorm, a:isRetry, 0, resp) endfunction +" ADD IMPORTS -------------------------------------------------------------- +fun! PSCIDEimportModule(module) + let args = filter(split(a:module, ' '), { idx, p -> p != ' ' }) + if len(args) >= 2 + let importCommand = + \ { "importCommand": "addQualifiedImport" + \ , "module": args[0] + \ , "qualifier": args[1] + \ } + else + let importCommand = + \ { "importCommand": "addImplicitImport" + \ , "module": args[0] + \ } + endif + let params = + \ { "file": expand("%:p") + \ , "importCommand": importCommand + \ } + + call s:callPscIde( + \ { "command": "import" , "params": params } + \ , "failed to add import", + \ 0, + \ function("s:PSCIDEimportModuleCallback") + \ ) +endfun + +fun! s:PSCIDEimportModuleCallback(resp) + if type(a:resp) == v:t_dict && a:resp.resultType ==# "success" + let view = winsaveview() + %d_ + call append(0, a:resp.result) + let view.lnum += 1 + call winrestview(view) + else + call s:echoError(get(a:resp, "result", "error")) + endif +endfun + +com! -buffer -nargs=+ -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule() +fun! PSCIDEimportModuleCompletion(ArgLead, CmdLine, CursorPos) + let resp = s:callPscIdeSync( + \ {'command': 'list', 'params': {'type': 'loadedModules'}}, + \ 'Failed to get loaded modules', + \ 0 + \ ) + if type(resp) == v:t_dict && resp.resultType == "success" + return join(resp.result, "\n") + else + return "" + endif +endfun + " UTILITY FUNCTIONS ---------------------------------------------------------- function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let expectedCWD = s:findRoot() From 24f9b86f696afa8c091bfca6cad905671b448167 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 19:38:49 +0200 Subject: [PATCH 094/111] allow to use arguments in some commands The default is to read identifiers from the current file position, unless arg is given. --- ftplugin/purescript_pscide.vim | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index edfd024..7cc2b04 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -284,7 +284,7 @@ function! s:ExtractModule() endfunction " Import given identifier -command! -buffer PSCIDEimportIdentifier call PSCIDEimportIdentifier(expand("")) +command! -buffer -nargs=* PSCIDEimportIdentifier call PSCIDEimportIdentifier(len() ? : expand("")) function! PSCIDEimportIdentifier(ident) call s:importIdentifier(a:ident, "") endfunction @@ -399,15 +399,11 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call winrestview(a:view) endfunction -command! -buffer PSCIDEgoToDefinition call PSCIDEgoToDefinition(expand("")) +command! -buffer -nargs=* PSCIDEgoToDefinition call PSCIDEgoToDefinition(len() ? : expand("")) function! PSCIDEgoToDefinition(ident) - call s:log('PSCIDEgoToDefinition identifier: ' . a:ident, 3) - let currentModule = s:ExtractModule() - call s:log('PSCIDEgoToDefinition currentModule: ' . currentModule, 3) - call s:callPscIde( - \ {'command': 'type', 'params': {'search': a:ident, 'filters': []}, 'currentModule': currentModule}, + \ {'command': 'type', 'params': {'search': a:ident, 'filters': []}, 'currentModule': currentModule}, \ 'Failed to get location info for: ' . a:ident, \ 0, \ { resp -> s:PSCIDEgoToDefinitionCallback(a:ident, resp) } @@ -618,7 +614,7 @@ endfunction " TYPE ----------------------------------------------------------------------- " Get type of word under cursor -command! -buffer PSCIDEtype call PSCIDEtype(expand(""), v:true) +command! -buffer -nargs=* PSCIDEtype call PSCIDEtype(len() ? : expand(""), v:true) function! PSCIDEtype(ident, filterModules) call s:getType( \ a:ident, @@ -694,7 +690,7 @@ function! s:ListImports(module) \ ) call s:log("PSCIDE s:ListImports result: " . string(resp), 3) " Only need module names right now, so pluck just those. - if type(a:resp) == v:t_dict && resp['resultType'] ==# 'success' + if type(resp) == v:t_dict && resp['resultType'] ==# 'success' " psc-ide >=0.11 returns imports on 'imports' property. return type(resp.result) == v:t_list ? resp.result : resp.result.imports else @@ -837,7 +833,7 @@ endfunction " PURSUIT -------------------------------------------------------------------- -command! -buffer PSCIDEpursuit call PSCIDEpursuit(expand("")) +command! -buffer -nargs=* PSCIDEpursuit call PSCIDEpursuit(len() ? : expand("")) function! PSCIDEpursuit(ident) call s:callPscIde( @@ -1059,7 +1055,7 @@ endfun setl completefunc=PSCIDEcomplete " SEARCH --------------------------------------------------------------------- -com! -buffer -nargs=1 PSCIDEsearch call PSCIDEsearch() +com! -buffer -nargs=* PSCIDEsearch call PSCIDEsearch(len() ? : expand("")) fun! PSCIDEsearch(ident) let matcher = s:flexMatcher(a:ident) call s:callPscIde( @@ -1206,7 +1202,7 @@ fun! s:PSCIDEimportModuleCallback(resp) endif endfun -com! -buffer -nargs=+ -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule() +com! -buffer -nargs=* -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule(len() ? : expand("")) fun! PSCIDEimportModuleCompletion(ArgLead, CmdLine, CursorPos) let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'loadedModules'}}, From 35f5eae225adfe22b6fffa9c2d9ba4e04a526552 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 19:49:37 +0200 Subject: [PATCH 095/111] restructure the script to avoid reevaluation --- ftplugin/purescript_pscide.vim | 79 ++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 7cc2b04..c6b75a4 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -5,6 +5,10 @@ else finish endif +if !exists("g:loaded_psc_ide_vim") + let g:loaded_psc_ide_vim = v:false +endif + if !exists('g:psc_ide_suggestions') let g:psc_ide_suggestions = {} endif @@ -101,6 +105,46 @@ endif let g:syntastic_purescript_checkers = ['pscide'] +" COMMANDS ------------------------------------------------------------------- +com! -buffer PSCIDEend call PSCIDEend() +com! -buffer -bang PSCIDEload call PSCIDEload(0, ) +com! -buffer -nargs=* PSCIDEimportIdentifier call PSCIDEimportIdentifier(len() ? : expand("")) +com! -buffer -nargs=* PSCIDEgoToDefinition call PSCIDEgoToDefinition(len() ? : expand("")) +com! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation(matchstr(getline(line(".")), '^\s*\zs\k\+\ze')) +com! -buffer PSCIDEcwd call PSCIDEcwd() +com! -buffer PSCIDEaddClause call PSCIDEaddClause() +com! -buffer -nargs=1 PSCIDEcaseSplit call PSCIDEcaseSplit() +com! -buffer -nargs=* PSCIDEtype call PSCIDEtype(len() ? : expand(""), v:true) +com! PSCIDElistImports call PSCIDElistImports() +com! -buffer -bang PSCIDEapplySuggestion call PSCIDEapplySuggestion() +com! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() +com! -buffer PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() +com! -buffer -nargs=* PSCIDEpursuit call PSCIDEpursuit(len() ? : expand("")) +com! -buffer PSCIDEprojectValidate call PSCIDEprojectValidate() +com! -buffer PSCIDElist call PSCIDElist() +com! -buffer -count=1 PSCIDEerr call PSCIDEerr() +com! -buffer PSCIDEstart call PSCIDEstart(0) +com! -buffer -nargs=* PSCIDEsearch call PSCIDEsearch(len() ? : expand("")) +com! -buffer -nargs=* -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule(len() ? : expand("")) + +" AUTOSTART ------------------------------------------------------------------ +if g:psc_ide_syntastic_mode == 0 + com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup purescript + au! BufWritePost *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup END +endif + +silent! call PSCIDEstart(0) +silent! call PSCIDEload(0, "") + +" INTERNALS ------------------------------------------------------------------- +" execute only once so we do not redefine functions when they are running +if g:loaded_psc_ide_vim + finish +endif +let g:loaded_psc_ide_vim = v:true + " START ---------------------------------------------------------------------- if !exists('s:pscidestarted') let s:pscidestarted = 0 @@ -116,7 +160,6 @@ let s:psc_ide_server = v:none "Looks for bower.json, assumes that's the root directory, starts "`purs ide server` in the background "Returns Nothing -command! -buffer PSCIDEstart call PSCIDEstart(0) function! PSCIDEstart(silent) if s:pscidestarted == 1 return @@ -197,7 +240,6 @@ endfunction " END ------------------------------------------------------------------------ " Tell the `purs ide server` to quit -command! -buffer PSCIDEend call PSCIDEend() function! PSCIDEend() if s:pscideexternal == 1 return @@ -236,7 +278,6 @@ endfunction " LOAD ----------------------------------------------------------------------- " Load module of current buffer + its dependencies into `purs ide server` -command! -buffer -bang PSCIDEload call PSCIDEload(0, ) function! PSCIDEload(logLevel, bang) if a:bang == "!" @@ -284,7 +325,6 @@ function! s:ExtractModule() endfunction " Import given identifier -command! -buffer -nargs=* PSCIDEimportIdentifier call PSCIDEimportIdentifier(len() ? : expand("")) function! PSCIDEimportIdentifier(ident) call s:importIdentifier(a:ident, "") endfunction @@ -399,7 +439,6 @@ function! s:PSCIDEimportIdentifierCallback(resp, ident, view, lines) call winrestview(a:view) endfunction -command! -buffer -nargs=* PSCIDEgoToDefinition call PSCIDEgoToDefinition(len() ? : expand("")) function! PSCIDEgoToDefinition(ident) let currentModule = s:ExtractModule() call s:callPscIde( @@ -510,7 +549,6 @@ function! s:PSCIDErebuildCallback(filename, resp) endfunction " Add type annotation -command! -buffer PSCIDEaddTypeAnnotation call PSCIDEaddTypeAnnotation(matchstr(getline(line(".")), '^\s*\zs\k\+\ze')) function! PSCIDEaddTypeAnnotation(ident) call s:getType( \ a:ident, @@ -531,7 +569,6 @@ endfunction " CWD ------------------------------------------------------------------------ " Get current working directory of `pure ide server` -command! -buffer PSCIDEcwd call PSCIDEcwd() function! PSCIDEcwd() call s:callPscIde( \ {'command': 'cwd'}, @@ -551,7 +588,6 @@ endfunction " ADDCLAUSE " Makes template function implementation from signature -command! -buffer PSCIDEaddClause call PSCIDEaddClause() function! PSCIDEaddClause() let lnr = line(".") let line = getline(lnr) @@ -579,7 +615,6 @@ endfunction " CASESPLIT " Hover cursor over variable in function declaration -> pattern match on all " different cases of the variable -command! -buffer -nargs=1 PSCIDEcaseSplit call PSCIDEcaseSplit() function! PSCIDEcaseSplit(type) let winview = winsaveview() let lnr = line(".") @@ -614,7 +649,6 @@ endfunction " TYPE ----------------------------------------------------------------------- " Get type of word under cursor -command! -buffer -nargs=* PSCIDEtype call PSCIDEtype(len() ? : expand(""), v:true) function! PSCIDEtype(ident, filterModules) call s:getType( \ a:ident, @@ -637,13 +671,12 @@ endfunction " LISTIMPORTS ----------------------------------------------------------------------- " List the modules imported by the current module -command! PSCIDElistImports call PSCIDElistImports() function! PSCIDElistImports() let currentModule = s:ExtractModule() call s:log('PSCIDElistImports ' . currentModule, 3) let imports = s:ListImports(currentModule) for import in imports - call s:EchoImport(import) + call s:echoImport(import) endfor if (len(imports) == 0) echom "PSC-IDE: No import information found for " . currentModule @@ -651,7 +684,7 @@ function! PSCIDElistImports() endfunction -function! s:EchoImport(import) +function! s:echoImport(import) echohl Identifier echon a:import["module"] echohl Normal @@ -728,7 +761,6 @@ endfunction " APPLYSUGGESTION ------------------------------------------------------ " Apply suggestion in loclist to buffer -------------------------------- -command! -buffer -bang PSCIDEapplySuggestion call PSCIDEapplySuggestion() function! PSCIDEapplySuggestion(bang) if empty(a:bang) call PSCIDEapplySuggestionPrime(expand("%:p") . "|" . line("."), v:true, 0) @@ -799,7 +831,6 @@ fun! s:UpdateSuggestions(startLine, newLines) endfun " Remove all import qualifications -command! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() function! PSCIDEremoveImportQualifications() let captureregex = "import\\s\\(\\S\\+\\)\\s*(.*)" let replace = "import \\1" @@ -809,7 +840,6 @@ function! PSCIDEremoveImportQualifications() endfunction " Add all import qualifications -command! -buffer PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() function! PSCIDEaddImportQualifications() let foundLines = [] let filename = expand("%:p") @@ -833,7 +863,6 @@ endfunction " PURSUIT -------------------------------------------------------------------- -command! -buffer -nargs=* PSCIDEpursuit call PSCIDEpursuit(len() ? : expand("")) function! PSCIDEpursuit(ident) call s:callPscIde( @@ -861,7 +890,6 @@ function! s:formatpursuit(record) endfunction " VALIDATE ------------------------------------------------------------------- -command! -buffer PSCIDEprojectValidate call PSCIDEprojectValidate() function! PSCIDEprojectValidate() let problems = s:projectProblems() @@ -875,7 +903,6 @@ function! PSCIDEprojectValidate() endfunction " LIST ----------------------------------------------------------------------- -command! -buffer PSCIDElist call PSCIDElist() function! PSCIDElist() let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'loadedModules'}}, @@ -1055,7 +1082,6 @@ endfun setl completefunc=PSCIDEcomplete " SEARCH --------------------------------------------------------------------- -com! -buffer -nargs=* PSCIDEsearch call PSCIDEsearch(len() ? : expand("")) fun! PSCIDEsearch(ident) let matcher = s:flexMatcher(a:ident) call s:callPscIde( @@ -1202,7 +1228,6 @@ fun! s:PSCIDEimportModuleCallback(resp) endif endfun -com! -buffer -nargs=* -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule(len() ? : expand("")) fun! PSCIDEimportModuleCompletion(ArgLead, CmdLine, CursorPos) let resp = s:callPscIdeSync( \ {'command': 'list', 'params': {'type': 'loadedModules'}}, @@ -1396,17 +1421,6 @@ function! PSCIDEerrors(llist) call setqflist(qflist) endfunction -" AUTOSTART ------------------------------------------------------------------ -if g:psc_ide_syntastic_mode == 0 - com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) - augroup purescript - au! BufWritePost *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) - augroup END -endif - -silent! call PSCIDEstart(0) -silent! call PSCIDEload(0, "") - " PSCIDEerr ------------------------------------------------------------------ fun! PSCIDEerr(nr) let qf = getqflist() @@ -1422,7 +1436,6 @@ fun! PSCIDEerr(nr) endif endfun -command! -buffer -count=1 PSCIDEerr call PSCIDEerr() " Parse Errors & Suggestions ------------------------------------------------- " Returns { error :: String, From 604d74889d3301d7c4edfe5ea440e66130040793 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Wed, 7 Jun 2017 23:57:25 +0200 Subject: [PATCH 096/111] s:searchFn --- ftplugin/purescript_pscide.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index c6b75a4..08d3f24 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1109,9 +1109,10 @@ fun! s:searchFn(resp) let llentry.bufnr = bufnr endif let llentry.filename = res.definedAt.name + let llentry.module = res.module let llentry.lnum = res.definedAt.start[0] let llentry.col = res.definedAt.start[1] - let llentry.text = printf("%-25S\t%s", res.identifier, res.type) + let llentry.text = printf("%s %s", res.identifier, res.type) call add(llist, llentry) endfor " echom json_encode(a:resp) From 067d1c88adf6badf3b3c84abc3c57da98098f92d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 8 Jun 2017 16:07:45 +0200 Subject: [PATCH 097/111] PSCIDEapplySuggestion - fix bang --- ftplugin/purescript_pscide.vim | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f9eba7a..f205228 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -766,9 +766,19 @@ function! PSCIDEapplySuggestion(bang) if empty(a:bang) call PSCIDEapplySuggestionPrime(expand("%:p") . "|" . line("."), v:true, 0) else - for key in keys(g:psc_ide_suggestions) - call PSCIDEapplySuggestionPrime(key, v:true, 0) - endfor + let l = 0 + let len = len(keys(g:psc_ide_suggestions)) + while l < len + " PSCIDEapplySuggestionPrime will change g:psc_ide_suggestions keys on + " the fly + let keys = keys(g:psc_ide_suggestions) + if len(keys) > 0 + let key = keys[0] + call PSCIDEapplySuggestionPrime(key, v:true, 0) + else + break + endif + endwhile endif endfunction @@ -807,13 +817,13 @@ function! PSCIDEapplySuggestionPrime(key, cursor, silent) call cursor(cursor[1], startColumn - 1) endif call remove(g:psc_ide_suggestions, a:key) - let g:psc_ide_suggestions = s:UpdateSuggestions(startLine, len(newLines) - 1) + let g:psc_ide_suggestions = s:updateSuggestions(startLine, len(newLines) - 1) else echom "PSCIDEapplySuggestion: multiline suggestions are not yet supported" endif endfunction -fun! s:UpdateSuggestions(startLine, newLines) +fun! s:updateSuggestions(startLine, newLines) let suggestions = {} for key in keys(g:psc_ide_suggestions) let sug = g:psc_ide_suggestions[key] From b92ff402c829644227c214901a001362af84aa2d Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 8 Jun 2017 22:36:37 +0200 Subject: [PATCH 098/111] s:onServerExit - fix, use s:echoWarn --- ftplugin/purescript_pscide.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f205228..fbfb80e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -198,7 +198,7 @@ function! PSCIDEstart(silent) endfunction function! s:onServerExit(ch, msg, ev) - call s:log("purs ide server exited: " . string(ev), 0) + call s:echoWarn("server exited: " . string(a:ev)) let s:pscidestarted = 0 endfunction From c5be474fb1aab08d487747465c13b7ecdb8286b2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 8 Jun 2017 22:37:46 +0200 Subject: [PATCH 099/111] PSCIDElistCallback - error messages --- ftplugin/purescript_pscide.vim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index fbfb80e..2584803 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -929,9 +929,11 @@ function! s:PSCIDElistCallback(resp) for m in a:resp["result"] echom m endfor - else - call s:echoError(get(a:resp, "result", "error")) endif + elseif type(a:resp) == v:t_dict + call s:echoError(get(a:resp, "result", "error")) + else + call s:echoError("error") endif endfunction From cf37a321dd18b7789cd1a0b9e73489ec81fa183a Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 8 Jun 2017 22:39:21 +0200 Subject: [PATCH 100/111] s:searchFn, PSCIDEerrors - set qf/loc list title --- ftplugin/purescript_pscide.vim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2584803..2c81dde 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1130,6 +1130,7 @@ fun! s:searchFn(resp) endfor " echom json_encode(a:resp) call setloclist(0, llist) + call setloclist(0, [], 'a', {'title': 'PureScript Search'}) lopen endfun @@ -1428,6 +1429,7 @@ function! PSCIDEerrors(llist) endif call sort(qflist, { e1, e2 -> e1["lnum"] == e2["lnum"] ? e1["col"] - e2["col"] : e1["lnum"] - e2["lnum"] }) call setqflist(qflist) + call setqflist([], 'a', {'title': 'PureScript Errors'}) endfunction " PSCIDEerr ------------------------------------------------------------------ From 8b9ce2ec4c342850ecb58cefb89c97fa98289ec4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Thu, 8 Jun 2017 23:46:38 +0200 Subject: [PATCH 101/111] messages: s:echoLog, s:echoWarn, s:echoError --- ftplugin/purescript_pscide.vim | 44 +++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2c81dde..f486644 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -185,8 +185,8 @@ function! PSCIDEstart(silent) exe "lcd" dir let jobid = async#job#start( \ command, - \ { "on_stderr": { ch, msg -> s:log("purs ide server error: " . string(msg), 0) } - \ , "on_stdout": { ch, msg -> s:log("purs ide server got stdout: " . string(msg), 0) } + \ { "on_stderr": { ch, msg -> s:echoWarn(s:toString(msg), v:true) } + \ , "on_stdout": { ch, msg -> s:echoLog(s:toString(msg), v:true) } \ , "on_exit": function("s:onServerExit") \ } \ ) @@ -198,7 +198,7 @@ function! PSCIDEstart(silent) endfunction function! s:onServerExit(ch, msg, ev) - call s:echoWarn("server exited: " . string(a:ev)) + call s:echoLog(s:toString(a:ev), v:true) let s:pscidestarted = 0 endfunction @@ -250,7 +250,8 @@ function! PSCIDEend() let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "on_exit": {job, status, ev -> s:PSCIDEendCallback() } - \ , "on_stderr": {err -> s:log("PSCIDEend error: " . string(err), 0)} + \ , "on_stdout": {err -> s:echoWarn(s:toString(err), v:true)} + \ , "on_stderr": {err -> s:echoWarn(s:toString(err), v:true)} \ }) call async#job#send(jobid, json_encode({'command': 'quit'})) call async#job#stop(jobid) @@ -932,8 +933,6 @@ function! s:PSCIDElistCallback(resp) endif elseif type(a:resp) == v:t_dict call s:echoError(get(a:resp, "result", "error")) - else - call s:echoError("error") endif endfunction @@ -1271,7 +1270,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) call s:log("s:PscIdeStartCallback: Starting new server", 1) call PSCIDEstart(1) else - call s:log("s:PscIdeStartCallback: External server CWD matches with what we need", 1) + call s:echoLog("started", v:true) let s:pscidestarted = 1 let s:pscideexternal = 1 endif @@ -1290,7 +1289,7 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) let jobid = async#job#start( \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], \ { "on_stdout": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } - \ , "on_stderr": { ch, err -> s:log("s:PscIdeStartCallback error: " . err, 3) } + \ , "on_stderr": { ch, err -> s:echoWarn(s:toString(err)) } \ }) call async#job#send(jobid, json_encode(a:cwdcommand)) call async#job#stop(jobid) @@ -1519,18 +1518,35 @@ function! s:mysystem(a, b) return system(a:a, a:b . "\n") endfunction -fun! s:echoError(msg) +fun! s:toString(msg) + if type(a:msg) == v:t_list + return join(map(copy(a:msg), { idx, msg -> s:toString(msg) }), " ") + elseif type(a:msg) == v:t_dict + let msg = {} + for key in a:msg + msg[key] = s:toString(a:msg[key]) + endfor + return string(msg) + else + return string(a:msg) + endif +endfun + +fun! s:echoError(msg, ...) + let title = a:0 > 0 && a:1 ? "purs ide server: " : "purs ide: " echohl ErrorMsg - echom "purs ide: " . a:msg + echom title . a:msg echohl Normal endfun -fun! s:echoWarn(msg) +fun! s:echoWarn(msg, ...) + let title = a:0 > 0 && a:1 ? "purs ide server: " : "purs ide: " echohl WarningMsg - echom "purs ide: " . a:msg + echom title . a:msg echohl Normal endfun -fun! s:echoLog(msg) - echom "purs ide: " .a:msg +fun! s:echoLog(msg, ...) + let title = a:0 > 0 && a:1 ? "purs ide server: " : "purs ide: " + echom title .a:msg endfun From 35d5277590d8ffb4cc0bdc64c7c85699fb07fa93 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 00:15:47 +0200 Subject: [PATCH 102/111] s:autoStart It has to be called at the end of the script (this can be simplified when we'll move function to vim's autoload directory). --- ftplugin/purescript_pscide.vim | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index f486644..513cdd2 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -128,19 +128,23 @@ com! -buffer -nargs=* PSCIDEsearch call PSCIDEsearch(len() ? : com! -buffer -nargs=* -complete=custom,PSCIDEimportModuleCompletion PSCIDEimportModule call PSCIDEimportModule(len() ? : expand("")) " AUTOSTART ------------------------------------------------------------------ -if g:psc_ide_syntastic_mode == 0 - com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) - augroup purescript - au! BufWritePost *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) - augroup END -endif +fun! s:autoStart() + if g:psc_ide_syntastic_mode == 0 + com! PSCIDErebuild call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup purescript + au! BufWritePost *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) + au! BufAdd *.purs call PSCIDErebuild(1, function("PSCIDEerrors")) + augroup END + endif -silent! call PSCIDEstart(0) -silent! call PSCIDEload(0, "") + silent! call PSCIDEstart(0) + silent! call PSCIDEload(0, "") +endfun " INTERNALS ------------------------------------------------------------------- " execute only once so we do not redefine functions when they are running if g:loaded_psc_ide_vim + call s:autoStart() finish endif let g:loaded_psc_ide_vim = v:true @@ -1550,3 +1554,6 @@ fun! s:echoLog(msg, ...) let title = a:0 > 0 && a:1 ? "purs ide server: " : "purs ide: " echom title .a:msg endfun + +" AUTOSTART ------------------------------------------------------------------ +call s:autoStart() From 3bfb63f764c01ba874e323ea416445c388bf82d4 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 00:56:22 +0200 Subject: [PATCH 103/111] PSCIDEstart - on_stdout: only log string messages --- ftplugin/purescript_pscide.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 513cdd2..e48d8c8 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -190,9 +190,9 @@ function! PSCIDEstart(silent) let jobid = async#job#start( \ command, \ { "on_stderr": { ch, msg -> s:echoWarn(s:toString(msg), v:true) } - \ , "on_stdout": { ch, msg -> s:echoLog(s:toString(msg), v:true) } + \ , "on_stdout": { ch, msg -> type(msg) == v:t_string ? s:echoLog(msg) : v:null } \ , "on_exit": function("s:onServerExit") - \ } + \ } \ ) lcd - From 71177a8475ec2ab981d885bb9370c97c1df31ac2 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 00:57:24 +0200 Subject: [PATCH 104/111] s:toString - return strings directly --- ftplugin/purescript_pscide.vim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index e48d8c8..a711841 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1523,7 +1523,9 @@ function! s:mysystem(a, b) endfunction fun! s:toString(msg) - if type(a:msg) == v:t_list + if type(a:msg) == v:t_string + echo a:msg + elseif type(a:msg) == v:t_list return join(map(copy(a:msg), { idx, msg -> s:toString(msg) }), " ") elseif type(a:msg) == v:t_dict let msg = {} From 0f157794efc135575385ee071349276d311fa62c Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 00:59:00 +0200 Subject: [PATCH 105/111] PSCIDEloadCallback --- ftplugin/purescript_pscide.vim | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index a711841..22b4659 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -306,10 +306,12 @@ function! PSCIDEload(logLevel, bang) endfunction function! s:PSCIDEloadCallback(logLevel, resp) - if type(a:resp) == v:t_dict && a:resp['resultType'] ==# "success" - call s:log("purs ide: successfully loaded modules: " . string(a:resp["result"]), a:logLevel) - else - call s:echoError(get(a:resp, "result", "error")) + if type(a:resp) == v:t_dict + if a:resp['resultType'] ==# "success" + call s:log("purs ide: successfully loaded modules: " . string(a:resp["result"]), a:logLevel) + else + call s:echoError(get(a:resp, "result", "error")) + endif endif endfunction From b88043671a1c874d112a160d04491334865c5d3e Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 01:01:24 +0200 Subject: [PATCH 106/111] PSCIDEend * use systemlist directly * disable messeges got from channel exit handler * format log message --- ftplugin/purescript_pscide.vim | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 22b4659..7536f2d 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -201,8 +201,11 @@ function! PSCIDEstart(silent) let s:pscidestarted = 1 endfunction +let s:onServerExit = v:true function! s:onServerExit(ch, msg, ev) - call s:echoLog(s:toString(a:ev), v:true) + if s:onServerExit + call s:echoLog(s:toString(a:ev), v:true) + endif let s:pscidestarted = 0 endfunction @@ -251,14 +254,20 @@ function! PSCIDEend() if s:pscideexternal == 1 return endif - let jobid = async#job#start( - \ ["purs", "ide", "client", "-p", g:psc_ide_server_port], - \ { "on_exit": {job, status, ev -> s:PSCIDEendCallback() } - \ , "on_stdout": {err -> s:echoWarn(s:toString(err), v:true)} - \ , "on_stderr": {err -> s:echoWarn(s:toString(err), v:true)} - \ }) - call async#job#send(jobid, json_encode({'command': 'quit'})) - call async#job#stop(jobid) + let s:onServerExit = v:false + let resp = systemlist( + \ "purs ide client -p " .g:psc_ide_server_port, + \ json_encode({"command": "quit"}) + \ ) + let s:onServerExit = v:true + let resp = join(resp, ' ') + if (resp =~ 'end of file$') + call s:echoLog("exit", v:true) + elseif (resp =~ 'couldn''t connect to purs ide server') + call s:echoLog("not running", v:true) + else + call s:echoLog(resp, v:true) + endif endfunction function! s:PSCIDEendCallback() From 988f56245acf5d6214b0306ec0687e41d636f8ee Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 01:02:09 +0200 Subject: [PATCH 107/111] PscIdeCallback - undefined `decoded` variable --- ftplugin/purescript_pscide.vim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 7536f2d..11f3dbf 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1370,9 +1370,13 @@ function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) catch /.*/ let s:pscidestarted = 0 let s:pscideexternal = 0 + let decoded = + \ { "resultType": "error" + \ , "result": "failed to decode response" + \ } if a:isRetry - call s:log("s:PscIdeCallback: Error: Failed to contact server", 0) + call s:echoLog("failed to contact server", v:true) endif if !a:isRetry " Seems saving often causes `purs ide server` to crash. Haven't been able From 22693339e0b406b6a7fb8ac5610866170654be2b Mon Sep 17 00:00:00 2001 From: FrigoEU Date: Fri, 9 Jun 2017 11:11:02 +0200 Subject: [PATCH 108/111] Remove PSCIDEremoveImporQualifications, not relevant anymore --- README.md | 2 -- ftplugin/purescript_pscide.vim | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/README.md b/README.md index 5686a69..d0d9143 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,7 @@ This plugin provides two kinds of syntax checking with syntastic. Controlling wh * :PSCIDEcaseSplit : Splits variables in a function declaration into its different constructors. Will probably get improved soon so you don't have to input the type yourself ![:PSCIDEcaseSplit gif](http://frigoeu.github.io/gifs/casesplit.gif) -* :PSCIDEremoveImportQualifications : Remove all qualifications from your imports -![:PSCIDEremoveimport gif](http://frigoeu.github.io/gifs/removeimport.gif) * :PSCIDEaddImportQualifications : Applies all import qualification suggestions in one go. Same as :PSCIDEapplySuggestion, but applies it to every line starting with "import" ![:PSCIDEaddimport gif](http://frigoeu.github.io/gifs/addimport.gif) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index b7528c5..62a223b 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -723,16 +723,6 @@ function! PSCIDEapplySuggestionPrime(lnr, filename, silent) endif endfunction -" Remove all import qualifications -command! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() -function! PSCIDEremoveImportQualifications() - let captureregex = "import\\s\\(\\S\\+\\)\\s*(.*)" - let replace = "import \\1" - let command = "silent %s:" . captureregex . ":" . replace . ":g|norm!``" - call s:log('Executing PSCIDEremoveImportQualifications command: ' . command, 3) - :exe command -endfunction - " Add all import qualifications command! -buffer PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() function! PSCIDEaddImportQualifications() From 400664b712696acad924ad046f83c112f83b461f Mon Sep 17 00:00:00 2001 From: FrigoEU Date: Fri, 9 Jun 2017 11:11:37 +0200 Subject: [PATCH 109/111] Fix boolean encoding in JSON --- ftplugin/purescript_pscide.vim | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 62a223b..7d79514 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -1140,16 +1140,13 @@ endfunction fun! s:jsonNULL() - return {'json_special_value': 'null'} + return v:null endf fun! s:jsonTrue() - return {'json_special_value': 'true'} + return v:true endf fun! s:jsonFalse() - return {'json_special_value': 'false'} -endf -fun! s:jsonToJSONBool(i) - return a:i ? s:jsonTrue() : s:jsonFalse() + return v:false endf " Parse Errors & Suggestions ------------------------------------------ From caed148100541419654593377b3688b0420d7152 Mon Sep 17 00:00:00 2001 From: FrigoEU Date: Fri, 9 Jun 2017 11:51:59 +0200 Subject: [PATCH 110/111] Fix async job stopping --- ftplugin/purescript_pscide.vim | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 7d79514..9ed1036 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -94,7 +94,6 @@ function! PSCIDEstart(silent) endfunction function! s:onServerExit(ch, msg, ev) - call s:log("purs ide server exited: " . string(ev), 0) let s:pscidestarted = 0 endfunction @@ -149,8 +148,7 @@ function! PSCIDEend() \ { "on_exit": {job, status, ev -> s:PSCIDEendCallback() } \ , "on_stderr": {err -> s:log("PSCIDEend error: " . string(err), 0)} \ }) - call async#job#send(jobid, json_encode({'command': 'quit'})) - call async#job#stop(jobid) + call async#job#send(jobid, json_encode({'command': 'quit'}) . "\n") endfunction function! s:PSCIDEendCallback() @@ -922,7 +920,7 @@ function! s:callPscIde(input, errorm, isRetry, cb) \ { "on_stdout": {ch, msg -> s:PscIdeStartCallback(a:input, a:errorm, a:cb, cwdcommand, msg)} \ , "on_stderr": {ch, err -> s:log("s:callPscIde error: " . string(err), 3)} \ }) - call async#job#stop(jobid) + call async#job#send(jobid, json_encode(cwdcommand) . "\n") return endif @@ -933,12 +931,12 @@ function! s:callPscIde(input, errorm, isRetry, cb) \ { "on_stdout": {ch, msg -> a:cb(s:PscIdeCallback(a:input, a:errorm, a:isRetry, a:cb, msg))} \ , "on_stderr": {ch, err -> s:log("s:callPscIde error: " . string(err), 0)} \ }) - call async#job#send(jobid, enc ."\n") - " call async#job#stop(jobid) + call async#job#send(jobid, enc . "\n") + " call async#job#stop(jobid) " Not needed I think, \n stops job endfunction function! s:callPscIdeSync(input, errorm, isRetry) - call s:log("callPscIde: start: Executing command: " . string(a:input), 3) + call s:log("callPscIdeSync: start: Executing command: " . string(a:input), 3) if s:projectvalid == 0 call PSCIDEprojectValidate() @@ -1003,14 +1001,20 @@ function! s:PscIdeStartCallback(input, errorm, cb, cwdcommand, cwdresp) \ { "on_stdout": { ch, resp -> s:PscIdeRetryCallback(a:input, a:errorm, a:cb, expectedCWD, resp) } \ , "on_stderr": { ch, err -> s:log("s:PscIdeStartCallback error: " . err, 3) } \ }) - call async#job#send(jobid, json_encode(a:cwdcommand)) - call async#job#stop(jobid) + call async#job#send(jobid, json_encode(a:cwdcommand) . "\n") endfunction function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) - call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . a:cwdresp2, 1) + call s:log("s:PscIdeRetryCallback: Raw response of trying to reach server again: " . string(a:cwdresp2), 1) + + if (type(a:cwdresp2) == type([])) + let json = a:cwdresp2[0] + else + let json = a:cwdresp2 + endif + try - let cwdresp2Decoded = json_decode(a:cwdresp2) + let cwdresp2Decoded = json_decode(json) catch /.*/ let cwdresp2Decoded = {"resultType": "failed", "error": a:cwdresp2} endtry @@ -1049,8 +1053,7 @@ function! s:PscIdeRetryCallback(input, errorm, cb, expectedCWD, cwdresp2) \ { "on_stdout": {ch, resp -> a:cb(s:PscIdeCallback(a:input, a:errorm, 1, a:cb, resp))} \ , "on_stderr": {ch, err -> s:log("s:PscIdeRetryCallback error: " . err, 3)} \ }) - call async#job#send(jobid, enc) - call async#job#stop(jobid) + call async#job#send(jobid, enc . "\n") endfunction function! s:PscIdeCallback(input, errorm, isRetry, cb, resp) From adff8fbdc510e3b5fa8439ebf6a96783df340d9f Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 9 Jun 2017 18:00:49 +0200 Subject: [PATCH 111/111] remove PSCIDEremoveImporQualifications (merge issue) --- ftplugin/purescript_pscide.vim | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ftplugin/purescript_pscide.vim b/ftplugin/purescript_pscide.vim index 2298845..00b0e7e 100644 --- a/ftplugin/purescript_pscide.vim +++ b/ftplugin/purescript_pscide.vim @@ -117,7 +117,6 @@ com! -buffer -nargs=1 PSCIDEcaseSplit call PSCIDEcaseSplit() com! -buffer -nargs=* PSCIDEtype call PSCIDEtype(len() ? : expand(""), v:true) com! PSCIDElistImports call PSCIDElistImports() com! -buffer -bang PSCIDEapplySuggestion call PSCIDEapplySuggestion() -com! -buffer PSCIDEremoveImportQualifications call PSCIDEremoveImportQualifications() com! -buffer PSCIDEaddImportQualifications call PSCIDEaddImportQualifications() com! -buffer -nargs=* PSCIDEpursuit call PSCIDEpursuit(len() ? : expand("")) com! -buffer PSCIDEprojectValidate call PSCIDEprojectValidate() @@ -849,15 +848,6 @@ fun! s:updateSuggestions(startLine, newLines) return suggestions endfun -" Remove all import qualifications -function! PSCIDEremoveImportQualifications() - let captureregex = "import\\s\\(\\S\\+\\)\\s*(.*)" - let replace = "import \\1" - let command = "silent %s:" . captureregex . ":" . replace . ":g|norm!``" - call s:log('Executing PSCIDEremoveImportQualifications command: ' . command, 3) - exe command -endfunction - " Add all import qualifications function! PSCIDEaddImportQualifications() let foundLines = []