-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput_no_newline.py
114 lines (107 loc) · 4.63 KB
/
input_no_newline.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/python3
"""Provide an input function that doesn't echo a newline."""
try:
from windows_specific import getwch, get_clipboard_data, sigtstp, input_code
except ImportError:
from unix_specific import getwch, get_clipboard_data, sigtstp, input_code
try:
from readline_available import (init_history_index, restore_history,
store_and_replace_history,
handle_prev_history, handle_next_history,
finalise_history)
except ImportError:
from readline_unavailable import (init_history_index, restore_history,
store_and_replace_history,
handle_prev_history, handle_next_history,
finalise_history)
from shared_stuff import ANSI, move_cursor, line_insert
def input_no_newline(prompt=''): # pylint: disable=too-many-branches, too-many-statements
"""Echo and return user input, except for the newline."""
print(prompt, end='', flush=True)
response = ''
position = 0
history_index = init_history_index()
input_replaced = False
history_modified = False
replacements = {}
while True:
char = getwch()
if char in input_code['CSI'][0]:
char = getwch()
if char == input_code['CSI'][1]:
# *NIX uses three characters
char = getwch()
if char == input_code['up']:
(history_index, input_replaced, history_modified) = (
handle_prev_history(
history_index, response, replacements, input_replaced,
history_modified
)
)
response = restore_history(history_index, response, position)
position = len(response)
elif char == input_code['down']:
(history_index, input_replaced, history_modified) = (
handle_next_history(
history_index, response, replacements, input_replaced,
history_modified
)
)
response = restore_history(history_index, response, position)
position = len(response)
elif char == input_code['right'] and position < len(response):
move_cursor('right')
position += 1
elif char == input_code['left'] and position > 0:
move_cursor('left')
position -= 1
elif char == input_code['end']:
move_cursor('right', len(response) - position)
position = len(response)
elif char == input_code['home']:
move_cursor('left', position)
position = 0
elif char == input_code['del'][0]:
if ''.join(input_code['del']) == '3~':
# *NIX uses '\x1b[3~' as its del key code, but only
# '\x1b[3' has currently been read from sys.stdin
getwch()
backlog = response[position+1 :]
response = response[:position] + backlog
line_insert(backlog)
elif char == input_code['backspace']:
if position > 0:
backlog = response[position:]
response = response[: position-1] + backlog
print('\b', end='', flush=True)
position -= 1
line_insert(backlog)
elif char == input_code['^C']:
raise KeyboardInterrupt
elif char == input_code['^D']:
raise EOFError
elif char == input_code['^V']:
paste = get_clipboard_data()
backlog = response[position:]
response = response[:position] + paste + backlog
position += len(paste)
line_insert(backlog, extra=paste)
elif char == input_code['^Z']:
sigtstp()
elif char == input_code['enter']:
finalise_history(history_index, response, replacements,
input_replaced, history_modified)
move_cursor('right', len(response) - position)
return response
else:
backlog = response[position:]
response = response[:position] + char + backlog
position += 1
line_insert(backlog, extra=char)
def main():
"""Called if script isn't imported."""
print('Hello, ', end='', flush=True)
name = input_no_newline() # pylint: disable=unused-variable
print(', how do you do?')
if __name__ == '__main__':
main()