code: plan9front

Download patch

ref: 828c577e03e15f59a69bff965893e3a670a8f10f
parent: 4e4bd869e97fecee8921ecd8d135de061e73f372
author: umbraticus <umbraticus@prosimetrum.com>
date: Sat Jun 1 18:55:26 EDT 2024

sam: introduce a new command M for adding commands to mouse b2 menu

--- 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",
 	"<rio>",
-	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);