Changeset 150


Ignore:
Timestamp:
10/15/02 16:27:31 (21 years ago)
Author:
piso
Message:

Shell extends CommandInterpreter?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/j/src/org/armedbear/j/Shell.java

    r146 r150  
    33 *
    44 * Copyright (C) 1998-2002 Peter Graves
    5  * $Id: Shell.java,v 1.11 2002-10-15 01:23:03 piso Exp $
     5 * $Id: Shell.java,v 1.12 2002-10-15 16:27:31 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    2222package org.armedbear.j;
    2323
    24 import gnu.regexp.RE;
    25 import gnu.regexp.REException;
    2624import gnu.regexp.REMatch;
    27 import gnu.regexp.UncheckedRE;
    2825import java.io.IOException;
    29 import java.io.InputStream;
    3026import java.io.OutputStreamWriter;
    3127import java.util.List;
    3228import java.util.StringTokenizer;
    33 import javax.swing.Icon;
    3429import javax.swing.SwingUtilities;
    3530import javax.swing.undo.CompoundEdit;
    3631
    37 public class Shell extends Buffer implements Constants
     32public class Shell extends CommandInterpreter implements Constants
    3833{
    3934    protected static final String JPTY_NOT_FOUND =
    4035        "Unable to start shell process (jpty not found in PATH)";
    4136
    42     private RE promptRE = new UncheckedRE(DEFAULT_SHELL_PROMPT_PATTERN);
    43 
    4437    protected String shellCommand;
    45 
    46     protected OutputStreamWriter stdin;
    47 
    4838    private Process process;
    49 
    50     protected ReaderThread stdoutThread;
    51     protected ReaderThread stderrThread;
    52 
    53     protected String input;
    54 
    5539    private String command; // First token on command line.
    56 
    57     protected Position posEndOfBuffer;
    58     protected Position posEndOfOutput;
    59 
    6040    private boolean promptIsStderr = true;
    61 
    62     protected boolean stripEcho = false;
    63 
    6441    private File oldDir;
    6542    private File currentDir;
    6643    private File initialDir;
    67 
    68     protected History history;
    6944
    7045    protected Shell()
     
    11691    }
    11792
    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.
    13693    protected void initializeHistory()
    13794    {
     
    255212    }
    256213
    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);
    448217        // If it's a local shell (i.e. not telnet or ssh), keep track of the
    449218        // current directory.
     
    469238                changeDirectory(arg);
    470239        }
    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()
    484243    {
    485244        Process p = getProcess();
     
    519278                        appendString("\nProcess exited\n");
    520279                        updateDisplayInAllFrames();
    521                         posEndOfOutput = new Position(posEndOfBuffer);
    522280                    }
    523281                };
     
    528286        };
    529287        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;
    545288    }
    546289
     
    605348    }
    606349
    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 
    627350    private void updateDirectory(String output)
    628351    {
     
    702425    }
    703426
    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 
    718427    // For the buffer list.
    719428    public String toString()
    720429    {
    721430        return shellCommand;
    722     }
    723 
    724     public Icon getIcon()
    725     {
    726         return Utilities.getIconFromFile("jpty.png");
    727431    }
    728432
     
    741445    {
    742446        return currentDir;
    743     }
    744 
    745     public boolean isModified()
    746     {
    747         return false;
    748447    }
    749448
     
    766465            s = sb.toString();
    767466        }
    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);
    805468    }
    806469
     
    813476                    updateDirectory(s);
    814477                    appendString(s);
    815                     posEndOfOutput = new Position(posEndOfBuffer);
    816478                }
    817479                updateLineFlags();
     
    824486    }
    825487
    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)
    844489    {
    845490        if (promptIsStderr) {
     
    860505            {
    861506                appendString(s);
    862                 posEndOfOutput = new Position(posEndOfBuffer);
    863507                updateLineFlags();
    864508                updateDisplayInAllFrames();
     
    953597    }
    954598
    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 
    997599    public static void shellTab()
    998600    {
     
    1008610            ((Shell)buffer).sendChar(3);
    1009611    }
    1010 
    1011     protected class StdoutThread extends ReaderThread
    1012     {
    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 ReaderThread
    1031     {
    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     }
    1048612}
Note: See TracChangeset for help on using the changeset viewer.