forked from Michealshodipo56/agent-swarm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_input.py
More file actions
171 lines (152 loc) · 5.81 KB
/
Copy pathtest_input.py
File metadata and controls
171 lines (152 loc) · 5.81 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python3
"""Test the clean_input function"""
import sys, tty, termios
def clean_input(prompt=""):
"""
Proper text input with backspace, delete, and arrow keys.
"""
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
buf = [] # Characters before cursor
after = [] # Characters after cursor (for right-arrow)
sys.stdout.write(prompt)
sys.stdout.flush()
def redraw():
"""Redraw the entire line from cursor position"""
# Move to start of input
if buf:
sys.stdout.write(f'\x1b[{len(buf)}D')
# Clear everything after prompt
total = len(buf) + len(after)
sys.stdout.write(' ' * total)
# Move back to start
sys.stdout.write(f'\x1b[{total}D')
# Write all characters
sys.stdout.write(''.join(buf))
if after:
sys.stdout.write(''.join(reversed(after)))
# Move cursor back to correct position
sys.stdout.write(f'\x1b[{len(after)}D')
sys.stdout.flush()
try:
tty.setraw(fd)
while True:
ch = sys.stdin.read(1)
# Enter
if ch in ('\r', '\n'):
sys.stdout.write('\r\n')
sys.stdout.flush()
return ''.join(buf + list(reversed(after)))
# CTRL+C
if ch == '\x03':
sys.stdout.write('\r\n')
sys.stdout.flush()
raise KeyboardInterrupt
# CTRL+D
if ch == '\x04':
sys.stdout.write('\r\n')
sys.stdout.flush()
raise EOFError
# Escape sequence
if ch == '\x1b':
seq = sys.stdin.read(2)
if seq == '[D': # Left arrow
if buf:
after.append(buf.pop())
sys.stdout.write('\x1b[D')
sys.stdout.flush()
elif seq == '[C': # Right arrow
if after:
buf.append(after.pop())
sys.stdout.write('\x1b[C')
sys.stdout.flush()
elif seq == '[3': # Possible delete key
tilde = sys.stdin.read(1) # Should be '~'
if tilde == '~' and after: # Delete key
after.pop()
# Redraw from current position
if after:
sys.stdout.write(''.join(reversed(after)))
sys.stdout.write(' ')
sys.stdout.write(f'\x1b[{len(after) + 1}D')
else:
sys.stdout.write(' \x1b[D')
sys.stdout.flush()
elif seq == '[H': # Home
if buf:
sys.stdout.write(f'\x1b[{len(buf)}D')
after = list(reversed(buf)) + after
buf = []
sys.stdout.flush()
elif seq == '[F': # End
if after:
sys.stdout.write(f'\x1b[{len(after)}C')
buf = buf + list(reversed(after))
after = []
sys.stdout.flush()
# Ignore other escape sequences
continue
# Backspace
if ch in ('\x7f', '\b'):
if buf:
buf.pop()
sys.stdout.write('\b \b') # Move back, clear, move back
if after:
# Redraw characters after cursor
sys.stdout.write(''.join(reversed(after)))
sys.stdout.write(' ')
sys.stdout.write(f'\x1b[{len(after) + 1}D')
sys.stdout.flush()
continue
# CTRL+U - clear line
if ch == '\x15':
total = len(buf) + len(after)
if total > 0:
sys.stdout.write(f'\x1b[{total}D')
sys.stdout.write(' ' * total)
sys.stdout.write(f'\x1b[{total}D')
buf = []
after = []
sys.stdout.flush()
continue
# CTRL+A - beginning
if ch == '\x01':
if buf:
sys.stdout.write(f'\x1b[{len(buf)}D')
after = list(reversed(buf)) + after
buf = []
sys.stdout.flush()
continue
# CTRL+E - end
if ch == '\x05':
if after:
sys.stdout.write(f'\x1b[{len(after)}C')
buf = buf + list(reversed(after))
after = []
sys.stdout.flush()
continue
# Regular printable character
if ord(ch) >= 32:
buf.append(ch)
if after:
# Insert in middle
sys.stdout.write(ch)
sys.stdout.write(''.join(reversed(after)))
sys.stdout.write(f'\x1b[{len(after)}D')
else:
sys.stdout.write(ch)
sys.stdout.flush()
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
# Test
if __name__ == "__main__":
print("Test: Type 'hello', backspace twice, type 'p', press Enter")
print("Expected output: 'help'")
print()
result = clean_input("> ")
print(f"You typed: '{result}'")
print()
if result == "help":
print("PASS")
else:
print(f"FAIL - expected 'help', got '{result}'")