/** * Output the specified character to the output stream without manipulating the current buffer. */ private final void printCharacter(final int c) throws IOException { if (c == '\t') { char cbuf[] = new char[TAB_WIDTH]; Arrays.fill(cbuf, ' '); out.write(cbuf); return; } out.write(c); }
/** * Move the cursor <i>where</i> characters, withough checking the current buffer. * * @see #where * @param where the number of characters to move to the right or left. */ private final void moveInternal(final int where) throws IOException { // debug ("move cursor " + where + " (" // + buf.cursor + " => " + (buf.cursor + where) + ")"); buf.cursor += where; char c; if (where < 0) { int len = 0; for (int i = buf.cursor; i < buf.cursor - where; i++) { if (buf.getBuffer().charAt(i) == '\t') len += TAB_WIDTH; else len++; } char cbuf[] = new char[len]; Arrays.fill(cbuf, BACKSPACE); out.write(cbuf); return; } else if (buf.cursor == 0) { return; } else if (mask != null) { c = mask.charValue(); } else { printCharacters(buf.buffer.substring(buf.cursor - where, buf.cursor).toCharArray()); return; } // null character mask: don't output anything if (NULL_MASK.equals(mask)) { return; } printCharacters(c, Math.abs(where)); }
/** * Output the specified characters to the output stream without manipulating the current buffer. */ private final void printCharacters(final char[] c) throws IOException { int len = 0; for (int i = 0; i < c.length; i++) if (c[i] == '\t') len += TAB_WIDTH; else len++; char cbuf[]; if (len == c.length) cbuf = c; else { cbuf = new char[len]; int pos = 0; for (int i = 0; i < c.length; i++) { if (c[i] == '\t') { Arrays.fill(cbuf, pos, pos + TAB_WIDTH, ' '); pos += TAB_WIDTH; } else { cbuf[pos] = c[i]; pos++; } } } out.write(cbuf); }
/** * Read a line from the <i>in</i> {@link InputStream}, and return the line (without any trailing * newlines). * * @param prompt the prompt to issue to the console, may be null. * @return a line that is read from the terminal, or null if there was null input (e.g., * <i>CTRL-D</i> was pressed). */ public String readLine(final String prompt, final Character mask) throws IOException { this.mask = mask; if (prompt != null) this.prompt = prompt; try { terminal.beforeReadLine(this, this.prompt, mask); if ((this.prompt != null) && (this.prompt.length() > 0)) { out.write(this.prompt); out.flush(); } // if the terminal is unsupported, just use plain-java reading if (!terminal.isSupported()) { return readLine(in); } while (true) { int[] next = readBinding(); if (next == null) { return null; } int c = next[0]; int code = next[1]; if (c == -1) { return null; } boolean success = true; switch (code) { case EXIT: // ctrl-d if (buf.buffer.length() == 0) { return null; } case COMPLETE: // tab success = complete(); break; case MOVE_TO_BEG: success = setCursorPosition(0); break; case KILL_LINE: // CTRL-K success = killLine(); break; case CLEAR_SCREEN: // CTRL-L success = clearScreen(); break; case KILL_LINE_PREV: // CTRL-U success = resetLine(); break; case NEWLINE: // enter moveToEnd(); printNewline(); // output newline return finishBuffer(); case DELETE_PREV_CHAR: // backspace success = backspace(); break; case DELETE_NEXT_CHAR: // delete success = deleteCurrentCharacter(); break; case MOVE_TO_END: success = moveToEnd(); break; case PREV_CHAR: success = moveCursor(-1) != 0; break; case NEXT_CHAR: success = moveCursor(1) != 0; break; case NEXT_HISTORY: success = moveHistory(true); break; case PREV_HISTORY: success = moveHistory(false); break; case REDISPLAY: break; case PASTE: success = paste(); break; case DELETE_PREV_WORD: success = deletePreviousWord(); break; case PREV_WORD: success = previousWord(); break; case NEXT_WORD: success = nextWord(); break; case START_OF_HISTORY: success = history.moveToFirstEntry(); if (success) setBuffer(history.current()); break; case END_OF_HISTORY: success = history.moveToLastEntry(); if (success) setBuffer(history.current()); break; case CLEAR_LINE: moveInternal(-(buf.buffer.length())); killLine(); break; case INSERT: buf.setOvertyping(!buf.isOvertyping()); break; case UNKNOWN: default: if (c != 0) { // ignore null chars ActionListener action = (ActionListener) triggeredActions.get(new Character((char) c)); if (action != null) action.actionPerformed(null); else putChar(c, true); } else success = false; } if (!(success)) { beep(); } flushConsole(); } } finally { terminal.afterReadLine(this, this.prompt, mask); } }
/** * Flush the console output stream. This is important for printout out single characters (like a * backspace or keyboard) that we want the console to handle immedately. */ public final void flushConsole() throws IOException { out.flush(); }