diff options
author | Kevin Hahn <hahn.kev@gmail.com> | 2022-07-23 21:17:30 +0700 |
---|---|---|
committer | Kevin Hahn <hahn.kev@gmail.com> | 2022-07-23 21:19:50 +0700 |
commit | eecbfae0e6d846f20bc836b5ee8a706501b2db40 (patch) | |
tree | 907352ecd34a65dc7b55553f8b502ce1501e7e8a | |
parent | be85f2c855f9075cadae3219f4dc1f3ce1f920ca (diff) | |
download | lua-language-server-eecbfae0e6d846f20bc836b5ee8a706501b2db40.zip |
add color support
-rw-r--r-- | script/core/color.lua | 77 | ||||
-rw-r--r-- | script/provider/provider.lua | 34 |
2 files changed, 111 insertions, 0 deletions
diff --git a/script/core/color.lua b/script/core/color.lua new file mode 100644 index 00000000..f5c792a3 --- /dev/null +++ b/script/core/color.lua @@ -0,0 +1,77 @@ +local files = require "files" +local guide = require "parser.guide" + +local colorPattern = string.rep('%x', 8) +---@param source parser.object +---@return boolean +local function isColor(source) + ---@type string + local text = source[1] + if text:len() ~= 8 then + return false + end + return text:match(colorPattern) +end + + +---@param colorText string +---@return Color +local function textToColor(colorText) + return { + alpha = tonumber(colorText:sub(1, 2), 16) / 255, + red = tonumber(colorText:sub(3, 4), 16) / 255, + green = tonumber(colorText:sub(5, 6), 16) / 255, + blue = tonumber(colorText:sub(7, 8), 16) / 255, + } +end + + +---@param color Color +---@return string +local function colorToText(color) + return ('' + .. string.format('%02x', math.tointeger(color.alpha * 255)) + .. string.format('%02x', math.tointeger(color.red * 255)) + .. string.format('%02x', math.tointeger(color.green * 255)) + .. string.format('%02x', math.tointeger(color.blue * 255))):upper() +end + +---@class Color +---@field red number +---@field green number +---@field blue number +---@field alpha number + +---@class ColorValue +---@field color Color +---@field start integer +---@field finish integer + +---@async +function colors(uri) + local state = files.getState(uri) + local text = files.getText(uri) + if not state or not text then + return nil + end + ---@type ColorValue[] + local colors = {} + + guide.eachSource(state.ast, function (source) ---@async + if source.type == 'string' and isColor(source) then + ---@type string + local colorText = source[1] + + colors[#colors+1] = { + start = source.start + 1, + finish = source.finish - 1, + color = textToColor(colorText) + } + end + end) + return colors +end +return { + colors = colors, + colorToText = colorToText +} diff --git a/script/provider/provider.lua b/script/provider/provider.lua index 1af5ea82..239a39d7 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -1021,6 +1021,40 @@ m.register 'textDocument/foldingRange' { end } +m.register 'textDocument/documentColor' { + capability = { + colorProvider = true + }, + ---@async + function (params) + local color = require 'core.color' + local uri = files.getRealUri(params.textDocument.uri) + workspace.awaitReady(uri) + if not files.exists(uri) then + return nil + end + local colors = color.colors(uri) + if not colors then + return nil + end + local results = {} + for _, colorValue in ipairs(colors) do + results[#results+1] = { + range = converter.packRange(uri, colorValue.start, colorValue.finish), + color = colorValue.color + } + end + return results + end +} + +m.register 'textDocument/colorPresentation' { + function (params) + local color = (require 'core.color').colorToText(params.color) + return {{label = color}} + end +} + m.register 'window/workDoneProgress/cancel' { function (params) log.debug('close proto(cancel):', params.token) |