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:
parent
3af88ff8d6
commit
8d3053bd93
2 changed files with 68 additions and 51 deletions
40
src/core.py
40
src/core.py
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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, that’s 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
|
||||||
|
|
Loading…
Reference in a new issue