More scalable display_name handling (actually the length).
[gsh.git] / gsh / control_commands_helpers.py
blobbe168c95b1ec8115002e4167487be2b88a23b919
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2006, 2007, 2008 Guillaume Chazarain <guichaz@gmail.com>
19 import os
20 from fnmatch import fnmatch
21 import readline
23 from gsh.host_syntax import expand_syntax
24 from gsh.console import console_output
25 from gsh import dispatchers
26 from gsh import remote_dispatcher
28 def toggle_shells(command, enable):
29 """Enable or disable the specified shells. If the command would have
30 no effect, it changes all other shells to the inverse enable value."""
31 if command and command != '*':
32 for i in selected_shells(command):
33 if i.state != remote_dispatcher.STATE_DEAD and i.enabled != enable:
34 break
35 else:
36 toggle_shells('*', not enable)
38 for i in selected_shells(command):
39 if i.state != remote_dispatcher.STATE_DEAD:
40 i.set_enabled(enable)
42 def selected_shells(command):
43 """Iterator over the shells with names matching the patterns.
44 An empty patterns matches all the shells"""
45 if not command or command == '*':
46 for i in dispatchers.all_instances():
47 yield i
48 return
49 selected = set()
50 instance_found = False
51 for pattern in command.split():
52 found = False
53 for expanded_pattern in expand_syntax(pattern):
54 for i in dispatchers.all_instances():
55 instance_found = True
56 if fnmatch(i.display_name, expanded_pattern):
57 found = True
58 if i not in selected:
59 selected.add(i)
60 yield i
61 if instance_found and not found:
62 console_output('%s not found\n' % pattern)
64 def complete_shells(line, text, predicate=lambda i: True):
65 """Return the shell names to include in the completion"""
66 res = [i.display_name + ' ' for i in dispatchers.all_instances() if \
67 i.display_name.startswith(text) and \
68 predicate(i) and \
69 ' ' + i.display_name + ' ' not in line]
70 return res
72 def expand_local_path(path):
73 return os.path.expanduser(os.path.expandvars(path) or '~')
75 def list_control_commands():
76 import gsh.control_commands
77 return [c[3:] for c in dir(gsh.control_commands) if c.startswith('do_')]
79 def get_control_command(name):
80 import gsh.control_commands
81 func = getattr(gsh.control_commands, 'do_' + name)
82 return func
84 def complete_control_command(line, text):
85 import gsh.control_commands
86 if readline.get_begidx() == 0:
87 # Completing control command name
88 cmds = list_control_commands()
89 prefix = text[1:]
90 matches = [':' + cmd + ' ' for cmd in cmds if cmd.startswith(prefix)]
91 else:
92 # Completing control command parameters
93 cmd = line.split()[0][1:]
94 def_compl = lambda line: []
95 compl_func = getattr(gsh.control_commands, 'complete_' + cmd, def_compl)
96 matches = compl_func(line, text)
97 return matches
99 def handle_control_command(line):
100 if not line:
101 return
102 cmd_name = line.split()[0]
103 try:
104 cmd_func = get_control_command(cmd_name)
105 except AttributeError:
106 console_output('Unknown control command: %s\n' % cmd_name)
107 else:
108 parameters = line[len(cmd_name) + 1:]
109 cmd_func(parameters)