Skip to content

Commit 460672d

Browse files
committed
Merge pull request #137 from tasdomas/set_environment_support
Environment setting support.
2 parents 338c484 + aafa0de commit 460672d

File tree

11 files changed

+256
-8
lines changed

11 files changed

+256
-8
lines changed

doc/examples.rst

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ JSON
162162
.. literalinclude:: ../examples/start-directory.json
163163
:language: json
164164

165-
Environment variables
166-
---------------------
165+
Environment variable replacing
166+
------------------------------
167167

168168
tmuxp will replace environment variables wrapped in curly brackets
169169
for the following variables:
@@ -206,6 +206,23 @@ JSON
206206
.. literalinclude:: ../examples/env-variables.json
207207
:language: json
208208

209+
Environment variables
210+
---------------------
211+
212+
tmuxp will set session environment variables.
213+
214+
YAML
215+
~~~~
216+
217+
.. literalinclude:: ../examples/session-environment.yaml
218+
:language: yaml
219+
220+
JSON
221+
~~~~
222+
223+
.. literalinclude:: ../examples/session-environment.json
224+
:language: json
225+
209226
Focusing
210227
--------
211228

examples/session-environment.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"environment": {
3+
"EDITOR": "/usr/bin/vim",
4+
"HOME": "/tmp/hm",
5+
},
6+
"windows": [
7+
{
8+
"panes": [
9+
null,
10+
],
11+
"window_name": "Blank pane test"
12+
},
13+
],
14+
"session_name": "Environment variables test"
15+
}

examples/session-environment.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
session_name: Environment variables test
2+
environment:
3+
EDITOR: /usr/bin/vim
4+
HOME: /tmp/hm
5+
windows:
6+
# Emptiness will simply open a blank pane, if no shell_command_before.
7+
# All these are equivalent
8+
- window_name: Blank pane test
9+
panes:
10+
-

tmuxp/common.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
2+
class EnvironmentMixin(object):
3+
4+
"""Mixin class for managing session and server level environment
5+
variables in tmux.
6+
7+
"""
8+
9+
_add_option = None
10+
11+
def __init__(self, add_option=None):
12+
self._add_option = add_option
13+
14+
def set_environment(self, name, value):
15+
"""Set environment ``$ tmux set-environment <name> <value>``.
16+
17+
:param name: the environment variable name. such as 'PATH'.
18+
:type option: string
19+
:param value: environment value.
20+
:type value: string
21+
22+
"""
23+
24+
args = ['set-environment']
25+
if self._add_option:
26+
args += [self._add_option]
27+
28+
args += [name, value]
29+
30+
proc = self.cmd(*args)
31+
32+
if proc.stderr:
33+
if isinstance(proc.stderr, list) and len(proc.stderr) == int(1):
34+
proc.stderr = proc.stderr[0]
35+
raise ValueError('tmux set-environment stderr: %s' % proc.stderr)
36+
37+
def unset_environment(self, name):
38+
"""Unset environment variable ``$ tmux set-environment -u <name>``.
39+
40+
:param name: the environment variable name. such as 'PATH'.
41+
:type option: string
42+
"""
43+
44+
args = ['set-environment']
45+
if self._add_option:
46+
args += [self._add_option]
47+
args += ['-u', name]
48+
49+
proc = self.cmd(*args)
50+
51+
if proc.stderr:
52+
if isinstance(proc.stderr, list) and len(proc.stderr) == int(1):
53+
proc.stderr = proc.stderr[0]
54+
raise ValueError('tmux set-environment stderr: %s' % proc.stderr)
55+
56+
def remove_environment(self, name):
57+
"""Remove environment variable ``$ tmux set-environment -r <name>``.
58+
59+
:param name: the environment variable name. such as 'PATH'.
60+
:type option: string
61+
"""
62+
63+
args = ['set-environment']
64+
if self._add_option:
65+
args += [self._add_option]
66+
args += ['-r', name]
67+
68+
proc = self.cmd(*args)
69+
70+
if proc.stderr:
71+
if isinstance(proc.stderr, list) and len(proc.stderr) == int(1):
72+
proc.stderr = proc.stderr[0]
73+
raise ValueError('tmux set-environment stderr: %s' % proc.stderr)
74+
75+
def show_environment(self, name=None):
76+
"""Show environment ``$tmux show-environment -t [session] <name>``.
77+
78+
Return dict of environment variables for the session or the value of a
79+
specific variable if the name is specified.
80+
81+
:param name: the environment variable name. such as 'PATH'.
82+
:type option: string
83+
"""
84+
tmux_args = ['show-environment']
85+
if self._add_option:
86+
tmux_args += [self._add_option]
87+
if name:
88+
tmux_args += [name]
89+
vars = self.cmd(*tmux_args).stdout
90+
vars = [tuple(item.split('=', 1)) for item in vars]
91+
vars_dict = {}
92+
for t in vars:
93+
if len(t) == 2:
94+
vars_dict[t[0]] = t[1]
95+
elif len(t) == 1:
96+
vars_dict[t[0]] = True
97+
else:
98+
raise ValueError('unexpected variable %s', t)
99+
100+
if name:
101+
return vars_dict.get(name)
102+
103+
return vars_dict

tmuxp/config.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,13 @@ def expand(sconf, cwd=None, parent=None):
189189
sconf['session_name'] = expandshell(sconf['session_name'])
190190
if 'window_name' in sconf:
191191
sconf['window_name'] = expandshell(sconf['window_name'])
192-
192+
if 'environment' in sconf:
193+
for key in sconf['environment']:
194+
val = sconf['environment'][key]
195+
val = expandshell(val)
196+
if any(val.startswith(a) for a in ['.', './']):
197+
val = os.path.normpath(os.path.join(cwd, val))
198+
sconf['environment'][key] = val
193199
# Any config section, session, window, pane that can contain the
194200
# 'shell_command' value
195201
if 'start_directory' in sconf:

tmuxp/server.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
from . import formats, exc
1515
from .session import Session
1616
from .util import tmux_cmd, TmuxRelationalObject
17+
from .common import EnvironmentMixin
1718

1819
logger = logging.getLogger(__name__)
1920

2021

21-
class Server(TmuxRelationalObject):
22+
class Server(TmuxRelationalObject, EnvironmentMixin):
2223

2324
"""The :term:`tmux(1)` server.
2425
@@ -54,6 +55,7 @@ def __init__(
5455
colors=None,
5556
**kwargs
5657
):
58+
EnvironmentMixin.__init__(self, '-g')
5759
self._windows = []
5860
self._panes = []
5961

@@ -383,7 +385,7 @@ def attach_session(self, target_session=None):
383385

384386
if proc.stderr:
385387
raise exc.TmuxpException(proc.stderr)
386-
388+
387389
def new_session(self,
388390
session_name=None,
389391
kill_session=False,

tmuxp/session.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313

1414
from . import util, formats, exc
1515
from .window import Window
16+
from .common import EnvironmentMixin
1617

1718
logger = logging.getLogger(__name__)
1819

1920

20-
class Session(util.TmuxMappingObject, util.TmuxRelationalObject):
21+
class Session(util.TmuxMappingObject, util.TmuxRelationalObject, EnvironmentMixin):
2122

2223
""":term:`tmux(1)` session.
2324
@@ -28,7 +29,7 @@ class Session(util.TmuxMappingObject, util.TmuxRelationalObject):
2829
childIdAttribute = 'window_id'
2930

3031
def __init__(self, server=None, **kwargs):
31-
32+
EnvironmentMixin.__init__(self)
3233
self.server = server
3334

3435
if not 'session_id' in kwargs:

tmuxp/testsuite/server.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,29 @@ def test_88_colors(self):
6767
self.assertIn('-8', proc.cmd)
6868
self.assertNotIn('-2', proc.cmd)
6969

70+
class Environment(TmuxTestCase):
71+
72+
def test_show_environment(self):
73+
"""Server.show_environment() returns dict."""
74+
75+
vars = self.server.show_environment()
76+
self.assertIsInstance(vars, dict)
77+
78+
def test_set_show_environment_single(self):
79+
"""Set environment then Server.show_environment(key)."""
80+
81+
self.server.set_environment('FOO', 'BAR')
82+
self.assertEqual('BAR', self.server.show_environment('FOO'))
83+
84+
self.server.set_environment('FOO', 'DAR')
85+
self.assertEqual('DAR', self.server.show_environment('FOO'))
86+
87+
self.assertEqual('DAR', self.server.show_environment()['FOO'])
88+
89+
def test_show_environment_not_set(self):
90+
"""Unset environment variable returns None."""
91+
self.assertEqual(None, self.server.show_environment('BAR'))
92+
7093

7194
def suite():
7295
suite = unittest.TestSuite()

tmuxp/testsuite/session.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,50 @@ def test_set_option_bad(self):
140140
self.session.set_option('afewewfew', 43)
141141

142142

143+
class Environment(TmuxTestCase):
144+
145+
def test_show_environment(self):
146+
"""Session.show_environment() returns dict."""
147+
148+
vars = self.session.show_environment()
149+
self.assertIsInstance(vars, dict)
150+
151+
def test_set_show_environment_single(self):
152+
"""Set environment then Session.show_environment(key)."""
153+
154+
self.session.set_environment('FOO', 'BAR')
155+
self.assertEqual('BAR', self.session.show_environment('FOO'))
156+
157+
self.session.set_environment('FOO', 'DAR')
158+
self.assertEqual('DAR', self.session.show_environment('FOO'))
159+
160+
self.assertEqual('DAR', self.session.show_environment()['FOO'])
161+
162+
def test_show_environment_not_set(self):
163+
"""Not set environment variable returns None."""
164+
self.assertEqual(None, self.session.show_environment('BAR'))
165+
166+
def test_remove_environment(self):
167+
"""Remove environment variable."""
168+
self.assertEqual(None, self.session.show_environment('BAM'))
169+
self.session.set_environment('BAM', 'OK')
170+
self.assertEqual('OK', self.session.show_environment('BAM'))
171+
self.session.remove_environment('BAM')
172+
self.assertEqual(None, self.session.show_environment('BAM'))
173+
174+
def test_unset_environment(self):
175+
"""Unset environment variable."""
176+
self.assertEqual(None, self.session.show_environment('BAM'))
177+
self.session.set_environment('BAM', 'OK')
178+
self.assertEqual('OK', self.session.show_environment('BAM'))
179+
self.session.unset_environment('BAM')
180+
self.assertEqual(None, self.session.show_environment('BAM'))
181+
182+
143183
def suite():
144184
suite = unittest.TestSuite()
145185
suite.addTest(unittest.makeSuite(Options))
186+
suite.addTest(unittest.makeSuite(Environment))
146187
suite.addTest(unittest.makeSuite(SessionNewTest))
147188
suite.addTest(unittest.makeSuite(SessionTest))
148189
return suite

tmuxp/testsuite/workspacebuilder.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def test_focus_pane_index(self):
186186
self.assertNotEqual(w.get('window_name'), 'man')
187187

188188
pane_path = '/usr'
189-
for i in range(10):
189+
for i in range(20):
190190
p = w.attached_pane()
191191
p.server._update_panes()
192192
if p.get('pane_current_path') == pane_path:
@@ -254,6 +254,32 @@ def test_window_options(self):
254254
w.select_layout(wconf['layout'])
255255

256256

257+
class EnvironmentVariables(TmuxTestCase):
258+
259+
yaml_config = """
260+
session_name: test env vars
261+
start_directory: '~'
262+
environment:
263+
FOO: BAR
264+
PATH: /tmp
265+
windows:
266+
- layout: main-horizontal
267+
panes:
268+
- pane
269+
window_name: editor
270+
"""
271+
272+
def test_environment_variables(self):
273+
sconfig = kaptan.Kaptan(handler='yaml')
274+
sconfig = sconfig.import_config(self.yaml_config).get()
275+
sconfig = config.expand(sconfig)
276+
277+
builder = WorkspaceBuilder(sconf=sconfig)
278+
builder.build(self.session)
279+
280+
self.assertEqual('BAR', self.session.show_environment('FOO'))
281+
self.assertEqual('/tmp', self.session.show_environment('PATH'))
282+
257283
class WindowAutomaticRename(TmuxTestCase):
258284

259285
yaml_config = """
@@ -869,4 +895,5 @@ def suite():
869895
suite.addTest(unittest.makeSuite(WindowAutomaticRename))
870896
suite.addTest(unittest.makeSuite(WindowIndexTest))
871897
suite.addTest(unittest.makeSuite(WindowOptions))
898+
suite.addTest(unittest.makeSuite(EnvironmentVariables))
872899
return suite

0 commit comments

Comments
 (0)