From bc23a23994779e0e71a11eab3b1cf60aa725de90 Mon Sep 17 00:00:00 2001
From: Thiago de Arruda <tpadilha84@gmail.com>
Date: Fri, 22 Feb 2013 18:28:39 -0300
Subject: [PATCH] Implemented -o flag for 'set-option'

This flag causes the set-option command to be ignored if the option is already
set. With this its possible to perform atomic test/set-if-empty operations.
---
 cmd-set-option.c | 34 +++++++++++++++++++++++++++++-----
 tmux.1           |  7 ++++++-
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/cmd-set-option.c b/cmd-set-option.c
index a09e6db..28105d8 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -63,8 +63,8 @@ struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *,
 
 const struct cmd_entry cmd_set_option_entry = {
 	"set-option", "set",
-	"agqst:uw", 1, 2,
-	"[-agsquw] [-t target-session|target-window] option [value]",
+	"agoqst:uw", 1, 2,
+	"[-agosquw] [-t target-session|target-window] option [value]",
 	0,
 	NULL,
 	NULL,
@@ -73,8 +73,8 @@ const struct cmd_entry cmd_set_option_entry = {
 
 const struct cmd_entry cmd_set_window_option_entry = {
 	"set-window-option", "setw",
-	"agqt:u", 1, 2,
-	"[-agqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
+	"agoqt:u", 1, 2,
+	"[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
 	0,
 	NULL,
 	NULL,
@@ -91,6 +91,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
 	struct client				*c;
 	struct options				*oo;
 	struct window				*w;
+  struct options_entry *current_entry;
 	const char				*optstr, *valstr;
 	u_int					 i;
 
@@ -150,6 +151,15 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
 	if (args_has(args, 'u')) {
 		if (cmd_set_option_unset(self, ctx, oe, oo, valstr) != 0)
 			return (CMD_RETURN_ERROR);
+	} else if (args_has(args, 'o')) {
+		if ((current_entry = options_find1(oo, optstr)) == NULL) {
+			if (cmd_set_option_set(self, ctx, oe, oo, valstr) != 0)
+				return (CMD_RETURN_ERROR);
+		} else {
+			if (!args_has(args, 'q'))
+				ctx->print(ctx, "already set: %s -> %s", optstr, current_entry->str);
+			return (CMD_RETURN_NORMAL);
+		}
 	} else {
 		if (cmd_set_option_set(self, ctx, oe, oo, valstr) != 0)
 			return (CMD_RETURN_ERROR);
@@ -187,6 +197,7 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
 	struct session	*s;
 	struct winlink	*wl;
 	struct options	*oo;
+	struct options_entry  *current_entry;
 
 	if (args_has(args, 's'))
 		oo = &global_options;
@@ -227,7 +238,20 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
 			ctx->error(ctx, "empty value");
 			return (CMD_RETURN_ERROR);
 		}
-		options_set_string(oo, optstr, "%s", valstr);
+		if (args_has(args, 'o')) {
+			if ((current_entry = options_find1(oo, optstr)) == NULL) {
+				options_set_string(oo, optstr, "%s", valstr);
+			} else {
+				if (!args_has(args, 'q'))
+					if (current_entry->type == OPTIONS_NUMBER)
+						ctx->print(ctx, "already set: %s -> %d", optstr, current_entry->num);
+					else
+						ctx->print(ctx, "already set: %s -> %s", optstr, current_entry->str);
+				return (CMD_RETURN_NORMAL);
+			}
+		} else {
+			options_set_string(oo, optstr, "%s", valstr);
+		}
 		if (!args_has(args, 'q'))
 			ctx->info(ctx, "set option: %s -> %s", optstr, valstr);
 	}
diff --git a/tmux.1 b/tmux.1
index 475bac0..f84b16a 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1996,7 +1996,7 @@ abc123
 Commands which set options are as follows:
 .Bl -tag -width Ds
 .It Xo Ic set-option
-.Op Fl agqsuw
+.Op Fl agoqsuw
 .Op Fl t Ar target-session | Ar target-window
 .Ar option Ar value
 .Xc
@@ -2025,6 +2025,11 @@ options.
 It is not possible to unset a global option.
 .Pp
 The
+.Fl o
+flag will cause the command to have no effect if the option is already set.
+It can be used to peform an atomic test/set-if-empty operation.
+.Pp
+The
 .Fl q
 flag suppresses the informational message (as if the
 .Ic quiet
-- 
1.8.1.3

