[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: UPDATE: command: negation



Hy Tylo,

On Thu, Nov 29, 2012 at 11:30:39AM -0800, Tyler Thomas Hart wrote:
> Thanks, I completely overlooked that!
> I've also changed the name of the function from
> invert_return to invert_return_command, since it seems like the syntax all
> the other commands use.
> 
> The patches for negation with command completion are attached. Should I be
> squashing my commits?

In future: Yes. I did this for you in this case and removed some
trailing whitespaces. I also changed COMMANDS to COMMAND in the
documentation because ! only accepts one command.

I also changed the "invert_return" to "negate" command so that the
naming is consistent.

Furthermore the completion function has to be called "complete_negate"
because it completes the arguments to the negate command, whereas e.g.
"complete_against_tags" completes a parameter by looking at the list of
tags. (But I am not sure if 'against' is the correct english word)

> I've implimented command completion using the check-and-shift method from
> complete_chain.

But you didn't change the parameters to complete_command, so argc and
pos were reduced by 2 and argv was incremented by 2. So I changed the
parameters. And there only is no completion if pos is <= 0, because for
pos = 1, the command name has to be completed.

I also added a note in the NEWS, please also add a appropriate NEWS
entry if you add a command or setting. You also should add your full
name in the author field.

Due to these modifications I'd like you to acknowledge the attached
patch (e.g. via e-mail or irc in #herbstluftwm), then I'll merge it to
master.

Regards,
Thorsten
>From 8d04c7e6c4bd86f9f7d1e159c445df7747fac399 Mon Sep 17 00:00:00 2001
From: Tyler Thomas Hart <htyler _at_ pdx _dot_ edu>
Date: Wed, 28 Nov 2012 15:22:57 -0800
Subject: [PATCH] Add command negation

---
 NEWS                 |  2 +-
 doc/herbstluftwm.txt |  5 +++++
 src/command.c        | 21 +++++++++++++++++++++
 src/command.h        |  2 ++
 src/main.c           |  1 +
 5 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 2559bcd..cc94217 100644
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Changes:
     * let new clients and monitors (and other items that are stacked) appear on
       top of the stacking order
     * chaining of commands now is possible with the new command: chain
-    * new commands: and or
+    * new commands: and or negate
     * tag switch locking for monitors. The new lock_tag and unlock_tag commands
       control, whether tag switching operations for a monitor are allowed.
     * set the urgent flag on _NET_WM_STATE_DEMANDS_ATTENTION
diff --git a/doc/herbstluftwm.txt b/doc/herbstluftwm.txt
index c617114..3910294 100644
--- a/doc/herbstluftwm.txt
+++ b/doc/herbstluftwm.txt
@@ -242,6 +242,11 @@ or 'SEPARATOR' ['COMMANDS' ...]::
     "or" behaves like the chain command but only executes the specified
     'COMMANDS' until one command returns the exit code 0.
 
+! 'COMMAND'::
+    "!" executes the provided command, but inverts their return value. If the
+    provided command returns a nonzero, "!" returns a 0, if the command returns
+    a zero, "!" returns a 1.
+
 focus_nth 'INDEX'::
     Focuses nth window in a frame. The first window has 'INDEX' 0, if INDEX is
     negative or greater than the last window index, then the last window is
diff --git a/src/command.c b/src/command.c
index d2e5073..72b93b1 100644
--- a/src/command.c
+++ b/src/command.c
@@ -167,6 +167,7 @@ struct {
     { "move",           EQ, 1,  .function = complete_against_tags },
     { "move_index",     EQ, 2,  .list = completion_use_index_args },
     { "or",             GE, 1,  .function = complete_chain },
+    { "!",              GE, 1,  .function = complete_negate },
     { "pseudotile",     EQ, 1,  .list = completion_flag_args },
     { "keybind",        GE, 2,  .function = complete_against_keybind_command },
     { "keyunbind",      EQ, 1,  .list = completion_keyunbind_args },
@@ -271,6 +272,17 @@ void complete_against_tags(int argc, char** argv, int pos, GString* output) {
     }
 }
 
+void complete_negate(int argc, char** argv, int pos, GString* output) {
+    if (pos <= 0) {
+        return;
+    }
+    // Remove the ! from the argv
+    (void)SHIFT(argc, argv);
+    pos--;
+    // Complete as normal
+    complete_against_commands(argc, argv, pos, output);
+}
+
 struct wcd { /* window id completion data */
     char* needle;
     size_t needlelen;
@@ -576,3 +588,12 @@ int command_chain_command(int argc, char** argv, GString* output) {
     return command_chain(separator, condition, argc, argv, output);
 }
 
+int negate_command(int argc, char** argv, GString* output) {
+    if (argc <= 1) {
+        return HERBST_NEED_MORE_ARGS;
+    }
+    (void)SHIFT(argc, argv);
+    int status = call_command(argc, argv, output);
+    return (!status);
+}
+
diff --git a/src/command.h b/src/command.h
index 200420a..a4e329e 100644
--- a/src/command.h
+++ b/src/command.h
@@ -45,6 +45,7 @@ void complete_against_list(char* needle, char** list, GString* output);
 void complete_against_tags(int argc, char** argv, int pos, GString* output);
 void complete_against_winids(int argc, char** argv, int pos, GString* output);
 void complete_merge_tag(int argc, char** argv, int pos, GString* output);
+void complete_negate(int argc, char** argv, int pos, GString* output);
 void complete_against_settings(int argc, char** argv, int pos, GString* output);
 void complete_against_keybinds(int argc, char** argv, int pos, GString* output);
 int complete_against_commands(int argc, char** argv, int position,
@@ -58,5 +59,6 @@ int command_chain(char* separator, bool (*condition)(int laststatus),
 
 int command_chain_command(int argc, char** argv, GString* output);
 
+int negate_command(int argc, char** argv, GString* output);
 #endif
 
diff --git a/src/main.c b/src/main.c
index 1dfea90..45a662c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -154,6 +154,7 @@ CommandBinding g_commands[] = {
     CMD_BIND(             "chain",          command_chain_command),
     CMD_BIND(             "and",            command_chain_command),
     CMD_BIND(             "or",             command_chain_command),
+    CMD_BIND(             "!",              negate_command),
     CMD_BIND(             "getenv",         getenv_command),
     CMD_BIND(             "setenv",         setenv_command),
     CMD_BIND(             "unsetenv",       unsetenv_command),
-- 
1.8.0