Skip to content

Commit ce8d9cb

Browse files
committed
Adding the Plugin System. Initial commit containing logic for 4/5 of the desired plugin api methods
1 parent 888b2b3 commit ce8d9cb

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

tmuxp/cli.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88
from __future__ import absolute_import
99

10+
import importlib
1011
import logging
1112
import os
1213
import sys
@@ -192,6 +193,35 @@ def set_layout_hook(session, hook_name):
192193
session.cmd(*cmd)
193194

194195

196+
def load_plugins(sconfig):
197+
plugins = []
198+
if 'plugins' in sconfig:
199+
for plugin in sconfig['plugins']:
200+
try:
201+
"""
202+
click.echo(
203+
click.style('[Loading] ', fg='green')
204+
+ click.style(f'Plugin: {plugin}', fg='blue', bold=True)
205+
)
206+
"""
207+
module_name = plugin.split('.')
208+
module_name = '.'.join(module_name[:-1])
209+
plugin_name = plugin.split('.')[-1]
210+
plugin = getattr(importlib.import_module(module_name), plugin_name)
211+
plugins.append(plugin())
212+
except Exception as error:
213+
click.echo(
214+
click.wrap_text(
215+
f'Error in loading {plugin}. Please make '
216+
f'sure {plugin} is installed.\n\n'
217+
f'{error}'
218+
)
219+
)
220+
221+
return plugins
222+
223+
224+
195225
def is_pure_name(path):
196226
"""
197227
Return True if path is a name and not a file path.
@@ -276,7 +306,7 @@ def scan_config(config, config_dir=None):
276306
277307
If config is directory, scan for .tmuxp.{yaml,yml,json} in directory. If
278308
one or more found, it will warn and pick the first.
279-
309+
[Loading]
280310
If config is ".", "./" or None, it will scan current directory.
281311
282312
If config is has no path and only a filename, e.g. "myconfig.yaml" it will
@@ -372,7 +402,7 @@ def scan_config(config, config_dir=None):
372402
return config
373403

374404

375-
def _reattach(session):
405+
def _reattach(session, plugins):
376406
"""
377407
Reattach session (depending on env being inside tmux already or not)
378408
@@ -388,6 +418,10 @@ def _reattach(session):
388418
389419
If not, ``tmux attach-session`` loads the client to the target session.
390420
"""
421+
422+
for plugin in plugins:
423+
plugin.reattach(session)
424+
391425
if 'TMUX' in os.environ:
392426
session.switch_client()
393427

@@ -513,8 +547,10 @@ def load_workspace(
513547

514548
which('tmux') # raise exception if tmux not found
515549

550+
plugins = load_plugins(sconfig)
551+
516552
try: # load WorkspaceBuilder object for tmuxp config / tmux server
517-
builder = WorkspaceBuilder(sconf=sconfig, server=t)
553+
builder = WorkspaceBuilder(sconf=sconfig, server=t, plugins=plugins)
518554
except exc.EmptyConfigException:
519555
click.echo('%s is empty or parsed no config data' % config_file, err=True)
520556
return
@@ -532,7 +568,7 @@ def load_workspace(
532568
default=True,
533569
)
534570
):
535-
_reattach(builder.session)
571+
_reattach(builder.session, plugins)
536572
return
537573

538574
try:

tmuxp/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ def validate_schema(sconf):
4242
if 'window_name' not in window:
4343
raise exc.ConfigError('config window is missing "window_name"')
4444

45+
if 'plugins' in sconf:
46+
if not isinstance(sconf['plugins'], list):
47+
raise exc.ConfigError('"plugins" only supports list type')
48+
4549
return True
4650

4751

tmuxp/workspacebuilder.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class WorkspaceBuilder(object):
6868
a session inside tmux (when `$TMUX` is in the env variables).
6969
"""
7070

71-
def __init__(self, sconf, server=None):
71+
def __init__(self, sconf, server=None, plugins=None):
7272
"""
7373
Initialize workspace loading.
7474
@@ -98,6 +98,8 @@ def __init__(self, sconf, server=None):
9898

9999
self.sconf = sconf
100100

101+
self.plugins = plugins if plugins is not None else []
102+
101103
def session_exists(self, session_name=None):
102104
exists = self.server.has_session(session_name)
103105
if not exists:
@@ -158,6 +160,9 @@ def build(self, session=None):
158160
assert session.id
159161

160162
assert isinstance(session, Session)
163+
164+
for plugin in self.plugins:
165+
plugin.before_workspace_builder(session)
161166

162167
focus = None
163168

@@ -183,6 +188,10 @@ def build(self, session=None):
183188
for option, value in self.sconf['environment'].items():
184189
self.session.set_environment(option, value)
185190

191+
# Runs after before_script
192+
for plugin in self.plugins:
193+
plugin.before_script(session)
194+
186195
for w, wconf in self.iter_create_windows(session):
187196
assert isinstance(w, Window)
188197

@@ -200,6 +209,8 @@ def build(self, session=None):
200209
if 'focus' in wconf and wconf['focus']:
201210
focus = w
202211

212+
for plugin in self.plugins:
213+
plugin.on_window_create(w)
203214
self.config_after_window(w, wconf)
204215

205216
if focus_pane:

0 commit comments

Comments
 (0)