i3-skip 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
i3_skip-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: i3-skip
3
+ Version: 0.1.0
4
+ Summary: i3 focus motion that treats tabbed/stacked containers as one window
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: i3ipc>=2.2
9
+
10
+ # i3-skip
11
+ i3 focus motion that treats a tabbed or stacked container as a single window rather than navigating between tabs.
12
+
13
+ AI-generated and unreviewed.
14
+
15
+ ## Motivation
16
+ I want two separate forms of motions. One for within tabbed ontainers, the other between visible windows.
17
+ I guess this is because I don't want to futz with my choices for stacked windows while i move around.
18
+ Also, it does kind of make sense to move between what is visible.
19
+
20
+ This program is a companian to i3-glue which glues together certain windows into tabbed containers.
21
+
22
+ ## Usage
23
+
24
+ ```sh
25
+ i3-skip left # focus the window/group to the left, skipping any tabs inside
26
+ i3-skip right
27
+ i3-skip up
28
+ i3-skip down
29
+ i3-skip toggle # cycle focus within the current tabbed/stacked group
30
+ ```
31
+
32
+ Bind your motion keys to the directional forms and one key to `toggle`, e.g. in
33
+ your i3 config:
34
+
35
+ ```
36
+ bindsym $mod+h exec i3-skip left
37
+ bindsym $mod+l exec i3-skip right
38
+ bindsym $mod+k exec i3-skip up
39
+ bindsym $mod+j exec i3-skip down
40
+ bindsym $mod+Tab exec i3-skip toggle
41
+ ```
42
+
43
+ ## Flags
44
+
45
+ - `--debug` — print the i3 commands sent
46
+
47
+ ## Install (editable, via pipx)
48
+
49
+ ```sh
50
+ pipx install i3-skip
51
+ ```
@@ -0,0 +1,42 @@
1
+ # i3-skip
2
+ i3 focus motion that treats a tabbed or stacked container as a single window rather than navigating between tabs.
3
+
4
+ AI-generated and unreviewed.
5
+
6
+ ## Motivation
7
+ I want two separate forms of motions. One for within tabbed ontainers, the other between visible windows.
8
+ I guess this is because I don't want to futz with my choices for stacked windows while i move around.
9
+ Also, it does kind of make sense to move between what is visible.
10
+
11
+ This program is a companian to i3-glue which glues together certain windows into tabbed containers.
12
+
13
+ ## Usage
14
+
15
+ ```sh
16
+ i3-skip left # focus the window/group to the left, skipping any tabs inside
17
+ i3-skip right
18
+ i3-skip up
19
+ i3-skip down
20
+ i3-skip toggle # cycle focus within the current tabbed/stacked group
21
+ ```
22
+
23
+ Bind your motion keys to the directional forms and one key to `toggle`, e.g. in
24
+ your i3 config:
25
+
26
+ ```
27
+ bindsym $mod+h exec i3-skip left
28
+ bindsym $mod+l exec i3-skip right
29
+ bindsym $mod+k exec i3-skip up
30
+ bindsym $mod+j exec i3-skip down
31
+ bindsym $mod+Tab exec i3-skip toggle
32
+ ```
33
+
34
+ ## Flags
35
+
36
+ - `--debug` — print the i3 commands sent
37
+
38
+ ## Install (editable, via pipx)
39
+
40
+ ```sh
41
+ pipx install i3-skip
42
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ i3-skip — i3 focus motion that treats tabbed/stacked containers as one window.
4
+
5
+ AI-generated. You probably don't want to use it. And yet it exists.
6
+
7
+ i3's directional focus walks *into* a tabbed or stacked container, tab by tab,
8
+ because a container's orientation is also its navigation axis. i3-skip makes
9
+ left/right/up/down step *over* such a container as a single unit, and gives you
10
+ a separate command to move *within* it.
11
+
12
+ Usage:
13
+ i3-skip left | right | up | down directional focus, skipping groups
14
+ i3-skip toggle cycle focus within the current group
15
+
16
+ Bind your motion keys to the directional form, and one key to `toggle`.
17
+
18
+ Flags:
19
+ --debug print the i3 commands sent
20
+
21
+ Runtime deps: i3 (via i3ipc).
22
+ """
23
+
24
+ import sys
25
+
26
+ import i3ipc
27
+
28
+
29
+ DEBUG = False
30
+ DIRECTIONS = ("left", "right", "up", "down")
31
+
32
+
33
+ def die(msg, code=1):
34
+ print(f"i3-skip: {msg}", file=sys.stderr)
35
+ sys.exit(code)
36
+
37
+
38
+ def dbg(msg):
39
+ if DEBUG:
40
+ print(f"[i3-skip:debug] {msg}", file=sys.stderr, flush=True)
41
+
42
+
43
+ def command(conn, cmd):
44
+ dbg(f"i3-msg: {cmd}")
45
+ for reply in conn.command(cmd):
46
+ if not reply.success:
47
+ print(f"i3-skip: command failed: {cmd!r}: {reply.error}",
48
+ file=sys.stderr)
49
+
50
+
51
+ def group_of(con):
52
+ """Nearest tabbed/stacked ancestor of `con` — the container to treat as a
53
+ single unit — or None if `con` is not inside one."""
54
+ node = con
55
+ while node is not None:
56
+ if node.layout in ("tabbed", "stacked"):
57
+ return node
58
+ node = node.parent
59
+ return None
60
+
61
+
62
+ def visible_leaf(con):
63
+ """A focusable leaf for `con`: itself if it is a window, else its first."""
64
+ if con.window:
65
+ return con
66
+ leaves = con.leaves()
67
+ return leaves[0] if leaves else con
68
+
69
+
70
+ def child_holding(group, target_id):
71
+ """Index of the group's child that contains the window `target_id`."""
72
+ for i, child in enumerate(group.nodes):
73
+ if child.id == target_id or any(d.id == target_id
74
+ for d in child.descendants()):
75
+ return i
76
+ return 0
77
+
78
+
79
+ def cmd_toggle(conn):
80
+ """Cycle focus to the next window within the current group (wraps)."""
81
+ focused = conn.get_tree().find_focused()
82
+ group = group_of(focused)
83
+ if group is None or len(group.nodes) < 2:
84
+ dbg("not in a multi-window group; nothing to toggle")
85
+ return
86
+ i = child_holding(group, focused.id)
87
+ nxt = group.nodes[(i + 1) % len(group.nodes)]
88
+ command(conn, f"[con_id={visible_leaf(nxt).id}] focus")
89
+
90
+
91
+ def cmd_skip(conn, direction):
92
+ """Directional focus that skips over the focused window's group. Focusing
93
+ the whole group container first makes i3's `focus <dir>` step over its
94
+ internal tabs instead of walking through them."""
95
+ focused = conn.get_tree().find_focused()
96
+ group = group_of(focused)
97
+ if group is not None:
98
+ command(conn, f"[con_id={group.id}] focus")
99
+ command(conn, f"focus {direction}")
100
+ # `focus <dir>` with nowhere to go leaves a non-leaf container focused;
101
+ # drop back into its visible window so focus is always on a real window.
102
+ now = conn.get_tree().find_focused()
103
+ if now is not None and not now.window:
104
+ command(conn, f"[con_id={visible_leaf(now).id}] focus")
105
+
106
+
107
+ def main():
108
+ global DEBUG
109
+ argv = sys.argv[1:]
110
+ if "--debug" in argv:
111
+ DEBUG = True
112
+ argv = [a for a in argv if a != "--debug"]
113
+ if not argv:
114
+ die("usage: i3-skip {left|right|up|down|toggle}")
115
+
116
+ cmd = argv[0]
117
+ conn = i3ipc.Connection()
118
+ if cmd == "toggle":
119
+ return cmd_toggle(conn)
120
+ if cmd in DIRECTIONS:
121
+ return cmd_skip(conn, cmd)
122
+ die(f"unknown command {cmd!r}: use {'|'.join(DIRECTIONS)}|toggle")
123
+
124
+
125
+ if __name__ == "__main__":
126
+ main()
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: i3-skip
3
+ Version: 0.1.0
4
+ Summary: i3 focus motion that treats tabbed/stacked containers as one window
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: i3ipc>=2.2
9
+
10
+ # i3-skip
11
+ i3 focus motion that treats a tabbed or stacked container as a single window rather than navigating between tabs.
12
+
13
+ AI-generated and unreviewed.
14
+
15
+ ## Motivation
16
+ I want two separate forms of motions. One for within tabbed ontainers, the other between visible windows.
17
+ I guess this is because I don't want to futz with my choices for stacked windows while i move around.
18
+ Also, it does kind of make sense to move between what is visible.
19
+
20
+ This program is a companian to i3-glue which glues together certain windows into tabbed containers.
21
+
22
+ ## Usage
23
+
24
+ ```sh
25
+ i3-skip left # focus the window/group to the left, skipping any tabs inside
26
+ i3-skip right
27
+ i3-skip up
28
+ i3-skip down
29
+ i3-skip toggle # cycle focus within the current tabbed/stacked group
30
+ ```
31
+
32
+ Bind your motion keys to the directional forms and one key to `toggle`, e.g. in
33
+ your i3 config:
34
+
35
+ ```
36
+ bindsym $mod+h exec i3-skip left
37
+ bindsym $mod+l exec i3-skip right
38
+ bindsym $mod+k exec i3-skip up
39
+ bindsym $mod+j exec i3-skip down
40
+ bindsym $mod+Tab exec i3-skip toggle
41
+ ```
42
+
43
+ ## Flags
44
+
45
+ - `--debug` — print the i3 commands sent
46
+
47
+ ## Install (editable, via pipx)
48
+
49
+ ```sh
50
+ pipx install i3-skip
51
+ ```
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ i3_skip/__init__.py
4
+ i3_skip/main.py
5
+ i3_skip.egg-info/PKG-INFO
6
+ i3_skip.egg-info/SOURCES.txt
7
+ i3_skip.egg-info/dependency_links.txt
8
+ i3_skip.egg-info/entry_points.txt
9
+ i3_skip.egg-info/requires.txt
10
+ i3_skip.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ i3-skip = i3_skip.main:main
@@ -0,0 +1 @@
1
+ i3ipc>=2.2
@@ -0,0 +1 @@
1
+ i3_skip
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = [ "setuptools>=68.0",]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "i3-skip"
7
+ version = "0.1.0"
8
+ description = "i3 focus motion that treats tabbed/stacked containers as one window"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.8"
12
+ dependencies = [ "i3ipc>=2.2",]
13
+
14
+ [project.scripts]
15
+ i3-skip = "i3_skip.main:main"
16
+
17
+ [tool.setuptools]
18
+ packages = [ "i3_skip",]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+