From 69c23047a9a70ca00b1f04b4112ab6f9debf329b Mon Sep 17 00:00:00 2001 From: "louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13" Date: Thu, 8 Jul 2010 19:27:53 +0000 Subject: Add many keyboard shortcuts. fixed #1507 --- src/config.py | 2 +- src/gui.py | 79 ++++++++++++++++++++++++++++++++----------------------- src/window.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 124 insertions(+), 41 deletions(-) diff --git a/src/config.py b/src/config.py index 9e067418..7d25fde4 100644 --- a/src/config.py +++ b/src/config.py @@ -124,5 +124,5 @@ except OSError: parser = argparse.ArgumentParser(prog="poezio", description='An XMPP ncurses client.') parser.add_argument('-f', '--file', default=CONFIG_PATH+'poezio.cfg', help='the config file you want to use', metavar="FILE") args = parser.parse_args() - +print args.file config = Config(args.file) diff --git a/src/gui.py b/src/gui.py index bff9c3be..abbe1329 100644 --- a/src/gui.py +++ b/src/gui.py @@ -37,7 +37,7 @@ from window import Window from user import User from room import Room from message import Message - +from keyboard import read_char from common import is_jid_the_same, jid_get_domain, is_jid def doupdate(): @@ -96,11 +96,25 @@ class Gui(object): "KEY_NPAGE": self.scroll_page_down, "KEY_DC": self.window.input.key_dc, "KEY_F(5)": self.rotate_rooms_left, + "^N": self.rotate_rooms_left, "KEY_F(6)": self.rotate_rooms_right, - "kLFT5": self.rotate_rooms_left, - "kRIT5": self.rotate_rooms_right, + "^P": self.rotate_rooms_right, "\t": self.auto_completion, - "KEY_BACKSPACE": self.window.input.key_backspace + "^I": self.auto_completion, + "KEY_RESIZE": self.window.resize, + "KEY_BACKSPACE": self.window.input.key_backspace, + '^J': self.execute, + '\n': self.execute, + '^D': self.window.input.key_dc, + '^W': self.window.input.delete_word, + '^K': self.window.input.delete_end_of_line, + '^U': self.window.input.delete_begining_of_line, + '^Y': self.window.input.paste_clipboard, + '^A': self.window.input.key_home, + '^E': self.window.input.key_end, + 'M-f': self.window.input.jump_word_right, + '^X': self.go_to_important_room, + 'M-b': self.window.input.jump_word_left } self.handler = Handler() @@ -116,37 +130,16 @@ class Gui(object): """ main loop waiting for the user to press a key """ - while 1: + while True: doupdate() - try: - key = stdscr.getkey() - except: - continue - if str(key) in self.key_func.keys(): - self.key_func[key]() - elif str(key) == 'KEY_RESIZE': - self.window.resize(stdscr) - self.window.refresh(self.rooms) - elif len(key) >= 4: - continue - elif ord(key) == 10: - self.execute() - elif ord(key) == 8 or ord(key) == 127: - self.window.input.key_backspace() - elif ord(key) < 32: - continue + char=read_char(stdscr) + # search for keyboard shortcut + if char in self.key_func.keys(): + self.key_func[char]() else: - if ord(key) == 27 and ord(stdscr.getkey()) == 91: - last = ord(stdscr.getkey()) # FIXME: ugly ugly workaround. - if last == 51: - self.window.input.key_dc() - continue - elif ord(key) > 190 and ord(key) < 225: - key = key+stdscr.getkey() - elif ord(key) == 226: - key = key+stdscr.getkey() - key = key+stdscr.getkey() - self.window.do_command(key) + # if len(char) > 1: + # continue # ignore non-handled keyboard shortcuts + self.window.do_command(char) def current_room(self): """ @@ -243,6 +236,25 @@ class Gui(object): return 1 self.window.input.auto_completion(sorted(self.current_room().users, compare_users)) + def go_to_important_room(self): + """ + Go to the next room with activity, in this order: + - A personal conversation with a new message + - A Muc with an highlight + - A Muc with any new message + """ + for room in self.rooms: + if room.color_state == 15: + self.command_win([room.nb]) + return + for room in self.rooms: + if room.color_state == 13: + self.command_win([room.nb]) + return + for room in self.rooms: + if room.color_state == 12: + self.command_win([room.nb]) + def rotate_rooms_right(self, args=None): """ rotate the rooms list to the right @@ -562,6 +574,7 @@ class Gui(object): self.window.refresh(self.rooms) return self.window.refresh(self.rooms) + self.current_room().set_color_state(11) def command_kick(self, args): """ diff --git a/src/window.py b/src/window.py index 6d8777a5..1461b247 100644 --- a/src/window.py +++ b/src/window.py @@ -326,6 +326,7 @@ class Input(Win): self.visible = visible self.history = [] self.text = u'' + self.clipboard = None self.pos = 0 # cursor position self.line_pos = 0 # position (in self.text) of # the first char to display on the screen @@ -342,6 +343,76 @@ class Input(Win): self.win.clear() self.win.addnstr(0, 0, self.text.encode('utf-8'), self.width-1) + def jump_word_left(self): + """ + Move the cursor one word to the left + """ + if not len(self.text) or self.pos == 0: + return + previous_space = self.text[:self.pos+self.line_pos].rfind(' ') + if previous_space == -1: + previous_space = 0 + diff = self.pos+self.line_pos-previous_space + for i in xrange(diff): + self.key_left() + + def jump_word_right(self): + """ + Move the cursor one word to the right + """ + if len(self.text) == self.pos+self.line_pos or not len(self.text): + return + next_space = self.text.find(' ', self.pos+self.line_pos+1) + if next_space == -1: + next_space = len(self.text) + diff = next_space - (self.pos+self.line_pos) + for i in xrange(diff): + self.key_right() + + def delete_word(self): + """ + Delete the word just before the cursor + """ + if not len(self.text) or self.pos == 0: + return + previous_space = self.text[:self.pos+self.line_pos].rfind(' ') + if previous_space == -1: + previous_space = 0 + diff = self.pos+self.line_pos-previous_space + for i in xrange(diff): + self.key_backspace(False) + self.rewrite_text() + + def delete_end_of_line(self): + """ + Cut the text from cursor to the end of line + """ + if len(self.text) == self.pos+self.line_pos: + return # nothing to cut + self.clipboard = self.text[self.pos+self.line_pos:] + self.text = self.text[:self.pos+self.line_pos] + self.key_end() + + def delete_begining_of_line(self): + """ + Cut the text from cursor to the begining of line + """ + if self.pos+self.line_pos == 0: + return + self.clipboard = self.text[:self.pos+self.line_pos] + self.text = self.text[self.pos+self.line_pos:] + self.key_home() + + def paste_clipboard(self): + """ + Insert what is in the clipboard at the cursor position + """ + if not self.clipboard or len(self.clipboard) == 0: + return + for letter in self.clipboard: + self.do_command(letter) + # self.do_command(self.clipboard[-1]) + def key_dc(self): """ delete char just after the cursor @@ -432,7 +503,7 @@ class Input(Win): self.pos += 1 self.rewrite_text() - def key_backspace(self): + def key_backspace(self, reset=True): """ Delete the char just before the cursor """ @@ -442,7 +513,8 @@ class Input(Win): return self.text = self.text[:self.pos+self.line_pos-1]+self.text[self.pos+self.line_pos:] self.key_left() - self.rewrite_text() + if reset: + self.rewrite_text() def auto_completion(self, user_list): """ @@ -535,10 +607,7 @@ class Input(Win): self.text += nick.decode('utf-8') self.key_end(False) - def do_command(self, key): - from common import debug - - debug("%s\n" % (len(self.text))) + def do_command(self, key, reset=True): self.reset_completion() self.text = self.text[:self.pos+self.line_pos]+key.decode('utf-8')+self.text[self.pos+self.line_pos:] (y, x) = self.win.getyx() @@ -546,7 +615,8 @@ class Input(Win): self.line_pos += 1 else: self.pos += 1 - self.rewrite_text() + if reset: + self.rewrite_text() def get_text(self): """ -- cgit v1.2.3