From: Michael D. Lowis Date: Tue, 26 Nov 2019 21:16:39 +0000 (-0500) Subject: reworked exec handling to allow auto complete shortucts to function properly X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d505d0ff8df116459bc23e99e12200cdb3e27b66;p=projs%2Ftide.git reworked exec handling to allow auto complete shortucts to function properly --- diff --git a/src/lib/exec.c b/src/lib/exec.c new file mode 100644 index 0000000..a12876e --- /dev/null +++ b/src/lib/exec.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include "config.h" + +typedef struct { + char* tag; + void (*action)(char*); +} Tag; + +static Tag* Builtins = NULL; + +void exec_init(Tag* p_tags) +{ + Builtins = p_tags; + /* setup the shell */ + if (!ShellCmd[0]) ShellCmd[0] = getenv("SHELL"); + if (!ShellCmd[0]) ShellCmd[0] = "/bin/sh"; + require(ShellCmd[0]); +} + +static Tag* tag_lookup(char* cmd) +{ + size_t len = 0; + Tag* tags = Builtins; + + for (char* tag = cmd; *tag && !isspace(*tag); tag++, len++) + { + /* do nothing */ + } + + while (tags->tag) + { + if (!strncmp(tags->tag, cmd, len)) + break; + tags++; + } + return (tags->tag ? tags : NULL); +} + +static void shell_exec(char* cmd) +{ + /* parse the command sigils */ + char op = '\0', **execcmd = NULL; + if (rissigil(*cmd)) op = *(cmd++); + execcmd = (op == ':' ? SedCmd : ShellCmd); + execcmd[2] = cmd; + + /* get the selection that the command will operate on */ + if (op && op != '<' && op != '!' && op != '&' && !view_selsize(win_view(EDIT))) + { + view_selectall(win_view(EDIT)); + } + char* input = view_getstr(win_view(EDIT)); + size_t len = (input ? strlen(input) : 0); + View *tags = win_view(TAGS), *edit = win_view(EDIT), *curr = win_view(FOCUSED); + + /* execute the job */ + if (op == '!' || op == '&') + { + free(input); + if (op == '&') + { + xpty_run(win_view(EDIT), execcmd); + } + else + { + job_start(execcmd, NULL, 0, NULL); + } + } + else if (op == '>') + { + job_start(execcmd, input, len, tags); + } + else if (op == '|' || op == ':') + { + job_start(execcmd, input, len, edit); + } + else + { + job_start(execcmd, input, len, (op != '<' ? curr : edit)); + } +} + +void exec_cmd(char* str) +{ + if (str && *str) + { + bool shellcmd = (str[0] == ':' && str[1] == ';'); + if (xpty_active() && (!rissigil(*str) || shellcmd)) + { + xpty_send(str); + } + else + { + shell_exec(str); + } + } +} + +void exec_cmdwarg(char* cmd, char* arg) +{ + /* skip leading space */ + for (; *cmd && isspace(*cmd); cmd++); + if (!*cmd) return; + /* see if it matches a builtin tag */ + Tag* tag = tag_lookup(cmd); + if (tag) + { + for (; *cmd && !isspace(*cmd); cmd++); /* strip off tag name */ + for (; *cmd && isspace(*cmd); cmd++); /* strip off leading space */ + arg = (*cmd ? strdup(cmd) : arg); + tag->action(!arg || !*arg ? NULL : arg); + } + else if (arg) + { + cmd = (arg ? strmcat(cmd, " '", arg, "'", 0) : strmcat(cmd)); + exec_cmd(cmd); + free(cmd); + } + else + { + exec_cmd(cmd); + } +} + +void exec_rawwarg(char* cmd, char* arg) +{ + cmd = (arg ? strmcat(cmd, " '", arg, "'", 0) : strmcat(cmd)); + shell_exec(cmd); + free(cmd); +} diff --git a/src/tide.c b/src/tide.c index 1b67ac9..6718d7b 100644 --- a/src/tide.c +++ b/src/tide.c @@ -10,21 +10,25 @@ #include #include +//#include +typedef struct { + char* tag; + void (*action)(char*); +} Tag; +void exec_init(Tag* p_tags); +void exec_cmd(char* cmd); +void exec_cmdwarg(char* cmd, char* arg); +void exec_rawwarg(char* cmd, char* arg); + #define INCLUDE_DEFS #include "config.h" /* predeclare some things */ -static void exec(char* cmd, char* arg); void cut(char* arg); void paste(char* arg); -typedef struct { - char* tag; - void (*action)(char*); -} Tag; - char* ARGV0; -static Tag* Builtins; +Tag* Builtins; static KeyBinding* Bindings; static WinRegion Focused = EDIT; static View Regions[NREGIONS]; @@ -177,7 +181,7 @@ static void xmousebtn(XConf* x, XEvent* e) case MouseActExec: { char* str = view_fetch(win_view(Focused), row, col, riscmd); - exec(str, NULL); + exec_cmdwarg(str, NULL); free(str); break; } @@ -188,7 +192,7 @@ static void xmousebtn(XConf* x, XEvent* e) if (!arg || !*arg) arg = view_getstr(win_view(EDIT)); if (!arg || !*arg) arg = view_getstr(win_view(TAGS)); char* str = view_fetch(win_view(Focused), row, col, riscmd); - if (str) exec(str, arg); + if (str) exec_cmdwarg(str, arg); free(str); free(arg); break; @@ -417,113 +421,6 @@ void win_setln(int line_num) SyncMouse = true; } -/* Tag/Cmd Execution - ******************************************************************************/ -static Tag* tag_lookup(char* cmd) -{ - size_t len = 0; - Tag* tags = Builtins; - - for (char* tag = cmd; *tag && !isspace(*tag); tag++, len++) - { - /* do nothing */ - } - - while (tags->tag) - { - if (!strncmp(tags->tag, cmd, len)) - break; - tags++; - } - return (tags->tag ? tags : NULL); -} - -static void cmd_exec(char* cmd) -{ - /* parse the command sigils */ - char op = '\0', **execcmd = NULL; - if (rissigil(*cmd)) op = *(cmd++); - execcmd = (op == ':' ? SedCmd : ShellCmd); - execcmd[2] = cmd; - - /* get the selection that the command will operate on */ - if (op && op != '<' && op != '!' && op != '&' && !view_selsize(win_view(EDIT))) - { - view_selectall(win_view(EDIT)); - } - char* input = view_getstr(win_view(EDIT)); - size_t len = (input ? strlen(input) : 0); - View *tags = win_view(TAGS), *edit = win_view(EDIT), *curr = win_view(FOCUSED); - - /* execute the job */ - if (op == '!' || op == '&') - { - free(input); - if (op == '&') - { - xpty_run(win_view(EDIT), execcmd); - } - else - { - job_start(execcmd, NULL, 0, NULL); - } - } - else if (op == '>') - { - job_start(execcmd, input, len, tags); - } - else if (op == '|' || op == ':') - { - job_start(execcmd, input, len, edit); - } - else - { - job_start(execcmd, input, len, (op != '<' ? curr : edit)); - } -} - -static void exec_or_send(char* str) -{ - if (str && *str) - { - bool shellcmd = (str[0] == ':' && str[1] == ';'); - if (xpty_active() && !rissigil(*str) && !shellcmd) - { - xpty_send(str); - } - else - { - cmd_exec(str); - } - } -} - -static void exec(char* cmd, char* arg) -{ - /* skip leading space */ - for (; *cmd && isspace(*cmd); cmd++); - if (!*cmd) return; - /* see if it matches a builtin tag */ - Tag* tag = tag_lookup(cmd); - if (tag) - { - for (; *cmd && !isspace(*cmd); cmd++); /* strip off tag name */ - for (; *cmd && isspace(*cmd); cmd++); /* strip off leading space */ - arg = (*cmd ? strdup(cmd) : arg); - tag->action(!arg || !*arg ? NULL : arg); - } - else if (arg) - { - cmd = (arg ? strmcat(cmd, " '", arg, "'", 0) : strmcat(cmd)); - exec_or_send(cmd); - free(cmd); - } - else - { - exec_or_send(cmd); - } -} - /* Keyboard and Tag Handlers ******************************************************************************/ static void change_focus(char* arg) @@ -591,7 +488,7 @@ static void execute(char* arg) { (void)arg; char* str = view_getcmd(win_view(FOCUSED)); - exec(str, NULL); + exec_cmdwarg(str, NULL); free(str); } @@ -604,12 +501,12 @@ static void find(char* arg) static void open_file(char* arg) { (void)arg; - cmd_exec(CMD_PICKFILE); + exec_cmd(CMD_PICKFILE); } static void pick_symbol(char* symbol) { - exec(CMD_GOTO_TAG, symbol); + exec_rawwarg(CMD_GOTO_TAG, symbol); } static void pick_ctag(char* arg) @@ -623,7 +520,7 @@ static void complete(char* arg) (void)arg; View* view = win_view(FOCUSED); view_selectobj(view, risword); - exec(CMD_COMPLETE, view_getstr(view)); + exec_rawwarg(CMD_COMPLETE, view_getstr(view)); } static void fcomplete(char* arg) @@ -631,7 +528,7 @@ static void fcomplete(char* arg) (void)arg; View* view = win_view(FOCUSED); view_selectobj(view, risfile); - exec(CMD_FCOMPLETE, view_getstr(view)); + exec_rawwarg(CMD_FCOMPLETE, view_getstr(view)); } static void jump_to(char* arg) @@ -680,13 +577,13 @@ static void eol_mode(char* arg) static void new_win(char* arg) { (void)arg; - cmd_exec(CMD_TIDE); + exec_cmd(CMD_TIDE); } static void lnexec(char* cmd) { select_line(NULL); - exec(cmd, NULL); + exec_cmdwarg(cmd, NULL); } static void tag_kill(char* cmd) @@ -712,7 +609,7 @@ static void tag_line(char* cmd) /* Main Routine ******************************************************************************/ -static Tag* Builtins = (Tag[]){ +Tag* Builtins = (Tag[]){ { .tag = "Cut", .action = cut }, { .tag = "Copy", .action = copy }, { .tag = "Del", .action = quit }, @@ -849,12 +746,8 @@ int main(int argc, char** argv) } OPTEND; - /* setup the shell */ - if (!ShellCmd[0]) ShellCmd[0] = getenv("SHELL"); - if (!ShellCmd[0]) ShellCmd[0] = "/bin/sh"; - require(ShellCmd[0]); - /* Initialize the window and views */ + exec_init(Builtins); win_init(); view_init(&Regions[TAGS], NULL); view_init(&Regions[EDIT], NULL); @@ -879,7 +772,7 @@ int main(int argc, char** argv) if (termcmd) { termcmd = strmcat("&", termcmd, 0); - cmd_exec(termcmd); + exec_cmd(termcmd); free(termcmd); }