Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

mg(1): shell-command

1 view
Skip to first unread message

Mark Lumsden

unread,
May 21, 2013, 4:04:10 PM5/21/13
to te...@openbsd.org
This diff modifies the shell-command-on-region function and gives us
shell-command. It makes getting output from other commands into mg
really easy. Comments/oks?

-lum

Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.135
diff -u -p -r1.135 def.h
--- def.h 25 Mar 2013 11:41:44 -0000 1.135
+++ def.h 21 May 2013 19:46:38 -0000
@@ -592,6 +592,7 @@ int region_get_data(struct region *, c
void region_put_data(const char *, int);
int markbuffer(int, int);
int piperegion(int, int);
+int shellcommand(int, int);
int pipeio(const char * const, char * const[], char * const, int,
struct buffer *);

Index: funmap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/funmap.c,v
retrieving revision 1.45
diff -u -p -r1.45 funmap.c
--- funmap.c 27 Dec 2012 18:51:52 -0000 1.45
+++ funmap.c 21 May 2013 19:46:38 -0000
@@ -179,6 +179,7 @@ static struct funmap functnames[] = {
{setfillcol, "set-fill-column",},
{setmark, "set-mark-command",},
{setprefix, "set-prefix-string",},
+ {shellcommand, "shell-command",},
{piperegion, "shell-command-on-region",},
{shrinkwind, "shrink-window",},
#ifdef NOTAB
Index: keymap.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/keymap.c,v
retrieving revision 1.50
diff -u -p -r1.50 keymap.c
--- keymap.c 7 Jun 2012 15:15:04 -0000 1.50
+++ keymap.c 21 May 2013 19:46:38 -0000
@@ -217,8 +217,9 @@ static PF metacV[] = {
pagenext /* ^V */
};

-static PF metasp[] = {
- justone /* space */
+static PF metaspex[] = {
+ justone, /* space */
+ shellcommand /* ! */
};

static PF metapct[] = {
@@ -317,7 +318,7 @@ struct KEYMAPE (8 + IMAPEXT) metamap = {
CCHR('V'), CCHR('V'), metacV, NULL
},
{
- ' ', ' ', metasp, NULL
+ ' ', '!', metaspex, NULL
},
{
'%', '%', metapct, NULL
Index: mg.1
===================================================================
RCS file: /cvs/src/usr.bin/mg/mg.1,v
retrieving revision 1.75
diff -u -p -r1.75 mg.1
--- mg.1 28 Dec 2012 16:12:50 -0000 1.75
+++ mg.1 21 May 2013 19:46:38 -0000
@@ -268,6 +268,8 @@ suspend-emacs
scroll-other-window
.It M-SPC
just-one-space
+.It M-!
+shell-command
.It M-.
find-tag
.It M-*
@@ -835,6 +837,8 @@ Used by auto-fill-mode.
Sets the mark in the current window to the current dot location.
.It set-prefix-string
Sets the prefix string to be used by the 'prefix-region' command.
+.It shell-command
+Execute external command from mini-buffer.
.It shell-command-on-region
Provide the text in region to the shell command as input.
.It shrink-window
Index: region.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/region.c,v
retrieving revision 1.32
diff -u -p -r1.32 region.c
--- region.c 27 Dec 2012 18:49:59 -0000 1.32
+++ region.c 21 May 2013 19:46:38 -0000
@@ -28,6 +28,7 @@ static int iomux(int, char * const, int,
static int preadin(int, struct buffer *);
static void pwriteout(int, char **, int *);
static int setsize(struct region *, RSIZE);
+static int shellcmdoutput(char * const[], char * const, int);

/*
* Kill the region. Ask "getregion" to figure out the bounds of the region.
@@ -406,9 +407,8 @@ int
piperegion(int f, int n)
{
struct region region;
- struct buffer *bp;
- int len, ret;
- char *cmd, cmdbuf[NFILEN], *shellp, *text;
+ int len;
+ char *cmd, cmdbuf[NFILEN], *text;
char *argv[] = {"sh", "-c", (char *) NULL, (char *) NULL};

/* C-u M-| is not supported yet */
@@ -436,6 +436,51 @@ piperegion(int f, int n)
return (FALSE);
}

+ region_get_data(&region, text, len);
+
+ return shellcmdoutput(argv, text, len);
+}
+
+/*
+ * Get command from mini-buffer and execute externally.
+ */
+/*ARGSUSED */
+int
+shellcommand(int f, int n)
+{
+
+ int len;
+ char *cmd, cmdbuf[NFILEN], *text;
+ char *argv[] = {"sh", "-c", (char *) NULL, (char *) NULL};
+
+ if (n > 1)
+ return (ABORT);
+
+ if ((cmd = eread("Shell command: ", cmdbuf, sizeof(cmdbuf),
+ EFNEW | EFCR)) == NULL || (cmd[0] == '\0'))
+ return (ABORT);
+
+ argv[2] = cmd;
+
+ len = strlen(cmd);
+
+ if ((text = malloc(len + 1)) == NULL) {
+ ewprintf("Cannot allocate memory.");
+ return (FALSE);
+ }
+
+ return shellcmdoutput(argv, NULL, 0);
+}
+
+
+int
+shellcmdoutput(char* const argv[], char* const text, int len)
+{
+
+ struct buffer *bp;
+ char *shellp;
+ int ret;
+
bp = bfind("*Shell Command Output*", TRUE);
bp->b_flag |= BFREADONLY;
if (bclear(bp) != TRUE) {
@@ -443,7 +488,6 @@ piperegion(int f, int n)
return (FALSE);
}

- region_get_data(&region, text, len);
shellp = getenv("SHELL");

ret = pipeio(shellp, argv, text, len, bp);

Jasper Lievisse Adriaanse

unread,
May 22, 2013, 3:33:47 AM5/22/13
to Mark Lumsden, te...@openbsd.org
On Tue, May 21, 2013 at 07:54:31PM +0000, Mark Lumsden wrote:
> This diff modifies the shell-command-on-region function and gives us
> shell-command. It makes getting output from other commands into mg
> really easy. Comments/oks?
>
> -lum

It seems Emacs doesn't split the window if the output from the command is only
a single line (like 'date'), which is behaviour I quite like if you want to
check something small.
--
Regards,

Jasper Lievisse Adriaanse,
Engineering team M:tier

Jasper Lievisse Adriaanse

unread,
May 22, 2013, 3:54:20 AM5/22/13
to Mark Lumsden, te...@openbsd.org
On Wed, May 22, 2013 at 07:42:42AM +0000, Mark Lumsden wrote:
> To make the shell-command-on-region and this command behave
> like that requires another diff.
>
> mark
I'm fine with this diff going in first and polishing it intree, it works fine
for commands with > 1 line of output.
--
Cheers,
Jasper

"Stay Hungry. Stay Foolish"

Mark Lumsden

unread,
May 22, 2013, 4:09:10 AM5/22/13
to Jasper Lievisse Adriaanse, te...@openbsd.org
To make the shell-command-on-region and this command behave
like that requires another diff.

mark

On Wed, May 22, 2013 at 09:32:45AM +0200, Jasper Lievisse Adriaanse wrote:

Florian Obser

unread,
May 22, 2013, 5:10:09 AM5/22/13
to Mark Lumsden, te...@openbsd.org
On Tue, May 21, 2013 at 07:54:31PM +0000, Mark Lumsden wrote:
you don't need len and *text

> + char *argv[] = {"sh", "-c", (char *) NULL, (char *) NULL};
> +
> + if (n > 1)
> + return (ABORT);
> +
> + if ((cmd = eread("Shell command: ", cmdbuf, sizeof(cmdbuf),
> + EFNEW | EFCR)) == NULL || (cmd[0] == '\0'))
> + return (ABORT);
> +
> + argv[2] = cmd;
> +

the following is unnecessary...

> + len = strlen(cmd);
> +
> + if ((text = malloc(len + 1)) == NULL) {
> + ewprintf("Cannot allocate memory.");
> + return (FALSE);
> + }

.. until here. In fact this is leaking text.

With that ok florian@

> +
> + return shellcmdoutput(argv, NULL, 0);
> +}
> +
> +
> +int
> +shellcmdoutput(char* const argv[], char* const text, int len)
> +{
> +
> + struct buffer *bp;
> + char *shellp;
> + int ret;
> +
> bp = bfind("*Shell Command Output*", TRUE);
> bp->b_flag |= BFREADONLY;
> if (bclear(bp) != TRUE) {
> @@ -443,7 +488,6 @@ piperegion(int f, int n)
> return (FALSE);
> }
>
> - region_get_data(&region, text, len);
> shellp = getenv("SHELL");
>
> ret = pipeio(shellp, argv, text, len, bp);
>

--
I'm not entirely sure you are real.

Mark Lumsden

unread,
May 22, 2013, 5:20:01 AM5/22/13
to Florian Obser, te...@openbsd.org
I am glad to say, 3 of you are on your toes today.

I sent the wrong diff, and to be honest I wasn't sure if any
one would notice.

Gold Stars to you all....
> ... until here. In fact this is leaking text.
0 new messages