aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Bakker <captaingroove@openmultimedia.org>2023-06-16 11:59:25 +0200
committerRandy Palamar <palamar@ualberta.ca>2023-07-18 21:06:46 -0600
commit80fbb7e1ead4d16f1f4d511d30df18eeb65ceafa (patch)
tree106950ed5bdcfbc14b18c6bc8e96df92aa951268
parent599ced0bfc378682053484a9658bd59c02c96973 (diff)
downloadvis-80fbb7e1ead4d16f1f4d511d30df18eeb65ceafa.tar.gz
vis-80fbb7e1ead4d16f1f4d511d30df18eeb65ceafa.tar.xz
Add fullscreen param to vis_pipe_collect() and Lua API vis:pipe()
This enables restoring the terminal from a fullscreen command like curses based program. Use cases are e.g. a file picker based on some external program like nnn (https://github.com/jarun/nnn).
-rw-r--r--sam.c4
-rw-r--r--ui-terminal-curses.c9
-rw-r--r--ui-terminal-vt100.c2
-rw-r--r--ui-terminal.c4
-rw-r--r--ui.h2
-rw-r--r--vis-cmds.c2
-rw-r--r--vis-lua.c5
-rw-r--r--vis-registers.c4
-rw-r--r--vis.c10
-rw-r--r--vis.h10
10 files changed, 34 insertions, 18 deletions
diff --git a/sam.c b/sam.c
index d088e9c..5a8a0b1 100644
--- a/sam.c
+++ b/sam.c
@@ -1739,7 +1739,7 @@ static bool cmd_filter(Vis *vis, Win *win, Command *cmd, const char *argv[], Sel
buffer_init(&bufout);
buffer_init(&buferr);
- int status = vis_pipe(vis, win->file, range, &argv[1], &bufout, read_buffer, &buferr, read_buffer);
+ int status = vis_pipe(vis, win->file, range, &argv[1], &bufout, read_buffer, &buferr, read_buffer, false);
if (vis->interrupted) {
vis_info_show(vis, "Command cancelled");
@@ -1779,7 +1779,7 @@ static bool cmd_pipeout(Vis *vis, Win *win, Command *cmd, const char *argv[], Se
Buffer buferr;
buffer_init(&buferr);
- int status = vis_pipe(vis, win->file, range, (const char*[]){ argv[1], NULL }, NULL, NULL, &buferr, read_buffer);
+ int status = vis_pipe(vis, win->file, range, (const char*[]){ argv[1], NULL }, NULL, NULL, &buferr, read_buffer, false);
if (vis->interrupted)
vis_info_show(vis, "Command cancelled");
diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c
index e5ab853..93f729e 100644
--- a/ui-terminal-curses.c
+++ b/ui-terminal-curses.c
@@ -242,9 +242,14 @@ static bool ui_curses_resize(UiTerm *tui, int width, int height) {
wresize(stdscr, height, width) == OK;
}
-static void ui_curses_save(UiTerm *tui) {
+static void ui_curses_save(UiTerm *tui, bool fscr) {
curs_set(1);
- reset_shell_mode();
+ if (fscr) {
+ def_prog_mode();
+ endwin();
+ } else {
+ reset_shell_mode();
+ }
}
static void ui_curses_restore(UiTerm *tui) {
diff --git a/ui-terminal-vt100.c b/ui-terminal-vt100.c
index 8ba8a1a..33ad7fb 100644
--- a/ui-terminal-vt100.c
+++ b/ui-terminal-vt100.c
@@ -172,7 +172,7 @@ static bool ui_vt100_resize(UiTerm *tui, int width, int height) {
return true;
}
-static void ui_vt100_save(UiTerm *tui) {
+static void ui_vt100_save(UiTerm *tui, bool fscr) {
cursor_visible(true);
}
diff --git a/ui-terminal.c b/ui-terminal.c
index 9cdfd7e..f3b9f04 100644
--- a/ui-terminal.c
+++ b/ui-terminal.c
@@ -627,9 +627,9 @@ static bool ui_getkey(Ui *ui, TermKeyKey *key) {
return ret == TERMKEY_RES_KEY;
}
-static void ui_terminal_save(Ui *ui) {
+static void ui_terminal_save(Ui *ui, bool fscr) {
UiTerm *tui = (UiTerm*)ui;
- ui_term_backend_save(tui);
+ ui_term_backend_save(tui, fscr);
termkey_stop(tui->termkey);
}
diff --git a/ui.h b/ui.h
index d87384a..94b45f5 100644
--- a/ui.h
+++ b/ui.h
@@ -99,7 +99,7 @@ struct Ui {
void (*suspend)(Ui*);
void (*resume)(Ui*);
bool (*getkey)(Ui*, TermKeyKey*);
- void (*terminal_save)(Ui*);
+ void (*terminal_save)(Ui*, bool fscr);
void (*terminal_restore)(Ui*);
TermKey* (*termkey_get)(Ui*);
int (*colors)(Ui*);
diff --git a/vis-cmds.c b/vis-cmds.c
index 2993267..fe1ab77 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -408,7 +408,7 @@ static const char *file_open_dialog(Vis *vis, const char *pattern) {
Filerange empty = text_range_new(0,0);
int status = vis_pipe(vis, vis->win->file, &empty,
(const char*[]){ buffer_content0(&bufcmd), NULL },
- &bufout, read_buffer, &buferr, read_buffer);
+ &bufout, read_buffer, &buferr, read_buffer, false);
if (status == 0)
strncpy(name, buffer_content0(&bufout), sizeof(name)-1);
diff --git a/vis-lua.c b/vis-lua.c
index 735445b..e304dd7 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -1331,6 +1331,7 @@ static int exit_func(lua_State *L) {
* @tparam[opt] File file the file to which the range applies
* @tparam[opt] Range range the range to pipe
* @tparam string command the command to execute
+ * @tparam[opt] bool fullscreen whether command is a fullscreen program (e.g. curses based)
* @treturn int code the exit status of the executed command
* @treturn string stdout the data written to stdout
* @treturn string stderr the data written to stderr
@@ -1348,7 +1349,8 @@ static int pipe_func(lua_State *L) {
range = getrange(L, 3);
}
const char *cmd = luaL_checkstring(L, cmd_idx);
- int status = vis_pipe_collect(vis, file, &range, (const char*[]){ cmd, NULL }, &out, &err);
+ bool fullscreen = lua_isboolean(L, cmd_idx + 1) && lua_toboolean(L, cmd_idx + 1);
+ int status = vis_pipe_collect(vis, file, &range, (const char*[]){ cmd, NULL }, &out, &err, fullscreen);
lua_pushinteger(L, status);
if (out)
lua_pushstring(L, out);
@@ -1363,6 +1365,7 @@ static int pipe_func(lua_State *L) {
vis_draw(vis);
return 3;
}
+
/***
* Redraw complete user interface.
*
diff --git a/vis-registers.c b/vis-registers.c
index 6de3374..1875da9 100644
--- a/vis-registers.c
+++ b/vis-registers.c
@@ -83,7 +83,7 @@ const char *register_slot_get(Vis *vis, Register *reg, size_t slot, size_t *len)
cmd[3] = "clipboard";
int status = vis_pipe(vis, vis->win->file,
&(Filerange){ .start = 0, .end = 0 },
- cmd, buf, read_buffer, &buferr, read_buffer);
+ cmd, buf, read_buffer, &buferr, read_buffer, false);
if (status != 0)
vis_info_show(vis, "Command failed %s", buffer_content0(&buferr));
@@ -167,7 +167,7 @@ bool register_slot_put_range(Vis *vis, Register *reg, size_t slot, Text *txt, Fi
cmd[3] = "clipboard";
int status = vis_pipe(vis, vis->win->file, range,
- cmd, NULL, NULL, &buferr, read_buffer);
+ cmd, NULL, NULL, &buferr, read_buffer, false);
if (status != 0)
vis_info_show(vis, "Command failed %s", buffer_content0(&buferr));
diff --git a/vis.c b/vis.c
index f21efa8..0ffbd39 100644
--- a/vis.c
+++ b/vis.c
@@ -1729,7 +1729,8 @@ Regex *vis_regex(Vis *vis, const char *pattern) {
int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[],
void *stdout_context, ssize_t (*read_stdout)(void *stdout_context, char *data, size_t len),
- void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len)) {
+ void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len),
+ bool fullscreen) {
/* if an invalid range was given, stdin (i.e. key board input) is passed
* through the external command. */
@@ -1754,7 +1755,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[],
return -1;
}
- vis->ui->terminal_save(vis->ui);
+ vis->ui->terminal_save(vis->ui, fullscreen);
pid_t pid = fork();
if (pid == -1) {
@@ -1958,13 +1959,14 @@ static ssize_t read_buffer(void *context, char *data, size_t len) {
return len;
}
-int vis_pipe_collect(Vis *vis, File *file, Filerange *range, const char *argv[], char **out, char **err) {
+int vis_pipe_collect(Vis *vis, File *file, Filerange *range, const char *argv[], char **out, char **err, bool fullscreen) {
Buffer bufout, buferr;
buffer_init(&bufout);
buffer_init(&buferr);
int status = vis_pipe(vis, file, range, argv,
&bufout, out ? read_buffer : NULL,
- &buferr, err ? read_buffer : NULL);
+ &buferr, err ? read_buffer : NULL,
+ fullscreen);
buffer_terminate(&bufout);
buffer_terminate(&buferr);
if (out)
diff --git a/vis.h b/vis.h
index 85a458a..f8c5680 100644
--- a/vis.h
+++ b/vis.h
@@ -898,6 +898,10 @@ bool vis_prompt_cmd(Vis*, const char *cmd);
* If the ``read_stdout`` and ``read_stderr`` callbacks are non-NULL they
* will be invoked when output from the forked process is available.
*
+ * If ``fullscreen`` is set to ``true`` the external process is assumed to
+ * be a fullscreen program (e.g. curses based) and the ui context is
+ * restored accordingly.
+ *
* @rst
* .. warning:: The editor core is blocked until this function returns.
* @endrst
@@ -906,7 +910,8 @@ bool vis_prompt_cmd(Vis*, const char *cmd);
*/
int vis_pipe(Vis*, File*, Filerange*, const char *argv[],
void *stdout_context, ssize_t (*read_stdout)(void *stdout_context, char *data, size_t len),
- void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len));
+ void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len),
+ bool fullscreen);
/**
* Pipe a Filerange to an external process, return its exit status and capture
@@ -914,12 +919,13 @@ int vis_pipe(Vis*, File*, Filerange*, const char *argv[],
* @param argv Argument list, must be ``NULL`` terminated.
* @param out Data written to ``stdout``, will be ``NUL`` terminated.
* @param err Data written to ``stderr``, will be ``NUL`` terminated.
+ * @param fullscreen Whether the external process is a fullscreen program (e.g. curses based)
* @rst
* .. warning:: The pointers stored in ``out`` and ``err`` need to be `free(3)`-ed
* by the caller.
* @endrst
*/
-int vis_pipe_collect(Vis*, File*, Filerange*, const char *argv[], char **out, char **err);
+int vis_pipe_collect(Vis*, File*, Filerange*, const char *argv[], char **out, char **err, bool fullscreen);
/**
* @}