From b2967a0320ec327d1271bb75d96156a5ff1c8758 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 5 Aug 2017 23:53:48 +0200 Subject: nvim -h: omit special-case options Group some options, and sort them alphabetically. `nvim -h` should fit on one (smallish) screen. Uncommon options don't need to be here, they live in the :help. --- src/nvim/main.c | 71 ++++++++++++++++++--------------------- src/nvim/testdir/test_startup.vim | 6 ++-- 2 files changed, 35 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 3f828d7be9..a665ad1de2 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1878,54 +1878,47 @@ static void usage(void) signal_stop(); // kill us with CTRL-C here, if you like mch_msg(_("Usage:\n")); - mch_msg(_(" nvim [arguments] [file ...] Edit specified file(s)\n")); - mch_msg(_(" nvim [arguments] - Read text from stdin\n")); - mch_msg(_(" nvim [arguments] -t Edit file where tag is defined\n")); - mch_msg(_(" nvim [arguments] -q [errorfile] Edit file with first error\n")); - mch_msg(_("\nArguments:\n")); + mch_msg(_(" nvim [options] [file ...] Edit file(s)\n")); + mch_msg(_(" nvim [options] - Read text from stdin\n")); + mch_msg(_(" nvim [options] -t Edit file where tag is defined\n")); + mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n")); + mch_msg(_("\nOptions:\n")); mch_msg(_(" -- Only file names after this\n")); -#if !defined(UNIX) - mch_msg(_(" --literal Don't expand wildcards\n")); -#endif - mch_msg(_(" -e Ex mode\n")); - mch_msg(_(" -E Improved Ex mode\n")); - mch_msg(_(" -s Silent (batch) mode (only for ex mode)\n")); + mch_msg(_(" + Start at end of file\n")); + mch_msg(_(" --cmd Execute before any config\n")); + mch_msg(_(" +, -c Execute after config and first file\n")); + mch_msg("\n"); + mch_msg(_(" -b Binary mode\n")); mch_msg(_(" -d Diff mode\n")); - mch_msg(_(" -R Read-only mode\n")); - mch_msg(_(" -Z Restricted mode\n")); + mch_msg(_(" -e, -E Ex mode, Improved Ex mode\n")); + mch_msg(_(" -es Silent (batch) mode\n")); + mch_msg(_(" -h, --help Print this help message\n")); + mch_msg(_(" -i Use this shada file\n")); mch_msg(_(" -m Modifications (writing files) not allowed\n")); mch_msg(_(" -M Modifications in text not allowed\n")); - mch_msg(_(" -b Binary mode\n")); - mch_msg(_(" -l Lisp mode\n")); - mch_msg(_(" -A Arabic mode\n")); - mch_msg(_(" -F Farsi mode\n")); - mch_msg(_(" -H Hebrew mode\n")); - mch_msg(_(" -V[N][file] Be verbose [level N][log messages to file]\n")); - mch_msg(_(" -D Debugging mode\n")); mch_msg(_(" -n No swap file, use memory only\n")); - mch_msg(_(" -r, -L List swap files and exit\n")); - mch_msg(_(" -r Recover crashed session\n")); - mch_msg(_(" -u Use instead of the default\n")); - mch_msg(_(" -i Use instead of the default\n")); - mch_msg(_(" --noplugin Don't load plugin scripts\n")); - mch_msg(_(" -o[N] Open N windows (default: one for each file)\n")); - mch_msg(_(" -O[N] Like -o but split vertically\n")); - mch_msg(_(" -p[N] Open N tab pages (default: one for each file)\n")); - mch_msg(_(" + Start at end of file\n")); - mch_msg(_(" + Start at line \n")); - mch_msg(_(" +/ Start at first occurrence of \n")); - mch_msg(_(" --cmd Execute before loading any vimrc\n")); - mch_msg(_(" -c Execute after loading the first file\n")); + mch_msg(_(" -o[N] Open N windows (default: one per file)\n")); + mch_msg(_(" -O[N] Open N vertical windows (default: one per file)\n")); + mch_msg(_(" -p[N] Open N tab pages (default: one per file)\n")); + mch_msg(_(" -r, -L List swap files\n")); + mch_msg(_(" -r Recover edit state for this file\n")); + mch_msg(_(" -R Read-only mode\n")); mch_msg(_(" -S Source after loading the first file\n")); mch_msg(_(" -s Read Normal mode commands from \n")); - mch_msg(_(" -w Append all typed characters to \n")); - mch_msg(_(" -W Write all typed characters to \n")); - mch_msg(_(" --startuptime Write startup timing messages to \n")); - mch_msg(_(" --api-info Dump API metadata serialized to msgpack and exit\n")); + mch_msg(_(" -u Use this config file\n")); + mch_msg(_(" -v, --version Print version information\n")); + mch_msg(_(" -V[N][file] Verbose [level][file]\n")); + mch_msg(_(" -Z Restricted mode\n")); + mch_msg("\n"); + mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n")); mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n")); mch_msg(_(" --headless Don't start a user interface\n")); - mch_msg(_(" -v, --version Print version information and exit\n")); - mch_msg(_(" -h, --help Print this help message and exit\n")); +#if !defined(UNIX) + mch_msg(_(" --literal Don't expand wildcards\n")); +#endif + mch_msg(_(" --noplugin Don't load plugins\n")); + mch_msg(_(" --startuptime Write startup timing messages to \n")); + mch_msg(_("\nSee \":help startup-options\" for all options.\n")); } diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 64f7f31294..5a38178bd5 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -76,11 +76,11 @@ func Test_help_arg() let found = [] for line in lines if line =~ '-R.*Read-only mode' - call add(found, 'Readonly mode') + call add(found, 'Readonly mode') endif " Watch out for a second --version line in the Gnome version. - if line =~ '--version.*Print version information and exit' - call add(found, "--version") + if line =~ '--version.*Print version information' + call add(found, "--version") endif endfor call assert_equal(['Readonly mode', '--version'], found) -- cgit From 6ca6a8134ddf62d3b6abc57185b096fd712cc873 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 00:29:25 +0200 Subject: intro: remove byline #6984 --- src/nvim/version.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index f5b45caefc..e024982faf 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1216,7 +1216,6 @@ void intro_message(int colon) static char *(lines[]) = { N_(NVIM_VERSION_LONG), "", - N_("by al."), N_("Nvim is open source and freely distributable"), N_("https://neovim.io/community"), "", -- cgit From af046a3a81c0d7ebc5219bf20c1463cb5ccd1b9b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 21:23:28 +0200 Subject: version: tweak layout, doc --- src/nvim/version.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index e024982faf..2a3fdbd70d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1089,13 +1089,7 @@ static void list_features(void) msg_putchar('\n'); } } else { - while (msg_col % width) { - int old_msg_col = msg_col; - msg_putchar(' '); - if (old_msg_col == msg_col) { - break; // XXX: Avoid infinite loop. - } - } + msg_putchar(' '); } } else { if (msg_col > 0) { @@ -1103,7 +1097,7 @@ static void list_features(void) } } } - MSG_PUTS("For differences from Vim, see :help vim-differences\n\n"); + MSG_PUTS("See \":help feature-compile\"\n\n"); } void list_version(void) @@ -1144,7 +1138,7 @@ void list_version(void) } #endif // ifdef HAVE_PATHDEF - version_msg(_("\n\nOptional features included (+) or not (-): ")); + version_msg(_("\n\nFeatures: ")); list_features(); -- cgit From b13070ec01844977f10cae38fc6f2a0fd9defad8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 23:30:28 +0200 Subject: doc/api: nvim_out_write() and friends References #7178 --- src/nvim/api/vim.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2bc31b2812..cfbe34b848 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -484,7 +484,8 @@ void nvim_set_option(String name, Object value, Error *err) set_option_to(NULL, SREQ_GLOBAL, name, value, err); } -/// Writes a message to vim output buffer +/// Writes a message to the Vim output buffer. Does not append "\n", the +/// message is buffered (won't display) until a linefeed is written. /// /// @param str Message void nvim_out_write(String str) @@ -493,7 +494,8 @@ void nvim_out_write(String str) write_msg(str, false); } -/// Writes a message to vim error buffer +/// Writes a message to the Vim error buffer. Does not append "\n", the +/// message is buffered (won't display) until a linefeed is written. /// /// @param str Message void nvim_err_write(String str) @@ -502,8 +504,8 @@ void nvim_err_write(String str) write_msg(str, true); } -/// Writes a message to vim error buffer. Appends a linefeed to ensure all -/// contents are written. +/// Writes a message to the Vim error buffer. Appends "\n", so the buffer is +/// flushed (and displayed). /// /// @param str Message /// @see nvim_err_write() -- cgit From 9882e25dc44f1165e1edc8b3898356e493b6b3fe Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 20 Aug 2017 02:13:04 +0200 Subject: clipboard: avoid error flood during :redir redir_write(): - This is a "batch" operation which was not yet covered by start_batch_changes() adjust_clipboard_name(): - msg() and friends during :redir will, of course, cause redir_write() to try to capture that message, which causes recursion. - EMSG() here is trouble: if it interrupts :redir it is a mess. Rather than deal with the mess, show a non-error message. closes #7182 closes #7184 closes #7183 ref #6048 ref #7032 --- src/nvim/eval.c | 18 +++++++------- src/nvim/message.c | 2 ++ src/nvim/ops.c | 69 ++++++++++++++++++++++++++++++++---------------------- 3 files changed, 52 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ac22d75a83..d6ee13857a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -22775,7 +22775,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments) bool eval_has_provider(const char *name) { -#define check_provider(name) \ +#define CHECK_PROVIDER(name) \ if (has_##name == -1) { \ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \ if (!has_##name) { \ @@ -22791,17 +22791,17 @@ bool eval_has_provider(const char *name) static int has_python3 = -1; static int has_ruby = -1; - if (!strcmp(name, "clipboard")) { - check_provider(clipboard); + if (strequal(name, "clipboard")) { + CHECK_PROVIDER(clipboard); return has_clipboard; - } else if (!strcmp(name, "python3")) { - check_provider(python3); + } else if (strequal(name, "python3")) { + CHECK_PROVIDER(python3); return has_python3; - } else if (!strcmp(name, "python")) { - check_provider(python); + } else if (strequal(name, "python")) { + CHECK_PROVIDER(python); return has_python; - } else if (!strcmp(name, "ruby")) { - check_provider(ruby); + } else if (strequal(name, "ruby")) { + CHECK_PROVIDER(ruby); return has_ruby; } diff --git a/src/nvim/message.c b/src/nvim/message.c index b90c475ede..fe4cb65779 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2519,6 +2519,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (redirecting()) { /* If the string doesn't start with CR or NL, go to msg_col */ if (*s != '\n' && *s != '\r') { + start_batch_changes(); while (cur_col < msg_col) { if (capture_ga) { ga_concat_len(capture_ga, " ", 1); @@ -2535,6 +2536,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) } cur_col++; } + end_batch_changes(); } size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5c6f4d0d07..7bbc72b091 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -58,8 +58,8 @@ static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */ static bool clipboard_didwarn_unnamed = false; // for behavior between start_batch_changes() and end_batch_changes()) -static bool clipboard_delay_update = false; // delay clipboard update static int batch_change_count = 0; // inside a script +static bool clipboard_delay_update = false; // delay clipboard update static bool clipboard_needs_update = false; // clipboard was updated /* @@ -5524,7 +5524,7 @@ int get_default_register_name(void) } /// Determine if register `*name` should be used as a clipboard. -/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if +/// In an unnamed operation, `*name` is `NUL` and will be adjusted to */+ if /// `clipboard=unnamed[plus]` is set. /// /// @param name The name of register, or `NUL` if unnamed. @@ -5535,33 +5535,44 @@ int get_default_register_name(void) /// if the register isn't a clipboard or provider isn't available. static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) { - if (*name == '*' || *name == '+') { - if(!eval_has_provider("clipboard")) { - if (!quiet) { - EMSG("clipboard: No provider. Try \":CheckHealth\" or " - "\":h clipboard\"."); - } - return NULL; - } - return &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; - } else if ((*name == NUL) && (cb_flags & CB_UNNAMEDMASK)) { - if(!eval_has_provider("clipboard")) { - if (!quiet && !clipboard_didwarn_unnamed) { - msg((char_u *)"clipboard: No provider. Try \":CheckHealth\" or " - "\":h clipboard\"."); - clipboard_didwarn_unnamed = true; - } - return NULL; +#define MSG_NO_CLIP "clipboard: No provider. " \ + "Try \":CheckHealth\" or \":h clipboard\"." + + yankreg_T *target = NULL; + bool explicit_cb_reg = (*name == '*' || *name == '+'); + bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK); + int save_redir_off = redir_off; + if (!explicit_cb_reg && !implicit_cb_reg) { + goto end; + } + + if (!eval_has_provider("clipboard")) { + if (batch_change_count == 1 && explicit_cb_reg && !quiet) { + redir_off = true; // Avoid recursion from :redir + emsg(). + // Do NOT error (emsg()) here--if it interrupts :redir we get into + // a weird state, stuck in "redirect mode". + msg((char_u *)MSG_NO_CLIP); + } else if (batch_change_count == 1 && implicit_cb_reg + && !quiet && !clipboard_didwarn_unnamed) { + redir_off = true; // Avoid recursion from :redir + emsg(). + msg((char_u *)MSG_NO_CLIP); + clipboard_didwarn_unnamed = true; } + // ... else, be silent (avoid a flood of messages). + goto end; + } + + if (explicit_cb_reg) { + target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; + goto end; + } else { // unnamed register: "implicit" clipboard if (writing && clipboard_delay_update) { clipboard_needs_update = true; - return NULL; + goto end; } else if (!writing && clipboard_needs_update) { - // use the internal value - return NULL; + goto end; // use the internal value } - yankreg_T *target; if (cb_flags & CB_UNNAMEDPLUS) { *name = (cb_flags & CB_UNNAMED && writing) ? '"': '+'; target = &y_regs[PLUS_REGISTER]; @@ -5569,10 +5580,12 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) *name = '*'; target = &y_regs[STAR_REGISTER]; } - return target; // unnamed register + goto end; } - // don't do anything for other register names - return NULL; + +end: + redir_off = save_redir_off; + return target; } static bool get_clipboard(int name, yankreg_T **target, bool quiet) @@ -5740,7 +5753,7 @@ static void set_clipboard(int name, yankreg_T *reg) (void)eval_call_provider("clipboard", "set", args); } -/// Avoid clipboard (slow) during batch operations (i.e., a script). +/// Avoid slow things (clipboard) during batch operations (while/for-loops). void start_batch_changes(void) { if (++batch_change_count > 1) { @@ -5750,7 +5763,7 @@ void start_batch_changes(void) clipboard_needs_update = false; } -/// Update the clipboard after batch changes finished. +/// Counterpart to start_batch_changes(). void end_batch_changes(void) { if (--batch_change_count > 0) { -- cgit From cc7e344f8357d07b1df17df0b322152d5c50739b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 20 Aug 2017 18:53:58 +0200 Subject: clipboard: remove start_batch_changes() in redir_write() start_batch_changes() doesn't avoid invoking the clipboard once-per-line, because the loop is actually in ex_echo(), which calls redir_write() for each message. But we've already entered start_batch_changes() by then, so that was never the problem. redir_write at /home/vagrant/old.neovim/build/../src/nvim/message.c:2523 msg_puts_attr_len at /home/vagrant/old.neovim/build/../src/nvim/message.c:1600 msg_outtrans_len_attr at /home/vagrant/old.neovim/build/../src/nvim/message.c:1221 ex_echo at /home/vagrant/old.neovim/build/../src/nvim/eval.c:19433 do_one_cmd at /home/vagrant/old.neovim/build/../src/nvim/ex_docmd.c:2242 Trying to defer _explicit_ clipboard updates is difficult. :redir @+ | silent echo system('cat foo') | redir END is essentially equivalent to: for l in readfile('foo') let @+ .= l endfor We cannot make judgements about when to ignore a script's bad decisions. start_batch_changes() only works around the case of clipboard=unnamed, i.e. _implicit_ clipboard updates (`:g/foo/d`). Not explicit assignment. --- src/nvim/message.c | 2 -- src/nvim/ops.c | 7 +++++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index fe4cb65779..b90c475ede 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2519,7 +2519,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (redirecting()) { /* If the string doesn't start with CR or NL, go to msg_col */ if (*s != '\n' && *s != '\r') { - start_batch_changes(); while (cur_col < msg_col) { if (capture_ga) { ga_concat_len(capture_ga, " ", 1); @@ -2536,7 +2535,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) } cur_col++; } - end_batch_changes(); } size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 7bbc72b091..6c873a96c0 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5558,7 +5558,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) msg((char_u *)MSG_NO_CLIP); clipboard_didwarn_unnamed = true; } - // ... else, be silent (avoid a flood of messages). + // ... else, be silent (don't flood during :while, :redir, etc.). goto end; } @@ -5567,10 +5567,12 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) goto end; } else { // unnamed register: "implicit" clipboard if (writing && clipboard_delay_update) { + // For "set" (copy), defer the clipboard call. clipboard_needs_update = true; goto end; } else if (!writing && clipboard_needs_update) { - goto end; // use the internal value + // For "get" (paste), use the internal value. + goto end; } if (cb_flags & CB_UNNAMEDPLUS) { @@ -5772,6 +5774,7 @@ void end_batch_changes(void) } clipboard_delay_update = false; if (clipboard_needs_update) { + // unnamed ("implicit" clipboard) set_clipboard(NUL, y_previous); clipboard_needs_update = false; } -- cgit