summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/type-formatting.lua27
-rw-r--r--script/parser/guide.lua2
-rw-r--r--script/provider/capability.lua4
-rw-r--r--script/provider/provider.lua39
-rw-r--r--test.lua1
-rw-r--r--test/type_formatting/init.lua30
6 files changed, 102 insertions, 1 deletions
diff --git a/script/core/type-formatting.lua b/script/core/type-formatting.lua
new file mode 100644
index 00000000..9b2dfe64
--- /dev/null
+++ b/script/core/type-formatting.lua
@@ -0,0 +1,27 @@
+local files = require 'files'
+
+local function checkEndAfterNL(results, uri, offset, ch)
+ if ch ~= '\n' then
+ return
+ end
+ local text = files.getText(uri)
+ results[#results+1] = {
+ start = #text,
+ finish = #text,
+ text = '\n',
+ }
+end
+
+return function (uri, offset, ch)
+ local ast = files.getAst(uri)
+ local text = files.getText(uri)
+ if not ast or not text then
+ return nil
+ end
+
+ local results = {}
+ -- add `end` after `\n`
+ checkEndAfterNL(results, uri, offset, ch)
+
+ return results
+end
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index cf525104..4ce241c7 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -644,7 +644,7 @@ function m.positionOf(lines, offset)
end
local lastLine = lines[#lines]
if offset > lastLine.finish then
- return #lines, lastLine.finish - lastLine.start + 1
+ return #lines, offset - lastLine.start
end
local min = 1
local max = #lines
diff --git a/script/provider/capability.lua b/script/provider/capability.lua
index a6195ebb..08b4779a 100644
--- a/script/provider/capability.lua
+++ b/script/provider/capability.lua
@@ -82,6 +82,10 @@ function m.getIniter()
},
},
foldingRangeProvider = true,
+ documentOnTypeFormattingProvider = {
+ firstTriggerCharacter = '\n',
+ moreTriggerCharacter = nil, -- string[]
+ },
workspace = {}
--documentOnTypeFormattingProvider = {
-- firstTriggerCharacter = '}',
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index f7579881..fa2b8874 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -825,6 +825,45 @@ proto.on('$/status/click', function ()
end
end)
+proto.on('textDocument/onTypeFormatting', function (params)
+ workspace.awaitReady()
+ local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5)
+ local ch = params.ch
+ local uri = params.textDocument.uri
+ if not files.exists(uri) then
+ return nil
+ end
+ local core = require 'core.type-formatting'
+ local offset = files.offset(uri, params.position)
+ local edits = core(uri, offset, ch)
+ if #edits == 0 then
+ return nil
+ end
+ local results = {}
+ for i, edit in ipairs(edits) do
+ results[i] = {
+ range = files.range(uri, edit.start, edit.finish),
+ newText = edit.text,
+ }
+ end
+ results = {
+ {
+ range = {
+ ['start'] = {
+ line = 1,
+ character = 5,
+ },
+ ['end'] = {
+ line = 1,
+ character = 5,
+ },
+ },
+ newText = '\nend',
+ }
+ }
+ return results
+end)
+
-- Hint
do
local function updateHint(uri)
diff --git a/test.lua b/test.lua
index bab770ac..cc11d2b4 100644
--- a/test.lua
+++ b/test.lua
@@ -73,6 +73,7 @@ local function main()
test 'signature'
test 'document_symbol'
test 'code_action'
+ test 'type_formatting'
test 'crossfile'
test 'full'
--test 'other'
diff --git a/test/type_formatting/init.lua b/test/type_formatting/init.lua
new file mode 100644
index 00000000..c7ef20ad
--- /dev/null
+++ b/test/type_formatting/init.lua
@@ -0,0 +1,30 @@
+local core = require 'core.type-formatting'
+local files = require 'files'
+local util = require 'utility'
+
+rawset(_G, 'TEST', true)
+
+function TEST(script)
+ return function (expect)
+ local pos = script:find('$', 1, true) - 1
+ local new_script = script:gsub('%$', '')
+ files.removeAll()
+ files.setText('', new_script)
+ local edits = core('', pos, expect.ch)
+ if edits then
+ assert(expect.edits)
+ assert(util.equal(edits, expect.edits))
+ else
+ assert(expect.edits == nil)
+ end
+ end
+end
+do return end
+TEST [[
+if true then$
+]]
+{
+ ch = '\n',
+ {
+ }
+}