From 4600b76efe80c9ba0461276412e58992d2300cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Fri, 13 Jan 2017 13:18:44 +0100 Subject: vis: introduce registers 0-9 and & to capture search matches These are currently only updated for `x` and `y` sam commands, whether they should be updated for other search related activities (`/`, `?`, `n`, `N`, `*`, `#` etc.) needs to be investigated. --- man/vis.1 | 13 +++++++++++++ sam.c | 13 +++++++++++-- vis.c | 10 ++++++++++ vis.h | 10 ++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/man/vis.1 b/man/vis.1 index d7cd675..00f1880 100644 --- a/man/vis.1 +++ b/man/vis.1 @@ -116,6 +116,13 @@ system clipboard integration via shell script .Xr vis-clipboard 1 .It \(dq0 yank register, most recently yanked range +.It \(dq1-\(dq9 +.It \(dq& +sub expression matches of most recent +.Ic x +or +.Ic y +command .It \(dq/ search register, most recently used search pattern .It \(dq: @@ -518,6 +525,12 @@ If the regular expression and its slashes are omitted, .Li "/.*\[rs]n/" is assumed. Null string matches potentially occur before every character of the range and at the end of the range. +.Pp +The +.Ic \(dq1-\(dq9 +and +.Ic \(dq& +registers are updated with the (sub) expression matches of the pattern. .It Ic y/regexp/ Bq command Like .Ic x , diff --git a/sam.c b/sam.c index a56bedb..5909a8e 100644 --- a/sam.c +++ b/sam.c @@ -1181,11 +1181,14 @@ static bool cmd_extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Cu if (cmd->regex) { bool trailing_match = false; size_t start = range->start, end = range->end, last_start = EPOS; - RegexMatch match[1]; + size_t nsub = 1 + text_regex_nsub(cmd->regex); + if (nsub > 10) + nsub = 10; + RegexMatch match[nsub]; while (start < end || trailing_match) { trailing_match = false; bool found = text_search_range_forward(txt, start, - end - start, cmd->regex, 1, match, + end - start, cmd->regex, nsub, match, start > range->start ? REG_NOTBOL : 0) == 0; Filerange r = text_range_empty(); if (found) { @@ -1216,6 +1219,12 @@ static bool cmd_extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Cu } if (text_range_valid(&r)) { + if (found) { + for (size_t i = 0; i < nsub; i++) { + Register *reg = &vis->registers[VIS_REG_AMPERSAND+i]; + register_put_range(vis, reg, txt, &match[i]); + } + } ret &= sam_execute(vis, win, cmd->cmd, NULL, &r); last_start = start; } diff --git a/vis.c b/vis.c index 691c3fc..94ea2e4 100644 --- a/vis.c +++ b/vis.c @@ -37,6 +37,16 @@ const MarkDef vis_marks[] = { const RegisterDef vis_registers[] = { [VIS_REG_DEFAULT] = { '"', "Unnamed register" }, [VIS_REG_ZERO] = { '0', "Yank register" }, + [VIS_REG_1] = { '1', "1st sub-expression match" }, + [VIS_REG_2] = { '2', "2nd sub-expression match" }, + [VIS_REG_3] = { '3', "3rd sub-expression match" }, + [VIS_REG_4] = { '4', "4th sub-expression match" }, + [VIS_REG_5] = { '5', "5th sub-expression match" }, + [VIS_REG_6] = { '6', "6th sub-expression match" }, + [VIS_REG_7] = { '7', "7th sub-expression match" }, + [VIS_REG_8] = { '8', "8th sub-expression match" }, + [VIS_REG_9] = { '9', "9th sub-expression match" }, + [VIS_REG_AMPERSAND] = { '&', "Last regex match" }, [VIS_REG_BLACKHOLE] = { '_', "/dev/null register" }, [VIS_REG_CLIPBOARD] = { '*', "System clipboard register, see vis-clipboard(1)" }, [VIS_MACRO_REPEAT] = { '.', "Last inserted text" }, diff --git a/vis.h b/vis.h index ab18d3b..4853c48 100644 --- a/vis.h +++ b/vis.h @@ -400,6 +400,16 @@ void vis_mark_set(Vis*, enum VisMark mark, size_t pos); enum VisRegister { VIS_REG_DEFAULT, /* used when no other register is specified */ VIS_REG_ZERO, /* yank register */ + VIS_REG_AMPERSAND, /* last regex match */ + VIS_REG_1, /* 1-9 last sub-expression matches */ + VIS_REG_2, + VIS_REG_3, + VIS_REG_4, + VIS_REG_5, + VIS_REG_6, + VIS_REG_7, + VIS_REG_8, + VIS_REG_9, VIS_REG_BLACKHOLE, /* /dev/null register */ VIS_REG_CLIPBOARD, /* system clipboard register */ VIS_MACRO_REPEAT, /* copy of the above macro once the recording is finished */ -- cgit v1.2.3