|
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
25
26
27
28
29
30
31
32
33
34
35
|
/* KEY DEFINITIONS
* 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;
|
|
36
|
public static final int BACKSPACE_DEL = 0x7F;
|
|
37
38
|
public static final int ESC = 0x1B;
public static final int ESC_SEQ = 0x5B;
|
|
39
40
41
|
public static final int FORWARD = 0x43;
public static final int BACKWARD = 0x44;
public static final int DEL = 0x33;
|
|
42
43
44
45
|
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;
|
|
46
47
48
49
|
public static final int INSERT_KEY = 0x32;
public static final int INS_SPACE = 0x40;
public static final int DEL_CHAR = 0x50;
public static final int NUM_0 = 0x30;
|
|
50
|
|
|
51
52
53
|
private Line line = new Line();
private boolean returnKey = false;
|
|
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
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();
}
|
|
76
77
|
private int parseKey(int key)
{
|
|
78
79
80
81
82
83
84
85
86
87
88
89
|
if(key < 0x20)
{
if(key == ESC)
{
return ESCAPE_SEQUENCE;
}
else if((key == BACKSPACE) || (key == RETURN_KEY))
{
return PRINTABLE;
}
return NON_PRINTABLE;
}
|
|
90
91
92
|
return PRINTABLE;
}
|
|
93
|
public void addChar(char c)
|
|
94
|
{
|
|
95
96
97
98
99
100
|
switch(line.getMode())
{
case INSERT:
if(line.getCursorPosition() != line.length()+1)
{
insertSpace();
|
|
101
|
}
|
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
System.out.print(c);
line.insertCharAt(c, line.getCursorPosition()-1);
line.setCursorPosition(line.getCursorPosition()+1);
break;
case OVERWRITE:
if(line.getCursorPosition() != line.length()+1)
{
line.removeCharAt(line.getCursorPosition()-1);
}
System.out.print(c);
line.insertCharAt(c, line.getCursorPosition()-1);
line.setCursorPosition(line.getCursorPosition()+1);
break;
}
|
|
117
118
119
120
|
}
public void delChar(int mode)
{
|
|
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
switch(mode)
{
case DEL_BACKWARD:
if(line.getCursorPosition() != 1)
{
System.out.print((char)BACKSPACE);
deleteCharacter();
line.removeCharAt(line.getCursorPosition()-2);
line.setCursorPosition(line.getCursorPosition()-1);
}
break;
case DEL_FORWARD:
if(line.getCursorPosition() != (line.length()+1))
{
line.removeCharAt(line.getCursorPosition()-1);
deleteCharacter();
}
break;
}
|
|
140
141
|
}
|
|
142
|
private void insertSpace()
|
|
143
144
145
|
{
System.out.print((char)ESC);
System.out.print((char)ESC_SEQ);
|
|
146
|
System.out.print((char)INS_SPACE);
|
|
147
148
|
}
|
|
149
|
private void deleteCharacter()
|
|
150
151
152
|
{
System.out.print((char)ESC);
System.out.print((char)ESC_SEQ);
|
|
153
|
System.out.print((char)DEL_CHAR);
|
|
154
155
156
157
|
}
public void moveCursorTo(int pos)
{
|
|
158
|
if((pos <= line.length()+1) && (pos >= 1))
|
|
159
|
{
|
|
160
|
if(pos > line.getCursorPosition())
|
|
161
|
{
|
|
162
163
164
165
|
System.out.print((char)ESC);
System.out.print((char)ESC_SEQ);
System.out.print((char)(NUM_0+pos-line.getCursorPosition()));
System.out.print((char)FORWARD);
|
|
166
167
|
}
|
|
168
|
else if(pos < line.getCursorPosition())
|
|
169
|
{
|
|
170
171
172
173
|
System.out.print((char)ESC);
System.out.print((char)ESC_SEQ);
System.out.print((char)(NUM_0-pos+line.getCursorPosition()));
System.out.print((char)BACKWARD);
|
|
174
|
}
|
|
175
|
line.setCursorPosition(pos);
|
|
176
177
178
|
}
}
|
|
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
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 "";
}
while(!returnKey)
{
try
{
int character = read();
|
|
200
|
System.err.print(Integer.toHexString(character) + " \n");
|
|
201
|
switch(parseKey(character))
|
|
202
|
{
|
|
203
|
case ESCAPE_SEQUENCE:
|
|
204
|
switch(read())
|
|
205
|
{
|
|
206
207
208
209
210
211
212
213
214
|
case ESC_SEQ:
switch(read())
{
case FORWARD:
moveCursorTo(line.getCursorPosition()+1);
break;
case BACKWARD:
moveCursorTo(line.getCursorPosition()-1);
|
|
215
216
|
break;
|
|
217
218
219
220
221
|
case DEL:
if(read() == TILDE)
{
delChar(DEL_FORWARD);
}
|
|
222
|
break;
|
|
223
224
225
226
227
228
|
case INSERT_KEY:
if(read() == TILDE)
{
line.toggleMode();
}
|
|
229
|
break;
|
|
230
231
232
233
234
235
236
237
|
}
break;
case HOME_END:
switch(read())
{
case HOME:
moveCursorTo(1);
|
|
238
|
break;
|
|
239
240
241
|
case END:
moveCursorTo(line.length()+1);
|
|
242
|
break;
|
|
243
244
|
}
break;
|
|
245
|
}
|
|
246
|
break;
|
|
247
248
249
250
251
252
|
case PRINTABLE:
switch(character)
{
case RETURN_KEY:
returnKey = true;
|
|
253
|
break;
|
|
254
255
256
257
|
case BACKSPACE:
case BACKSPACE_DEL:
delChar(DEL_BACKWARD);
|
|
258
|
break;
|
|
259
260
261
|
default:
addChar((char)character);
|
|
262
|
break;
|
|
263
|
}
|
|
264
|
break;
|
|
265
266
267
|
case NON_PRINTABLE:
//ignore
|
|
268
|
break;
|
|
269
270
271
272
|
}
}
catch (IOException e)
{
|
|
273
|
System.out.println("Error reading line");
|
|
274
275
276
277
278
279
280
281
282
283
284
285
|
break;
}
}
try
{
unsetRaw();
}
catch (Exception e)
{
System.out.println("Couldn't unset raw mode");
return "";
}
|
|
286
|
System.out.println("");
|
|
287
|
return line.toString();
|
|
288
289
|
}
}
|