summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-09-09 22:14:25 -0400
committerpommicket <pommicket@gmail.com>2023-09-09 22:14:25 -0400
commitc9c4b74376017b52a024705622c42d7d35c5bda0 (patch)
treeb6f4b504a2d2adcd47151d3bd88c0b8147140801
parent16fbe87451b0ca3e8fa35fd04e0afbfab368ea65 (diff)
start incremental sync support
-rw-r--r--lsp-parse.c29
-rw-r--r--lsp.c15
-rw-r--r--lsp.h8
-rw-r--r--main.c1
4 files changed, 46 insertions, 7 deletions
diff --git a/lsp-parse.c b/lsp-parse.c
index e941f1a..ff243fb 100644
--- a/lsp-parse.c
+++ b/lsp-parse.c
@@ -151,6 +151,35 @@ static uint32_t *parse_trigger_characters(const JSON *json, JSONArray trigger_ch
static void parse_capabilities(LSP *lsp, const JSON *json, JSONObject capabilities) {
LSPCapabilities *cap = &lsp->capabilities;
+ {
+ // document syncing capabilities
+ JSONValue sync_value = json_object_get(json, capabilities, "textDocumentSync");
+ double change_type_double = sync_value.type == JSON_NUMBER
+ ? sync_value.val.number
+ : json_object_get_number(json, json_force_object(sync_value), "change");
+ int change_type = isfinite(change_type_double)
+ && change_type_double >= 0
+ && change_type_double <= 2
+ ? (int)change_type_double
+ : 0;
+ bool open_close = true;
+ if (sync_value.type == JSON_NUMBER) {
+ // nothing to do.
+ // i think. it's unclear whether we're supposed to send didOpen/didClose
+ // with this type (it's deprecated, so the spec isn't giving us any information)
+ } else if (sync_value.type == JSON_OBJECT) {
+ JSONObject sync = sync_value.val.object;
+ open_close = json_object_get_bool(json, sync, "openClose", false);
+ if (!open_close) {
+ // we're not even allowed to send didChange without a didOpen first,
+ // so this should always be zero? spec is really unclear here.
+ change_type = 0;
+ }
+ }
+ cap->open_close_support = open_close;
+ cap->sync_support = change_type >= 1;
+ cap->incremental_sync_support = change_type == 2;
+ }
// check CompletionOptions
JSONValue completion_value = json_object_get(json, capabilities, "completionProvider");
diff --git a/lsp.c b/lsp.c
index e8cb630..025e2be 100644
--- a/lsp.c
+++ b/lsp.c
@@ -227,12 +227,14 @@ static bool lsp_supports_request(LSP *lsp, const LSPRequest *request) {
case LSP_REQUEST_WORKSPACE_FOLDERS:
case LSP_REQUEST_PUBLISH_DIAGNOSTICS:
return false;
- case LSP_REQUEST_INITIALIZE:
- case LSP_REQUEST_INITIALIZED:
- case LSP_REQUEST_CANCEL:
case LSP_REQUEST_DID_OPEN:
case LSP_REQUEST_DID_CLOSE:
+ return cap->open_close_support;
case LSP_REQUEST_DID_CHANGE:
+ return cap->sync_support;
+ case LSP_REQUEST_INITIALIZE:
+ case LSP_REQUEST_INITIALIZED:
+ case LSP_REQUEST_CANCEL:
case LSP_REQUEST_CONFIGURATION:
case LSP_REQUEST_SHUTDOWN:
case LSP_REQUEST_EXIT:
@@ -436,8 +438,11 @@ static bool lsp_receive(LSP *lsp, size_t max_size) {
// kind of a hack. this is needed because arr_set_len zeroes the data.
arr_hdr_(lsp->received_data)->len = (u32)received_so_far;
lsp->received_data[received_so_far] = '\0';// null terminate
- #if LSP_SHOW_S2C
- printf("%s%s%s\n",term_italics(stdout),lsp->received_data,term_clear(stdout));
+ #if 0
+ const int limit = 1000;
+ printf("%s%.*s%s%s\n",term_italics(stdout),limit,lsp->received_data,
+ strlen(lsp->received_data) > (size_t)limit ? "..." : "",
+ term_clear(stdout));
#endif
u64 response_offset=0, response_size=0;
diff --git a/lsp.h b/lsp.h
index 395f5ee..27f2706 100644
--- a/lsp.h
+++ b/lsp.h
@@ -588,6 +588,12 @@ typedef struct {
} LSPDocumentData;
typedef struct {
+ /// send didChange?
+ bool sync_support;
+ /// can didChange notifications have partial changes?
+ bool incremental_sync_support;
+ /// send didOpen/didClose?
+ bool open_close_support;
bool signature_help_support;
bool completion_support;
bool hover_support;
@@ -866,7 +872,7 @@ void lsp_write_quit(void);
/// print server-to-client communication
#define LSP_SHOW_S2C 0
/// print client-to-server communication
-#define LSP_SHOW_C2S 1
+#define LSP_SHOW_C2S 0
#endif // LSP_INTERNAL
diff --git a/main.c b/main.c
index 7506c08..d1569f7 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,6 @@
/*
TODO:
- figure out what's wrong with godot language server
-- automatically restart server
FUTURE FEATURES:
- autodetect indentation (tabs vs spaces)
- custom file/build command associations