|
1
2
3
4
5
6
|
package pad.prac1;
import java.io.*;
public class EditableBufferedReader extends BufferedReader
{
|
|
7
8
9
10
|
/*
* MODE DEFINITIONS
*/
|
|
11
12
13
14
|
public static final int DEL_BACKWARD = 0;
public static final int DEL_FORWARD = 1;
public static final int INSERT = 0;
public static final int OVERWRITE = 1;
|
|
15
16
17
18
19
20
|
/*
* TYPE DEFINITIONS
*/
public static final int ESCAPE_SEQUENCE = 0;
|
|
21
22
|
public static final int PRINTABLE = 1;
public static final int NON_PRINTABLE = 2;
|
|
23
24
|
/* KEY DEFINITIONS
|
|
25
|
*
|
|
26
27
28
29
30
31
32
33
34
35
36
|
* ESC (0x1B) starts an escape sequence
* ESC+[+C (0x1B 0x5B 0x43) Cursor Forward
* ESC+[+D (0x1B 0x5B 0x44) Cursor Backward
* ESC+[+2+~ (0x1B 0x5B 0x32 0x7E) Insert
* ESC+[+3+~ (0x1B 0x5B 0x33 0x7E) Delete forward
* ESC+O+H (0x1B 0x4F 0x48) Home
* ESC+O+F (0x1B 0x4F 0x46) End
*/
public static final int RETURN_KEY = 0x0D;
public static final int BACKSPACE = 0x08;
|
|
37
|
public static final int BACKSPACE_DEL = 0x7F;
|
|
38
39
|
public static final int ESC = 0x1B;
public static final int ESC_SEQ = 0x5B;
|
|
40
41
42
|
public static final int FORWARD = 0x43;
public static final int BACKWARD = 0x44;
public static final int DEL = 0x33;
|
|
43
44
45
46
|
public static final int TILDE = 0x7E;
public static final int HOME_END = 0x4F;
public static final int HOME = 0x48;
public static final int END = 0x46;
|
|
47
48
49
|
public static final int INSERT_KEY = 0x32;
public static final int INS_SPACE = 0x40;
public static final int DEL_CHAR = 0x50;
|
|
50
51
|
public static final int EOF = 0x04;
public static final int LINE_FEED = 0x0A;
|
|
52
|
|
|
53
54
55
|
private Console console = new Console();
private Line line = new Line(console);
private boolean endOfFile = false;
|
|
56
|
|
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
public EditableBufferedReader(Reader in)
{
super(in);
}
public EditableBufferedReader(Reader in, int sz)
{
super(in,sz);
}
private void setRaw() throws IOException, InterruptedException
{
String[] cmd = {"/bin/sh", "-c", "stty raw -echo </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();
}
private void unsetRaw() throws IOException, InterruptedException
{
String[] cmd = {"/bin/sh", "-c", "stty -raw echo </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();
}
|
|
79
80
|
private int parseKey(int key)
{
|
|
81
82
83
84
85
86
|
if(key < 0x20)
{
if(key == ESC)
{
return ESCAPE_SEQUENCE;
}
|
|
87
|
else if((key == BACKSPACE) || (key == RETURN_KEY) || (key == EOF))
|
|
88
89
90
91
92
|
{
return PRINTABLE;
}
return NON_PRINTABLE;
}
|
|
93
94
95
|
return PRINTABLE;
}
|
|
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
public int read() throws IOException
{
return super.read();
}
public String readLine()
{
try
{
setRaw();
}
catch (Exception e)
{
System.out.println("Couldn't set terminal in raw mode");
return "";
}
|
|
112
|
while(!endOfFile)
|
|
113
114
115
116
|
{
try
{
int character = read();
|
|
117
|
//System.err.print((String)(Integer.toHexString(character) + " ").toUpperCase());
|
|
118
|
switch(parseKey(character))
|
|
119
|
{
|
|
120
|
case ESCAPE_SEQUENCE:
|
|
121
|
switch(read())
|
|
122
|
{
|
|
123
124
125
126
|
case ESC_SEQ:
switch(read())
{
case FORWARD:
|
|
127
|
line.setCursorTo(line.getCursorPosition()+1);
|
|
128
129
130
|
break;
case BACKWARD:
|
|
131
|
line.setCursorTo(line.getCursorPosition()-1);
|
|
132
133
|
break;
|
|
134
135
136
|
case DEL:
if(read() == TILDE)
{
|
|
137
|
line.delChar(DEL_FORWARD);
|
|
138
|
}
|
|
139
|
break;
|
|
140
141
142
143
144
145
|
case INSERT_KEY:
if(read() == TILDE)
{
line.toggleMode();
}
|
|
146
|
break;
|
|
147
148
149
150
151
152
153
|
}
break;
case HOME_END:
switch(read())
{
case HOME:
|
|
154
|
line.setCursorTo(1);
|
|
155
|
break;
|
|
156
157
|
case END:
|
|
158
|
line.setCursorTo(line.length()+1);
|
|
159
|
break;
|
|
160
161
|
}
break;
|
|
162
|
}
|
|
163
|
break;
|
|
164
165
166
167
|
case PRINTABLE:
switch(character)
{
|
|
168
169
|
case EOF:
endOfFile = true;
|
|
170
|
break;
|
|
171
172
173
|
case BACKSPACE:
case BACKSPACE_DEL:
|
|
174
|
line.delChar(DEL_BACKWARD);
|
|
175
|
break;
|
|
176
177
178
|
case RETURN_KEY:
character = LINE_FEED;
|
|
179
|
default:
|
|
180
|
line.addChar((char)character);
|
|
181
|
break;
|
|
182
|
}
|
|
183
|
break;
|
|
184
185
186
|
case NON_PRINTABLE:
//ignore
|
|
187
|
break;
|
|
188
189
190
191
|
}
}
catch (IOException e)
{
|
|
192
|
System.out.println("Error reading line");
|
|
193
194
195
196
197
198
199
200
201
202
203
204
|
break;
}
}
try
{
unsetRaw();
}
catch (Exception e)
{
System.out.println("Couldn't unset raw mode");
return "";
}
|
|
205
|
System.out.println("");
|
|
206
|
return line.toString();
|
|
207
208
|
}
}
|
|
209
210
211
212
213
214
215
216
217
218
219
220
|
/* TO-DO
*
* up/down keys (needs text to work)
* pgup pgdown keys (goesto penultima linea visible)
* read terminal size
* update size dynamically
* long strings wrap down
* cursor keys skip final \n on a line
* careful if overwrite mode and final character is \n
*/
|