Repository: rsteube/carapace
Pull request #973 (2024-01-06 20:07:18)

Action: added Unless


Patch:
diff --git a/action.go b/action.go
index eba6722..865e9a7 100644
--- a/action.go
+++ b/action.go
@@ -452,6 +452,16 @@ func (a Action) UniqueListF(divider string, f func(s string) string) Action {
 	})
 }
 
+// Unless skips invokation if given condition succeeds.
+func (a Action) Unless(condition func(c Context) bool) Action {
+	return ActionCallback(func(c Context) Action {
+		if condition(c) {
+			return ActionValues()
+		}
+		return a
+	})
+}
+
 // Usage sets the usage.
 func (a Action) Usage(usage string, args ...interface{}) Action {
 	return a.UsageF(func() string {
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
index 6f943bf..f37b390 100644
--- a/docs/src/SUMMARY.md
+++ b/docs/src/SUMMARY.md
@@ -43,6 +43,7 @@
     - [Timeout](./carapace/action/timeout.md)
     - [UniqueList](./carapace/action/uniqueList.md)
     - [UniqueListF](./carapace/action/uniqueListF.md)
+    - [Unless](./carapace/action/unless.md)
     - [Usage](./carapace/action/usage.md)
     - [UsageF](./carapace/action/usageF.md)
   - [InvokedAction](./carapace/invokedAction.md)
diff --git a/docs/src/carapace/action/unless.cast b/docs/src/carapace/action/unless.cast
new file mode 100644
index 0000000..6330283
--- /dev/null
+++ b/docs/src/carapace/action/unless.cast
@@ -0,0 +1,60 @@
+{"version": 2, "width": 108, "height": 24, "timestamp": 1704580675, "env": {"SHELL": "elvish", "TERM": "tmux-256color"}}
+[0.077611, "o", "\u001b[?7h\u001b[7m⏎\u001b[m                                                                                                           \r \r\u001b[?7l\u001b[?2004h"]
+[0.078303, "o", "\u001b[?25l\r???>                                                                                                   ???> \r\u001b[5C\u001b[?25h\u001b[?25l\r\u001b[5C\u001b[K\r\u001b[5C\u001b[?25h"]
+[0.092405, "o", "\u001b[?25l\r\r\u001b[5C\u001b[?25h"]
+[0.092532, "o", "\u001b[?25l\r\u001b[K\u001b[0;1;36m~\u001b[0;m \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \r\u001b[6C\u001b[?25h"]
+[0.501527, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[0;32me\u001b[0;m\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[7C\u001b[?25h"]
+[0.502665, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[7C\u001b[?25h"]
+[0.514318, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[7C\u001b[?25h"]
+[0.514567, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[7C\u001b[?25h"]
+[0.729453, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;31mex\u001b[0;m\r\u001b[8C\u001b[?25h"]
+[0.934243, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;32mexa\u001b[0;m\r\u001b[9C\u001b[?25h"]
+[0.934401, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[9C\u001b[?25h"]
+[0.935079, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[9C\u001b[?25h"]
+[1.078257, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;31mexam\u001b[0;m\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[10C\u001b[?25h"]
+[1.130292, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[10C\u001b[0;31mp\u001b[0;m\r\u001b[11C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[11C\u001b[?25h"]
+[1.277002, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[11C\u001b[0;31ml\u001b[0;m\r\u001b[12C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[12C\u001b[?25h"]
+[1.319499, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;32mexample\u001b[0;m\r\u001b[13C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[13C\u001b[?25h"]
+[1.392949, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[13C \r\u001b[14C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[14C\u001b[?25h"]
+[1.931041, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[14C\u001b[0;4maction \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;34maction\u001b[0;2;7m (action example)                                                \r\n\u001b[0;34malias\u001b[0;2m (action example)                                                 \r\n\u001b[0;mchain\u001b[0;2m (shorthand chain)                                                \r\n\u001b[0;mcompat                                                                 \r\ncompletion\u001b[0;2m (Generate the autocompletion script for the specified shell)\r\n\u001b[0;34mflag\u001b[0;2m (flag example)                                                    \r\n\u001b[0;mgroup\u001b[0;2m (group example)                                                  \r\n\u001b[0;mhelp\u001b[0;2m (Help about any command)                                          \r\n\u001b[0;minterspersed\u001b[0;2m (interspersed example)                                    \r\n\u001b[0;33mmodifier\u001b[0;2m (modifier example)                                            \r\n\u001b[0;mmultiparts\u001b[0;2m (multiparts example)                                        \r\n\u001b[0;35mplugin\u001b[0;2m (dynamic plugin command)                                        \r\n\u001b[0;mspecial                                                                \r\nsubcommand\u001b[0;2m (subcommand example)                                        \u001b[0;m\u001b[14A\r\u001b[22C\u001b[?25h"]
+[2.258815, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[22Cm\r\n\r\n\r\n\u001b[1C\u001b[Kompat                                                                 \r\n\u001b[4C\u001b[Kletion\u001b[0;2m (Generate the autocompletion script for the specified shell)\r\n\u001b[0;m\u001b[K\u001b[0;34mflag\u001b[0;2m (flag example)                                                    \r\n\u001b[0;m\u001b[Kgroup\u001b[0;2m (group example)                                                  \r\n\u001b[0;m\u001b[Khelp\u001b[0;2m (Help about any command)                                          \r\n\u001b[0;m\u001b[Kinterspersed\u001b[0;2m (interspersed example)                                    \r\n\u001b[0;m\u001b[K\u001b[0;33mmodifier\u001b[0;2m (modifier example)                                            \r\n\u001b[0;m\u001b[Kmultiparts\u001b[0;2m (multiparts example)                                        \r\n\u001b[0;m\u001b[K\u001b[0;35mplugin\u001b[0;2m (dynamic plugin command)                                        \r\n\u001b[0;m\u001b[Ksubcommand\u001b[0;2m (subcommand example)                                        \u001b[0;m\r\n\u001b[J\u001b[A\u001b[12A\r\u001b[23C\u001b[?25h"]
+[2.259838, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\u001b[12A\r\u001b[23C\u001b[?25h"]
+[2.330185, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[14C\u001b[K\u001b[0;4mmodifier \r\n\u001b[23C\u001b[0;mo\r\n\u001b[K\u001b[0;7;33mmodifier\u001b[0;2;7m (modifier example)\u001b[0;m\r\n\u001b[J\u001b[A\u001b[1A\r\u001b[24C\u001b[?25h"]
+[2.333674, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[24C\u001b[?25h"]
+[2.333998, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[24C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[24C\u001b[?25h"]
+[2.450807, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[24Cd\r\n\u001b[1A\r\u001b[25C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[25C\u001b[?25h"]
+[2.911046, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[14C\u001b[Kmodifier \r\n\u001b[J\u001b[A\r\u001b[23C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[23C\u001b[?25h"]
+[3.501728, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[23C-\r\u001b[24C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[24C\u001b[?25h"]
+[3.63236, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[24C-\r\u001b[25C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[25C\u001b[?25h"]
+[3.755864, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[23C\u001b[K\u001b[0;4m--batch \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;34m--batch\u001b[0;2;7m (Batch())                                   \u001b[0;m  \u001b[0;34m--retain\u001b[0;2m (Retain())          \r\n\u001b[0;34m--cache\u001b[0;2m (Cache())                                   \u001b[0;m  \u001b[0;34m--shift\u001b[0;2m (Shift())            \r\n\u001b[0;34m--cache-key\u001b[0;2m (Cache())                               \u001b[0;m  \u001b[0;34m--split\u001b[0;2m (Split())            \r\n\u001b[0;34m--chdir\u001b[0;2m (Chdir())                                   \u001b[0;m  \u001b[0;34m--splitp\u001b[0;2m (SplitP())          \r\n\u001b[0;34m--chdirf\u001b[0;2m (ChdirF())                                 \u001b[0;m  \u001b[0;34m--style\u001b[0;2m (Style())            \r\n\u001b[0;34m--filter\u001b[0;2m (Filter())                                 \u001b[0;m  \u001b[0;34m--stylef\u001b[0;2m (StyleF())          \r\n\u001b[0;34m--filterargs\u001b[0;2m (FilterArgs())                         \u001b[0;m  \u001b[0;34m--styler\u001b[0;2m (StyleR())          \r\n\u001b[0;34m--filterparts\u001b[0;2m (FilterParts())                       \u001b[0;m  \u001b[0;34m--suffix\u001b[0;2m (Suffix())          \r\n\u001b[0;m--help\u001b[0;2m (help for modifier)                          \u001b[0;m  \u001b[0;34m--suppress\u001b[0;2m (Suppress())      \r\n\u001b[0;34m--invoke\u001b[0;2m (Invoke())                                 \u001b[0;m  \u001b[0;34m--tag\u001b[0;2m (Tag())                \r\n\u001b[0;34m--list\u001b[0;2m (List())                                     \u001b[0;m  \u001b[0;34m--tagf\u001b[0;2m (TagF())              \r\n\u001b[0;34m--multiparts\u001b[0;2m (MultiParts())                         \u001b[0;m  \u001b[0;34m--timeout\u001b[0;2m (Timeout())        \r\n\u001b[0;34m--multipartsp\u001b[0;2m (MultiPartsP())                       \u001b[0;m  \u001b[0;34m--uniquelist\u001b[0;2m (UniqueList())  \r\n\u001b[0;34m--nospace\u001b[0;2m (NoSpace())                               \u001b[0;m  \u001b[0;34m--uniquelistf\u001b[0;2m (UniqueListF())\r\n\u001b[0;33m--persistentFlag\u001b[0;2m (Help message for persistentFlag)  \u001b[0;m  \u001b[0;34m--unless\u001b[0;2m (Unless())          \r\n\u001b[0;34m--persistentFlag2\u001b[0;2m (Help message for persistentFlag2)\u001b[0;m  \u001b[0;34m--usage\u001b[0;2m (Usage())            \r\n\u001b[0;34m--prefix\u001b[0;2m (Prefix())                                 \u001b[0;m\u001b[17A\r\u001b[22C\u001b[?25h"]
+[3.757363, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\u001b[17A\r\u001b[22C\u001b[?25h"]
+[4.121816, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[25C\u001b[K\u001b[0;4mmultiparts \r\n\u001b[22C\u001b[0;mu\r\n\u001b[2C\u001b[K\u001b[0;7;34mmultiparts\u001b[0;2;7m (MultiParts())  \u001b[0;m  \u001b[0;34m--suppress\u001b[0;2m (Suppress())    \u001b[0;m  \u001b[0;34m--uniquelistf\u001b[0;2m (UniqueListF())\r\n\u001b[2C\u001b[0;m\u001b[K\u001b[0;34mmultipartsp\u001b[0;2m (MultiPartsP())\u001b[0;m  \u001b[0;34m--timeout\u001b[0;2m (Timeout())      \u001b[0;m  \u001b[0;34m--unless\u001b[0;2m (Unless())          \r\n\u001b[2C\u001b[0;m\u001b[K\u001b[0;34msuffix\u001b[0;2m (Suffix())          \u001b[0;m  \u001b[0;34m--uniquelist\u001b[0;2m (UniqueList())\u001b[0;m  \u001b[0;34m--usage\u001b[0;2m (Usage())            \u001b[0;m\r\n\u001b[J\u001b[A\u001b[3A\r\u001b[23C\u001b[?25h"]
+[4.297384, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[25C\u001b[K\u001b[0;4muniquelist \r\n\u001b[23C\u001b[0;mn\r\n\u001b[2C\u001b[K\u001b[0;7;34muniquelist\u001b[0;2;7m (UniqueList())\u001b[0;m  \u001b[0;34m--uniquelistf\u001b[0;2m (UniqueListF())\u001b[0;m  \u001b[0;34m--unless\u001b[0;2m (Unless())\u001b[0;m\r\n\u001b[J\u001b[A\u001b[1A\r\u001b[24C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[24C\u001b[?25h"]
+[4.368639, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[27C\u001b[K\u001b[0;4mless \r\n\u001b[24C\u001b[0;ml\r\n\u001b[4C\u001b[K\u001b[0;7;34mless\u001b[0;2;7m (Unless())\u001b[0;m\u001b[1A\r\u001b[25C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\u001b[1A\r\u001b[25C\u001b[?25h"]
+[5.060184, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[23C\u001b[K--unless \r\n\u001b[J\u001b[A\r\u001b[32C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[32C\u001b[?25h"]
+[5.459028, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[0;4m./local \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7m./local\u001b[0;m  /abs  one  three  two  ~/home\u001b[1A\r\u001b[22C\u001b[?25h"]
+[7.834727, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[32C\u001b[K\r\n\u001b[J\u001b[A\r\u001b[32C\u001b[?25h"]
+[8.483363, "o", "\u001b[?25l\u001b[1A\rUnbound key: Alt-t\u001b[K\r\n\u001b[K\u001b[0;1;36m~\u001b[0;m \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \u001b[0;32mexample\u001b[0;m modifier --unless \r\u001b[32C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[32C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[32C\u001b[?25h"]
+[9.179995, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32Ct\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[9.677383, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[K\u001b[0;4mthree \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7mthree\u001b[0;m  two\u001b[1A\r\u001b[22C\u001b[?25h"]
+[10.781412, "o", "\u001b[?25l\u001b[2A\r\r\n\u001b[32C\u001b[Kt\r\n\u001b[J\u001b[A\r\u001b[33C\u001b[?25h"]
+[11.425598, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[K\r\u001b[32C\u001b[?25h"]
+[11.713544, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C/\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[11.91868, "o", "\u001b[?25l\u001b[1A\r\u001b[0;2musage: \u001b[0;mUnless()\u001b[K\r\n\u001b[0;31merror:\u001b[0;m no candidates\u001b[K\r\n\u001b[K\u001b[0;1;36m~\u001b[0;m \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \u001b[0;32mexample\u001b[0;m modifier --unless /\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[12.885206, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[K\r\u001b[32C\u001b[?25h"]
+[13.300142, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C~\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[13.682684, "o", "\u001b[?25l\u001b[1A\r\u001b[0;2musage: \u001b[0;mUnless()\u001b[K\r\n\u001b[0;31merror:\u001b[0;m no candidates\u001b[K\r\n\u001b[K\u001b[0;1;36m~\u001b[0;m \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \u001b[0;32mexample\u001b[0;m modifier --unless ~\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[14.234812, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[K\r\u001b[32C\u001b[?25h"]
+[14.536332, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C.\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[14.745416, "o", "\u001b[?25l\u001b[1A\r\u001b[0;2musage: \u001b[0;mUnless()\u001b[K\r\n\u001b[0;31merror:\u001b[0;m no candidates\u001b[K\r\n\u001b[K\u001b[0;1;36m~\u001b[0;m \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \u001b[0;32mexample\u001b[0;m modifier --unless .\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[15.535869, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32C\u001b[K\r\u001b[32C\u001b[?25h"]
+[15.782019, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[32Co\r\u001b[33C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[33C\u001b[?25h"]
+[15.911862, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[33Cne \r\u001b[36C\u001b[?25h"]
+[16.916407, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[6C\u001b[?25h"]
+[16.917521, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[6C\u001b[?25h"]
+[16.929318, "o", "\u001b[?25l\u001b[1A\r\r\n\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[6C\u001b[?25h"]
+[17.205288, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[0;32me\u001b[0;m\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[7C\u001b[?25h"]
+[17.380397, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;31mex\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[8C\u001b[?25h"]
+[17.567313, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[8C\u001b[0;31mi\u001b[0;m\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[9C\u001b[?25h"]
+[17.658512, "o", "\u001b[?25l\u001b[1A\r\r\n\u001b[6C\u001b[K\u001b[0;32mexit\u001b[0;m\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[1A\r\r\n\r\u001b[10C\u001b[?25h"]
+[17.773903, "o", "\u001b[?25l\u001b[1A\r\r\n\r\n\r\u001b[?25h\u001b[?7h\u001b[?2004l\r"]
diff --git a/docs/src/carapace/action/unless.md b/docs/src/carapace/action/unless.md
new file mode 100644
index 0000000..ebfe448
--- /dev/null
+++ b/docs/src/carapace/action/unless.md
@@ -0,0 +1,19 @@
+# Unless
+
+[`Unless`] skips invokation if given [condition] succeeds.
+
+```go
+carapace.ActionValues(
+	"./local",
+	"~/home",
+	"/abs",
+	"one",
+	"two",
+	"three",
+).Unless(condition.CompletingPath)
+```
+
+![](./unless.cast)
+
+[`Unless`]:https://pkg.go.dev/github.com/rsteube/carapace#Action.Unless
+[condition]:https://pkg.go.dev/github.com/rsteube/carapace/pkg/condition
diff --git a/example/cmd/modifier.go b/example/cmd/modifier.go
index 7ceda38..6228ae5 100644
--- a/example/cmd/modifier.go
+++ b/example/cmd/modifier.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/rsteube/carapace"
 	"github.com/rsteube/carapace/pkg/cache"
+	"github.com/rsteube/carapace/pkg/condition"
 	"github.com/rsteube/carapace/pkg/style"
 	"github.com/rsteube/carapace/pkg/traverse"
 	"github.com/spf13/cobra"
@@ -50,6 +51,7 @@ func init() {
 	modifierCmd.Flags().String("timeout", "", "Timeout()")
 	modifierCmd.Flags().String("uniquelist", "", "UniqueList()")
 	modifierCmd.Flags().String("uniquelistf", "", "UniqueListF()")
+	modifierCmd.Flags().String("unless", "", "Unless()")
 	modifierCmd.Flags().String("usage", "", "Usage()")
 
 	rootCmd.AddCommand(modifierCmd)
@@ -264,6 +266,14 @@ func init() {
 		}).UniqueListF(",", func(s string) string {
 			return strings.SplitN(s, ":", 2)[0]
 		}),
+		"unless": carapace.ActionValues(
+			"./local",
+			"~/home",
+			"/abs",
+			"one",
+			"two",
+			"three",
+		).Unless(condition.CompletingPath),
 		"usage": carapace.ActionValues().Usage("explicit usage"),
 	})
 
diff --git a/pkg/condition/condition.go b/pkg/condition/condition.go
new file mode 100644
index 0000000..e533ede
--- /dev/null
+++ b/pkg/condition/condition.go
@@ -0,0 +1,75 @@
+package condition
+
+import (
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+
+	"github.com/rsteube/carapace"
+	"github.com/rsteube/carapace/pkg/util"
+)
+
+// Arch returns true if any of the given strings matches `runtime.GOARCH`.
+func Arch(s ...string) func(c carapace.Context) bool {
+	return func(c carapace.Context) bool {
+		for _, arch := range s {
+			if arch == runtime.GOARCH {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// Arch returns true if any of the given strings matches `runtime.GOOS`.
+func Os(s ...string) func(c carapace.Context) bool {
+	return func(c carapace.Context) bool {
+		for _, os := range s {
+			if os == runtime.GOOS {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// Excutable returns true if any of the given strings matches an executable in PATH.
+func Executable(s ...string) func(c carapace.Context) bool {
+	return func(c carapace.Context) bool {
+		for _, executable := range s {
+			// TODO needs to use Context.Env
+			if _, err := exec.LookPath(executable); err == nil {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// Retuns true if given string is a valid file or directory.
+func File(s string) func(c carapace.Context) bool {
+	return func(c carapace.Context) bool {
+		if _, err := os.Stat(s); err == nil {
+			return true
+		}
+		return false
+	}
+}
+
+// CompletingPath returns true when Context.Value is assumed a path.
+// Either
+// - it has a path prefix
+// - it contains a filepath delimiter and the first segment is a valid directory
+// - it is a valid file or directory
+func CompletingPath(c carapace.Context) bool {
+	if util.HasPathPrefix(c.Value) {
+		return true
+	}
+	if s := c.Value; strings.ContainsAny(s, "/\\") {
+		s = strings.SplitN(s, "/", 2)[0]
+		s = strings.SplitN(s, "\\", 2)[0]
+		return File(s)(c)
+	}
+	return File(c.Value)(c)
+}


Test patch:
diff --git a/example/cmd/modifier_test.go b/example/cmd/modifier_test.go
index ca258c7..59899d8 100644
--- a/example/cmd/modifier_test.go
+++ b/example/cmd/modifier_test.go
@@ -463,6 +463,34 @@ func TestSplitP(t *testing.T) {
 				Usage("SplitP()"))
 	})
 }
+func TestUnless(t *testing.T) {
+	sandbox.Package(t, "github.com/rsteube/carapace/example")(func(s *sandbox.Sandbox) {
+		s.Run("modifier", "--unless", "").
+			Expect(carapace.ActionValues(
+				"./local",
+				"~/home",
+				"/abs",
+				"one",
+				"two",
+				"three",
+			).Usage("Unless()"))
+
+		s.Run("modifier", "--unless", "t").
+			Expect(carapace.ActionValues(
+				"two",
+				"three",
+			).Usage("Unless()"))
+
+		s.Run("modifier", "--unless", ".").
+			Expect(carapace.ActionValues().Usage("Unless()"))
+
+		s.Run("modifier", "--unless", "~").
+			Expect(carapace.ActionValues().Usage("Unless()"))
+
+		s.Run("modifier", "--unless", "/").
+			Expect(carapace.ActionValues().Usage("Unless()"))
+	})
+}
 
 func TestUniqueList(t *testing.T) {
 	sandbox.Package(t, "github.com/rsteube/carapace/example")(func(s *sandbox.Sandbox) {