fixes #2164. Restore multiline messages on paste of big text. That’s now faster and works ~100% of the time (no more message cut in two part for no reason, I think)

This commit is contained in:
Florent Le Coz 2011-05-29 00:35:11 +02:00
parent 3af88ff8d6
commit 8d3053bd93
2 changed files with 68 additions and 51 deletions

View file

@ -670,23 +670,31 @@ class Core(object):
""" """
# curses.ungetch(0) # FIXME # curses.ungetch(0) # FIXME
while self.running: while self.running:
char = self.read_keyboard() char_list = self.read_keyboard()
# Special case for M-x where x is a number # Special case for M-x where x is a number
if char.startswith('M-') and len(char) == 3: if len(char_list) == 1:
try: char = char_list[0]
nb = int(char[2]) if char.startswith('M-') and len(char) == 3:
except ValueError: try:
pass nb = int(char[2])
else: except ValueError:
if self.current_tab().nb == nb: pass
self.go_to_previous_tab()
else: else:
self.command_win('%d' % nb) if self.current_tab().nb == nb:
# search for keyboard shortcut self.go_to_previous_tab()
if char in self.key_func: else:
self.key_func[char]() self.command_win('%d' % nb)
# search for keyboard shortcut
if char in self.key_func:
self.key_func[char]()
else:
res = self.do_command(char)
if res:
self.refresh_window()
else: else:
self.do_command(char) for char in char_list:
self.do_command(char)
self.refresh_window()
self.doupdate() self.doupdate()
def current_tab(self): def current_tab(self):
@ -1419,9 +1427,7 @@ class Core(object):
def do_command(self, key): def do_command(self, key):
if not key: if not key:
return return
res = self.current_tab().on_input(key) return self.current_tab().on_input(key)
if res:
self.refresh_window()
def on_roster_enter_key(self, roster_row): def on_roster_enter_key(self, roster_row):
""" """

View file

@ -24,8 +24,6 @@ shortcut, like ^A, M-a or KEY_RESIZE)
import time import time
last_timeout = time.time()
def get_next_byte(s): def get_next_byte(s):
""" """
Read the next byte of the utf-8 char Read the next byte of the utf-8 char
@ -41,44 +39,57 @@ def get_next_byte(s):
return (None, c) return (None, c)
return (ord(c), c.encode('latin-1')) # returns a number and a bytes object return (ord(c), c.encode('latin-1')) # returns a number and a bytes object
def read_char(s): def read_char(s, timeout=1000):
""" """
Read one utf-8 char Read one utf-8 char
see http://en.wikipedia.org/wiki/UTF-8#Description see http://en.wikipedia.org/wiki/UTF-8#Description
""" """
global last_timeout s.timeout(timeout) # The timeout for timed events to be checked every second
s.timeout(1000) ret_list = []
# The list of all chars. For example if you paste a text, the list the chars pasted
# so that they can be handled at once.
(first, char) = get_next_byte(s) (first, char) = get_next_byte(s)
if first is None and char is None: while first is not None or char is not None:
last_timeout = time.time() if not isinstance(first, int): # Keyboard special, like KEY_HOME etc
return None return [char]
if not isinstance(first, int): # Keyboard special, like KEY_HOME etc if first == 127 or first == 8:
return char return ["KEY_BACKSPACE"]
if first == 127 or first == 8: s.timeout(0) # we are now getting the missing utf-8 bytes to get a whole char
return "KEY_BACKSPACE" if first < 127: # ASCII char on one byte
if first < 127: # ASCII char on one byte if first <= 26: # transform Ctrl+* keys
if first <= 26: # transform Ctrl+* keys char = chr(first + 64)
char = chr(first + 64) ret_list.append("^"+char)
# if char == 'M' and time.time() - last_char_time < 0.0005: (first, char) = get_next_byte(s)
# char = 'J' continue
return "^"+char if first == 27:
if first == 27: second = read_char(s, 0)
second = read_char(s) res = 'M-%s' % (second[0],)
res = 'M-%s' % (second,) ret_list.append(res)
return res (first, char) = get_next_byte(s)
if 194 <= first: continue
(code, c) = get_next_byte(s) # 2 bytes char if 194 <= first:
char += c (code, c) = get_next_byte(s) # 2 bytes char
if 224 <= first: char += c
(code, c) = get_next_byte(s) # 3 bytes char if 224 <= first:
char += c (code, c) = get_next_byte(s) # 3 bytes char
if 240 <= first: char += c
(code, c) = get_next_byte(s) # 4 bytes char if 240 <= first:
char += c (code, c) = get_next_byte(s) # 4 bytes char
try: char += c
return char.decode('utf-8') # return all the concatened byte objets, decoded try:
except UnicodeDecodeError: ret_list.append(char.decode('utf-8')) # return all the concatened byte objets, decoded
except UnicodeDecodeError:
return None
# s.timeout(1) # timeout to detect a paste of many chars
(first, char) = get_next_byte(s)
if not ret_list:
# nothing at all was read, thats a timed event timeout
return None return None
if len(ret_list) != 1:
if ret_list[-1] == '^M':
ret_list.pop(-1)
return [char if char != '^M' else '^J' for char in ret_list]
return ret_list
if __name__ == '__main__': if __name__ == '__main__':
import curses import curses