aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/private/helpers.c2
-rw-r--r--src/nvim/api/vim.c15
-rw-r--r--src/nvim/diff.c211
-rw-r--r--src/nvim/ops.c23
-rw-r--r--src/nvim/options.lua12
-rw-r--r--src/nvim/viml/parser/expressions.c2
-rw-r--r--src/nvim/viml/parser/expressions.h2
7 files changed, 147 insertions, 120 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 4884a44cea..38a82343c3 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1505,7 +1505,7 @@ void add_user_command(String name, Object command, Dict(user_command) *opts, int
goto err;
}
- bool force = api_object_to_bool(opts->force, "force", false, err);
+ bool force = api_object_to_bool(opts->force, "force", true, err);
if (ERROR_SET(err)) {
goto err;
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 693d2083e6..59db12f2c0 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -383,7 +383,7 @@ error:
/// @param str String to be converted.
/// @param from_part Legacy Vim parameter. Usually true.
/// @param do_lt Also translate <lt>. Ignored if `special` is false.
-/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
+/// @param special Replace |keycodes|, e.g. <CR> becomes a "\r" char.
/// @see replace_termcodes
/// @see cpoptions
String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special)
@@ -1163,7 +1163,7 @@ static void term_close(void *data)
/// Send data to channel `id`. For a job, it writes it to the
/// stdin of the process. For the stdio channel |channel-stdio|,
/// it writes to Nvim's stdout. For an internal terminal instance
-/// (|nvim_open_term()|) it writes directly to terimal output.
+/// (|nvim_open_term()|) it writes directly to terminal output.
/// See |channel-bytes| for more information.
///
/// This function writes raw data, not RPC messages. If the channel
@@ -2394,11 +2394,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
/// - mods: (string) Command modifiers, if any |<mods>|
/// @param opts Optional command attributes. See |command-attributes| for more details. To use
/// boolean attributes (such as |:command-bang| or |:command-bar|) set the value to
-/// "true". When using a Lua function for {command} you can also provide a "desc"
-/// key that will be displayed when listing commands. In addition to the string
-/// options listed in |:command-complete|, the "complete" key also accepts a Lua
-/// function which works like the "customlist" completion mode
-/// |:command-complete-customlist|.
+/// "true". In addition to the string options listed in |:command-complete|, the
+/// "complete" key also accepts a Lua function which works like the "customlist"
+/// completion mode |:command-completion-customlist|. Additional parameters:
+/// - desc: (string) Used for listing the command when a Lua function is used for
+/// {command}.
+/// - force: (boolean, default true) Override any previous definition.
/// @param[out] err Error details, if any.
void nvim_add_user_command(String name, Object command, Dict(user_command) *opts, Error *err)
FUNC_API_SINCE(9)
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 4f4da7c2a9..340fec230c 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -82,6 +82,14 @@ typedef struct {
garray_T dout_ga; // used for internal diff
} diffout_T;
+// used for recording hunks from xdiff
+typedef struct {
+ linenr_T lnum_orig;
+ long count_orig;
+ linenr_T lnum_new;
+ long count_new;
+} diffhunk_T;
+
// two diff inputs and one result
typedef struct {
diffin_T dio_orig; // original file input
@@ -852,7 +860,7 @@ static void diff_try_update(diffio_T *dio, int idx_orig, exarg_T *eap)
}
// Read the diff output and add each entry to the diff list.
- diff_read(idx_orig, idx_new, &dio->dio_diff);
+ diff_read(idx_orig, idx_new, dio);
clear_diffin(&dio->dio_new);
clear_diffout(&dio->dio_diff);
@@ -1078,7 +1086,7 @@ static int diff_file_internal(diffio_T *diffio)
emit_cfg.ctxlen = 0; // don't need any diff_context here
emit_cb.priv = &diffio->dio_diff;
- emit_cb.out_line = xdiff_out;
+ emit_cfg.hunk_func = xdiff_out;
if (xdl_diff(&diffio->dio_orig.din_mmfile,
&diffio->dio_new.din_mmfile,
&param, &emit_cfg, &emit_cb) < 0) {
@@ -1519,20 +1527,20 @@ void ex_diffoff(exarg_T *eap)
/// @param idx_orig idx of original file
/// @param idx_new idx of new file
/// @dout diff output
-static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
+static void diff_read(int idx_orig, int idx_new, diffio_T *dio)
{
FILE *fd = NULL;
int line_idx = 0;
diff_T *dprev = NULL;
diff_T *dp = curtab->tp_first_diff;
diff_T *dn, *dpl;
+ diffout_T *dout = &dio->dio_diff;
char_u linebuf[LBUFLEN]; // only need to hold the diff line
char_u *line;
long off;
int i;
- linenr_T lnum_orig, lnum_new;
- long count_orig, count_new;
int notset = true; // block "*dp" not set yet
+ diffhunk_T *hunk;
enum {
DIFF_ED,
DIFF_UNIFIED,
@@ -1549,70 +1557,79 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
}
}
+ if (!dio->dio_internal) {
+ hunk = xmalloc(sizeof(*hunk));
+ }
+
for (;;) {
- if (fd == NULL) {
+ if (dio->dio_internal) {
if (line_idx >= dout->dout_ga.ga_len) {
break; // did last line
}
- line = ((char_u **)dout->dout_ga.ga_data)[line_idx++];
+ hunk = ((diffhunk_T **)dout->dout_ga.ga_data)[line_idx++];
} else {
- if (vim_fgets(linebuf, LBUFLEN, fd)) {
- break; // end of file
- }
- line = linebuf;
- }
-
- if (diffstyle == DIFF_NONE) {
- // Determine diff style.
- // ed like diff looks like this:
- // {first}[,{last}]c{first}[,{last}]
- // {first}a{first}[,{last}]
- // {first}[,{last}]d{first}
- //
- // unified diff looks like this:
- // --- file1 2018-03-20 13:23:35.783153140 +0100
- // +++ file2 2018-03-20 13:23:41.183156066 +0100
- // @@ -1,3 +1,5 @@
- if (isdigit(*line)) {
- diffstyle = DIFF_ED;
- } else if ((STRNCMP(line, "@@ ", 3) == 0)) {
- diffstyle = DIFF_UNIFIED;
- } else if ((STRNCMP(line, "--- ", 4) == 0) // -V501
- && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
- && (STRNCMP(line, "+++ ", 4) == 0)
- && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
- && (STRNCMP(line, "@@ ", 3) == 0)) {
- diffstyle = DIFF_UNIFIED;
+ if (fd == NULL) {
+ if (line_idx >= dout->dout_ga.ga_len) {
+ break; // did last line
+ }
+ line = ((char_u **)dout->dout_ga.ga_data)[line_idx++];
} else {
- // Format not recognized yet, skip over this line. Cygwin diff
- // may put a warning at the start of the file.
- continue;
+ if (vim_fgets(linebuf, LBUFLEN, fd)) {
+ break; // end of file
+ }
+ line = linebuf;
}
- }
- if (diffstyle == DIFF_ED) {
- if (!isdigit(*line)) {
- continue; // not the start of a diff block
- }
- if (parse_diff_ed(line, &lnum_orig, &count_orig,
- &lnum_new, &count_new) == FAIL) {
- continue;
- }
- } else {
- assert(diffstyle == DIFF_UNIFIED);
- if (STRNCMP(line, "@@ ", 3) != 0) {
- continue; // not the start of a diff block
+ if (diffstyle == DIFF_NONE) {
+ // Determine diff style.
+ // ed like diff looks like this:
+ // {first}[,{last}]c{first}[,{last}]
+ // {first}a{first}[,{last}]
+ // {first}[,{last}]d{first}
+ //
+ // unified diff looks like this:
+ // --- file1 2018-03-20 13:23:35.783153140 +0100
+ // +++ file2 2018-03-20 13:23:41.183156066 +0100
+ // @@ -1,3 +1,5 @@
+ if (isdigit(*line)) {
+ diffstyle = DIFF_ED;
+ } else if ((STRNCMP(line, "@@ ", 3) == 0)) {
+ diffstyle = DIFF_UNIFIED;
+ } else if ((STRNCMP(line, "--- ", 4) == 0) // -V501
+ && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
+ && (STRNCMP(line, "+++ ", 4) == 0)
+ && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
+ && (STRNCMP(line, "@@ ", 3) == 0)) {
+ diffstyle = DIFF_UNIFIED;
+ } else {
+ // Format not recognized yet, skip over this line. Cygwin diff
+ // may put a warning at the start of the file.
+ continue;
+ }
}
- if (parse_diff_unified(line, &lnum_orig, &count_orig,
- &lnum_new, &count_new) == FAIL) {
- continue;
+
+ if (diffstyle == DIFF_ED) {
+ if (!isdigit(*line)) {
+ continue; // not the start of a diff block
+ }
+ if (parse_diff_ed(line, hunk) == FAIL) {
+ continue;
+ }
+ } else {
+ assert(diffstyle == DIFF_UNIFIED);
+ if (STRNCMP(line, "@@ ", 3) != 0) {
+ continue; // not the start of a diff block
+ }
+ if (parse_diff_unified(line, hunk) == FAIL) {
+ continue;
+ }
}
}
// Go over blocks before the change, for which orig and new are equal.
// Copy blocks from orig to new.
while (dp != NULL
- && lnum_orig > dp->df_lnum[idx_orig] + dp->df_count[idx_orig]) {
+ && hunk->lnum_orig > dp->df_lnum[idx_orig] + dp->df_count[idx_orig]) {
if (notset) {
diff_copy_entry(dprev, dp, idx_orig, idx_new);
}
@@ -1622,19 +1639,19 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
}
if ((dp != NULL)
- && (lnum_orig <= dp->df_lnum[idx_orig] + dp->df_count[idx_orig])
- && (lnum_orig + count_orig >= dp->df_lnum[idx_orig])) {
+ && (hunk->lnum_orig <= dp->df_lnum[idx_orig] + dp->df_count[idx_orig])
+ && (hunk->lnum_orig + hunk->count_orig >= dp->df_lnum[idx_orig])) {
// New block overlaps with existing block(s).
// First find last block that overlaps.
for (dpl = dp; dpl->df_next != NULL; dpl = dpl->df_next) {
- if (lnum_orig + count_orig < dpl->df_next->df_lnum[idx_orig]) {
+ if (hunk->lnum_orig + hunk->count_orig < dpl->df_next->df_lnum[idx_orig]) {
break;
}
}
// If the newly found block starts before the old one, set the
// start back a number of lines.
- off = dp->df_lnum[idx_orig] - lnum_orig;
+ off = dp->df_lnum[idx_orig] - hunk->lnum_orig;
if (off > 0) {
for (i = idx_orig; i < idx_new; ++i) {
@@ -1642,15 +1659,15 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
dp->df_lnum[i] -= off;
}
}
- dp->df_lnum[idx_new] = lnum_new;
- dp->df_count[idx_new] = count_new;
+ dp->df_lnum[idx_new] = hunk->lnum_new;
+ dp->df_count[idx_new] = hunk->count_new;
} else if (notset) {
// new block inside existing one, adjust new block
- dp->df_lnum[idx_new] = lnum_new + off;
- dp->df_count[idx_new] = count_new - off;
+ dp->df_lnum[idx_new] = hunk->lnum_new + off;
+ dp->df_count[idx_new] = hunk->count_new - off;
} else {
// second overlap of new block with existing block
- dp->df_count[idx_new] += count_new - count_orig
+ dp->df_count[idx_new] += hunk->count_new - hunk->count_orig
+ dpl->df_lnum[idx_orig] +
dpl->df_count[idx_orig]
- (dp->df_lnum[idx_orig] +
@@ -1659,7 +1676,7 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
// Adjust the size of the block to include all the lines to the
// end of the existing block or the new diff, whatever ends last.
- off = (lnum_orig + count_orig)
+ off = (hunk->lnum_orig + hunk->count_orig)
- (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]);
if (off < 0) {
@@ -1691,10 +1708,10 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
// Allocate a new diffblock.
dp = diff_alloc_new(curtab, dprev, dp);
- dp->df_lnum[idx_orig] = lnum_orig;
- dp->df_count[idx_orig] = count_orig;
- dp->df_lnum[idx_new] = lnum_new;
- dp->df_count[idx_new] = count_new;
+ dp->df_lnum[idx_orig] = hunk->lnum_orig;
+ dp->df_count[idx_orig] = hunk->count_orig;
+ dp->df_lnum[idx_new] = hunk->lnum_new;
+ dp->df_count[idx_new] = hunk->count_new;
// Set values for other buffers, these must be equal to the
// original buffer, otherwise there would have been a change
@@ -1718,6 +1735,10 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
notset = true;
}
+ if (!dio->dio_internal) {
+ xfree(hunk);
+ }
+
if (fd != NULL) {
fclose(fd);
}
@@ -3026,8 +3047,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp)
/// Handle an ED style diff line.
/// Return FAIL if the line does not contain diff info.
///
-static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, linenr_T *lnum_new,
- long *count_new)
+static int parse_diff_ed(char_u *line, diffhunk_T *hunk)
{
char_u *p;
long f1, l1, f2, l2;
@@ -3061,18 +3081,18 @@ static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, li
}
if (difftype == 'a') {
- *lnum_orig = f1 + 1;
- *count_orig = 0;
+ hunk->lnum_orig = f1 + 1;
+ hunk->count_orig = 0;
} else {
- *lnum_orig = f1;
- *count_orig = l1 - f1 + 1;
+ hunk->lnum_orig = f1;
+ hunk->count_orig = l1 - f1 + 1;
}
if (difftype == 'd') {
- *lnum_new = f2 + 1;
- *count_new = 0;
+ hunk->lnum_new = f2 + 1;
+ hunk->count_new = 0;
} else {
- *lnum_new = f2;
- *count_new = l2 - f2 + 1;
+ hunk->lnum_new = f2;
+ hunk->count_new = l2 - f2 + 1;
}
return OK;
}
@@ -3081,8 +3101,7 @@ static int parse_diff_ed(char_u *line, linenr_T *lnum_orig, long *count_orig, li
/// Parses unified diff with zero(!) context lines.
/// Return FAIL if there is no diff information in "line".
///
-static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_orig,
- linenr_T *lnum_new, long *count_new)
+static int parse_diff_unified(char_u *line, diffhunk_T *hunk)
{
char_u *p;
long oldline, oldcount, newline, newcount;
@@ -3120,10 +3139,10 @@ static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_ori
newline = 1;
}
- *lnum_orig = oldline;
- *count_orig = oldcount;
- *lnum_new = newline;
- *count_new = newcount;
+ hunk->lnum_orig = oldline;
+ hunk->count_orig = oldcount;
+ hunk->lnum_new = newline;
+ hunk->count_new = newcount;
return OK;
}
@@ -3135,25 +3154,17 @@ static int parse_diff_unified(char_u *line, linenr_T *lnum_orig, long *count_ori
/// Callback function for the xdl_diff() function.
/// Stores the diff output in a grow array.
///
-static int xdiff_out(void *priv, mmbuffer_t *mb, int nbuf)
+static int xdiff_out(long start_a, long count_a, long start_b, long count_b,
+ void *priv)
{
diffout_T *dout = (diffout_T *)priv;
- char_u *p;
-
- // The header line always comes by itself, text lines in at least two
- // parts. We drop the text part.
- if (nbuf > 1) {
- return 0;
- }
-
- // sanity check
- if (STRNCMP(mb[0].ptr, "@@ ", 3) != 0) {
- return 0;
- }
+ diffhunk_T *p = xmalloc(sizeof(*p));
ga_grow(&dout->dout_ga, 1);
-
- p = vim_strnsave((char_u *)mb[0].ptr, mb[0].size);
- ((char_u **)dout->dout_ga.ga_data)[dout->dout_ga.ga_len++] = p;
+ p->lnum_orig = start_a + 1;
+ p->count_orig = count_a;
+ p->lnum_new = start_b + 1;
+ p->count_new = count_b;
+ ((diffhunk_T **)dout->dout_ga.ga_data)[dout->dout_ga.ga_len++] = p;
return 0;
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 6c2db1e9ac..013a78bdac 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -915,10 +915,29 @@ int do_record(int c)
apply_autocmds(EVENT_RECORDINGENTER, NULL, NULL, false, curbuf);
}
} else { // stop recording
+ save_v_event_T save_v_event;
+ // Set the v:event dictionary with information about the recording.
+ dict_T *dict = get_v_event(&save_v_event);
+
+ // The recorded text contents.
+ p = get_recorded();
+ if (p != NULL) {
+ // Remove escaping for CSI and K_SPECIAL in multi-byte chars.
+ vim_unescape_csi(p);
+ (void)tv_dict_add_str(dict, S_LEN("regcontents"), (const char *)p);
+ }
+
+ // Name of requested register, or empty string for unnamed operation.
+ char buf[NUMBUFLEN+2];
+ buf[0] = (char)regname;
+ buf[1] = NUL;
+ (void)tv_dict_add_str(dict, S_LEN("regname"), buf);
+
// Get the recorded key hits. K_SPECIAL and CSI will be escaped, this
// needs to be removed again to put it in a register. exec_reg then
// adds the escaping back later.
apply_autocmds(EVENT_RECORDINGLEAVE, NULL, NULL, false, curbuf);
+ restore_v_event(dict, &save_v_event);
reg_recorded = reg_recording;
reg_recording = 0;
if (ui_has(kUIMessages)) {
@@ -926,13 +945,9 @@ int do_record(int c)
} else {
msg("");
}
- p = get_recorded();
if (p == NULL) {
retval = FAIL;
} else {
- // Remove escaping for CSI and K_SPECIAL in multi-byte chars.
- vim_unescape_csi(p);
-
// We don't want to change the default register here, so save and
// restore the current register name.
old_y_previous = y_previous;
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 28b4eb9fe2..5133fe7ac8 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -411,7 +411,7 @@ return {
},
{
full_name='compatible', abbreviation='cp',
- short_desc=N_("No description"),
+ short_desc=N_("No description"),
type='bool', scope={'global'},
redraw={'all_windows'},
varname='p_force_off',
@@ -665,14 +665,14 @@ return {
},
{
full_name='edcompatible', abbreviation='ed',
- short_desc=N_("No description"),
+ short_desc=N_("No description"),
type='bool', scope={'global'},
varname='p_force_off',
defaults={if_true=false}
},
{
full_name='emoji', abbreviation='emo',
- short_desc=N_("No description"),
+ short_desc=N_("No description"),
type='bool', scope={'global'},
redraw={'all_windows', 'ui_option'},
varname='p_emoji',
@@ -1184,7 +1184,7 @@ return {
},
{
full_name='inccommand', abbreviation='icm',
- short_desc=N_("Live preview of substitution"),
+ short_desc=N_("Live preview of substitution"),
type='string', scope={'global'},
redraw={'all_windows'},
varname='p_icm',
@@ -2499,7 +2499,7 @@ return {
},
{
full_name='termencoding', abbreviation='tenc',
- short_desc=N_("Terminal encodig"),
+ short_desc=N_("Terminal encoding"),
type='string', scope={'global'},
defaults={if_true=""}
},
@@ -2622,7 +2622,7 @@ return {
},
{
full_name='ttyfast', abbreviation='tf',
- short_desc=N_("No description"),
+ short_desc=N_("No description"),
type='bool', scope={'global'},
no_mkrc=true,
varname='p_force_on',
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index ba6cfab98b..8a14710351 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -1536,7 +1536,7 @@ static inline void east_set_error(const ParserState *const pstate, ExprASTError
/* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
/* handle environment variables like those bash uses for */ \
/* `export -f`: their names consist not only of alphanumeric */ \
- /* characetrs. */ \
+ /* characters. */ \
case kExprNodeComplexIdentifier: \
case kExprNodePlainIdentifier: \
case kExprNodeCurlyBracesIdentifier: { \
diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h
index fe9327b27d..9d0bc9d468 100644
--- a/src/nvim/viml/parser/expressions.h
+++ b/src/nvim/viml/parser/expressions.h
@@ -57,7 +57,7 @@ typedef enum {
} LexExprTokenType;
typedef enum {
- kExprCmpEqual, ///< Equality, unequality.
+ kExprCmpEqual, ///< Equality, inequality.
kExprCmpMatches, ///< Matches regex, not matches regex.
kExprCmpGreater, ///< `>` or `<=`
kExprCmpGreaterOrEqual, ///< `>=` or `<`.