Last active
September 12, 2017 02:12
-
-
Save ssilva/930d188bd30a985a47199683390ec400 to your computer and use it in GitHub Desktop.
msgpack neovim c client proof of concept
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
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/socket.h> | |
#include <msgpack.h> | |
/* | |
* $ NVIM_LISTEN_ADDRESS=127.0.0.1:8888 nvim | |
* | |
*/ | |
void unpack_stream(msgpack_sbuffer *sbuf) | |
{ | |
msgpack_unpacker unpacker; | |
msgpack_unpacker_init(&unpacker, MSGPACK_UNPACKER_INIT_BUFFER_SIZE); | |
// Feed the unpacked with data | |
msgpack_unpacker_reserve_buffer(&unpacker, sbuf->size); | |
memcpy(msgpack_unpacker_buffer(&unpacker), sbuf->data, sbuf->size); | |
msgpack_unpacker_buffer_consumed(&unpacker, sbuf->size); | |
msgpack_unpacked result; | |
msgpack_unpacked_init(&result); | |
while (msgpack_unpacker_next(&unpacker, &result)) { | |
msgpack_object_print(stdout, result.data); | |
puts(""); | |
} | |
} | |
void unpack(msgpack_sbuffer *sbuf) | |
{ | |
msgpack_zone mempool; | |
msgpack_zone_init(&mempool, 2048); | |
msgpack_object deserialized; | |
msgpack_unpack(sbuf->data, sbuf->size, NULL, &mempool, &deserialized); | |
msgpack_object_print(stdout, deserialized); | |
puts(""); | |
msgpack_zone_destroy(&mempool); | |
} | |
void prepare(msgpack_sbuffer *sbuf) | |
{ | |
msgpack_packer packer; | |
msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write); | |
// [0, id, 0, "method", ["param1", "param2"]] | |
msgpack_pack_array(&packer, 4); | |
msgpack_pack_int(&packer, 0); | |
msgpack_pack_int(&packer, 82); | |
char method[] = "vim_command"; | |
msgpack_pack_str(&packer, sizeof(method) - 1); | |
msgpack_pack_str_body(&packer, method, sizeof(method) - 1); | |
msgpack_pack_array(&packer, 1); | |
char param[] = "echo \"hello world\""; | |
msgpack_pack_str(&packer, sizeof(param) - 1); | |
msgpack_pack_str_body(&packer, param, sizeof(param) - 1); | |
} | |
int connect_nvim(unsigned int port) | |
{ | |
int sfd = socket(AF_INET, SOCK_STREAM, 0); | |
if (sfd == -1) { | |
fprintf(stderr, "Error opening socket\n"); | |
return -1; | |
} | |
struct sockaddr_in addr; | |
addr.sin_port = htons(port); | |
addr.sin_addr.s_addr = 0; | |
addr.sin_addr.s_addr = INADDR_ANY; | |
addr.sin_family = AF_INET; | |
if (connect(sfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { | |
fprintf(stderr, "Error connecting to socket\n"); | |
return -1; | |
} | |
return sfd; | |
} | |
int main(int argc, char **argv) | |
{ | |
// FIXME Do not hard-code the port | |
//char *nvim_listen_addr = getenv("NVIM_LISTEN_ADDRESS"); | |
//if (nvim_listen_addr) | |
// printf("Detected env var: %s\n", nvim_listen_addr); | |
int sfd = connect_nvim(8888); | |
msgpack_sbuffer sbuf; | |
msgpack_sbuffer_init(&sbuf); | |
prepare(&sbuf); | |
printf("About to send: "); | |
unpack(&sbuf); | |
if (write(sfd, sbuf.data, sbuf.size) == -1) { | |
fprintf(stderr, "Error sending data\n"); | |
return 1; | |
} | |
if (read(sfd, sbuf.data, sbuf.size) == -1) { | |
fprintf(stderr, "Error receiving data\n"); | |
return 1; | |
} | |
close(sfd); | |
printf("Received: "); | |
unpack(&sbuf); | |
msgpack_sbuffer_destroy(&sbuf); | |
return 0; | |
} |
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
TARGET=nvim-c-client | |
CC=gcc | |
DEBUG=-g | |
OPT=-O0 | |
WARN=-Wall | |
PTHREAD=-pthread | |
CCFLAGS=$(DEBUG) $(OPT) $(WARN) $(PTHREAD) -pipe | |
MSGPACKLIB=`pkg-config --cflags --libs msgpack` | |
LD=gcc | |
#LDFLAGS=$(PTHREAD) $(MSGPACKLIB) -export-dynamic | |
LDFLAGS=$(MSGPACKLIB) | |
OBJS=main.o | |
all: $(OBJS) | |
$(LD) -o $(TARGET) $(OBJS) $(LDFLAGS) | |
main.o: src/main.c | |
$(CC) -c $(CCFLAGS) src/main.c $(MSGPACKLIB) -o main.o | |
clean: | |
rm -f *.o $(TARGET) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment