i3 - improved tiling WM


Workspace command number selection

Patch status: merged

Patch by Tony Crisci

Long description:

If a `workspace {N}` or `move to workspace {N}` command is given with N
as a plain number, the workspace of this number is selected for the
context of the command if one exists and there is no workspace with a
name that exactly matches N.

To apply this patch, use:
curl http://cr.i3wm.org/patch/602/raw.patch | git am

b/src/commands.c

19
@@ -513,7 +513,27 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
20
 
21
     LOG("should move window to workspace %s\n", name);
22
     /* get the workspace */
23
-    Con *ws = workspace_get(name, NULL);
24
+    Con *ws = NULL;
25
+    Con *output = NULL;
26
+
27
+    /* first look for a workspace with this name */
28
+    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
29
+        GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name));
30
+    }
31
+
32
+    /* if the name is plain digits, we interpret this as a "workspace number"
33
+     * command */
34
+    if (!ws && name_is_digits(name)) {
35
+        long parsed_num = ws_name_to_number(name);
36
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
37
+            GREP_FIRST(ws, output_get_content(output),
38
+                    child->num == parsed_num);
39
+        }
40
+    }
41
+
42
+    /* if no workspace was found, make a new one */
43
+    if (!ws)
44
+        ws = workspace_get(name, NULL);
45
 
46
     ws = maybe_auto_back_and_forth_workspace(ws);
47
 
48
@@ -1013,7 +1033,30 @@ void cmd_workspace_name(I3_CMD, char *name) {
49
     DLOG("should switch to workspace %s\n", name);
50
     if (maybe_back_and_forth(cmd_output, name))
51
         return;
52
-    workspace_show_by_name(name);
53
+
54
+    Con *ws = NULL;
55
+    Con *output = NULL;
56
+
57
+    /* first look for a workspace with this name */
58
+    TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
59
+        GREP_FIRST(ws, output_get_content(output), !strcasecmp(child->name, name));
60
+    }
61
+
62
+    /* if the name is only digits, we interpret this as a "workspace number"
63
+     * command */
64
+    if (!ws && name_is_digits(name)) {
65
+        long parsed_num = ws_name_to_number(name);
66
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes) {
67
+            GREP_FIRST(ws, output_get_content(output),
68
+                    child->num == parsed_num);
69
+        }
70
+    }
71
+
72
+    /* if no workspace was found, make a new one */
73
+    if (!ws)
74
+        ws = workspace_get(name, NULL);
75
+
76
+    workspace_show(ws);
77
 
78
     cmd_output->needs_tree_render = true;
79
     // XXX: default reply for now, make this a better reply

b/testcases/t/232-cmd-workspace-number-selection.t

85
@@ -0,0 +1,52 @@
86
+#!perl
87
+# vim:ts=4:sw=4:expandtab
88
+#
89
+# Please read the following documents before working on tests:
90
+# • http://build.i3wm.org/docs/testsuite.html
91
+#   (or docs/testsuite)
92
+#
93
+# • http://build.i3wm.org/docs/lib-i3test.html
94
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
95
+#
96
+# • http://build.i3wm.org/docs/ipc.html
97
+#   (or docs/ipc)
98
+#
99
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
100
+#   (unless you are already familiar with Perl)
101
+#
102
+# Test that `workspace {N}` acts like `workspace number {N}` when N is a plain
103
+# digit, and likewise for `move to workspace {N}`.
104
+# Ticket: #1238
105
+# Bug still in: 4.8-16-g3f5a0f0
106
+use i3test;
107
+
108
+cmd 'workspace 5:foo';
109
+open_window;
110
+fresh_workspace;
111
+cmd 'workspace 5';
112
+
113
+is(focused_ws, '5:foo',
114
+    'a command to switch to a workspace with a bare number should switch to a workspace of that number');
115
+
116
+fresh_workspace;
117
+my $win = open_window;
118
+cmd '[id="' . $win->{id} . '"] move to workspace 5';
119
+
120
+is(@{get_ws('5:foo')->{nodes}}, 2,
121
+    'a command to move a container to a workspace with a bare number should move that container to a workspace of that number');
122
+
123
+fresh_workspace;
124
+cmd 'workspace 7';
125
+open_window;
126
+cmd 'workspace 7:foo';
127
+$win = open_window;
128
+
129
+cmd 'workspace 7';
130
+is(focused_ws, '7',
131
+    'a workspace with a name that is a matching plain number should be preferred when switching');
132
+
133
+cmd '[id="' . $win->{id} . '"] move to workspace 7';
134
+is(@{get_ws('7')->{nodes}}, 2,
135
+    'a workspace with a name that is a matching plain number should be preferred when moving');
136
+
137
+done_testing;