def input_stream(self):
"""Waiting an input and run a proper method according to type of input"""
while True:
self.search(self.query)
self.display()
ch = self.search_window.getch()
if curses.ascii.isprint(ch):
self.write(ch)
self.reset_top()
elif ch in (curses.ascii.BS, curses.ascii.DEL, curses.KEY_BACKSPACE):
self.delete()
self.reset_top()
elif ch == curses.KEY_UP:
self.scroll(self.UP)
elif ch == curses.KEY_DOWN:
self.scroll(self.DOWN)
elif ch in (curses.ascii.LF, curses.ascii.NL):
self.open_link()
elif ch == curses.ascii.ESC:
break
python类KEY_BACKSPACE的实例源码
def put(self, char):
pos = self._cursor.position
cnt = len(self._text)
if isinstance(char, str) and cnt < self._max_len and ord(char) >= 0x20:
self._text = self._text[:pos] + char + self._text[pos:]
self._cursor.count = len(self._text)
self._cursor.position = pos + 1
elif char == curses.KEY_LEFT and pos > 0:
self._cursor.position = pos - 1
elif char == curses.KEY_RIGHT and pos < cnt:
self._cursor.position = pos + 1
elif char == curses.KEY_HOME:
self._cursor.position = 0
elif char == curses.KEY_END:
self._cursor.position = cnt
elif char == curses.KEY_BACKSPACE and pos > 0:
self._text = self._text[:pos - 1] + self._text[pos:]
self._cursor.count = len(self._text)
self._cursor.position = pos - 1
elif char == curses.KEY_DC:
self._text = self._text[:pos] + self._text[pos + 1:]
self._cursor.count = len(self._text)
def __init__(self, *args, **kwargs):
self.vim_handlers = {
# movement
'k': self.h_exit_up,
'j': self.h_exit_down,
'h': self.h_cursor_left,
'l': self.h_cursor_right,
curses.ascii.SP: self.h_cursor_right, # Space
curses.KEY_BACKSPACE: self.h_cursor_left,
# deletion
'X': self.h_delete_left,
'x': self.h_delete_right,
# insert chars
'i': self.h_vim_insert_mode,
'a': self.h_vim_append_char,
'A': self.h_vim_append_char_at_end,
}
super().__init__(*args, **kwargs) # set_up_handlers is called in __init__
def do_command(self, ch):
if ch == 127: # backspace
Textbox.do_command(self,curses.KEY_BACKSPACE)
self.win.refresh()
return 1
if ch == 27:
Textbox.gather(self)
return -1
return Textbox.do_command(self, ch)
def get_key(self):
code = self.win.getch()
if code > 0:
# Accept newline and carriage return as enter key
if code == curses.ascii.NL or code == curses.ascii.CR:
code = curses.KEY_ENTER
# Accept newline and carriage return as enter key
if code == curses.ascii.BS:
code = curses.KEY_BACKSPACE
return code
def on_key(self, ch):
x = self.pos
# ascii 32-126 (inclusive)
if curses.ascii.isprint(ch):
if len(self.value) < self.max_length:
self.value = self.value[:x] + chr(ch) + self.value[x:]
self.pos += 1
elif ch == curses.KEY_LEFT:
if x > 0:
self.pos -= 1
elif ch == curses.KEY_RIGHT:
if x < len(self.value):
self.pos += 1
elif ch == curses.KEY_BACKSPACE:
if x > 0:
self.value = self.value[:x - 1] + self.value[x:]
self.pos -= 1
elif ch == curses.KEY_DC:
if x < len(self.value):
self.value = self.value[:x] + self.value[x + 1:]
elif ch == curses.KEY_HOME:
self.pos = 0
elif ch == curses.KEY_END:
self.pos = len(self.value)
else:
return False
self.update()
return True
def on_key(self, ch):
if not self.active:
return
if self.selected:
if ch in (curses.ascii.ESC, curses.KEY_BACKSPACE):
self.cancel_selection()
elif ch == curses.KEY_LEFT:
if self.selection > 0 and self.selection < 4 or self.selection > 4:
self.set_selection(self.selection - 1)
elif ch == curses.KEY_RIGHT:
if self.selection < 3 or self.selection > 3 and self.selection < 7:
self.set_selection(self.selection + 1)
elif ch == curses.KEY_UP:
if self.selection > 3:
self.set_selection(self.selection - 4)
elif ch == curses.KEY_DOWN:
if self.selection < 4 and self.selected_source == 'hand':
self.set_selection(self.selection + 4)
elif ch in (curses.KEY_ENTER, curses.ascii.SP):
self.confirm_selection()
else:
if ch == curses.KEY_LEFT:
if self.selection > 0:
self.set_selection(self.selection - 1)
elif ch == curses.KEY_RIGHT:
if self.selection + 1 < len(self.selectable_sources):
self.set_selection(self.selection + 1)
elif ch in (curses.KEY_ENTER, curses.ascii.SP):
self.confirm_selection()
def poll_event(self):
"""
Checks if an event happens and returns a string related to the event.
Returns -1 if nothing happened during self.screen.timeout milliseconds.
If the event is a normal (letter) key press,
the letter is returned (case sensitive)
:return: Event type
"""
self.mutex.acquire()
ch = self.screen.getch()
self.mutex.release()
if ch == -1:
return EVENT_SKIP
elif ch == 27:
return EVENT_ESC
elif ch == curses.KEY_RESIZE:
return EVENT_RESIZE
elif ch == 10 or ch == curses.KEY_ENTER:
return EVENT_ENTER
elif ch == 127 or ch == curses.KEY_BACKSPACE:
return EVENT_BACKSPACE
elif ch == curses.KEY_UP:
return EVENT_UP
elif ch == curses.KEY_DOWN:
return EVENT_DOWN
elif ch == curses.KEY_LEFT:
return EVENT_LEFT
elif ch == curses.KEY_RIGHT:
return EVENT_RIGHT
elif ch == 3:
return EVENT_CTRL_C
elif ch == 409:
return EVENT_CLICK
elif 0 <= ch < 256:
return chr(ch)
else:
return EVENT_UNHANDLED
def _sanitise_key(k):
if k in (127, curses.KEY_BACKSPACE, curses.KEY_DC):
k = solent_keycode('backspace')
return k
def test_should_put_backspace(self):
input = TextInput(max_len=10)
input.put('a')
input.put('b')
input.put(curses.KEY_BACKSPACE)
self.assertEqual('a', input.text)
self.assertEqual(1, input.cursor)
def test_should_put_backspace_before_end(self):
input = TextInput(max_len=10)
input.put('a')
input.put('b')
input.put(curses.KEY_LEFT)
input.put(curses.KEY_BACKSPACE)
self.assertEqual('b', input.text)
self.assertEqual(0, input.cursor)
def test_should_not_put_backspace_at_beginning(self):
input = TextInput(max_len=10)
input.put('a')
input.put(curses.KEY_LEFT)
input.put(curses.KEY_BACKSPACE)
self.assertEqual('a', input.text)
self.assertEqual(0, input.cursor)
def vim_remove_handlers(self):
"""Remove vim keybindings from list of keybindings. Used when
entering Insert mode.
"""
for handler in self.vim_handlers:
del self.handlers[handler]
# revert backspace to what it normally does
self.handlers[curses.KEY_BACKSPACE] = self.h_delete_left
def _create_pocket(self):
pocket_name = ""
while True:
self.screen.clear()
self._draw_tab_bar()
self.screen.addstr(2, 2, "Pocket name:")
self.screen.addstr(4, 4, pocket_name)
c = self.screen.getch()
if c == 27:
self._status = "Cancelled"
break
elif c == curses.KEY_ENTER or c == 10 or c == 13:
ec = await api.Pocket.create(self._ws, pocket_name)
if ec:
self._status = ec.name
else:
self._status = "Created"
break
elif c == curses.KEY_BACKSPACE:
pocket_name = pocket_name[:-1]
elif c == curses.KEY_LEFT or c == curses.KEY_RIGHT:
pass
else:
pocket_name += chr(c)
def _enter_password_tab2(self):
password = ""
while True:
self.screen.clear()
self._draw_tab_bar()
self.screen.addstr(2, 2, "Password:")
self.screen.addstr(4, 2, "*" * len(password))
c = self.screen.getch()
if c == curses.KEY_BACKSPACE:
password = password[:-1]
elif c == curses.KEY_ENTER or c == 10 or c == 13:
return password
elif c == curses.KEY_LEFT:
self._current_tab -= 1
if self._current_tab < 0:
self._current_tab = len(self._account_names) - 1
await self._activate_account()
return None
elif c == curses.KEY_RIGHT:
self._current_tab += 1
if self._current_tab >= len(self._account_names):
self._current_tab = 0
await self._activate_account()
return None
else:
password += chr(c)
def _enter_password(self):
password = ""
while True:
self.screen.clear()
self.screen.addstr(1, 2, "Enter a password:")
self.screen.addstr(3, 2, "*" * len(password))
c = self.screen.getch()
if c == curses.KEY_BACKSPACE:
password = password[:-1]
elif c == curses.KEY_ENTER or c == 10 or c == 13:
return password
else:
password += chr(c)
def start(self):
"""
start iterates the file and paints the text on the screen.
exits when q is pressed.
"""
try:
fileptr = 0
key = ''
lines = 1
while True:
# get the cursor position for further manipulation
y, x = self.stdscr.getyx()
key = self.stdscr.getch()
if key == curses.KEY_BACKSPACE or key == curses.KEY_DC or \
key == curses.KEY_DL or key == 127 :
# handle backspace
if x == 0 and y == 0:
continue
# take the file pointer back one step
fileptr -= 1
# update the screen
if x == 0:
lines -= 1
self.stdscr.addstr(y-1, len(self.virtualfile[lines-1]), ' ')
self.stdscr.move(y-1, len(self.virtualfile[lines-1]))
else:
self.stdscr.addstr(y, x-1, ' ')
self.stdscr.move(y, x-1)
elif key == curses.KEY_UP or key == curses.KEY_DOWN or \
key == curses.KEY_RESIZE or key == -1:
# ignore
continue
else:
text = self.get_text(fileptr)
# increase the lines if there are "\n" s
lines += sum([1 if c == '\n' else 0 for c in text])
fileptr += self.n
self.stdscr.addstr(text)
self.stdscr.refresh()
# graceful exit
curses.endwin()
except KeyboardInterrupt:
curses.endwin()
exit()
def keys_init(self):
"""Define methods for each key.
"""
self.keys = {
curses.KEY_BACKSPACE: self.backspace,
CTRL('h'): self.backspace,
curses.ascii.BS: self.backspace,
curses.ascii.DEL: self.backspace,
curses.ascii.ETX: self.close,
curses.KEY_DC: self.del_char,
CTRL('d'): self.del_char,
CTRL('u'): self.del_to_bol,
CTRL('k'): self.del_to_eol,
curses.KEY_DOWN: self.down,
CTRL('n'): self.down,
curses.KEY_END: self.end,
CTRL('e'): self.end,
curses.KEY_F1: self.help,
curses.KEY_HOME: self.home,
CTRL('a'): self.home,
curses.KEY_ENTER: self.insert_line_or_quit,
curses.ascii.NL: self.insert_line_or_quit,
curses.ascii.LF: self.insert_line_or_quit,
"\n": self.insert_line_or_quit,
curses.KEY_LEFT: self.left,
CTRL('b'): self.left,
curses.KEY_NPAGE: self.page_down,
curses.KEY_PPAGE: self.page_up,
CTRL('v'): self.paste,
CTRL('x'): self.quit,
curses.KEY_F2: self.quit,
curses.KEY_F3: self.quit_nosave,
curses.ascii.ESC: self.quit_nosave,
curses.KEY_RESIZE: self.resize,
-1: self.resize,
curses.KEY_RIGHT: self.right,
CTRL('f'): self.right,
curses.KEY_UP: self.up,
CTRL('p'): self.up,
}
def _send_screen(self):
ec, self._history = await api.Wallet.history(self._ws,
self._active_pocket)
self._send_fields = ["", "", "", ""]
self._selected_send_item = 0
while True:
await self._display_history()
c = self.screen.getch()
if c == curses.KEY_UP:
self._selected_send_item -= 1
if self._selected_send_item < 0:
self._selected_send_item = 3
elif c == curses.KEY_DOWN:
self._selected_send_item += 1
if self._selected_send_item > 3:
self._selected_send_item = 0
elif c == curses.KEY_ENTER or c == 10 or c == 13:
if self._selected_send_item == 0:
break
_, addr, amount, fee = self._send_fields
try:
decimal.Decimal(amount)
except decimal.InvalidOperation:
self._status = "Invalid amount"
break
try:
decimal.Decimal(fee)
except decimal.InvalidOperation:
self._status = "Invalid fee"
break
addr_type = await api.Daemon.validate_address(self._ws,
addr)
if addr_type == "invalid":
self._status = "Invalid address"
break
dests = [(addr, amount)]
ec, tx_hash = await api.Wallet.send(self._ws, dests, fee=fee,
pocket=self._active_pocket)
if ec:
self._status = ec.name
else:
self._status = "Sent %s" % tx_hash
break
elif c == curses.KEY_BACKSPACE:
self._send_fields[self._selected_send_item] = \
self._send_fields[self._selected_send_item][:-1]
elif c == curses.KEY_LEFT or c == curses.KEY_RIGHT:
pass
else:
self._send_fields[self._selected_send_item] += chr(c)
def _new_account(self):
index = 0
account_name = ""
password = ""
is_testnet = False
while True:
self.screen.clear()
self.screen.addstr(1, 2, "Account name:")
if index == 0:
color = self._active_account_color()
else:
color = self._inactive_account_color()
row_len = 26
acc_row = account_name + "_" * (row_len - len(account_name))
self.screen.addstr(2, 2, acc_row, color)
self.screen.addstr(3, 2, "Password:")
if index == 1:
color = self._active_account_color()
else:
color = self._inactive_account_color()
pass_row = "*" * len(password) + "_" * (row_len - len(password))
self.screen.addstr(4, 2, pass_row, color)
if index == 2:
color = self._active_account_color()
else:
color = self._inactive_account_color()
mark = "X" if is_testnet else " "
self.screen.addstr(6, 2, "[%s] Testnet" % mark, color)
c = self.screen.getch()
if c == curses.KEY_BACKSPACE:
if index == 0:
account_name = account_name[:-1]
elif index == 1:
password = password[:-1]
elif c == curses.KEY_ENTER or c == 10 or c == 13:
ec = await api.Account.create(self._ws, account_name,
password, is_testnet)
if ec:
self._status = ec.name
break
elif c == curses.KEY_UP:
index -= 1
if index < 0:
index = 2
elif c == curses.KEY_DOWN:
index += 1
if index >= 3:
index = 0
elif c == ord(" ") and index == 2:
is_testnet = not is_testnet
else:
if index == 0:
account_name += chr(c)
elif index == 1:
password += chr(c)