summaryrefslogtreecommitdiff
path: root/server/src/core/completion.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/core/completion.lua')
-rw-r--r--server/src/core/completion.lua83
1 files changed, 72 insertions, 11 deletions
diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua
index 4a487441..d0da95cd 100644
--- a/server/src/core/completion.lua
+++ b/server/src/core/completion.lua
@@ -397,6 +397,14 @@ local function searchEmmyKeyword(vm, source, word, callback)
end
end
+local function searchEmmyClass(vm, source, word, callback)
+ vm.emmyMgr:eachClass(function (class)
+ if matchKey(word, class:getName()) then
+ callback(class:getName(), class:getSource(), CompletionItemKind.Class)
+ end
+ end)
+end
+
local function searchSource(vm, source, word, callback)
if source.type == 'keyword' then
searchAsKeyowrd(vm, source, word, callback)
@@ -430,6 +438,9 @@ local function searchSource(vm, source, word, callback)
searchEmmyKeyword(vm, source, word, callback)
return
end
+ if source:get 'target class' then
+ searchEmmyClass(vm, source, word, callback)
+ end
end
local function searchInRequire(vm, select, source, callback)
@@ -650,11 +661,9 @@ local function makeList(source, pos, word)
end, list
end
-local function searchToclose(text, word, callback, pos)
- if #word > 0 then
- pos = pos - 1
- end
- if text:sub(pos, pos) ~= '*' then
+local function searchToclose(text, source, word, callback)
+ local pos = source.start
+ if text:sub(pos-1, pos-1) ~= '*' then
return false
end
if not matchKey(word, 'toclose') then
@@ -685,7 +694,62 @@ local function keywordSource(vm, word, pos)
}
end
-return function (vm, text, pos, word, oldText)
+local function findStartPos(pos, buf)
+ local res = nil
+ for i = pos, 1, -1 do
+ local c = buf:sub(i, i)
+ if c:find '[%w_]' then
+ res = i
+ else
+ break
+ end
+ end
+ if not res then
+ for i = pos, 1, -1 do
+ local c = buf:sub(i, i)
+ if c == '.' or c == ':' or c == '|' then
+ res = i
+ break
+ elseif c == '#' or c == '@' then
+ res = i + 1
+ break
+ elseif c:find '[%s%c]' then
+ else
+ break
+ end
+ end
+ end
+ if not res then
+ return pos
+ end
+ return res
+end
+
+local function findWord(position, text)
+ local word = text
+ for i = position, 1, -1 do
+ local c = text:sub(i, i)
+ if not c:find '[%w_]' then
+ word = text:sub(i+1, position)
+ break
+ end
+ end
+ return word:match('^([%w_]*)')
+end
+
+local function getSource(vm, pos, text, filter)
+ local word = findWord(pos, text)
+ local source = findSource(vm, pos, filter)
+ if source then
+ return source, pos, word
+ end
+ pos = findStartPos(pos, text)
+ source = findSource(vm, pos, filter)
+ or keywordSource(vm, word, pos)
+ return source, pos, word
+end
+
+return function (vm, text, pos, oldText)
local filter = {
['name'] = true,
['string'] = true,
@@ -695,10 +759,7 @@ return function (vm, text, pos, word, oldText)
['emmyIncomplete'] = true,
['call'] = true,
}
- local source = findSource(vm, pos, filter)
- or findSource(vm, pos-1, filter)
- or findSource(vm, pos+1, filter)
- or keywordSource(vm, word, pos)
+ local source, pos, word = getSource(vm, pos, text, filter)
if not source then
return nil
end
@@ -709,7 +770,7 @@ return function (vm, text, pos, word, oldText)
end
end
local callback, list = makeList(source, pos, word)
- if searchToclose(text, word, callback, pos) then
+ if searchToclose(text, source, word, callback) then
return list
end
searchSpecial(vm, source, word, callback, pos)