Changeset 150
- Timestamp:
- 10/15/02 16:27:31 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/j/src/org/armedbear/j/Shell.java
r146 r150 3 3 * 4 4 * Copyright (C) 1998-2002 Peter Graves 5 * $Id: Shell.java,v 1.1 1 2002-10-15 01:23:03piso Exp $5 * $Id: Shell.java,v 1.12 2002-10-15 16:27:31 piso Exp $ 6 6 * 7 7 * This program is free software; you can redistribute it and/or … … 22 22 package org.armedbear.j; 23 23 24 import gnu.regexp.RE;25 import gnu.regexp.REException;26 24 import gnu.regexp.REMatch; 27 import gnu.regexp.UncheckedRE;28 25 import java.io.IOException; 29 import java.io.InputStream;30 26 import java.io.OutputStreamWriter; 31 27 import java.util.List; 32 28 import java.util.StringTokenizer; 33 import javax.swing.Icon;34 29 import javax.swing.SwingUtilities; 35 30 import javax.swing.undo.CompoundEdit; 36 31 37 public class Shell extends Buffer implements Constants32 public class Shell extends CommandInterpreter implements Constants 38 33 { 39 34 protected static final String JPTY_NOT_FOUND = 40 35 "Unable to start shell process (jpty not found in PATH)"; 41 36 42 private RE promptRE = new UncheckedRE(DEFAULT_SHELL_PROMPT_PATTERN);43 44 37 protected String shellCommand; 45 46 protected OutputStreamWriter stdin;47 48 38 private Process process; 49 50 protected ReaderThread stdoutThread;51 protected ReaderThread stderrThread;52 53 protected String input;54 55 39 private String command; // First token on command line. 56 57 protected Position posEndOfBuffer;58 protected Position posEndOfOutput;59 60 40 private boolean promptIsStderr = true; 61 62 protected boolean stripEcho = false;63 64 41 private File oldDir; 65 42 private File currentDir; 66 43 private File initialDir; 67 68 protected History history;69 44 70 45 protected Shell() … … 116 91 } 117 92 118 public final RE getPromptRE()119 {120 return promptRE;121 }122 123 public final void setPromptRE(String pattern)124 {125 Debug.assertTrue(promptRE != null);126 try {127 promptRE = new RE(pattern);128 }129 catch (REException e) {130 Log.error(e);131 }132 Debug.assertTrue(promptRE != null);133 }134 135 // Derived classes override this method.136 93 protected void initializeHistory() 137 94 { … … 255 212 } 256 213 257 private void home() 258 { 259 final Editor editor = Editor.currentEditor(); 260 if (editor.getDotOffset() == 0) 261 return; 262 editor.addUndo(SimpleEdit.MOVE); 263 editor.beginningOfBlock(); 264 int offset = 0; 265 if (promptRE != null) { 266 Line dotLine = editor.getDotLine(); 267 if (dotLine.next() == null || dotLine.flags() == STATE_INPUT) { 268 REMatch match = promptRE.getMatch(dotLine.getText()); 269 if (match != null) 270 offset = match.getEndIndex(); 271 } 272 } 273 // If we're already at the prompt or to the left of it, go to column 0. 274 if (editor.getDotOffset() <= offset) 275 offset = 0; 276 editor.getDot().setOffset(offset); 277 editor.getDisplay().moveCaretToDotCol(); 278 } 279 280 private void backspace() 281 { 282 boolean ok = true; 283 final Editor editor = Editor.currentEditor(); 284 if (editor.getDotLine() == posEndOfOutput.getLine()) { 285 if (editor.getDotOffset() <= posEndOfOutput.getOffset()) 286 ok = false; 287 } else{ 288 String text = editor.getDotLine().getText(); 289 if (promptRE != null) { 290 REMatch match = promptRE.getMatch(text); 291 if (match != null) { 292 if (editor.getDotOffset() <= match.getEndIndex()) 293 ok = false; 294 } 295 } 296 } 297 if (ok) 298 editor.backspace(); 299 } 300 301 private void getInputFromHistory(int direction) 302 { 303 final Editor editor = Editor.currentEditor(); 304 final Line dotLine = editor.getDotLine(); 305 if (dotLine.next() != null) { 306 editor.status("Not at command line"); 307 return; 308 } 309 if (editor.getLastCommand() != COMMAND_HISTORY) 310 history.reset(); 311 String currentInput = dotLine.getText(); 312 REMatch prompt = promptRE.getMatch(currentInput); 313 // Actual input does not include prompt. 314 if (prompt != null) 315 currentInput = currentInput.substring(prompt.getEndIndex()); 316 String s; 317 while (true) { 318 s = direction < 0 ? history.getPrevious() : history.getNext(); 319 if (s == null) 320 break; 321 if (!s.equals(currentInput)) 322 break; 323 } 324 if (s != null) { 325 CompoundEdit compoundEdit = beginCompoundEdit(); 326 editor.addUndo(SimpleEdit.LINE_EDIT); 327 328 // Keep the prompt, if any, but replace whatever is after it. 329 if (prompt != null) 330 dotLine.setText(prompt.toString() + s); 331 else 332 dotLine.setText(s); 333 334 editor.updateDotLine(); 335 editor.addUndo(SimpleEdit.MOVE); 336 editor.getDot().setOffset(dotLine.length()); 337 editor.moveCaretToDotCol(); 338 endCompoundEdit(compoundEdit); 339 } 340 editor.setCurrentCommand(COMMAND_HISTORY); 341 } 342 343 private void previousInput() 344 { 345 getInputFromHistory(-1); 346 } 347 348 private void nextInput() 349 { 350 getInputFromHistory(1); 351 } 352 353 private void escape() 354 { 355 Editor editor = Editor.currentEditor(); 356 if (editor.getMark() != null || editor.getDotLine().next() != null) { 357 // There's a marked block, or we're not at the command line. 358 editor.escape(); 359 return; 360 } 361 362 // Check for transient buffer in other editor in current frame. 363 Editor ed = editor.getOtherEditor(); 364 if (ed != null && ed.getBuffer().isTransient()) { 365 editor.unsplitWindow(); 366 editor.maybeKillBuffer(ed.getBuffer()); 367 return; 368 } 369 370 String text = editor.getDotLine().getText(); 371 REMatch match = promptRE.getMatch(text); 372 if (match == null) 373 return; 374 String prompt = match.toString(); 375 if (text.equals(prompt) && editor.getDotOffset() == prompt.length()) 376 return; // Nothing to do. 377 378 CompoundEdit compoundEdit = beginCompoundEdit(); 379 if (!text.equals(prompt)) { 380 editor.addUndo(SimpleEdit.LINE_EDIT); 381 editor.getDotLine().setText(prompt); 382 Editor.updateInAllEditors(editor.getDotLine()); 383 } 384 if (editor.getDotOffset() != prompt.length()) { 385 editor.addUndo(SimpleEdit.MOVE); 386 editor.getDot().setOffset(prompt.length()); 387 editor.moveCaretToDotCol(); 388 } 389 endCompoundEdit(compoundEdit); 390 } 391 392 private void enter() 393 { 394 if (!checkProcess()) 395 return; 396 final Editor editor = Editor.currentEditor(); 397 final Line dotLine = editor.getDotLine(); 398 if (posEndOfOutput == null) { 399 // Ignore input before first prompt is displayed. 400 dotLine.setText(""); 401 return; 402 } 403 if (posEndOfOutput.getLine() == dotLine) { 404 if (posEndOfOutput.getOffset() < dotLine.length()) 405 input = dotLine.getText().substring(posEndOfOutput.getOffset()); 406 else 407 input = ""; 408 } else { 409 // We're not at the end of the buffer. 410 input = stripPrompt(dotLine.getText()); 411 } 412 enter(input); 413 } 414 415 private void enter(final String s) 416 { 417 if (s.length() != 0) { 418 history.append(s); 419 history.save(); 420 } 421 final Editor editor = Editor.currentEditor(); 422 Line dotLine = editor.getDotLine(); 423 if (dotLine.next() != null) { 424 // Go to end of buffer (if we're not already there) to append input. 425 editor.eob(); 426 dotLine = editor.getDotLine(); 427 428 // Keep the prompt, but throw away anything after it. 429 final REMatch match = promptRE.getMatch(dotLine.getText()); 430 if (match != null) 431 dotLine.setText(dotLine.substring(0, match.getEndIndex())); 432 433 // Append s. 434 dotLine.setText(dotLine.getText() + s); 435 } 436 if (dotLine.flags() == 0) 437 dotLine.setFlags(STATE_INPUT); 438 editor.eol(); 439 editor.insertLineSeparator(); 440 editor.getDotLine().setFlags(0); 441 if (needsRenumbering) 442 renumber(); 443 editor.moveCaretToDotCol(); 444 editor.getDisplay().setReframe(-2); 445 posEndOfBuffer = editor.getDotCopy(); 446 resetUndo(); 447 214 protected void enter(final String s) 215 { 216 super.enter(s); 448 217 // If it's a local shell (i.e. not telnet or ssh), keep track of the 449 218 // current directory. … … 469 238 changeDirectory(arg); 470 239 } 471 472 stripEcho = true; 473 474 try { 475 stdin.write(s.concat("\n")); 476 stdin.flush(); 477 } 478 catch (IOException e) { 479 Log.error(e); 480 } 481 } 482 483 private boolean checkProcess() 240 } 241 242 protected boolean checkProcess() 484 243 { 485 244 Process p = getProcess(); … … 519 278 appendString("\nProcess exited\n"); 520 279 updateDisplayInAllFrames(); 521 posEndOfOutput = new Position(posEndOfBuffer);522 280 } 523 281 }; … … 528 286 }; 529 287 new Thread(r).start(); 530 }531 532 private String stripPrompt(String s)533 {534 if (promptRE != null) {535 REMatch match = promptRE.getMatch(s);536 if (match != null)537 return s.substring(match.getEndIndex());538 }539 // Look for login name or password prompt.540 RE re = new UncheckedRE(".*: ?");541 REMatch match = re.getMatch(s);542 if (match != null)543 return s.substring(match.getEndIndex());544 return s;545 288 } 546 289 … … 605 348 } 606 349 607 public int load()608 {609 try {610 lockWrite();611 }612 catch (InterruptedException e) {613 Log.debug(e);614 return LOAD_FAILED; // Shouldn't happen.615 }616 try {617 appendLine("");618 setLoaded(true);619 posEndOfBuffer = new Position(getFirstLine(), 0);620 }621 finally {622 unlockWrite();623 }624 return LOAD_COMPLETED;625 }626 627 350 private void updateDirectory(String output) 628 351 { … … 702 425 } 703 426 704 private void sendChar(int c)705 {706 final Editor editor = Editor.currentEditor();707 if (editor.getDotLine().next() == null)708 editor.getDotLine().setFlags(STATE_INPUT);709 try {710 stdin.write(c);711 stdin.flush();712 }713 catch (IOException e) {714 Log.error(e);715 }716 }717 718 427 // For the buffer list. 719 428 public String toString() 720 429 { 721 430 return shellCommand; 722 }723 724 public Icon getIcon()725 {726 return Utilities.getIconFromFile("jpty.png");727 431 } 728 432 … … 741 445 { 742 446 return currentDir; 743 }744 745 public boolean isModified()746 {747 return false;748 447 } 749 448 … … 766 465 s = sb.toString(); 767 466 } 768 try { 769 lockWrite(); 770 } 771 catch (InterruptedException e) { 772 Log.error(e); 773 return; 774 } 775 try { 776 Position pos = posEndOfBuffer; 777 insertString(pos, s); 778 if (needsRenumbering) 779 renumber(); 780 if (pos != posEndOfBuffer) 781 posEndOfBuffer.moveTo(pos); 782 enforceOutputLimit(Property.SHELL_OUTPUT_LIMIT); 783 } 784 finally { 785 unlockWrite(); 786 } 787 } 788 789 protected void updateDisplayInAllFrames() 790 { 791 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 792 Editor ed = it.nextEditor(); 793 if (ed.getBuffer() == this) { 794 ed.eob(); 795 ed.getDisplay().setReframe(-2); 796 ed.setUpdateFlag(REPAINT); 797 ed.updateDisplay(); 798 } 799 } 800 } 801 802 protected String stdOutFilter(String s) 803 { 804 return s; 467 super.appendString(s); 805 468 } 806 469 … … 813 476 updateDirectory(s); 814 477 appendString(s); 815 posEndOfOutput = new Position(posEndOfBuffer);816 478 } 817 479 updateLineFlags(); … … 824 486 } 825 487 826 protected String stdErrFilter(String s) 827 { 828 if (stripEcho && input != null && s.startsWith(input)) { 829 int begin = input.length(); 830 if (s.length() > begin && s.charAt(begin) == '\r') 831 ++begin; 832 if (s.length() > begin && s.charAt(begin) == '\n') 833 ++begin; 834 s = s.substring(begin); 835 836 // Strip echo only once per command line. 837 stripEcho = false; 838 } 839 840 return s; 841 } 842 843 private void stdErrUpdate(final String s) 488 protected void stdErrUpdate(final String s) 844 489 { 845 490 if (promptIsStderr) { … … 860 505 { 861 506 appendString(s); 862 posEndOfOutput = new Position(posEndOfBuffer);863 507 updateLineFlags(); 864 508 updateDisplayInAllFrames(); … … 953 597 } 954 598 955 public static void shellEscape()956 {957 final Buffer buffer = Editor.currentEditor().getBuffer();958 if (buffer instanceof Shell)959 ((Shell)buffer).escape();960 }961 962 public static void shellHome()963 {964 final Buffer buffer = Editor.currentEditor().getBuffer();965 if (buffer instanceof Shell)966 ((Shell)buffer).home();967 }968 969 public static void shellBackspace()970 {971 final Buffer buffer = Editor.currentEditor().getBuffer();972 if (buffer instanceof Shell)973 ((Shell)buffer).backspace();974 }975 976 public static void shellPreviousInput()977 {978 final Buffer buffer = Editor.currentEditor().getBuffer();979 if (buffer instanceof Shell)980 ((Shell)buffer).previousInput();981 }982 983 public static void shellNextInput()984 {985 final Buffer buffer = Editor.currentEditor().getBuffer();986 if (buffer instanceof Shell)987 ((Shell)buffer).nextInput();988 }989 990 public static void shellEnter()991 {992 final Buffer buffer = Editor.currentEditor().getBuffer();993 if (buffer instanceof Shell)994 ((Shell)buffer).enter();995 }996 997 599 public static void shellTab() 998 600 { … … 1008 610 ((Shell)buffer).sendChar(3); 1009 611 } 1010 1011 protected class StdoutThread extends ReaderThread1012 {1013 // If this constructor is private, we run into jikes 1.15 bug #2256.1014 StdoutThread(InputStream stdout)1015 {1016 super(stdout);1017 }1018 1019 public String filter(String s)1020 {1021 return stdOutFilter(s);1022 }1023 1024 public void update(String s)1025 {1026 stdOutUpdate(s);1027 }1028 }1029 1030 protected class StderrThread extends ReaderThread1031 {1032 // If this constructor is private, we run into jikes 1.15 bug #2256.1033 StderrThread(InputStream stderr)1034 {1035 super(stderr);1036 }1037 1038 public String filter(String s)1039 {1040 return stdErrFilter(s);1041 }1042 1043 public void update(String s)1044 {1045 stdErrUpdate(s);1046 }1047 }1048 612 }
Note: See TracChangeset
for help on using the changeset viewer.