mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge PR #1060 'Implement --embedded-mode command-line option'
This commit is contained in:
commit
e0d812ab64
@ -10,10 +10,23 @@ git clone --depth=1 -b master git://github.com/neovim/python-client
|
|||||||
cd python-client
|
cd python-client
|
||||||
sudo pip install .
|
sudo pip install .
|
||||||
sudo pip install nose
|
sudo pip install nose
|
||||||
test_cmd="nosetests --verbosity=2"
|
# We run the tests twice:
|
||||||
|
# - First by connecting with an nvim instance spawned by "expect"
|
||||||
|
# - Second by starting nvim in embedded mode through the python client
|
||||||
|
# This is required until nvim is mature enough to always run in embedded mode
|
||||||
|
test_cmd="nosetests --verbosity=2 --nologcapture"
|
||||||
nvim_cmd="valgrind -q --track-origins=yes --leak-check=yes --suppressions=$suppressions --log-file=$tmpdir/valgrind-%p.log ../build/bin/nvim -u NONE"
|
nvim_cmd="valgrind -q --track-origins=yes --leak-check=yes --suppressions=$suppressions --log-file=$tmpdir/valgrind-%p.log ../build/bin/nvim -u NONE"
|
||||||
if ! ../scripts/run-api-tests.exp "$test_cmd" "$nvim_cmd"; then
|
if ! ../scripts/run-api-tests.exp "$test_cmd" "$nvim_cmd"; then
|
||||||
valgrind_check "$tmpdir"
|
valgrind_check "$tmpdir"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
valgrind_check "$tmpdir"
|
||||||
|
|
||||||
|
export NEOVIM_SPAWN_ARGV="[\"valgrind\", \"-q\", \"--track-origins=yes\", \"--leak-check=yes\", \"--suppressions=$suppressions\", \"--log-file=$tmpdir/valgrind-%p.log\", \"../build/bin/nvim\", \"-u\", \"NONE\", \"--embedded-mode\"]"
|
||||||
|
if ! nosetests --verbosity=2 --nologcapture; then
|
||||||
|
valgrind_check "$tmpdir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
valgrind_check "$tmpdir"
|
valgrind_check "$tmpdir"
|
||||||
|
@ -20,43 +20,6 @@ set nvim_id $spawn_id
|
|||||||
# Reset function that can be invoked by test runners to put nvim in a cleaner
|
# Reset function that can be invoked by test runners to put nvim in a cleaner
|
||||||
# state
|
# state
|
||||||
send {
|
send {
|
||||||
:function BeforeEachTest()
|
|
||||||
set all&
|
|
||||||
let &initpython = 'python -c "import neovim; neovim.start_host()"'
|
|
||||||
redir => groups
|
|
||||||
silent augroup
|
|
||||||
redir END
|
|
||||||
for group in split(groups)
|
|
||||||
exe 'augroup '.group
|
|
||||||
autocmd!
|
|
||||||
augroup END
|
|
||||||
endfor
|
|
||||||
autocmd!
|
|
||||||
tabnew
|
|
||||||
let curbufnum = eval(bufnr('%'))
|
|
||||||
redir => buflist
|
|
||||||
silent ls!
|
|
||||||
redir END
|
|
||||||
let bufnums = []
|
|
||||||
for buf in split(buflist, '\n')
|
|
||||||
let bufnum = eval(split(buf, '[ u]')[0])
|
|
||||||
if bufnum != curbufnum
|
|
||||||
call add(bufnums, bufnum)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if len(bufnums) > 0
|
|
||||||
exe 'silent bwipeout! '.join(bufnums, ' ')
|
|
||||||
endif
|
|
||||||
silent tabonly
|
|
||||||
for k in keys(g:)
|
|
||||||
exe 'unlet g:'.k
|
|
||||||
endfor
|
|
||||||
filetype plugin indent off
|
|
||||||
mapclear
|
|
||||||
mapclear!
|
|
||||||
abclear
|
|
||||||
comclear
|
|
||||||
endfunction
|
|
||||||
:echo "read"."y"
|
:echo "read"."y"
|
||||||
}
|
}
|
||||||
# wait until nvim is ready
|
# wait until nvim is ready
|
||||||
|
@ -2011,6 +2011,10 @@ void free_cmdline_buf(void)
|
|||||||
*/
|
*/
|
||||||
static void draw_cmdline(int start, int len)
|
static void draw_cmdline(int start, int len)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (cmdline_star > 0)
|
if (cmdline_star > 0)
|
||||||
|
@ -1233,6 +1233,9 @@ EXTERN char *ignoredp;
|
|||||||
* os_unix.c */
|
* os_unix.c */
|
||||||
EXTERN int curr_tmode INIT(= TMODE_COOK); /* contains current terminal mode */
|
EXTERN int curr_tmode INIT(= TMODE_COOK); /* contains current terminal mode */
|
||||||
|
|
||||||
|
// If a msgpack-rpc channel should be started over stdin/stdout
|
||||||
|
EXTERN bool embedded_mode INIT(= false);
|
||||||
|
|
||||||
/// Used to track the status of external functions.
|
/// Used to track the status of external functions.
|
||||||
/// Currently only used for iconv().
|
/// Currently only used for iconv().
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -256,10 +256,10 @@ int main(int argc, char **argv)
|
|||||||
TIME_MSG("shell init");
|
TIME_MSG("shell init");
|
||||||
|
|
||||||
|
|
||||||
/*
|
if (!embedded_mode) {
|
||||||
* Print a warning if stdout is not a terminal.
|
// Print a warning if stdout is not a terminal.
|
||||||
*/
|
check_tty(¶ms);
|
||||||
check_tty(¶ms);
|
}
|
||||||
|
|
||||||
/* This message comes before term inits, but after setting "silent_mode"
|
/* This message comes before term inits, but after setting "silent_mode"
|
||||||
* when the input is not a tty. */
|
* when the input is not a tty. */
|
||||||
@ -267,8 +267,16 @@ int main(int argc, char **argv)
|
|||||||
printf(_("%d files to edit\n"), GARGCOUNT);
|
printf(_("%d files to edit\n"), GARGCOUNT);
|
||||||
|
|
||||||
if (params.want_full_screen && !silent_mode) {
|
if (params.want_full_screen && !silent_mode) {
|
||||||
termcapinit(params.term); /* set terminal name and get terminal
|
if (embedded_mode) {
|
||||||
capabilities (will set full_screen) */
|
// In embedded mode don't do terminal-related initializations, assume an
|
||||||
|
// initial screen size of 80x20
|
||||||
|
full_screen = true;
|
||||||
|
set_shellsize(80, 20, false);
|
||||||
|
} else {
|
||||||
|
// set terminal name and get terminal capabilities (will set full_screen)
|
||||||
|
// Do some initialization of the screen
|
||||||
|
termcapinit(params.term);
|
||||||
|
}
|
||||||
screen_start(); /* don't know where cursor is now */
|
screen_start(); /* don't know where cursor is now */
|
||||||
TIME_MSG("Termcap init");
|
TIME_MSG("Termcap init");
|
||||||
}
|
}
|
||||||
@ -405,14 +413,18 @@ int main(int argc, char **argv)
|
|||||||
TIME_MSG("waiting for return");
|
TIME_MSG("waiting for return");
|
||||||
}
|
}
|
||||||
|
|
||||||
starttermcap(); /* start termcap if not done by wait_return() */
|
if (!embedded_mode) {
|
||||||
TIME_MSG("start termcap");
|
starttermcap(); // start termcap if not done by wait_return()
|
||||||
may_req_ambiguous_char_width();
|
TIME_MSG("start termcap");
|
||||||
|
may_req_ambiguous_char_width();
|
||||||
|
setmouse(); // may start using the mouse
|
||||||
|
|
||||||
setmouse(); /* may start using the mouse */
|
if (scroll_region) {
|
||||||
if (scroll_region)
|
scroll_region_reset(); // In case Rows changed
|
||||||
scroll_region_reset(); /* In case Rows changed */
|
}
|
||||||
scroll_start(); /* may scroll the screen to the right position */
|
|
||||||
|
scroll_start(); // may scroll the screen to the right position
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't clear the screen when starting in Ex mode, unless using the GUI.
|
* Don't clear the screen when starting in Ex mode, unless using the GUI.
|
||||||
@ -1015,11 +1027,13 @@ static void command_line_scan(mparm_T *parmp)
|
|||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
msg_didout = FALSE;
|
msg_didout = FALSE;
|
||||||
mch_exit(0);
|
mch_exit(0);
|
||||||
} else if (STRICMP(argv[0] + argv_idx, "api-msgpack-metadata") == 0) {
|
} else if (STRICMP(argv[0] + argv_idx, "api-msgpack-metadata") == 0) {
|
||||||
for (unsigned int i = 0; i<msgpack_metadata_size; i++) {
|
for (unsigned int i = 0; i<msgpack_metadata_size; i++) {
|
||||||
putchar(msgpack_metadata[i]);
|
putchar(msgpack_metadata[i]);
|
||||||
}
|
}
|
||||||
mch_exit(0);
|
mch_exit(0);
|
||||||
|
} else if (STRICMP(argv[0] + argv_idx, "embedded-mode") == 0) {
|
||||||
|
embedded_mode = true;
|
||||||
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
|
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
|
||||||
#if !defined(UNIX)
|
#if !defined(UNIX)
|
||||||
parmp->literal = TRUE;
|
parmp->literal = TRUE;
|
||||||
@ -2200,6 +2214,8 @@ static void usage(void)
|
|||||||
main_msg(_("--startuptime <file>\tWrite startup timing messages to <file>"));
|
main_msg(_("--startuptime <file>\tWrite startup timing messages to <file>"));
|
||||||
main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
|
main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
|
||||||
main_msg(_("--api-msgpack-metadata\tDump API metadata information and exit"));
|
main_msg(_("--api-msgpack-metadata\tDump API metadata information and exit"));
|
||||||
|
main_msg(_("--embedded-mode\tUse stdin/stdout as a msgpack-rpc channel. "
|
||||||
|
"This can be used for embedding Neovim into other programs"));
|
||||||
main_msg(_("-h or --help\tPrint Help (this message) and exit"));
|
main_msg(_("-h or --help\tPrint Help (this message) and exit"));
|
||||||
main_msg(_("--version\t\tPrint version information and exit"));
|
main_msg(_("--version\t\tPrint version information and exit"));
|
||||||
|
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
|
#include "nvim/os_unix.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
#include "nvim/map.h"
|
#include "nvim/map.h"
|
||||||
#include "nvim/log.h"
|
#include "nvim/log.h"
|
||||||
#include "nvim/lib/kvec.h"
|
#include "nvim/lib/kvec.h"
|
||||||
|
|
||||||
|
#define CHANNEL_BUFFER_SIZE 0xffff
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t request_id;
|
uint64_t request_id;
|
||||||
bool errored;
|
bool errored;
|
||||||
@ -64,6 +67,10 @@ void channel_init(void)
|
|||||||
channels = pmap_new(uint64_t)();
|
channels = pmap_new(uint64_t)();
|
||||||
event_strings = pmap_new(cstr_t)();
|
event_strings = pmap_new(cstr_t)();
|
||||||
msgpack_sbuffer_init(&out_buffer);
|
msgpack_sbuffer_init(&out_buffer);
|
||||||
|
|
||||||
|
if (embedded_mode) {
|
||||||
|
channel_from_stdio();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Teardown the module
|
/// Teardown the module
|
||||||
@ -117,7 +124,10 @@ void channel_from_stream(uv_stream_t *stream)
|
|||||||
stream->data = NULL;
|
stream->data = NULL;
|
||||||
channel->is_job = false;
|
channel->is_job = false;
|
||||||
// read stream
|
// read stream
|
||||||
channel->data.streams.read = rstream_new(parse_msgpack, 1024, channel, NULL);
|
channel->data.streams.read = rstream_new(parse_msgpack,
|
||||||
|
CHANNEL_BUFFER_SIZE,
|
||||||
|
channel,
|
||||||
|
NULL);
|
||||||
rstream_set_stream(channel->data.streams.read, stream);
|
rstream_set_stream(channel->data.streams.read, stream);
|
||||||
rstream_start(channel->data.streams.read);
|
rstream_start(channel->data.streams.read);
|
||||||
// write stream
|
// write stream
|
||||||
@ -256,6 +266,25 @@ void channel_unsubscribe(uint64_t id, char *event)
|
|||||||
unsubscribe(channel, event);
|
unsubscribe(channel, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an API channel from stdin/stdout. This is used when embedding
|
||||||
|
/// Neovim
|
||||||
|
static void channel_from_stdio(void)
|
||||||
|
{
|
||||||
|
Channel *channel = register_channel();
|
||||||
|
channel->is_job = false;
|
||||||
|
// read stream
|
||||||
|
channel->data.streams.read = rstream_new(parse_msgpack,
|
||||||
|
CHANNEL_BUFFER_SIZE,
|
||||||
|
channel,
|
||||||
|
NULL);
|
||||||
|
rstream_set_file(channel->data.streams.read, 0);
|
||||||
|
rstream_start(channel->data.streams.read);
|
||||||
|
// write stream
|
||||||
|
channel->data.streams.write = wstream_new(0);
|
||||||
|
wstream_set_file(channel->data.streams.write, 1);
|
||||||
|
channel->data.streams.uv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void job_out(RStream *rstream, void *data, bool eof)
|
static void job_out(RStream *rstream, void *data, bool eof)
|
||||||
{
|
{
|
||||||
Job *job = data;
|
Job *job = data;
|
||||||
@ -278,6 +307,7 @@ static void job_err(RStream *rstream, void *data, bool eof)
|
|||||||
static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
||||||
{
|
{
|
||||||
Channel *channel = data;
|
Channel *channel = data;
|
||||||
|
channel->rpc_call_level++;
|
||||||
|
|
||||||
if (eof) {
|
if (eof) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
@ -287,10 +317,9 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof)
|
|||||||
"closed by the client",
|
"closed by the client",
|
||||||
channel->id);
|
channel->id);
|
||||||
call_set_error(channel, buf);
|
call_set_error(channel, buf);
|
||||||
return;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->rpc_call_level++;
|
|
||||||
uint32_t count = rstream_available(rstream);
|
uint32_t count = rstream_available(rstream);
|
||||||
DLOG("Feeding the msgpack parser with %u bytes of data from RStream(%p)",
|
DLOG("Feeding the msgpack parser with %u bytes of data from RStream(%p)",
|
||||||
count,
|
count,
|
||||||
@ -469,7 +498,12 @@ static void close_channel(Channel *channel)
|
|||||||
} else {
|
} else {
|
||||||
rstream_free(channel->data.streams.read);
|
rstream_free(channel->data.streams.read);
|
||||||
wstream_free(channel->data.streams.write);
|
wstream_free(channel->data.streams.write);
|
||||||
uv_close((uv_handle_t *)channel->data.streams.uv, close_cb);
|
if (channel->data.streams.uv) {
|
||||||
|
uv_close((uv_handle_t *)channel->data.streams.uv, close_cb);
|
||||||
|
} else {
|
||||||
|
// When the stdin channel closes, it's time to go
|
||||||
|
mch_exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(channel);
|
free(channel);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/os/event.h"
|
#include "nvim/os/event.h"
|
||||||
|
#include "nvim/os/signal.h"
|
||||||
#include "nvim/os/rstream_defs.h"
|
#include "nvim/os/rstream_defs.h"
|
||||||
#include "nvim/os/rstream.h"
|
#include "nvim/os/rstream.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
@ -34,6 +35,10 @@ static bool eof = false, started_reading = false;
|
|||||||
|
|
||||||
void input_init(void)
|
void input_init(void)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
read_stream = rstream_new(read_cb, READ_BUFFER_SIZE, NULL, NULL);
|
read_stream = rstream_new(read_cb, READ_BUFFER_SIZE, NULL, NULL);
|
||||||
rstream_set_file(read_stream, read_cmd_fd);
|
rstream_set_file(read_stream, read_cmd_fd);
|
||||||
}
|
}
|
||||||
@ -41,18 +46,30 @@ void input_init(void)
|
|||||||
// Listen for input
|
// Listen for input
|
||||||
void input_start(void)
|
void input_start(void)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rstream_start(read_stream);
|
rstream_start(read_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop listening for input
|
// Stop listening for input
|
||||||
void input_stop(void)
|
void input_stop(void)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rstream_stop(read_stream);
|
rstream_stop(read_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copies (at most `count`) of was read from `read_cmd_fd` into `buf`
|
// Copies (at most `count`) of was read from `read_cmd_fd` into `buf`
|
||||||
uint32_t input_read(char *buf, uint32_t count)
|
uint32_t input_read(char *buf, uint32_t count)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return rstream_read(read_stream, buf, count);
|
return rstream_read(read_stream, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +146,11 @@ bool os_isatty(int fd)
|
|||||||
|
|
||||||
static bool input_poll(int32_t ms)
|
static bool input_poll(int32_t ms)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
EventSource input_sources[] = { signal_event_source(), NULL };
|
||||||
|
return event_poll(ms, input_sources);
|
||||||
|
}
|
||||||
|
|
||||||
EventSource input_sources[] = {
|
EventSource input_sources[] = {
|
||||||
rstream_event_source(read_stream),
|
rstream_event_source(read_stream),
|
||||||
NULL
|
NULL
|
||||||
|
@ -39,7 +39,10 @@ void signal_init(void)
|
|||||||
uv_signal_start(&shup, signal_cb, SIGHUP);
|
uv_signal_start(&shup, signal_cb, SIGHUP);
|
||||||
uv_signal_start(&squit, signal_cb, SIGQUIT);
|
uv_signal_start(&squit, signal_cb, SIGQUIT);
|
||||||
uv_signal_start(&sterm, signal_cb, SIGTERM);
|
uv_signal_start(&sterm, signal_cb, SIGTERM);
|
||||||
uv_signal_start(&swinch, signal_cb, SIGWINCH);
|
if (!embedded_mode) {
|
||||||
|
// TODO(tarruda): There must be an API function for resizing window
|
||||||
|
uv_signal_start(&swinch, signal_cb, SIGWINCH);
|
||||||
|
}
|
||||||
#ifdef SIGPWR
|
#ifdef SIGPWR
|
||||||
uv_signal_init(uv_default_loop(), &spwr);
|
uv_signal_init(uv_default_loop(), &spwr);
|
||||||
uv_signal_start(&spwr, signal_cb, SIGPWR);
|
uv_signal_start(&spwr, signal_cb, SIGPWR);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ struct wstream {
|
|||||||
size_t maxmem;
|
size_t maxmem;
|
||||||
// Number of pending requests
|
// Number of pending requests
|
||||||
size_t pending_reqs;
|
size_t pending_reqs;
|
||||||
bool freed;
|
bool freed, free_handle;
|
||||||
// (optional) Write callback and data
|
// (optional) Write callback and data
|
||||||
wstream_cb cb;
|
wstream_cb cb;
|
||||||
void *data;
|
void *data;
|
||||||
@ -60,6 +61,7 @@ WStream * wstream_new(size_t maxmem)
|
|||||||
rv->curmem = 0;
|
rv->curmem = 0;
|
||||||
rv->pending_reqs = 0;
|
rv->pending_reqs = 0;
|
||||||
rv->freed = false;
|
rv->freed = false;
|
||||||
|
rv->free_handle = false;
|
||||||
rv->cb = NULL;
|
rv->cb = NULL;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -68,9 +70,13 @@ WStream * wstream_new(size_t maxmem)
|
|||||||
/// Frees all memory allocated for a WStream instance
|
/// Frees all memory allocated for a WStream instance
|
||||||
///
|
///
|
||||||
/// @param wstream The `WStream` instance
|
/// @param wstream The `WStream` instance
|
||||||
void wstream_free(WStream *wstream)
|
void wstream_free(WStream *wstream) {
|
||||||
{
|
|
||||||
if (!wstream->pending_reqs) {
|
if (!wstream->pending_reqs) {
|
||||||
|
handle_set_wstream((uv_handle_t *)wstream->stream, NULL);
|
||||||
|
if (wstream->free_handle) {
|
||||||
|
uv_close((uv_handle_t *)wstream->stream, close_cb);
|
||||||
|
}
|
||||||
|
|
||||||
free(wstream);
|
free(wstream);
|
||||||
} else {
|
} else {
|
||||||
wstream->freed = true;
|
wstream->freed = true;
|
||||||
@ -87,6 +93,24 @@ void wstream_set_stream(WStream *wstream, uv_stream_t *stream)
|
|||||||
wstream->stream = stream;
|
wstream->stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the underlying file descriptor that will be written to. Only pipes
|
||||||
|
/// are supported for now.
|
||||||
|
///
|
||||||
|
/// @param wstream The `WStream` instance
|
||||||
|
/// @param file The file descriptor
|
||||||
|
void wstream_set_file(WStream *wstream, uv_file file)
|
||||||
|
{
|
||||||
|
uv_handle_type type = uv_guess_handle(file);
|
||||||
|
|
||||||
|
assert(type == UV_NAMED_PIPE || type == UV_TTY);
|
||||||
|
wstream->stream = xmalloc(sizeof(uv_pipe_t));
|
||||||
|
uv_pipe_init(uv_default_loop(), (uv_pipe_t *)wstream->stream, 0);
|
||||||
|
uv_pipe_open((uv_pipe_t *)wstream->stream, file);
|
||||||
|
wstream->stream->data = NULL;
|
||||||
|
handle_set_wstream((uv_handle_t *)wstream->stream, wstream);
|
||||||
|
wstream->free_handle = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets a callback that will be called on completion of a write request,
|
/// Sets a callback that will be called on completion of a write request,
|
||||||
/// indicating failure/success.
|
/// indicating failure/success.
|
||||||
///
|
///
|
||||||
@ -211,3 +235,16 @@ static void release_wbuffer(WBuffer *buffer)
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void close_cb(uv_handle_t *handle)
|
||||||
|
{
|
||||||
|
WStream *wstream = handle_get_wstream(handle);
|
||||||
|
|
||||||
|
if (wstream) {
|
||||||
|
free(wstream);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(handle->data);
|
||||||
|
free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,18 @@ static int did_set_icon = FALSE;
|
|||||||
*/
|
*/
|
||||||
void mch_write(char_u *s, int len)
|
void mch_write(char_u *s, int len)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
// TODO(tarruda): This is a temporary hack to stop Neovim from writing
|
||||||
|
// messages to stdout in embedded mode. In the future, embedded mode will
|
||||||
|
// be the only possibility(GUIs will always start neovim with a msgpack-rpc
|
||||||
|
// over stdio) and this function won't exist.
|
||||||
|
//
|
||||||
|
// The reason for this is because before Neovim fully migrates to a
|
||||||
|
// msgpack-rpc-driven architecture, we must have a fully functional
|
||||||
|
// UI working
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ignored = (int)write(1, (char *)s, len);
|
ignored = (int)write(1, (char *)s, len);
|
||||||
if (p_wd) /* Unix is too fast, slow down a bit more */
|
if (p_wd) /* Unix is too fast, slow down a bit more */
|
||||||
os_microdelay(p_wd, false);
|
os_microdelay(p_wd, false);
|
||||||
|
@ -2360,6 +2360,9 @@ void set_shellsize(int width, int height, int mustset)
|
|||||||
*/
|
*/
|
||||||
void settmode(int tmode)
|
void settmode(int tmode)
|
||||||
{
|
{
|
||||||
|
if (embedded_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (full_screen) {
|
if (full_screen) {
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user