summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ds.c14
-rw-r--r--json.c5
-rw-r--r--lsp-write-request.c30
-rw-r--r--main.c1
4 files changed, 39 insertions, 11 deletions
diff --git a/ds.c b/ds.c
index ef4a1b4..eb235d6 100644
--- a/ds.c
+++ b/ds.c
@@ -297,7 +297,6 @@ void str_builder_append(StrBuilder *builder, const char *s) {
size_t prev_len = prev_size - 1; // null terminator
// note: this zeroes the newly created elements, so we have a new null terminator
arr_set_len(builder->str, prev_size + s_len);
- // -1 for null terminator
memcpy(builder->str + prev_len, s, s_len);
}
@@ -331,3 +330,16 @@ u32 str_builder_len(StrBuilder *builder) {
return arr_len(builder->str) - 1;
}
+char *str_builder_get_ptr(StrBuilder *builder, size_t index) {
+ assert(index <= str_builder_len(builder));
+ return &builder->str[index];
+}
+
+void str_builder_shrink(StrBuilder *builder, size_t new_len) {
+ if (new_len > str_builder_len(builder)) {
+ assert(0);
+ return;
+ }
+ arr_set_len(builder->str, new_len + 1);
+}
+
diff --git a/json.c b/json.c
index 5d83b89..c11d907 100644
--- a/json.c
+++ b/json.c
@@ -605,7 +605,9 @@ void json_debug_print(const JSON *json) {
// e.g. converts "Hello\nworld" to "Hello\\nworld"
// if out_sz is at least 2 * strlen(str) + 1, the string will fit.
-void json_escape_to(char *out, size_t out_sz, const char *in) {
+// returns the number of bytes actually written, not including the null terminator.
+size_t json_escape_to(char *out, size_t out_sz, const char *in) {
+ char *start = out;
char *end = out + out_sz;
assert(out_sz);
@@ -653,6 +655,7 @@ void json_escape_to(char *out, size_t out_sz, const char *in) {
}
brk:
*out = '\0';
+ return (size_t)(out - start);
}
// e.g. converts "Hello\nworld" to "Hello\\nworld"
diff --git a/lsp-write-request.c b/lsp-write-request.c
index e5d671d..f375559 100644
--- a/lsp-write-request.c
+++ b/lsp-write-request.c
@@ -74,11 +74,23 @@ static void write_arr_elem(JSONWriter *o) {
}
}
-static void write_string(JSONWriter *o, const char* string) {
- // @TODO: escape in-place
- char *escaped = json_escape(string);
- str_builder_appendf(&o->builder, "\"%s\"", escaped);
- free(escaped);
+static void write_escaped(JSONWriter *o, const char *string) {
+ StrBuilder *b = &o->builder;
+ size_t output_index = str_builder_len(b);
+ size_t capacity = 2 * strlen(string) + 1;
+ // append a bunch of null bytes which will hold the escaped string
+ str_builder_append_null(b, capacity);
+ char *out = str_builder_get_ptr(b, output_index);
+ // do the escaping
+ size_t length = json_escape_to(out, capacity, string);
+ // shrink down to just the escaped text
+ str_builder_shrink(&o->builder, output_index + length);
+}
+
+static void write_string(JSONWriter *o, const char *string) {
+ str_builder_append(&o->builder, "\"");
+ write_escaped(o, string);
+ str_builder_append(&o->builder, "\"");
}
static void write_key(JSONWriter *o, const char *key) {
@@ -121,10 +133,10 @@ static void write_key_string(JSONWriter *o, const char *key, const char *s) {
}
static void write_file_uri(JSONWriter *o, DocumentID document) {
- // @OPTIM : could store escaped document paths instead of document paths
- char *escaped_path = json_escape(o->lsp->document_paths[document]);
- str_builder_appendf(&o->builder, "\"file:///%s\"", escaped_path);
- free(escaped_path);
+ const char *path = o->lsp->document_paths[document];
+ str_builder_append(&o->builder, "\"file:///");
+ write_escaped(o, path);
+ str_builder_append(&o->builder, "\"");
}
static void write_key_file_uri(JSONWriter *o, const char *key, DocumentID document) {
diff --git a/main.c b/main.c
index f0321ee..df88311 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
/*
@TODO:
- send didClose
+- don't select the one and only completion when user types stuff
- LSP setting
- scroll through completions
- figure out under which circumstances backspace should close completions