Skip to content

Commit

Permalink
Remove libuv timer dependency (#11)
Browse files Browse the repository at this point in the history
* Remove libuv timer dependency
  • Loading branch information
someone-stole-my-name committed Jun 25, 2022
1 parent 1b6aea2 commit ab42ea6
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 69 deletions.
123 changes: 72 additions & 51 deletions lua/yaml-companion/context/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,67 +9,88 @@ M.default_schema = function()
end

M.ctxs = {}
M.initialized_client_ids = {}

M.setup = function(bufnr, client)
local timer = vim.loop.new_timer()
M.store_initialized_handler = function(_, _, ctx, _)
local client_id = ctx.client_id
M.initialized_client_ids[client_id] = true

local client = vim.lsp.get_client_by_id(client_id)
local buffers = vim.lsp.get_buffers_by_client_id(client_id)

-- The store for this client_id has been initialized, we must check
-- all existing buffers and update then accordingly.
for _, bufnr in ipairs(buffers) do
if M.ctxs[bufnr] and M.ctxs[bufnr].executed == false then
M.autodiscover(bufnr, client)
end
end
end

M.autodiscover = function(bufnr, client)
if not M.initialized_client_ids[client.id] then
return
end

local schema = lsp.get_jsonschema(bufnr, client)
local options = require("yaml-companion.config").options

if schema and schema.result and schema.result[1] and schema.result[1].uri then
-- if LSP returns a name that means it came from SchemaStore
-- and we can use it right away
if schema.result[1].name then
M.ctxs[bufnr].schema = schema
M.ctxs[bufnr].executed = true

-- if it returned something without a name it means it came from our own
-- internal schema table and we have to loop through it to get the name
else
for _, option_schema in ipairs(options.schemas.result) do
if option_schema.uri == schema.result[1].uri then
M.ctxs[bufnr].schema = {
result = {
{ name = option_schema.name, uri = option_schema.uri },
},
}
M.ctxs[bufnr].executed = true
end
end
end

-- if LSP is not using any schema, use registered matchers
else
for _, matcher in pairs(matchers) do
local result = matcher.match(bufnr)
if result then
M.schema(bufnr, {
result = {
{ name = result.name, uri = result.uri },
},
})
M.ctxs[bufnr].executed = true
end
end
end

-- No schema matched
M.ctxs[bufnr].executed = true
end

M.setup = function(bufnr, client)
local state = {
bufnr = bufnr,
client = client,
schema = default_schema,
timer = timer,
executed = false,
}

-- This timer runs periodically until
-- it updates the context state for the buffer
timer:start(
1000,
1000,
vim.schedule_wrap(function()
-- if we get an schema from the LSP
local schema = lsp.get_jsonschema(bufnr)
local options = require("yaml-companion.config").options

if schema and schema.result and schema.result[1] and schema.result[1].uri then
-- if LSP returns a name that means it came from SchemaStore
-- and we can use it right away
if schema.result[1].name then
M.ctxs[bufnr].schema = schema
timer:close()

-- if it returned something without a name it means it came from our own
-- internal schema table and we have to loop through it to get the name
else
for _, option_schema in ipairs(options.schemas.result) do
if option_schema.uri == schema.result[1].uri then
M.ctxs[bufnr].schema = {
result = {
{ name = option_schema.name, uri = option_schema.uri },
},
}
timer:close()
end
end
end
M.ctxs[bufnr] = state

-- if LSP is not using any schema, use registered matchers
else
for _, matcher in pairs(matchers) do
local result = matcher.match(bufnr)
if result then
M.schema(bufnr, {
result = {
{ name = result.name, uri = result.uri },
},
})
timer:close()
end
end
end
end)
)
-- The first time this won't work because the client is not initialized yet
-- but it will be called once per client from the initialized_handler when it is.
M.autodiscover(bufnr, client)

M.ctxs[bufnr] = state
return lsp.support_schema_selection(bufnr, client)
end

M.schema = function(bufnr, schema)
Expand Down
1 change: 1 addition & 0 deletions lua/yaml-companion/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ M.setup = function(opts)
config.setup(opts, function(client, bufnr)
ctx.setup(bufnr, client)
end)
vim.lsp.handlers["yaml/schema/store/initialized"] = ctx.store_initialized_handler
return config.options.lspconfig
end

Expand Down
33 changes: 29 additions & 4 deletions lua/yaml-companion/lsp/requests.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
local M = {}

local lsp = vim.lsp
local sync_timeout = 1000

-- let the yamlls attached to {bufnr} know that we support
-- schema selection and it should fire a 'yaml/schema/store/initialized'
-- when ready to use it
---@param bufnr number
---@return table
M.support_schema_selection = function(bufnr, client)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
client = client or lsp.get_active_clients({ name = "yamlls", bufnr = bufnr })[1]

if client then
return client.notify("yaml/supportSchemaSelection")
end
end

-- get all known schemas by the yamlls attached to {bufnr}
---@param bufnr number
---@return table
M.get_all_jsonschemas = function(bufnr)
local client = require("yaml-companion.lsp.util").client(bufnr)
M.get_all_jsonschemas = function(bufnr, client)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
client = client or lsp.get_active_clients({ name = "yamlls", bufnr = bufnr })[1]

if client then
return client.request_sync(
"yaml/get/all/jsonSchemas",
Expand All @@ -20,8 +41,12 @@ end
-- get schemas used for {bufnr} by the yamlls attached to it
---@param bufnr number
---@return table
M.get_jsonschema = function(bufnr)
local client = require("yaml-companion.lsp.util").client(bufnr)
M.get_jsonschema = function(bufnr, client)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
client = client or lsp.get_active_clients({ name = "yamlls", bufnr = bufnr })[1]

if client then
local schemas = client.request_sync(
"yaml/get/jsonSchema",
Expand Down
17 changes: 3 additions & 14 deletions lua/yaml-companion/lsp/util.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
local M = {}

local nvim_lsp = vim.lsp
local yaml_lsp = require("yaml-companion.lsp.requests")
local lsp = require("yaml-companion.lsp.requests")
local matchers = require("yaml-companion._matchers")._loaded

-- returns the yamlls client attached to {bufnr} if it has an active yamlls attached
M.client = function(bufnr)
local clients = nvim_lsp.buf_get_clients(bufnr)
for _, value in pairs(clients) do
if value.name == "yamlls" then
return value
end
end
end

--- Get all of the yaml schemas currently available to the server.
--- @return table schemas: merged list of user-defined and server-provided yaml schemas
--- @return table schemas: merged list of user-defined, server-provided, and matcher-provided yaml schemas
M.get_all_yaml_schemas = function()
local schemas = yaml_lsp.get_all_jsonschemas(0)
local schemas = lsp.get_all_jsonschemas(0)

if schemas == nil then
return
Expand Down

0 comments on commit ab42ea6

Please sign in to comment.