diff --git a/lua-lsp/analyze.lua b/lua-lsp/analyze.lua index 0d3a37b..ef15ffd 100644 --- a/lua-lsp/analyze.lua +++ b/lua-lsp/analyze.lua @@ -12,7 +12,7 @@ local TOPLEVEL = {} --- turn a luacomplete type into a lsp value local function translate_luacomplete(into, data) local function visit_field(key, value, scope) - local Id = {tag = "Id", key, pos=0, posEnd=0, canGoto = false} + local Id = {tag = "Id", key, pos=0, posEnd=0, file = "__NONE__"} if value.type == "table" then local fields if key == TOPLEVEL then @@ -79,7 +79,7 @@ local FILE_SCOPE = 2 local function gen_scopes(len, ast, uri) if not Globals then -- FIXME: we need to teach the rest of the system that it's okay for a - -- scope to not have positions + -- scopes to not have positions Globals = setmetatable({},{ id=GLOBAL_SCOPE, pos=0, posEnd=math.huge, origin="global" }) @@ -479,7 +479,7 @@ local function gen_scopes(len, ast, uri) end end elseif node.tag == "Comment" then - log("found comment <%d, %d>", node.pos, node.posEnd) + log.debug("found comment <%d, %d>", node.pos, node.posEnd) end end diff --git a/lua-lsp/formatting.lua b/lua-lsp/formatting.lua index 9f67399..3a9cb85 100644 --- a/lua-lsp/formatting.lua +++ b/lua-lsp/formatting.lua @@ -18,8 +18,8 @@ end -- https://github.com/martin-eden/lua_code_formatter drivers['lcf.workshop.base'] = function() -- luacheck: globals request - local get_ast = request('!lua.code.get_ast') - local get_formatted_code = request('!lua.code.ast_as_code') + local get_ast = request('!.lua.code.get_ast') + local get_formatted_code = request('!.lua.code.ast_as_code') return { format = function(text, opts) return get_formatted_code(get_ast(text), { @@ -42,7 +42,7 @@ local noDriver = { for mod, driver in pairs(drivers) do local ok, m_or_err = pcall(require, mod) if ok then - return m_or_err + return driver(m_or_err) end end diff --git a/lua-lsp/log.lua b/lua-lsp/log.lua index 15f1221..e856f06 100644 --- a/lua-lsp/log.lua +++ b/lua-lsp/log.lua @@ -136,6 +136,7 @@ function log.debug(...) --}) end end +log.d = log.debug setmetatable(log, { __call = function(_, ...) diff --git a/lua-lsp/loop.lua b/lua-lsp/loop.lua index 5d06c9e..fd03877 100644 --- a/lua-lsp/loop.lua +++ b/lua-lsp/loop.lua @@ -25,6 +25,7 @@ local function reload_all() package.loaded[name] = nil end end + log.verbose("===========================") method_handlers = require 'lua-lsp.methods' end diff --git a/lua-lsp/methods.lua b/lua-lsp/methods.lua index db1355d..d0faa3b 100644 --- a/lua-lsp/methods.lua +++ b/lua-lsp/methods.lua @@ -378,7 +378,7 @@ local function getp(doc, t, k, isDefinition) -- luacheck: ignore 542 local pair = t and t[k] if not pair then - log("no pair for %q in %_", k, t) + log.debug("no pair for %q in %_", k, t) return nil end local key, value = unpack(pair) @@ -528,7 +528,7 @@ method_handlers["textDocument/completion"] = function(params, id) local line, char, pos = line_for(document, params.position) local word = line.text:sub(1, char-1):match("[A-Za-z_][%w_.:]*$") if not word then - log("%q: %_", line.text:sub(1, char-1), word) + log.debug("%q: %_", line.text:sub(1, char-1), word) end local items = {} @@ -540,7 +540,7 @@ method_handlers["textDocument/completion"] = function(params, id) items = {} }) end - log("looking for %q in scope id %d", word, getmetatable(scope).id) + log.debug("looking for %q in scope id %d", word, getmetatable(scope).id) if word:find("[:.]") then local path_ids, _ = split_path(word) @@ -551,7 +551,7 @@ method_handlers["textDocument/completion"] = function(params, id) local last = ii == #path_ids if last then local is_method = not not word:find(":") - log("Is method? %_", is_method) + log.debug("Is method? %_", is_method) for iname, _, val in iter_scope(_scope) do if type(iname) == "string" and iname:sub(1, _iword:len()) == _iword then @@ -602,25 +602,28 @@ method_handlers["textDocument/definition"] = function(params, id) local _, word_e = line.text:sub(char, -1):find("[%w_]*") word_e = word_e + char - 1 local word = line.text:sub(word_s, word_e) - log("definition for %q", word) + log.debug("definition for %q", word) local symbol, _, doc2 = definition_of(params.textDocument, params.position) - if not symbol or symbol.canGoto == false then + if not symbol or symbol.file == "__NONE__" then -- symbol not found - log("Symbol not found: %q", word) + log.warning("Symbol not found: %q", word) + if symbol then + log.warning("did find: %t", symbol) + end return rpc.respond(id, json.null) end local doc = document if doc ~= doc2 then - log("defined in external file %q", doc2.uri) + log.debug("defined in external file %q", doc2.uri) end local sub = doc2.text:sub(symbol.pos, symbol.posEnd) local word_end = word:match("([^.:]+)$") local a, b = string.find(sub, word_end, 1, true) - log("find %q in %q", word_end, sub) + log.debug("find %q in %q", word_end, sub) if not a then error(("failed to find %q in %q\nword from %q") :format(word_end, sub, doc2.uri)) @@ -645,7 +648,7 @@ method_handlers["textDocument/hover"] = function(params, id) local _, word_e = line.text:sub(char, -1):find("[%w_]*") word_e = word_e + char - 1 local word = line.text:sub(word_s, word_e) - log("hover for %q", word) + log.debug("hover for %q", word) local symbol, value = definition_of(params.textDocument, params.position) if symbol then @@ -677,11 +680,11 @@ method_handlers["textDocument/documentSymbol"] = function(params, id) -- FIXME: report table keys too, like a.b.c -- also consider making a linear list of symbols we can just iterate -- through - for i=2, #document.scopes do + for i=1, #document.scopes do local scope = document.scopes[i] for _, pair in pairs(scope) do local symbol, _ = unpack(pair) - if symbol.canGoto ~= false then + if symbol.file ~= "__NONE__" then table.insert(symbols, { name = symbol[1], kind = 13, @@ -704,7 +707,7 @@ method_handlers["textDocument/formatting"] = function(params, id) local format = require 'lua-lsp.formatting' local new = format.format(doc.text, { indent = indent, - maxChars = 80, + maxChars = 120, }) rpc.respond(id, { @@ -741,7 +744,7 @@ end method_handlers["workspace/didChangeConfiguration"] = function(params) assert(params.settings) merge_(Config, params.settings) - log("Config loaded, new config: %t", Config) + log.info("Config loaded, new config: %t", Config) end function method_handlers.shutdown(_, id) diff --git a/spec/definition_spec.lua b/spec/definition_spec.lua index 8fc815f..1f7d733 100644 --- a/spec/definition_spec.lua +++ b/spec/definition_spec.lua @@ -1,4 +1,9 @@ local mock_loop = require 'spec.mock_loop' + +local function not_empty(t) + assert.not_same({}, t) +end + describe("textDocument/didOpen", function() it("triggers", function() mock_loop(function(rpc, s_rpc) @@ -64,7 +69,7 @@ describe("textDocument/definition", function() end) end) - it("handles multiple symbols", function() + it("handles multiple symbols #tmp", function() mock_loop(function(rpc) local text = "local jack\nlocal diane\n return jack, diane\n" local doc = { @@ -77,6 +82,7 @@ describe("textDocument/definition", function() textDocument = doc, position = {line = 2, character = 8} -- jack }, function(out) + not_empty(out) assert.same({line=0, character=6}, out.range.start) end) @@ -84,6 +90,7 @@ describe("textDocument/definition", function() textDocument = doc, position = {line = 2, character = 14} -- diane }, function(out) + not_empty(out) assert.same({line=1, character=6}, out.range.start) end) end) @@ -106,6 +113,7 @@ describe("textDocument/definition", function() textDocument = doc, position = {line = 3, character = 8} -- jackv2 }, function(out) + not_empty(out) assert.same({line=2, character=6}, out.range.start) end) @@ -113,6 +121,7 @@ describe("textDocument/definition", function() textDocument = doc, position = {line = 1, character = 0} -- jackv1 }, function(out) + not_empty(out) assert.same({line=0, character=6}, out.range.start) end) end) @@ -135,6 +144,7 @@ return jack.diane + jack.jill textDocument = doc, position = {line=2, character=12} -- jack.diane }, function(out) + not_empty(out) assert.same({line=0, character=15}, out.range.start) end) @@ -142,6 +152,7 @@ return jack.diane + jack.jill textDocument = doc, position = {line = 2, character = 25} -- jack.jill }, function(out) + not_empty(out) assert.same({line=1, character=5}, out.range.start) end) end) @@ -166,6 +177,7 @@ return jack.diane() + jack.jill() + jack:little_ditty() textDocument = doc, position = {line=3, character=12} -- jack.diane }, function(out) + not_empty(out) assert.same({line=0, character=15}, out.range.start) end) @@ -180,6 +192,7 @@ return jack.diane() + jack.jill() + jack:little_ditty() textDocument = doc, position = {line=3, character=41} -- jack:little_ditty }, function(out) + not_empty(out) assert.same({line=2, character=14}, out.range.start) end) end) @@ -200,6 +213,7 @@ return jack.diane() + jack.jill() + jack:little_ditty() textDocument = doc, position = {line = 1, character = 8} -- jackv2 }, function(out) + not_empty(out) assert.same({line=0, character=13}, out.range.start) end) end) @@ -219,6 +233,7 @@ return jack.diane() + jack.jill() + jack:little_ditty() textDocument = doc, position = {line = 1, character = 8} -- jackv2 }, function(out) + not_empty(out) assert.same({line=0, character=7}, out.range.start) end) end) @@ -245,6 +260,7 @@ return jack.diane() + jack.jill() + jack:little_ditty() textDocument = doc, position = {line = 2, character = 8} -- jackv2 }, function(out) + not_empty(out) assert.same({line=0, character=6}, out.range.start) end) end) diff --git a/spec/format_spec.lua b/spec/format_spec.lua index 30b26f9..a956fa6 100644 --- a/spec/format_spec.lua +++ b/spec/format_spec.lua @@ -1,6 +1,12 @@ local mock_loop = require 'spec.mock_loop' local fmt = require 'lua-lsp.formatting' +local match = string.match +local function trim(s) + return match(s,'^()%s*$') and '' or match(s,'^%s*(.*%S)') +end + + describe("textDocument/formatting", function() if fmt.driver == "noop" then pending("can't run: No formatter installed", function() end) @@ -45,6 +51,10 @@ end start={line=0, character=0}, ["end"]={line=6, character=3} }, out.range) + -- LCF does not do a final empty line, so trim to get rid of + -- the difference + formatted = trim(formatted) + out.newText = trim(out.newText) assert.same(formatted, out.newText) callme = true end) diff --git a/spec/symbols_spec.lua b/spec/symbols_spec.lua index 222855c..a5e0e76 100644 --- a/spec/symbols_spec.lua +++ b/spec/symbols_spec.lua @@ -76,6 +76,7 @@ describe("textDocument/documentSymbol", function() rpc.request("textDocument/documentSymbol", { textDocument = doc, }, function(out) + assert.not_same({}, out) local set = {} for _, o in ipairs(out) do set[o.name] = o.kind end assert.same({