Last active
July 17, 2024 03:12
-
-
Save thacuber2a03/7285effd7ad6cec17e24a70fd30be467 to your computer and use it in GitHub Desktop.
the nothing language server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- NOTE: to TC of the future | |
-- if you attempt to make an actual language server, *please* read the specification | |
-- https://microsoft.github.io/language-server-protocol/specifications/specification-current | |
-- here's a sample server so you can read along too, in case you ever forget how it's done | |
-- | |
-- NOTE: for everyone else | |
-- the nothing language server: a (really buggy) language server that does nothing | |
-- this thing is public domain (we're talking https://unlicense.org/) | |
-- | |
-- NOTE: for both | |
-- it doesn't use sockets, it uses standard I/O | |
-- go look up sockets somewhere else fool | |
-- (I don't know sockets either) | |
-- you'll have to use https://github.com/rxi/json.lua for this one, | |
-- but any json library with a "decode" and "encode" methods will suffice | |
local json = require 'json' | |
-- shorthand for sending a table back | |
local function send(t) | |
t.jsonrpc = '2.0' | |
local out = json.encode(t) | |
-- output the header, and then the content | |
-- https://microsoft.github.io/language-server-protocol/specifications/specification-current#headerPart | |
io.stdout:write('Content-Length: ', #out) | |
io.stdout:write('\r\n\r\n', out, '\n') | |
end | |
-- these are the most important streams in this program | |
-- so it just makes sense to disable buffering on them | |
io.stdin:setvbuf 'no' | |
io.stdout:setvbuf 'no' | |
local intialized = false | |
-- all requests sent by the client that runs this server | |
-- will be logged in this file, might be helpful for actual lsp development | |
local requestsSent = assert(io.open('requests.txt', 'w+b')) | |
while true do | |
local input = io.read() | |
if input then | |
-- this is *not* a good way to parse the header. | |
-- please just parse it properly. | |
local len = tonumber(assert(input:match 'Content%-Length: (%d+)')) | |
if input:match 'Content%-Type: .-' then input = io.read() end | |
input = io.read() -- obligatory empty line | |
input = io.read(len) | |
requestsSent:write(input, '\n') | |
local request = json.decode(input) | |
if not intialized then | |
-- https://microsoft.github.io/language-server-protocol/specifications/specification-current#initialize | |
if request.method == 'exit' then | |
requestsSent:close() | |
os.exit(-1) | |
elseif request.method == 'initialize' then | |
send { id = request.id, method = 'initialized' } | |
else | |
-- spoiler: -32002 means uninitalized server | |
send { id = request.id, code = -32002 } | |
end | |
else | |
-- do nothing | |
-- yeah, mindblowing | |
end | |
end | |
-- do *not* yield using this. | |
-- I'm pretty sure it will either completely | |
-- freeze both the server and the client, or | |
-- cause something else to happen, but it's | |
-- probably not good, I have not tried it | |
-- and nor will I | |
os.execute 'sleep 1' | |
end | |
-- now you'll have to go on from here, good luck and hope you arrive at your destination sane :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment