From f86b0aa1e843646056c08a91fcc759aa0d8a57ba Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 8 Sep 2023 19:16:37 -0400 Subject: better LSP over TCP --- keywords.h | 9 +++++---- keywords.py | 2 +- lsp-write.c | 16 ++++++++++++---- lsp.c | 15 +++++++++++++-- main.c | 6 ++---- os-posix.c | 13 ++++++++++--- os.h | 6 ++++++ ted.cfg | 2 +- 8 files changed, 50 insertions(+), 19 deletions(-) diff --git a/keywords.h b/keywords.h index 116a65d..0dadb6d 100644 --- a/keywords.h +++ b/keywords.h @@ -433,7 +433,7 @@ static const Keyword syntax_keywords_gdscript_V[135] = {{"VBoxContainer", SYNTAX static const Keyword syntax_keywords_gdscript_W[16] = {{"WeakRef", SYNTAX_BUILTIN},{"WebRTCDataChannel", SYNTAX_BUILTIN},{"WebRTCDataChannelExtension", SYNTAX_BUILTIN},{"WebRTCMultiplayerPeer", SYNTAX_BUILTIN},{"WebRTCPeerConnection", SYNTAX_BUILTIN},{"WebRTCPeerConnectionExtension", SYNTAX_BUILTIN},{"WebSocketMultiplayerPeer", SYNTAX_BUILTIN},{"WebSocketPeer", SYNTAX_BUILTIN},{"WebXRInterface", SYNTAX_BUILTIN},{"Window", SYNTAX_BUILTIN},{"WorkerThreadPool", SYNTAX_BUILTIN},{"World2D", SYNTAX_BUILTIN},{"World3D", SYNTAX_BUILTIN},{"WorldBoundaryShape2D", SYNTAX_BUILTIN},{"WorldBoundaryShape3D", SYNTAX_BUILTIN},{"WorldEnvironment", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_X[12] = {{"X509Certificate", SYNTAX_BUILTIN},{"XMLParser", SYNTAX_BUILTIN},{"XRAnchor3D", SYNTAX_BUILTIN},{"XRCamera3D", SYNTAX_BUILTIN},{"XRController3D", SYNTAX_BUILTIN},{"XRInterface", SYNTAX_BUILTIN},{"XRInterfaceExtension", SYNTAX_BUILTIN},{"XRNode3D", SYNTAX_BUILTIN},{"XROrigin3D", SYNTAX_BUILTIN},{"XRPose", SYNTAX_BUILTIN},{"XRPositionalTracker", SYNTAX_BUILTIN},{"XRServer", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_Z[2] = {{"ZIPPacker", SYNTAX_BUILTIN},{"ZIPReader", SYNTAX_BUILTIN}}; -static const Keyword syntax_keywords_gdscript_a[10] = {{"abs", SYNTAX_BUILTIN},{"absf", SYNTAX_BUILTIN},{"absi", SYNTAX_BUILTIN},{"acos", SYNTAX_BUILTIN},{"as", SYNTAX_KEYWORD},{"asin", SYNTAX_BUILTIN},{"assert", SYNTAX_KEYWORD},{"atan", SYNTAX_BUILTIN},{"atan2", SYNTAX_BUILTIN},{"await", SYNTAX_KEYWORD}}; +static const Keyword syntax_keywords_gdscript_a[11] = {{"abs", SYNTAX_BUILTIN},{"absf", SYNTAX_BUILTIN},{"absi", SYNTAX_BUILTIN},{"acos", SYNTAX_BUILTIN},{"and", SYNTAX_KEYWORD},{"as", SYNTAX_KEYWORD},{"asin", SYNTAX_BUILTIN},{"assert", SYNTAX_KEYWORD},{"atan", SYNTAX_BUILTIN},{"atan2", SYNTAX_BUILTIN},{"await", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_gdscript_b[7] = {{"bezier_derivative", SYNTAX_BUILTIN},{"bezier_interpolate", SYNTAX_BUILTIN},{"bool", SYNTAX_BUILTIN},{"break", SYNTAX_KEYWORD},{"breakpoint", SYNTAX_KEYWORD},{"bytes_to_var", SYNTAX_BUILTIN},{"bytes_to_var_with_objects", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_c[16] = {{"ceil", SYNTAX_BUILTIN},{"ceilf", SYNTAX_BUILTIN},{"ceili", SYNTAX_BUILTIN},{"clamp", SYNTAX_BUILTIN},{"clampf", SYNTAX_BUILTIN},{"clampi", SYNTAX_BUILTIN},{"class", SYNTAX_KEYWORD},{"class_name", SYNTAX_KEYWORD},{"const", SYNTAX_KEYWORD},{"continue", SYNTAX_KEYWORD},{"cos", SYNTAX_BUILTIN},{"cosh", SYNTAX_BUILTIN},{"cubic_interpolate", SYNTAX_BUILTIN},{"cubic_interpolate_angle", SYNTAX_BUILTIN},{"cubic_interpolate_angle_in_time", SYNTAX_BUILTIN},{"cubic_interpolate_in_time", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_d[2] = {{"db_to_linear", SYNTAX_BUILTIN},{"deg_to_rad", SYNTAX_BUILTIN}}; @@ -443,16 +443,17 @@ static const Keyword syntax_keywords_gdscript_h[1] = {{"hash", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_i[14] = {{"if", SYNTAX_KEYWORD},{"in", SYNTAX_KEYWORD},{"instance_from_id", SYNTAX_BUILTIN},{"int", SYNTAX_BUILTIN},{"inverse_lerp", SYNTAX_BUILTIN},{"is", SYNTAX_KEYWORD},{"is_equal_approx", SYNTAX_BUILTIN},{"is_finite", SYNTAX_BUILTIN},{"is_inf", SYNTAX_BUILTIN},{"is_instance_id_valid", SYNTAX_BUILTIN},{"is_instance_valid", SYNTAX_BUILTIN},{"is_nan", SYNTAX_BUILTIN},{"is_same", SYNTAX_BUILTIN},{"is_zero_approx", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_l[5] = {{"lerp", SYNTAX_BUILTIN},{"lerp_angle", SYNTAX_BUILTIN},{"lerpf", SYNTAX_BUILTIN},{"linear_to_db", SYNTAX_BUILTIN},{"log", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_m[8] = {{"match", SYNTAX_KEYWORD},{"max", SYNTAX_BUILTIN},{"maxf", SYNTAX_BUILTIN},{"maxi", SYNTAX_BUILTIN},{"min", SYNTAX_BUILTIN},{"minf", SYNTAX_BUILTIN},{"mini", SYNTAX_BUILTIN},{"move_toward", SYNTAX_BUILTIN}}; -static const Keyword syntax_keywords_gdscript_n[2] = {{"nearest_po2", SYNTAX_BUILTIN},{"null", SYNTAX_CONSTANT}}; +static const Keyword syntax_keywords_gdscript_n[3] = {{"nearest_po2", SYNTAX_BUILTIN},{"not", SYNTAX_KEYWORD},{"null", SYNTAX_CONSTANT}}; +static const Keyword syntax_keywords_gdscript_o[1] = {{"or", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_gdscript_p[14] = {{"pass", SYNTAX_KEYWORD},{"pingpong", SYNTAX_BUILTIN},{"posmod", SYNTAX_BUILTIN},{"pow", SYNTAX_BUILTIN},{"preload", SYNTAX_KEYWORD},{"print", SYNTAX_BUILTIN},{"print_rich", SYNTAX_BUILTIN},{"print_verbose", SYNTAX_BUILTIN},{"printerr", SYNTAX_BUILTIN},{"printraw", SYNTAX_BUILTIN},{"prints", SYNTAX_BUILTIN},{"printt", SYNTAX_BUILTIN},{"push_error", SYNTAX_BUILTIN},{"push_warning", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_r[15] = {{"rad_to_deg", SYNTAX_BUILTIN},{"rand_from_seed", SYNTAX_BUILTIN},{"randf", SYNTAX_BUILTIN},{"randf_range", SYNTAX_BUILTIN},{"randfn", SYNTAX_BUILTIN},{"randi", SYNTAX_BUILTIN},{"randi_range", SYNTAX_BUILTIN},{"randomize", SYNTAX_BUILTIN},{"remap", SYNTAX_BUILTIN},{"return", SYNTAX_KEYWORD},{"rid_allocate_id", SYNTAX_BUILTIN},{"rid_from_int64", SYNTAX_BUILTIN},{"round", SYNTAX_BUILTIN},{"roundf", SYNTAX_BUILTIN},{"roundi", SYNTAX_BUILTIN}}; -static const Keyword syntax_keywords_gdscript_s[17] = {{"seed", SYNTAX_BUILTIN},{"self", SYNTAX_KEYWORD},{"sign", SYNTAX_BUILTIN},{"signal", SYNTAX_KEYWORD},{"signf", SYNTAX_BUILTIN},{"signi", SYNTAX_BUILTIN},{"sin", SYNTAX_BUILTIN},{"sinh", SYNTAX_BUILTIN},{"smoothstep", SYNTAX_BUILTIN},{"snapped", SYNTAX_BUILTIN},{"snappedf", SYNTAX_BUILTIN},{"snappedi", SYNTAX_BUILTIN},{"sqrt", SYNTAX_BUILTIN},{"static", SYNTAX_KEYWORD},{"step_decimals", SYNTAX_BUILTIN},{"str", SYNTAX_BUILTIN},{"str_to_var", SYNTAX_BUILTIN}}; +static const Keyword syntax_keywords_gdscript_s[18] = {{"seed", SYNTAX_BUILTIN},{"self", SYNTAX_KEYWORD},{"sign", SYNTAX_BUILTIN},{"signal", SYNTAX_KEYWORD},{"signf", SYNTAX_BUILTIN},{"signi", SYNTAX_BUILTIN},{"sin", SYNTAX_BUILTIN},{"sinh", SYNTAX_BUILTIN},{"smoothstep", SYNTAX_BUILTIN},{"snapped", SYNTAX_BUILTIN},{"snappedf", SYNTAX_BUILTIN},{"snappedi", SYNTAX_BUILTIN},{"sqrt", SYNTAX_BUILTIN},{"static", SYNTAX_KEYWORD},{"step_decimals", SYNTAX_BUILTIN},{"str", SYNTAX_BUILTIN},{"str_to_var", SYNTAX_BUILTIN},{"super", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_gdscript_t[4] = {{"tan", SYNTAX_BUILTIN},{"tanh", SYNTAX_BUILTIN},{"true", SYNTAX_CONSTANT},{"typeof", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_v[5] = {{"var", SYNTAX_KEYWORD},{"var_to_bytes", SYNTAX_BUILTIN},{"var_to_bytes_with_objects", SYNTAX_BUILTIN},{"var_to_str", SYNTAX_BUILTIN},{"void", SYNTAX_KEYWORD}}; static const Keyword syntax_keywords_gdscript_w[5] = {{"weakref", SYNTAX_BUILTIN},{"while", SYNTAX_KEYWORD},{"wrap", SYNTAX_BUILTIN},{"wrapf", SYNTAX_BUILTIN},{"wrapi", SYNTAX_BUILTIN}}; static const Keyword syntax_keywords_gdscript_y[1] = {{"yield", SYNTAX_KEYWORD}}; static const KeywordList syntax_all_keywords_gdscript[128] = { - ['A'] = {syntax_keywords_gdscript_A, arr_count(syntax_keywords_gdscript_A)}, ['B'] = {syntax_keywords_gdscript_B, arr_count(syntax_keywords_gdscript_B)}, ['C'] = {syntax_keywords_gdscript_C, arr_count(syntax_keywords_gdscript_C)}, ['D'] = {syntax_keywords_gdscript_D, arr_count(syntax_keywords_gdscript_D)}, ['E'] = {syntax_keywords_gdscript_E, arr_count(syntax_keywords_gdscript_E)}, ['F'] = {syntax_keywords_gdscript_F, arr_count(syntax_keywords_gdscript_F)}, ['G'] = {syntax_keywords_gdscript_G, arr_count(syntax_keywords_gdscript_G)}, ['H'] = {syntax_keywords_gdscript_H, arr_count(syntax_keywords_gdscript_H)}, ['I'] = {syntax_keywords_gdscript_I, arr_count(syntax_keywords_gdscript_I)}, ['J'] = {syntax_keywords_gdscript_J, arr_count(syntax_keywords_gdscript_J)}, ['K'] = {syntax_keywords_gdscript_K, arr_count(syntax_keywords_gdscript_K)}, ['L'] = {syntax_keywords_gdscript_L, arr_count(syntax_keywords_gdscript_L)}, ['M'] = {syntax_keywords_gdscript_M, arr_count(syntax_keywords_gdscript_M)}, ['N'] = {syntax_keywords_gdscript_N, arr_count(syntax_keywords_gdscript_N)}, ['O'] = {syntax_keywords_gdscript_O, arr_count(syntax_keywords_gdscript_O)}, ['P'] = {syntax_keywords_gdscript_P, arr_count(syntax_keywords_gdscript_P)}, ['Q'] = {syntax_keywords_gdscript_Q, arr_count(syntax_keywords_gdscript_Q)}, ['R'] = {syntax_keywords_gdscript_R, arr_count(syntax_keywords_gdscript_R)}, ['S'] = {syntax_keywords_gdscript_S, arr_count(syntax_keywords_gdscript_S)}, ['T'] = {syntax_keywords_gdscript_T, arr_count(syntax_keywords_gdscript_T)}, ['U'] = {syntax_keywords_gdscript_U, arr_count(syntax_keywords_gdscript_U)}, ['V'] = {syntax_keywords_gdscript_V, arr_count(syntax_keywords_gdscript_V)}, ['W'] = {syntax_keywords_gdscript_W, arr_count(syntax_keywords_gdscript_W)}, ['X'] = {syntax_keywords_gdscript_X, arr_count(syntax_keywords_gdscript_X)}, ['Z'] = {syntax_keywords_gdscript_Z, arr_count(syntax_keywords_gdscript_Z)}, ['a'] = {syntax_keywords_gdscript_a, arr_count(syntax_keywords_gdscript_a)}, ['b'] = {syntax_keywords_gdscript_b, arr_count(syntax_keywords_gdscript_b)}, ['c'] = {syntax_keywords_gdscript_c, arr_count(syntax_keywords_gdscript_c)}, ['d'] = {syntax_keywords_gdscript_d, arr_count(syntax_keywords_gdscript_d)}, ['e'] = {syntax_keywords_gdscript_e, arr_count(syntax_keywords_gdscript_e)}, ['f'] = {syntax_keywords_gdscript_f, arr_count(syntax_keywords_gdscript_f)}, ['h'] = {syntax_keywords_gdscript_h, arr_count(syntax_keywords_gdscript_h)}, ['i'] = {syntax_keywords_gdscript_i, arr_count(syntax_keywords_gdscript_i)}, ['l'] = {syntax_keywords_gdscript_l, arr_count(syntax_keywords_gdscript_l)}, ['m'] = {syntax_keywords_gdscript_m, arr_count(syntax_keywords_gdscript_m)}, ['n'] = {syntax_keywords_gdscript_n, arr_count(syntax_keywords_gdscript_n)}, ['p'] = {syntax_keywords_gdscript_p, arr_count(syntax_keywords_gdscript_p)}, ['r'] = {syntax_keywords_gdscript_r, arr_count(syntax_keywords_gdscript_r)}, ['s'] = {syntax_keywords_gdscript_s, arr_count(syntax_keywords_gdscript_s)}, ['t'] = {syntax_keywords_gdscript_t, arr_count(syntax_keywords_gdscript_t)}, ['v'] = {syntax_keywords_gdscript_v, arr_count(syntax_keywords_gdscript_v)}, ['w'] = {syntax_keywords_gdscript_w, arr_count(syntax_keywords_gdscript_w)}, ['y'] = {syntax_keywords_gdscript_y, arr_count(syntax_keywords_gdscript_y)} + ['A'] = {syntax_keywords_gdscript_A, arr_count(syntax_keywords_gdscript_A)}, ['B'] = {syntax_keywords_gdscript_B, arr_count(syntax_keywords_gdscript_B)}, ['C'] = {syntax_keywords_gdscript_C, arr_count(syntax_keywords_gdscript_C)}, ['D'] = {syntax_keywords_gdscript_D, arr_count(syntax_keywords_gdscript_D)}, ['E'] = {syntax_keywords_gdscript_E, arr_count(syntax_keywords_gdscript_E)}, ['F'] = {syntax_keywords_gdscript_F, arr_count(syntax_keywords_gdscript_F)}, ['G'] = {syntax_keywords_gdscript_G, arr_count(syntax_keywords_gdscript_G)}, ['H'] = {syntax_keywords_gdscript_H, arr_count(syntax_keywords_gdscript_H)}, ['I'] = {syntax_keywords_gdscript_I, arr_count(syntax_keywords_gdscript_I)}, ['J'] = {syntax_keywords_gdscript_J, arr_count(syntax_keywords_gdscript_J)}, ['K'] = {syntax_keywords_gdscript_K, arr_count(syntax_keywords_gdscript_K)}, ['L'] = {syntax_keywords_gdscript_L, arr_count(syntax_keywords_gdscript_L)}, ['M'] = {syntax_keywords_gdscript_M, arr_count(syntax_keywords_gdscript_M)}, ['N'] = {syntax_keywords_gdscript_N, arr_count(syntax_keywords_gdscript_N)}, ['O'] = {syntax_keywords_gdscript_O, arr_count(syntax_keywords_gdscript_O)}, ['P'] = {syntax_keywords_gdscript_P, arr_count(syntax_keywords_gdscript_P)}, ['Q'] = {syntax_keywords_gdscript_Q, arr_count(syntax_keywords_gdscript_Q)}, ['R'] = {syntax_keywords_gdscript_R, arr_count(syntax_keywords_gdscript_R)}, ['S'] = {syntax_keywords_gdscript_S, arr_count(syntax_keywords_gdscript_S)}, ['T'] = {syntax_keywords_gdscript_T, arr_count(syntax_keywords_gdscript_T)}, ['U'] = {syntax_keywords_gdscript_U, arr_count(syntax_keywords_gdscript_U)}, ['V'] = {syntax_keywords_gdscript_V, arr_count(syntax_keywords_gdscript_V)}, ['W'] = {syntax_keywords_gdscript_W, arr_count(syntax_keywords_gdscript_W)}, ['X'] = {syntax_keywords_gdscript_X, arr_count(syntax_keywords_gdscript_X)}, ['Z'] = {syntax_keywords_gdscript_Z, arr_count(syntax_keywords_gdscript_Z)}, ['a'] = {syntax_keywords_gdscript_a, arr_count(syntax_keywords_gdscript_a)}, ['b'] = {syntax_keywords_gdscript_b, arr_count(syntax_keywords_gdscript_b)}, ['c'] = {syntax_keywords_gdscript_c, arr_count(syntax_keywords_gdscript_c)}, ['d'] = {syntax_keywords_gdscript_d, arr_count(syntax_keywords_gdscript_d)}, ['e'] = {syntax_keywords_gdscript_e, arr_count(syntax_keywords_gdscript_e)}, ['f'] = {syntax_keywords_gdscript_f, arr_count(syntax_keywords_gdscript_f)}, ['h'] = {syntax_keywords_gdscript_h, arr_count(syntax_keywords_gdscript_h)}, ['i'] = {syntax_keywords_gdscript_i, arr_count(syntax_keywords_gdscript_i)}, ['l'] = {syntax_keywords_gdscript_l, arr_count(syntax_keywords_gdscript_l)}, ['m'] = {syntax_keywords_gdscript_m, arr_count(syntax_keywords_gdscript_m)}, ['n'] = {syntax_keywords_gdscript_n, arr_count(syntax_keywords_gdscript_n)}, ['o'] = {syntax_keywords_gdscript_o, arr_count(syntax_keywords_gdscript_o)}, ['p'] = {syntax_keywords_gdscript_p, arr_count(syntax_keywords_gdscript_p)}, ['r'] = {syntax_keywords_gdscript_r, arr_count(syntax_keywords_gdscript_r)}, ['s'] = {syntax_keywords_gdscript_s, arr_count(syntax_keywords_gdscript_s)}, ['t'] = {syntax_keywords_gdscript_t, arr_count(syntax_keywords_gdscript_t)}, ['v'] = {syntax_keywords_gdscript_v, arr_count(syntax_keywords_gdscript_v)}, ['w'] = {syntax_keywords_gdscript_w, arr_count(syntax_keywords_gdscript_w)}, ['y'] = {syntax_keywords_gdscript_y, arr_count(syntax_keywords_gdscript_y)} }; static const Keyword syntax_keywords_comment_B[1] = {{"BUG", SYNTAX_TODO}}; diff --git a/keywords.py b/keywords.py index 1a0f831..eaf3918 100755 --- a/keywords.py +++ b/keywords.py @@ -614,7 +614,7 @@ keywords_gdscript = [ 'if', 'elif', 'else', 'for', 'while', 'match', 'break', 'continue', 'pass', 'return', 'class', 'class_name', 'extends', 'is', 'in', 'as', 'self', 'signal', 'func', 'static', 'const', 'enum', 'var', 'breakpoint', - 'preload', 'await', 'yield', 'assert', 'void', + 'preload', 'await', 'yield', 'assert', 'void', 'not', 'and', 'or', 'super', ] builtins_gdscript = [ diff --git a/lsp-write.c b/lsp-write.c index 9722a7b..17aef7f 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -334,10 +334,18 @@ static void message_writer_write_and_free(LSP *lsp, JSONWriter *o) { fprintf(lsp->log, "LSP MESSAGE FROM CLIENT TO SERVER\n%s\n\n", content + header_size); } - if (lsp->socket) - socket_write(lsp->socket, content, strlen(content)); - else - process_write(lsp->process, content, strlen(content)); + long long bytes_written = lsp->socket + ? socket_write(lsp->socket, content, strlen(content)) + : process_write(lsp->process, content, strlen(content)); + + if (bytes_written == -1) { + // we'll handle this properly next time we do a read. + if (lsp->log) fprintf(lsp->log, "LSP server closed connection unexpectedly\n"); + } else if (bytes_written < 0) { + if (lsp->log) fprintf(lsp->log, "Error writing to LSP server (errno = %d)\n", errno); + } else { + assert((size_t)bytes_written == strlen(content)); + } str_builder_free(&builder); } diff --git a/lsp.c b/lsp.c index 113091b..9d98b8c 100644 --- a/lsp.c +++ b/lsp.c @@ -400,10 +400,21 @@ static bool lsp_receive(LSP *lsp, size_t max_size) { long long bytes_read = lsp->socket ? socket_read(lsp->socket, lsp->received_data + received_so_far, max_size) : process_read(lsp->process, lsp->received_data + received_so_far, max_size); - if (bytes_read <= 0) { + + if (bytes_read == -1) { // no data return true; } + if (bytes_read == 0) { + lsp_set_error(lsp, "LSP server closed connection unexpectedly."); + return false; + } + if (bytes_read < 0) { + if (lsp->log) + fprintf(lsp->log, "Error reading from server (errno = %d).\n", errno); + return true; + } + received_so_far += (size_t)bytes_read; // kind of a hack. this is needed because arr_set_len zeroes the data. arr_hdr_(lsp->received_data)->len = (u32)received_so_far; @@ -704,7 +715,7 @@ void lsp_free(LSP *lsp) { SDL_DestroyMutex(lsp->error_mutex); SDL_DestroySemaphore(lsp->quit_sem); process_kill(&lsp->process); - + socket_close(&lsp->socket); arr_free(lsp->received_data); str_hash_table_clear(&lsp->document_ids); diff --git a/main.c b/main.c index c070760..acbeaa2 100644 --- a/main.c +++ b/main.c @@ -1,10 +1,8 @@ /* TODO: -- highlight not, super in godot (where do those appear in the godot docs?) -- what's goin wrong with godot (test other servers over TCP) - - check for server stops running over TCP -- automatically restart server +- figure out what's wrong with godot language server - LSP textDocument/formatting and textDocument/rangeFormatting +- automatically restart server FUTURE FEATURES: - autodetect indentation (tabs vs spaces) - custom file/build command associations diff --git a/os-posix.c b/os-posix.c index 0c408a5..34a7f7b 100644 --- a/os-posix.c +++ b/os-posix.c @@ -456,9 +456,8 @@ Socket *socket_connect_tcp(const char *address, u16 port) { } if (connect(fd, &addr, sizeof addr) < 0) { - strbuf_printf(s->error, "couldn't connect to %u.%u.%u.%u:%u (%s)", - address[0], address[1], address[2], address[3], port, - strerror(errno)); + strbuf_printf(s->error, "couldn't connect to %s:%u (%s)", + address, port, strerror(errno)); } set_nonblocking(fd); @@ -487,3 +486,11 @@ long long socket_write(Socket *s, const char *data, size_t size) { } return write_fd(s->fd, s->error, sizeof s->error, data, size); } + +void socket_close(Socket **psocket) { + Socket *s = *psocket; + if (!s) return; + if (s->fd > 0) + close(s->fd); + *psocket = NULL; +} diff --git a/os.h b/os.h index a937b40..bb52d63 100644 --- a/os.h +++ b/os.h @@ -188,6 +188,12 @@ long long socket_read(Socket *socket, char *data, size_t size); /// -1 if the read end of the socket was closed\n /// or a non-negative number indicating the number of bytes written. long long socket_write(Socket *socket, const char *data, size_t size); +/// close socket +/// +/// if `*psocket` is `NULL`, this does nothing. +/// +/// sets `*psocket` to `NULL`. +void socket_close(Socket **psocket); #endif // OS_H_ diff --git a/ted.cfg b/ted.cfg index b7a06dd..6b9aaf7 100644 --- a/ted.cfg +++ b/ted.cfg @@ -60,7 +60,7 @@ phantom-completions = on # and such will open them. document-links = on # enable LSP support (for autocompletion, etc.) -# you can also set `lsp = ""` but this is a quick way to disable LSP servers for all langauges +# this is a quick way to disable LSP servers for all langauges lsp-enabled = yes # enable this to log all messages between ted and the LSP server # (may require restarting ted to update) -- cgit v1.2.3