From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <9front-bounces@9front.inri.net> X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI autolearn=ham autolearn_force=no version=3.4.4 Received: from 9front.inri.net (9front.inri.net [168.235.81.73]) by inbox.vuxu.org (Postfix) with ESMTP id 6253C294B5 for ; Sat, 1 Jun 2024 13:45:23 +0200 (CEST) Received: from asquith.prosimetrum.com ([125.236.209.157]) by 9front; Sat Jun 1 07:44:17 -0400 2024 Message-ID: <7335757DA3222A181B6A8E6C78515DD2@prosimetrum.com> Date: Sat, 01 Jun 2024 23:44:52 +1200 From: umbraticus@prosimetrum.com To: 9front@9front.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: managed converged template-oriented configuration-aware ActivityPub over HTTP general-purpose framework-oriented framework Subject: [9front] sam menu command patch Reply-To: 9front@9front.org Precedence: bulk Others may find this useful; allows adding commands to sam's b2 menu. Rather than some kind of polling watch script, I prefer something like ^echo w; window 'mk && 6.out' from within sam; this makes such workflows even more convenient. You can combine with ^mysaminit and load all your favourite commands into the menu on startup. diff 40cb72e7f8cda9d21e1b7f738f6281e181c0de9e uncommitted --- a/sys/man/1/sam +++ b/sys/man/1/sam @@ -630,7 +630,7 @@ do not have defaults. .PD .SS Miscellany -.TF (empty) +.TF M_command .TP .B k Set the current file's mark to the range. Does not set dot. @@ -653,6 +653,7 @@ move further back in time. The only commands for which u is ineffective are .BR cd , +.BR M , .BR u , .BR q , .B w @@ -663,6 +664,10 @@ is negative, .B u `redoes,' undoing the undo, going forwards in time again. +.TP +.BI \*aM " command +Toggle the appearance of a menu entry for the command in the button 2 menu. +Selecting the entry with button 2 will run the command. .TP (empty) If the range is explicit, set dot to the range. --- a/sys/src/cmd/sam/cmd.c +++ b/sys/src/cmd/sam/cmd.c @@ -18,6 +18,7 @@ 'i', 1, 0, 0, 0, aDot, 0, 0, i_cmd, 'k', 0, 0, 0, 0, aDot, 0, 0, k_cmd, 'm', 0, 0, 1, 0, aDot, 0, 0, m_cmd, + 'M', 0, 0, 0, 0, aNo, 0, linex, M_cmd, 'n', 0, 0, 0, 0, aNo, 0, 0, n_cmd, 'p', 0, 0, 0, 0, aDot, 0, 0, p_cmd, 'q', 0, 0, 0, 0, aNo, 0, 0, q_cmd, --- a/sys/src/cmd/sam/mesg.c +++ b/sys/src/cmd/sam/mesg.c @@ -55,6 +55,7 @@ [Hack] "Hack", [Hexit] "Hexit", [Hplumb] "Hplumb", + [Hmenucmd] "Hmenucmd", }; char *tname[] = { @@ -82,6 +83,8 @@ [Tack] "Tack", [Texit] "Texit", [Tplumb] "Tplumb", + [Tmenucmd] "Tmenucmd", + [Tmenucmdsend] "Tmenucmdsend", }; void @@ -566,6 +569,22 @@ free(c); } plumbfree(pm); + break; + + case Tmenucmd: + dprint((char*)inp); + break; + + case Tmenucmdsend: + termlocked++; + str = tmpcstr((char*)inp); + Straddc(str, '\n'); + loginsert(cmd, cmd->nc, str->s, str->n); + freetmpstr(str); + fileupdate(cmd, FALSE, TRUE); + cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nc; + telldot(cmd); + termcommand(); break; case Texit: --- a/sys/src/cmd/sam/mesg.h +++ b/sys/src/cmd/sam/mesg.h @@ -1,8 +1,9 @@ /* VERSION 1 introduces plumbing 2 increases SNARFSIZE from 4096 to 32000 3 adds a triple click + 4 adds M command (add b2 menu action) */ -#define VERSION 3 +#define VERSION 4 #define TBLOCKSIZE 512 /* largest piece of text sent to terminal */ #define DATASIZE (UTFmax*TBLOCKSIZE+30) /* ... including protocol header stuff */ @@ -36,6 +37,8 @@ Texit, /* exit */ Tplumb, /* send plumb message */ Ttclick, /* triple click */ + Tmenucmd, /* list custom cmds in b2 menu */ + Tmenucmdsend, /* execute custom cmd from b2 menu */ TMAX, }Tmesg; /* @@ -69,6 +72,7 @@ Hack, /* request acknowledgement */ Hexit, Hplumb, /* return plumb message to terminal - version 1 */ + Hmenucmd, /* modify custom cmds in b2 menu */ HMAX, }Hmesg; typedef struct Header{ --- a/sys/src/cmd/sam/parse.h +++ b/sys/src/cmd/sam/parse.h @@ -57,7 +57,8 @@ int c_cmd(File*, Cmd*), cd_cmd(File*, Cmd*), d_cmd(File*, Cmd*); int D_cmd(File*, Cmd*), e_cmd(File*, Cmd*); int f_cmd(File*, Cmd*), g_cmd(File*, Cmd*), i_cmd(File*, Cmd*); -int k_cmd(File*, Cmd*), m_cmd(File*, Cmd*), n_cmd(File*, Cmd*); +int k_cmd(File*, Cmd*), m_cmd(File*, Cmd*); +int M_cmd(File*, Cmd*), n_cmd(File*, Cmd*); int p_cmd(File*, Cmd*), q_cmd(File*, Cmd*); int s_cmd(File*, Cmd*), u_cmd(File*, Cmd*), w_cmd(File*, Cmd*); int x_cmd(File*, Cmd*), X_cmd(File*, Cmd*), plan9_cmd(File*, Cmd*); --- a/sys/src/cmd/sam/xec.c +++ b/sys/src/cmd/sam/xec.c @@ -167,6 +167,17 @@ } int +M_cmd(File *f, Cmd *cp) +{ + USED(f); + if(downloaded) + outTS(Hmenucmd, cp->ctext); + else + dprint("not downloaded\n"); + return TRUE; +} + +int n_cmd(File *f, Cmd *cp) { int i; --- a/sys/src/cmd/samterm/menu.c +++ b/sys/src/cmd/samterm/menu.c @@ -29,9 +29,6 @@ Look, Exch, Search, - NMENU2 = Search, - Send = Search, - NMENU2C }; enum Menu3 @@ -51,7 +48,7 @@ "plumb", "look", "", - 0, /* storage for last pattern */ + nil, /* storage for last pattern */ }; char *menu3str[] = { @@ -66,7 +63,34 @@ Menu menu2c ={0, genmenu2c}; Menu menu3 = {0, genmenu3}; +typedef struct Menucmd Menucmd; +struct Menucmd{ + char *cmd; + Menucmd *next; +}*menucmds; + +char* +findmenucmd(int n){ + Menucmd *m; + + for(m = menucmds; n > 0 && m != nil; n--) + m = m->next; + if(n == 0 && m != nil) + return m->cmd; + return nil; +} + void +menucmdhit(char *s) +{ + if(s == nil) + return; + outstart(Tmenucmdsend); + outcopy(strlen(s), (uchar*)s); + outsend(); +} + +void menu2hit(void) { Text *t=(Text *)which->user1; @@ -109,12 +133,18 @@ break; case Search: - outcmd(); - if(t==&cmd) - outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1); - else - outT0(Tsearch); - setlock(); + if(t == &cmd || menu2str[Search] != nil){ + outcmd(); + if(t == &cmd) + outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1); + else + outT0(Tsearch); + setlock(); + break; + } + default: + m -= Search + (t == &cmd || menu2str[Search] != nil); + menucmdhit(findmenucmd(m)); break; } } @@ -285,6 +315,37 @@ menu2str[Search] = pat; } +void +menucmd(char *s) +{ + Menucmd **mp, *m; + + while(*s == ' ' || *s == '\t') + s++; + if(*s == 0){ + outstart(Tmenucmd); + for(m = menucmds; m != nil; m = m->next){ + outcopy(3, (uchar*)"\tM "); + outcopy(strlen(m->cmd), (uchar*)m->cmd); + outcopy(1, (uchar*)"\n"); + } + outsend(); + return; + } + for(mp = &menucmds; *mp != nil; mp = &(*mp)->next) + if(!strcmp(s, (*mp)->cmd)){ + m = *mp; + *mp = m->next; + free(m->cmd); + free(m); + return; + } + *mp = m = malloc(sizeof(Menucmd)); + if(m == nil) panic("malloc"); + m->cmd = strdup(s); + m->next = nil; +} + #define NBUF 64 static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '}; @@ -299,15 +360,23 @@ *t = 0; return (char *)buf; } + char* genmenu2(int n) { Text *t=(Text *)which->user1; char *p; - if(n>=NMENU2+(menu2str[Search]!=0)) - return 0; - p = menu2str[n]; - if(!hostlock && !t->lock || n==Search || n==Look) + if(n < Search || n == Search && menu2str[Search] != nil) + p = menu2str[n]; + else{ + n -= Search + (menu2str[Search] != nil); + p = findmenucmd(n); + if(p == nil) + return nil; + } + if(!hostlock && !t->lock + || p == menu2str[Search] + || p == menu2str[Look]) return p; return paren(p); } @@ -316,12 +385,12 @@ { Text *t=(Text *)which->user1; char *p; - if(n >= NMENU2C) - return 0; - if(n == Send) - p="send"; - else + if(n < Search) p = menu2str[n]; + else if(n == Search) + p = "send"; + else if((p = findmenucmd(n - Search - 1)) == nil) + return nil; if(!hostlock && !t->lock) return p; return paren(p); --- a/sys/src/cmd/samterm/mesg.c +++ b/sys/src/cmd/samterm/mesg.c @@ -300,6 +300,10 @@ case Hplumb: hplumb(m); break; + + case Hmenucmd: + menucmd((char *)indata); + break; } } --- a/sys/src/cmd/samterm/samterm.h +++ b/sys/src/cmd/samterm/samterm.h @@ -146,6 +146,7 @@ void menudel(int); Text *sweeptext(int, int); void setpat(char*); +void menucmd(char*); void scrdraw(Flayer*, long tot); int rcontig(Rasp*, ulong, ulong, int); int rmissing(Rasp*, ulong, ulong);