Commit 90d375bfc0dd0411f3ae044e4d45c674841b132b
1 parent
9d73d5b1
git-svn-id: svn://imanolbarba.net/PAD@9 c2ee353e-ed0d-4329-bf56-03aec153487f
Showing
10 changed files
with
225 additions
and
131 deletions
readline/bin/pad/prac1/Command.class
0 → 100644
No preview for this file type
readline/bin/pad/prac1/Console.class
0 → 100644
No preview for this file type
readline/bin/pad/prac1/EditableBufferedReader.class
No preview for this file type
readline/bin/pad/prac1/Line.class
No preview for this file type
readline/bin/pad/prac1/MainClass.class
No preview for this file type
readline/src/pad/prac1/Command.java
0 → 100644
1 | +package pad.prac1; | ||
2 | + | ||
3 | +public class Command | ||
4 | +{ | ||
5 | + /* | ||
6 | + * COMMAND DEFINITIONS | ||
7 | + */ | ||
8 | + | ||
9 | + public static final int INSERT_CHAR = 0; | ||
10 | + public static final int DELETE_CHAR = 1; | ||
11 | + public static final int MOVE_CURSOR = 2; | ||
12 | + | ||
13 | + private int type; | ||
14 | + private int value; | ||
15 | + | ||
16 | + public Command(int t, int v) | ||
17 | + { | ||
18 | + type = t; | ||
19 | + value = v; | ||
20 | + } | ||
21 | + | ||
22 | + public Command(int t) | ||
23 | + { | ||
24 | + type = t; | ||
25 | + } | ||
26 | + | ||
27 | + public int getType() | ||
28 | + { | ||
29 | + return type; | ||
30 | + } | ||
31 | + | ||
32 | + public int getValue() | ||
33 | + { | ||
34 | + return value; | ||
35 | + } | ||
36 | + | ||
37 | +} |
readline/src/pad/prac1/Console.java
0 → 100644
1 | +package pad.prac1; | ||
2 | + | ||
3 | +import java.util.Observable; | ||
4 | +import java.util.Observer; | ||
5 | + | ||
6 | +public class Console implements Observer | ||
7 | +{ | ||
8 | + public void moveCursorTo(int pos, int currentPos, int length) | ||
9 | + { | ||
10 | + if(pos > currentPos) | ||
11 | + { | ||
12 | + System.out.print((char)EditableBufferedReader.ESC); | ||
13 | + System.out.print((char)EditableBufferedReader.ESC_SEQ); | ||
14 | + System.out.print(pos - currentPos); | ||
15 | + System.out.print((char)EditableBufferedReader.FORWARD); | ||
16 | + } | ||
17 | + else if(pos < currentPos) | ||
18 | + { | ||
19 | + System.out.print((char)EditableBufferedReader.ESC); | ||
20 | + System.out.print((char)EditableBufferedReader.ESC_SEQ); | ||
21 | + System.out.print(currentPos-pos); | ||
22 | + System.out.print((char)EditableBufferedReader.BACKWARD); | ||
23 | + } | ||
24 | + } | ||
25 | + | ||
26 | + private void insertSpace() | ||
27 | + { | ||
28 | + System.out.print((char)EditableBufferedReader.ESC); | ||
29 | + System.out.print((char)EditableBufferedReader.ESC_SEQ); | ||
30 | + System.out.print((char)EditableBufferedReader.INS_SPACE); | ||
31 | + } | ||
32 | + | ||
33 | + private void delChar() | ||
34 | + { | ||
35 | + System.out.print((char)EditableBufferedReader.ESC); | ||
36 | + System.out.print((char)EditableBufferedReader.ESC_SEQ); | ||
37 | + System.out.print((char)EditableBufferedReader.DEL_CHAR); | ||
38 | + } | ||
39 | + | ||
40 | + public void addChar(char c, Line line) | ||
41 | + { | ||
42 | + if(line.getCursorPosition() != line.length()+1) | ||
43 | + { | ||
44 | + insertSpace(); | ||
45 | + } | ||
46 | + System.out.print(c); | ||
47 | + } | ||
48 | + | ||
49 | + public void update(Observable obs, Object arg) | ||
50 | + { | ||
51 | + Line line = (Line)obs; | ||
52 | + Command cmd = (Command)arg; | ||
53 | + switch(cmd.getType()) | ||
54 | + { | ||
55 | + case Command.INSERT_CHAR: | ||
56 | + addChar((char)cmd.getValue(),line); | ||
57 | + break; | ||
58 | + | ||
59 | + case Command.DELETE_CHAR: | ||
60 | + delChar(); | ||
61 | + break; | ||
62 | + | ||
63 | + case Command.MOVE_CURSOR: | ||
64 | + moveCursorTo(cmd.getValue(),line.getCursorPosition(),line.length()); | ||
65 | + break; | ||
66 | + } | ||
67 | + } | ||
68 | +} |
readline/src/pad/prac1/EditableBufferedReader.java
@@ -22,6 +22,7 @@ public class EditableBufferedReader extends BufferedReader | @@ -22,6 +22,7 @@ public class EditableBufferedReader extends BufferedReader | ||
22 | public static final int NON_PRINTABLE = 2; | 22 | public static final int NON_PRINTABLE = 2; |
23 | 23 | ||
24 | /* KEY DEFINITIONS | 24 | /* KEY DEFINITIONS |
25 | + * | ||
25 | * ESC (0x1B) starts an escape sequence | 26 | * ESC (0x1B) starts an escape sequence |
26 | * ESC+[+C (0x1B 0x5B 0x43) Cursor Forward | 27 | * ESC+[+C (0x1B 0x5B 0x43) Cursor Forward |
27 | * ESC+[+D (0x1B 0x5B 0x44) Cursor Backward | 28 | * ESC+[+D (0x1B 0x5B 0x44) Cursor Backward |
@@ -46,10 +47,12 @@ public class EditableBufferedReader extends BufferedReader | @@ -46,10 +47,12 @@ public class EditableBufferedReader extends BufferedReader | ||
46 | public static final int INSERT_KEY = 0x32; | 47 | public static final int INSERT_KEY = 0x32; |
47 | public static final int INS_SPACE = 0x40; | 48 | public static final int INS_SPACE = 0x40; |
48 | public static final int DEL_CHAR = 0x50; | 49 | public static final int DEL_CHAR = 0x50; |
49 | - public static final int NUM_0 = 0x30; | 50 | + public static final int EOF = 0x04; |
51 | + public static final int LINE_FEED = 0x0A; | ||
50 | 52 | ||
51 | - private Line line = new Line(); | ||
52 | - private boolean returnKey = false; | 53 | + private Console console = new Console(); |
54 | + private Line line = new Line(console); | ||
55 | + private boolean endOfFile = false; | ||
53 | 56 | ||
54 | public EditableBufferedReader(Reader in) | 57 | public EditableBufferedReader(Reader in) |
55 | { | 58 | { |
@@ -81,7 +84,7 @@ public class EditableBufferedReader extends BufferedReader | @@ -81,7 +84,7 @@ public class EditableBufferedReader extends BufferedReader | ||
81 | { | 84 | { |
82 | return ESCAPE_SEQUENCE; | 85 | return ESCAPE_SEQUENCE; |
83 | } | 86 | } |
84 | - else if((key == BACKSPACE) || (key == RETURN_KEY)) | 87 | + else if((key == BACKSPACE) || (key == RETURN_KEY) || (key == EOF)) |
85 | { | 88 | { |
86 | return PRINTABLE; | 89 | return PRINTABLE; |
87 | } | 90 | } |
@@ -90,92 +93,6 @@ public class EditableBufferedReader extends BufferedReader | @@ -90,92 +93,6 @@ public class EditableBufferedReader extends BufferedReader | ||
90 | return PRINTABLE; | 93 | return PRINTABLE; |
91 | } | 94 | } |
92 | 95 | ||
93 | - public void addChar(char c) | ||
94 | - { | ||
95 | - switch(line.getMode()) | ||
96 | - { | ||
97 | - case INSERT: | ||
98 | - if(line.getCursorPosition() != line.length()+1) | ||
99 | - { | ||
100 | - insertSpace(); | ||
101 | - } | ||
102 | - System.out.print(c); | ||
103 | - line.insertCharAt(c, line.getCursorPosition()-1); | ||
104 | - line.setCursorPosition(line.getCursorPosition()+1); | ||
105 | - break; | ||
106 | - | ||
107 | - case OVERWRITE: | ||
108 | - if(line.getCursorPosition() != line.length()+1) | ||
109 | - { | ||
110 | - line.removeCharAt(line.getCursorPosition()-1); | ||
111 | - } | ||
112 | - System.out.print(c); | ||
113 | - line.insertCharAt(c, line.getCursorPosition()-1); | ||
114 | - line.setCursorPosition(line.getCursorPosition()+1); | ||
115 | - break; | ||
116 | - } | ||
117 | - } | ||
118 | - | ||
119 | - public void delChar(int mode) | ||
120 | - { | ||
121 | - switch(mode) | ||
122 | - { | ||
123 | - case DEL_BACKWARD: | ||
124 | - if(line.getCursorPosition() != 1) | ||
125 | - { | ||
126 | - System.out.print((char)BACKSPACE); | ||
127 | - deleteCharacter(); | ||
128 | - line.removeCharAt(line.getCursorPosition()-2); | ||
129 | - line.setCursorPosition(line.getCursorPosition()-1); | ||
130 | - } | ||
131 | - break; | ||
132 | - case DEL_FORWARD: | ||
133 | - if(line.getCursorPosition() != (line.length()+1)) | ||
134 | - { | ||
135 | - line.removeCharAt(line.getCursorPosition()-1); | ||
136 | - deleteCharacter(); | ||
137 | - } | ||
138 | - break; | ||
139 | - } | ||
140 | - } | ||
141 | - | ||
142 | - private void insertSpace() | ||
143 | - { | ||
144 | - System.out.print((char)ESC); | ||
145 | - System.out.print((char)ESC_SEQ); | ||
146 | - System.out.print((char)INS_SPACE); | ||
147 | - } | ||
148 | - | ||
149 | - private void deleteCharacter() | ||
150 | - { | ||
151 | - System.out.print((char)ESC); | ||
152 | - System.out.print((char)ESC_SEQ); | ||
153 | - System.out.print((char)DEL_CHAR); | ||
154 | - } | ||
155 | - | ||
156 | - public void moveCursorTo(int pos) | ||
157 | - { | ||
158 | - if((pos <= line.length()+1) && (pos >= 1)) | ||
159 | - { | ||
160 | - if(pos > line.getCursorPosition()) | ||
161 | - { | ||
162 | - System.out.print((char)ESC); | ||
163 | - System.out.print((char)ESC_SEQ); | ||
164 | - System.out.print(Integer.toString(pos-line.getCursorPosition())); | ||
165 | - System.out.print((char)FORWARD); | ||
166 | - } | ||
167 | - | ||
168 | - else if(pos < line.getCursorPosition()) | ||
169 | - { | ||
170 | - System.out.print((char)ESC); | ||
171 | - System.out.print((char)ESC_SEQ); | ||
172 | - System.out.print(Integer.toString(line.getCursorPosition()-pos)); | ||
173 | - System.out.print((char)BACKWARD); | ||
174 | - } | ||
175 | - line.setCursorPosition(pos); | ||
176 | - } | ||
177 | - } | ||
178 | - | ||
179 | public int read() throws IOException | 96 | public int read() throws IOException |
180 | { | 97 | { |
181 | return super.read(); | 98 | return super.read(); |
@@ -192,12 +109,12 @@ public class EditableBufferedReader extends BufferedReader | @@ -192,12 +109,12 @@ public class EditableBufferedReader extends BufferedReader | ||
192 | System.out.println("Couldn't set terminal in raw mode"); | 109 | System.out.println("Couldn't set terminal in raw mode"); |
193 | return ""; | 110 | return ""; |
194 | } | 111 | } |
195 | - while(!returnKey) | 112 | + while(!endOfFile) |
196 | { | 113 | { |
197 | try | 114 | try |
198 | { | 115 | { |
199 | int character = read(); | 116 | int character = read(); |
200 | - //System.err.print(Integer.toHexString(character) + " \n"); | 117 | + //System.err.print((String)(Integer.toHexString(character) + " ").toUpperCase()); |
201 | switch(parseKey(character)) | 118 | switch(parseKey(character)) |
202 | { | 119 | { |
203 | case ESCAPE_SEQUENCE: | 120 | case ESCAPE_SEQUENCE: |
@@ -207,17 +124,17 @@ public class EditableBufferedReader extends BufferedReader | @@ -207,17 +124,17 @@ public class EditableBufferedReader extends BufferedReader | ||
207 | switch(read()) | 124 | switch(read()) |
208 | { | 125 | { |
209 | case FORWARD: | 126 | case FORWARD: |
210 | - moveCursorTo(line.getCursorPosition()+1); | 127 | + line.setCursorTo(line.getCursorPosition()+1); |
211 | break; | 128 | break; |
212 | 129 | ||
213 | case BACKWARD: | 130 | case BACKWARD: |
214 | - moveCursorTo(line.getCursorPosition()-1); | 131 | + line.setCursorTo(line.getCursorPosition()-1); |
215 | break; | 132 | break; |
216 | 133 | ||
217 | case DEL: | 134 | case DEL: |
218 | if(read() == TILDE) | 135 | if(read() == TILDE) |
219 | { | 136 | { |
220 | - delChar(DEL_FORWARD); | 137 | + line.delChar(DEL_FORWARD); |
221 | } | 138 | } |
222 | break; | 139 | break; |
223 | 140 | ||
@@ -234,11 +151,11 @@ public class EditableBufferedReader extends BufferedReader | @@ -234,11 +151,11 @@ public class EditableBufferedReader extends BufferedReader | ||
234 | switch(read()) | 151 | switch(read()) |
235 | { | 152 | { |
236 | case HOME: | 153 | case HOME: |
237 | - moveCursorTo(1); | 154 | + line.setCursorTo(1); |
238 | break; | 155 | break; |
239 | 156 | ||
240 | case END: | 157 | case END: |
241 | - moveCursorTo(line.length()+1); | 158 | + line.setCursorTo(line.length()+1); |
242 | break; | 159 | break; |
243 | } | 160 | } |
244 | break; | 161 | break; |
@@ -248,17 +165,19 @@ public class EditableBufferedReader extends BufferedReader | @@ -248,17 +165,19 @@ public class EditableBufferedReader extends BufferedReader | ||
248 | case PRINTABLE: | 165 | case PRINTABLE: |
249 | switch(character) | 166 | switch(character) |
250 | { | 167 | { |
251 | - case RETURN_KEY: | ||
252 | - returnKey = true; | 168 | + case EOF: |
169 | + endOfFile = true; | ||
253 | break; | 170 | break; |
254 | 171 | ||
255 | case BACKSPACE: | 172 | case BACKSPACE: |
256 | case BACKSPACE_DEL: | 173 | case BACKSPACE_DEL: |
257 | - delChar(DEL_BACKWARD); | 174 | + line.delChar(DEL_BACKWARD); |
258 | break; | 175 | break; |
259 | - | 176 | + |
177 | + case RETURN_KEY: | ||
178 | + character = LINE_FEED; | ||
260 | default: | 179 | default: |
261 | - addChar((char)character); | 180 | + line.addChar((char)character); |
262 | break; | 181 | break; |
263 | } | 182 | } |
264 | break; | 183 | break; |
@@ -287,3 +206,15 @@ public class EditableBufferedReader extends BufferedReader | @@ -287,3 +206,15 @@ public class EditableBufferedReader extends BufferedReader | ||
287 | return line.toString(); | 206 | return line.toString(); |
288 | } | 207 | } |
289 | } | 208 | } |
209 | + | ||
210 | + | ||
211 | +/* TO-DO | ||
212 | + * | ||
213 | + * up/down keys (needs text to work) | ||
214 | + * pgup pgdown keys (goesto penultima linea visible) | ||
215 | + * read terminal size | ||
216 | + * update size dynamically | ||
217 | + * long strings wrap down | ||
218 | + * cursor keys skip final \n on a line | ||
219 | + * careful if overwrite mode and final character is \n | ||
220 | + */ |
readline/src/pad/prac1/Line.java
1 | package pad.prac1; | 1 | package pad.prac1; |
2 | 2 | ||
3 | -public class Line | 3 | +import java.util.Observable; |
4 | + | ||
5 | +public class Line extends Observable | ||
4 | { | 6 | { |
5 | - /* | ||
6 | - * MODE DEFINITIONS | ||
7 | - */ | ||
8 | - | ||
9 | - public static final int INSERT = 0; | ||
10 | - public static final int OVERWRITE = 1; | ||
11 | - | ||
12 | private String line; | 7 | private String line; |
13 | private int cursorPosition; | 8 | private int cursorPosition; |
14 | private int writeMode; | 9 | private int writeMode; |
10 | + private Console console; | ||
15 | 11 | ||
16 | - public Line() | 12 | + public Line(Console cons) |
17 | { | 13 | { |
14 | + console = cons; | ||
18 | line = ""; | 15 | line = ""; |
19 | - writeMode = INSERT; | 16 | + writeMode = EditableBufferedReader.INSERT; |
20 | cursorPosition = 1; | 17 | cursorPosition = 1; |
18 | + addObserver(console); | ||
21 | } | 19 | } |
22 | 20 | ||
23 | public int length() | 21 | public int length() |
@@ -30,22 +28,44 @@ public class Line | @@ -30,22 +28,44 @@ public class Line | ||
30 | return cursorPosition; | 28 | return cursorPosition; |
31 | } | 29 | } |
32 | 30 | ||
33 | - public void setCursorPosition(int pos) | 31 | + public void toggleMode() |
34 | { | 32 | { |
35 | - cursorPosition = pos; | 33 | + writeMode = 1 - writeMode; |
36 | } | 34 | } |
37 | 35 | ||
38 | - public int getMode() | 36 | + private void sendCommand(int type, int value) |
39 | { | 37 | { |
40 | - return writeMode; | 38 | + setChanged(); |
39 | + notifyObservers(new Command(type,value)); | ||
41 | } | 40 | } |
42 | 41 | ||
43 | - public void toggleMode() | 42 | + private void sendCommand(int type) |
44 | { | 43 | { |
45 | - writeMode = 1 - writeMode; | 44 | + setChanged(); |
45 | + notifyObservers(new Command(type)); | ||
46 | + } | ||
47 | + | ||
48 | + private void insertCharAt(char c, int pos) | ||
49 | + { | ||
50 | + if(pos == 0) | ||
51 | + { | ||
52 | + String s = ""; | ||
53 | + s += c; | ||
54 | + line = s + line; | ||
55 | + } | ||
56 | + else if(pos == line.length()) | ||
57 | + { | ||
58 | + line += c; | ||
59 | + } | ||
60 | + else | ||
61 | + { | ||
62 | + String s = ""; | ||
63 | + s += c; | ||
64 | + line = line.substring(0, pos).concat(s).concat(line.substring(pos,line.length())); | ||
65 | + } | ||
46 | } | 66 | } |
47 | 67 | ||
48 | - public void removeCharAt(int pos) | 68 | + private void removeCharAt(int pos) |
49 | { | 69 | { |
50 | if(pos >= 0) | 70 | if(pos >= 0) |
51 | { | 71 | { |
@@ -64,23 +84,61 @@ public class Line | @@ -64,23 +84,61 @@ public class Line | ||
64 | } | 84 | } |
65 | } | 85 | } |
66 | 86 | ||
67 | - public void insertCharAt(char c, int pos) | 87 | + public void addChar(char c) |
68 | { | 88 | { |
69 | - if(pos == 0) | 89 | + if(c == EditableBufferedReader.LINE_FEED) |
70 | { | 90 | { |
71 | - String s = ""; | ||
72 | - s += c; | ||
73 | - line = s + line; | 91 | + sendCommand(Command.INSERT_CHAR,EditableBufferedReader.RETURN_KEY); |
74 | } | 92 | } |
75 | - else if(pos == line.length()) | 93 | + switch(writeMode) |
76 | { | 94 | { |
77 | - line += c; | 95 | + case EditableBufferedReader.INSERT: |
96 | + sendCommand(Command.INSERT_CHAR,(int)c); | ||
97 | + insertCharAt(c, cursorPosition-1); | ||
98 | + cursorPosition++; | ||
99 | + break; | ||
100 | + | ||
101 | + case EditableBufferedReader.OVERWRITE: | ||
102 | + if(cursorPosition != line.length()+1) | ||
103 | + { | ||
104 | + removeCharAt(cursorPosition-1); | ||
105 | + } | ||
106 | + sendCommand(Command.INSERT_CHAR,(int)c); | ||
107 | + insertCharAt(c, cursorPosition-1); | ||
108 | + cursorPosition++; | ||
109 | + break; | ||
78 | } | 110 | } |
79 | - else | 111 | + } |
112 | + | ||
113 | + public void delChar(int mode) | ||
114 | + { | ||
115 | + switch(mode) | ||
80 | { | 116 | { |
81 | - String s = ""; | ||
82 | - s += c; | ||
83 | - line = line.substring(0, pos).concat(s).concat(line.substring(pos,line.length())); | 117 | + case EditableBufferedReader.DEL_BACKWARD: |
118 | + if(cursorPosition != 1) | ||
119 | + { | ||
120 | + sendCommand(Command.MOVE_CURSOR,cursorPosition-1); | ||
121 | + sendCommand(Command.DELETE_CHAR); | ||
122 | + removeCharAt(cursorPosition-2); | ||
123 | + cursorPosition--; | ||
124 | + } | ||
125 | + break; | ||
126 | + case EditableBufferedReader.DEL_FORWARD: | ||
127 | + if(cursorPosition != (line.length()+1)) | ||
128 | + { | ||
129 | + removeCharAt(cursorPosition-1); | ||
130 | + sendCommand(Command.DELETE_CHAR,1); | ||
131 | + } | ||
132 | + break; | ||
133 | + } | ||
134 | + } | ||
135 | + | ||
136 | + public void setCursorTo(int pos) | ||
137 | + { | ||
138 | + if((pos <= line.length()+1) && (pos >= 1) && (pos != cursorPosition)) | ||
139 | + { | ||
140 | + sendCommand(Command.MOVE_CURSOR,pos); | ||
141 | + cursorPosition = pos; | ||
84 | } | 142 | } |
85 | } | 143 | } |
86 | 144 |
readline/src/pad/prac1/MainClass.java
@@ -9,7 +9,7 @@ public class MainClass | @@ -9,7 +9,7 @@ public class MainClass | ||
9 | { | 9 | { |
10 | InputStreamReader input = new InputStreamReader(System.in); | 10 | InputStreamReader input = new InputStreamReader(System.in); |
11 | EditableBufferedReader editable = new EditableBufferedReader(input); | 11 | EditableBufferedReader editable = new EditableBufferedReader(input); |
12 | - System.out.println("Line read: " + editable.readLine()); | 12 | + System.out.println("\nLine read: \n" + editable.readLine()); |
13 | editable.close(); | 13 | editable.close(); |
14 | } | 14 | } |
15 | 15 |