From b7c2ce741a207f82a51443b49d953508e64165e4 Mon Sep 17 00:00:00 2001 From: KlzXS Date: Thu, 10 Oct 2019 15:07:16 +0200 Subject: [PATCH] Implemented edit selection buffer (#345) * Implemented edit selection buffer * Added checks and changed keybind * Forgot check and style fixes * Don't work late at night again You forget things when you're tired --- src/nnn.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nnn.h | 3 ++ 2 files changed, 90 insertions(+) diff --git a/src/nnn.c b/src/nnn.c index 961fab8d..fe234501 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -886,6 +886,87 @@ static void endselection(void) } } +static bool seledit(void) +{ + bool ret = FALSE; + int fd, lines = 0; + ssize_t count; + + if (!selbufpos) { + DPRINTF_S("empty selection"); + return FALSE; + } + + fd = create_tmp_file(); + if (fd == -1) { + DPRINTF_S("couldn't create tmp file"); + return FALSE; + } + + seltofile(fd, NULL); + close(fd); + + spawn(editor, g_tmpfpath, NULL, NULL, F_CLI); + + if ((fd = open(g_tmpfpath, O_RDONLY)) == -1) { + DPRINTF_S("couldn't read tmp file"); + unlink(g_tmpfpath); + return FALSE; + } + + struct stat sb; + fstat(fd, &sb); + + if (sb.st_size > selbufpos) { + DPRINTF_S("edited buffer larger than pervious"); + goto emptyedit; + } + + count = read(fd, pselbuf, selbuflen); + close(fd); + unlink(g_tmpfpath); + + if (!count) { + ret = TRUE; + goto emptyedit; + } + + if (count < 0) { + DPRINTF_S("error reading tmp file"); + goto emptyedit; + } + + resetselind(); + selbufpos = count; + /* The last character should be '\n' */ + pselbuf[--count] = '\0'; + for (--count; count > 0; --count) { + /* Replace every '\n' that separates two paths */ + if (pselbuf[count] == '\n' && pselbuf[count + 1] == '/') { + ++lines; + pselbuf[count] = '\0'; + } + } + + if (lines > nselected) { + DPRINTF_S("files added to selection"); + goto emptyedit; + } + + nselected = lines; + writesel(pselbuf, selbufpos - 1); + + return TRUE; + +emptyedit: + resetselind(); + nselected = 0; + selbufpos = 0; + cfg.selmode = 0; + writesel(NULL, 0); + return ret; +} + static bool selsafe(void) { /* Fail if selection file path not generated */ @@ -4139,6 +4220,12 @@ nochange: printwait(messages[NONE_SELECTED], &presel); goto nochange; + case SEL_SELEDIT: + if (!seledit()){ + printwait("edit failed!", &presel); + goto nochange; + } + break; case SEL_CP: case SEL_MV: case SEL_RMMUL: diff --git a/src/nnn.h b/src/nnn.h index 19a95873..241e16e9 100644 --- a/src/nnn.h +++ b/src/nnn.h @@ -79,6 +79,7 @@ enum action { SEL_SELMUL, SEL_SELALL, SEL_SELLST, + SEL_SELEDIT, SEL_CP, SEL_MV, SEL_RMMUL, @@ -209,6 +210,8 @@ static struct key bindings[] = { { 'a', SEL_SELALL }, /* Show list of copied files */ { 'M', SEL_SELLST }, + /* Edit selection buffer */ + { 'K', SEL_SELEDIT }, /* Copy from selection buffer */ { 'P', SEL_CP }, /* Move from selection buffer */