9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] sam menu command patch
@ 2024-06-01 11:44 umbraticus
  2024-06-01 12:30 ` qwx
  0 siblings, 1 reply; 2+ messages in thread
From: umbraticus @ 2024-06-01 11:44 UTC (permalink / raw)
  To: 9front

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [9front] sam menu command patch
  2024-06-01 11:44 [9front] sam menu command patch umbraticus
@ 2024-06-01 12:30 ` qwx
  0 siblings, 0 replies; 2+ messages in thread
From: qwx @ 2024-06-01 12:30 UTC (permalink / raw)
  To: 9front

On Sat Jun  1 13:43:46 +0200 2024, umbraticus@prosimetrum.com wrote:
> 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.

Fuck yes.  Let's merge it.

I don't think this mail alone does the patch justice.  Here are two
examples of a collection of samscripts one can preload:

http://runjimmyrunrunyoufuckerrun.com/rc/s
http://shithub.us/qwx/rc/HEAD/bin/s/f.html

To load these, you do ^s in sam, and they are now usable within it.
Check out the u script in either file: !u starts a new rio window
showing the description of these and their usage (from my own
script):

^r [cmd]     # run command in cwd and send output to jam.err window
^R [cmd]     # run command and send output to jam.err window
^T	# write to disk any modified files
!o name expr # save a sam command
^O expr      # run any rc function
^w [cmd]     # open window in cwd
^W [cmd]     # open window in current file's directory
^dump		# print all files in menu
!u [fn...]   # print sam fn usage
^+ [n]       # increase indent
^- [n]       # decrease indent
[etc.]

What this patch does is allow you in addition to add these to your mb2
mouse menu.  For example, my s script sources a file in my $home/lib
directory that looks like this:

cat <<!
M ^W
M ^-
M ^+
M ^T
M ^r D
M ^r mk install
M ^r mk clean
M |fmt -l 82
M ^r mk coarsen.install
M ^R ass
!
fn dicks {
	for(i in 01 02 03 04 05 06 07 08 09 10 11 12) mk testct^$i^.install
}

Then I can open the mouse menu and select ^T to write all open files,
or select a line of text and do ^+ to indent it, or run ^r mk install
to rebuild what I have in the current directory, or ^R d to open a
vdiff in the directory the current file is in, or !fmt -l 80 over the
selection, or run some command I've been using a lot, or [etc.]

It's just examples.  You can select something in the command window,
type M and 'send' it, and you have a menu item to re-run it at
moment's notice.  You delete menu items by just issuing the same M
command as before.  It's incredibly effective, I love it and I vouch
for it 1000%.

Thanks,
qwx

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-06-01 12:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-01 11:44 [9front] sam menu command patch umbraticus
2024-06-01 12:30 ` qwx

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).