Skip to content

Commit

Permalink
Implemented synchronize-panes + added window options.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanslenders committed Jan 8, 2016
1 parent 9545b3b commit 369b1ed
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 22 deletions.
3 changes: 3 additions & 0 deletions pymux/arrangement.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ def __init__(self, index=0):
#: When true, the current pane is zoomed in.
self.zoom = False

#: When True, send input to all panes simultaniously.
self.synchronize_panes = False

# Give unique ID.
Window._window_counter += 1
self.window_id = Window._window_counter
Expand Down
14 changes: 11 additions & 3 deletions pymux/commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,19 +561,27 @@ def source_file(pymux, cli, variables):


@cmd('set-option', options='<option> <value>')
def set_option(pymux, cli, variables):
def set_option(pymux, cli, variables, window=False):
name = variables['<option>']
value = variables['<value>']

option = pymux.options.get(name)
if window:
option = pymux.window_options.get(name)
else:
option = pymux.options.get(name)

if option:
try:
option.set_value(pymux, value)
option.set_value(pymux, cli, value)
except SetOptionError as e:
raise CommandException(e.message)
else:
raise CommandException('Invalid option: %s' % (name, ))

@cmd('set-window-option', options='<option> <value>')
def set_window_option(pymux, cli, variables):
set_option(pymux, cli, variables, window=True)


@cmd('display-panes')
def display_panes(pymux, cli, variables):
Expand Down
12 changes: 8 additions & 4 deletions pymux/commands/completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,15 @@ def get_completions_for_parts(parts, last_part, complete_event, pymux):
flags = get_option_flags_for_command(parts[0])
completer = WordCompleter(sorted(flags), WORD=True)

elif len(parts) == 1 and parts[0] == 'set-option':
completer = WordCompleter(sorted(pymux.options.keys()), sentence=True)
elif len(parts) == 1 and parts[0] in ('set-option', 'set-window-option'):
options = pymux.options if parts[0] == 'set-option' else pymux.window_options

elif len(parts) == 2 and parts[0] == 'set-option':
option = pymux.options.get(parts[1])
completer = WordCompleter(sorted(options.keys()), sentence=True)

elif len(parts) == 2 and parts[0] in ('set-option', 'set-window-option'):
options = pymux.options if parts[0] == 'set-option' else pymux.window_options

option = options.get(parts[1])
if option:
completer = WordCompleter(sorted(option.get_all_values(pymux)), sentence=True)

Expand Down
18 changes: 14 additions & 4 deletions pymux/key_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,34 @@ def _(event):
# the pane that will probably echo back the typed characters.
# When we receive them, they are draw to the UI and it's
# invalidated.
pane = pymux.arrangement.get_active_pane(event.cli)
w = pymux.arrangement.get_active_window(event.cli)
pane = w.active_pane

if pane.clock_mode:
# Leave clock mode on key press.
pane.clock_mode = False
pymux.invalidate()
else:
pane.process.write_key(event.key_sequence[0].key)
# Write input to pane. If 'synchronize_panes' is on, write
# input to all panes in the current window.
panes = w.panes if w.synchronize_panes else [pane]
for p in panes:
p.process.write_key(event.key_sequence[0].key)

@registry.add_binding(Keys.BracketedPaste, filter=pane_input_allowed, invalidate_ui=False)
def _(event):
"""
Pasting to the active pane. (Using bracketed paste.)
"""
pane = pymux.arrangement.get_active_pane(event.cli)
w = pymux.arrangement.get_active_window(event.cli)
pane = w.active_pane

if not pane.clock_mode:
pane.process.write_input(event.data, paste=True)
# Paste input to pane. If 'synchronize_panes' is on, paste
# input to all panes in the current window.
panes = w.panes if w.synchronize_panes else [pane]
for p in panes:
p.process.write_input(event.data, paste=True)

@registry.add_binding(Keys.Any, filter=has_prefix)
def _(event):
Expand Down
3 changes: 2 additions & 1 deletion pymux/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from .key_bindings import KeyBindingsManager
from .layout import LayoutManager, Justify
from .log import logger
from .options import ALL_OPTIONS
from .options import ALL_OPTIONS, ALL_WINDOW_OPTIONS
from .process import Process
from .rc import STARTUP_COMMANDS
from .server import ServerConnection, bind_socket
Expand Down Expand Up @@ -110,6 +110,7 @@ def __init__(self, source_file=None, startup_command=None):
self.default_shell = get_default_shell()

self.options = ALL_OPTIONS
self.window_options = ALL_WINDOW_OPTIONS

# When no panes are available.
self.original_cwd = os.getcwd()
Expand Down
31 changes: 21 additions & 10 deletions pymux/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'SetOptionError',
'OnOffOption',
'ALL_OPTIONS',
'ALL_WINDOW_OPTIONS',
)


Expand All @@ -29,7 +30,7 @@ def get_all_values(self):
"""

@abstractmethod
def set_value(self):
def set_value(self, pymux, cli, value):
" Set option. This can raise SetOptionError. "


Expand All @@ -45,17 +46,22 @@ class OnOffOption(Option):
"""
Boolean on/off option.
"""
def __init__(self, attribute_name):
def __init__(self, attribute_name, window_option=False):
self.attribute_name = attribute_name
self.window_option = window_option

def get_all_values(self, pymux):
return ['on', 'off']

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
value = value.lower()

if value in ('on', 'off'):
setattr(pymux, self.attribute_name, (value == 'on'))
if self.window_option:
w = pymux.arrangement.get_active_window(cli)
setattr(w, self.attribute_name, (value == 'on'))
else:
setattr(pymux, self.attribute_name, (value == 'on'))
else:
raise SetOptionError('Expecting "yes" or "no".')

Expand All @@ -73,7 +79,7 @@ def get_all_values(self, pymux):
self.possible_values + [getattr(pymux, self.attribute_name)]
))

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
setattr(pymux, self.attribute_name, value)


Expand All @@ -91,7 +97,7 @@ def get_all_values(self, pymux):
['%s' % getattr(pymux, self.attribute_name)]
))

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
"""
Take a string, and return an integer. Raise SetOptionError when the
given text does not parse to a positive integer.
Expand All @@ -110,7 +116,7 @@ class KeyPrefixOption(Option):
def get_all_values(self, pymux):
return PYMUX_TO_PROMPT_TOOLKIT_KEYS.keys()

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
# Translate prefix to prompt_toolkit
try:
keys = pymux_key_to_prompt_toolkit_key_sequence(value)
Expand All @@ -125,7 +131,7 @@ class BaseIndexOption(Option):
def get_all_values(self, pymux):
return ['0', '1']

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
try:
value = int(value)
except ValueError:
Expand All @@ -142,7 +148,7 @@ def __init__(self, attribute_name):
def get_all_values(self, pymux):
return ['emacs', 'vi']

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
if value in ('emacs', 'vi'):
setattr(pymux, self.attribute_name, value == 'vi')
else:
Expand All @@ -155,7 +161,7 @@ def __init__(self, attribute_name):
def get_all_values(self, pymux):
return Justify._ALL

def set_value(self, pymux, value):
def set_value(self, pymux, cli, value):
if value in Justify._ALL:
setattr(pymux, self.attribute_name, value)
else:
Expand Down Expand Up @@ -185,3 +191,8 @@ def set_value(self, pymux, value):
'default_shell', [get_default_shell()]),
'status-justify': JustifyOption('status_justify'),
}


ALL_WINDOW_OPTIONS = {
'synchronize_panes': OnOffOption('synchronize_panes', window_option=True),
}

0 comments on commit 369b1ed

Please sign in to comment.