From 39eef45bca02c4328ba76992571fcb6a39118d79 Mon Sep 17 00:00:00 2001
From: red-agent <hell.director@gmail.com>
Date: Thu, 17 Sep 2009 13:25:25 +0300
Subject: [PATCH] Command auto-completion along with some fixes

---
 src/chat_control.py       | 49 ++++++++++++++++++++++++++++++++++++++-
 src/commands/framework.py |  5 ++--
 src/groupchat_control.py  |  7 ++++++
 3 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/chat_control.py b/src/chat_control.py
index 66e13114b2..5aeba6248e 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -148,7 +148,52 @@ class ChatControlBase(MessageControl, CommonCommands):
 	event_keymod):
 		# Derived should implement this rather than connecting to the event
 		# itself.
-		pass
+
+		event = gtk.gdk.Event(gtk.gdk.KEY_PRESS)
+		event.keyval = event_keyval
+		event.state = event_keymod
+		event.time = 0
+
+		buffer = widget.get_buffer()
+		start, end = buffer.get_bounds()
+
+		if event.keyval -- gtk.keysyms.Tab:
+			position = buffer.get_insert()
+			end = buffer.get_iter_at_mark(position)
+
+			text = buffer.get_text(start, end, False)
+			text = text.decode('utf8')
+
+			if (text.startswith(self.COMMAND_PREFIX) and not
+				text.startswith(self.COMMAND_PREFIX * 2)):
+
+				text = text.split()[0]
+				bare = text.lstrip(self.COMMAND_PREFIX)
+
+				if len(text) == 1:
+					self.command_hits = []
+					for command in self.list_commands():
+						for name in command.names:
+							self.command_hits.append(name)
+				else:
+					if (self.last_key_tabs and self.command_hits and
+						self.command_hits[0].startswith(bare)):
+						self.command_hits.append(self.command_hits.pop(0))
+					else:
+						self.command_hits = []
+						for command in self.list_commands():
+							for name in command.names:
+								if name.startswith(bare):
+									self.command_hits.append(name)
+
+				if self.command_hits:
+					buffer.delete(start, end)
+					buffer.insert_at_cursor(self.COMMAND_PREFIX + self.command_hits[0] + ' ')
+					self.last_key_tabs = True
+
+				return True
+
+			self.last_key_tabs = False
 
 	def status_url_clicked(self, widget, url):
 		helpers.launch_browser_mailer('url', url)
@@ -305,6 +350,8 @@ class ChatControlBase(MessageControl, CommonCommands):
 		self.smooth = True
 		self.msg_textview.grab_focus()
 
+		self.command_hits = []
+
 	def set_speller(self):
 		# now set the one the user selected
 		per_type = 'contacts'
diff --git a/src/commands/framework.py b/src/commands/framework.py
index 72b0000b2f..9520533ffa 100644
--- a/src/commands/framework.py
+++ b/src/commands/framework.py
@@ -370,11 +370,10 @@ class CommandProcessor(object):
         """
         command_name = self.SAFE_NAME_SCAN_PATTERN.match(name)
         if command_name:
-            command = Dispatcher.retrieve_command(self, command_name.group('name'))
+            command = self.retrieve_command(command_name.group('name'))
             if command:
                 return command
-            raise AttributeError(name)
-        return super(CommandProcessor, self).__getattr__(name)
+        raise AttributeError(name)
 
     @classmethod
     def prepare_name(cls, name):
diff --git a/src/groupchat_control.py b/src/groupchat_control.py
index 6b959a5e0f..4d6acf591f 100644
--- a/src/groupchat_control.py
+++ b/src/groupchat_control.py
@@ -1783,6 +1783,13 @@ class GroupchatControl(ChatControlBase, GroupChatCommands):
 
 			splitted_text = text.split()
 
+			# HACK: Not the best soltution.
+			if (text.startswith(self.COMMAND_PREFIX) and not
+				text.startswith(self.COMMAND_PREFIX * 2)):
+				return super(GroupchatControl,
+					self).handle_message_textview_mykey_press(widget, event_keyval,
+							event_keymod)
+
 			# nick completion
 			# check if tab is pressed with empty message
 			if len(splitted_text): # if there are any words
-- 
GitLab