summary refs log tree commit diff stats
path: root/ranger/container/commandlist.py
blob: 9c4c77a0953cf50d69d8efc5653fe44a2e31bead (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""CommandLists are dictionary-like objects which give you a command
for a given key combination. CommandLists must be initialized
before use."""
class CommandList(object):
	dummy_object = None
	dummies_in_paths = False
	paths = {}
	commandlist = []
	def __init__(self):
		self.commandlist = []
		self.paths = {}
	
	def __getitem__(self, key):
		"""Returns the command with the given key combination"""
		return self.paths[key]

	def rebuild_paths(self):
		"""Fill the path dictionary with dummie objects.
We need to know when to clear the keybuffer (when a wrong key is pressed)
and when to wait for the rest of the key combination. For "gg" we
will assign "g" to a dummy which tells the program to do the latter
and wait."""
		if self.dummies_in_paths:
			self.remove_dummies()
		
		for cmd in self.commandlist:
			for key in cmd.keys:
				for path in self.keypath(key):
					if path not in self.paths:
						self.paths[path] = self.dummy_object

		self.dummies_in_paths = True

	def keypath(self, tup):
		"""split a tuple like (a,b,c,d) into [(a,), (a,b), (a,b,c)]"""
		length = len(tup)

		if length == 0:
			return ()
		if length == 1:
			return (tup, )

		current = []
		all = []
		
		for i in range(len(tup) - 1):
			current.append(tup[i])
			all.append(tuple(current))

		return all

	def remove_dummies(self):
		"""remove dummie objects in case you have to rebuild a path dictionary which already contains dummie objects."""
		for k in tuple(paths.keys()):
			if paths[k] == self.dummy_object: del paths[k]
		self.dummies_in_paths = False


	def str_to_tuple(self, obj):
		"""splits a string into a tuple of integers"""
		if isinstance(obj, tuple):
			return obj
		elif isinstance(obj, str):
			return tuple(map(ord, list(obj)))
		elif isinstance(obj, int):
			return (obj, )
		else:
			raise TypeError('need a str, int or tuple for str_to_tuple')
	
	def bind(self, fnc, *keys):
		"""create a Command object and assign it to the given key combinations."""
		if len(keys) == 0: return

		keys = tuple(map(self.str_to_tuple, keys))

		cmd = Command(fnc, keys)

		self.commandlist.append(cmd)
		for key in keys:
			self.paths[key] = cmd
	
class Command(object):
	keys = []
	def __init__(self, fnc, keys):
		self.keys = keys
		self.execute = fnc
	
	def execute(self, *args):
		"""Execute the command."""