Search in sources :

Example 1 with InterpreterResponse

use of org.python.pydev.shared_interactive_console.console.InterpreterResponse in project Pydev by fabioz.

the class ScriptConsoleDocumentListener method execCommand.

/**
 * Here is where we run things not using the UI thread. It's a recursive function. In summary, it'll
 * run each line in the commands received in a new thread, and as each finishes, it calls itself again
 * for the next command. The last command will reconnect to the document.
 *
 * Exceptions had to be locally handled, because they're not well tolerated under this scenario
 * (if on of the callbacks fail, the others won't be executed and we'd get into a situation
 * where the shell becomes unusable).
 */
private void execCommand(final boolean addedNewLine, final String delim, final String[] finalIndentString, final String cmd, final List<String> commands, final int currentCommand, final String text, final char addedParen, final int start, final char addedCloseParen, final int newDeltaCaretPosition) {
    applyStyleToUserAddedText(cmd, doc.getLength());
    // the cmd could be something as '\n'
    appendText(cmd);
    // and the command line the actual contents to be executed at this time
    final String commandLine = getCommandLine();
    if (handler.isOnStateWhereCommandHandlingShouldStop(commandLine)) {
        return;
    }
    history.update(commandLine);
    // handle the command line:
    // When the user presses a return and goes to a new line,  the contents of the current line are sent to
    // the interpreter (and its results properly handled).
    appendText(getDelimeter());
    final boolean finalAddedNewLine = addedNewLine;
    final String finalDelim = delim;
    final ICallback<Object, InterpreterResponse> onResponseReceived = new ICallback<Object, InterpreterResponse>() {

        @Override
        public Object call(final InterpreterResponse arg) {
            // When we receive the response, we must handle it in the UI thread.
            Runnable runnable = new Runnable() {

                @Override
                public void run() {
                    try {
                        processResult(arg);
                        if (finalAddedNewLine) {
                            List<String> historyList = history.getAsList();
                            IDocument historyDoc = new Document(StringUtils.join("\n", historyList.subList(historyFullLine, historyList.size())) + "\n");
                            int currHistoryLen = historyDoc.getLength();
                            if (currHistoryLen > 0) {
                                DocCmd docCmd = new DocCmd(currHistoryLen - 1, 0, finalDelim);
                                strategy.customizeNewLine(historyDoc, docCmd);
                                // remove any new line added!
                                finalIndentString[0] = docCmd.text.replaceAll("\\r\\n|\\n|\\r", "");
                                if (currHistoryLen != historyDoc.getLength()) {
                                    Log.log("Error: the document passed to the customizeNewLine should not be changed!");
                                }
                            }
                        }
                    } catch (Throwable e) {
                        // Yeap, it can never fail!
                        Log.log(e);
                    }
                    if (currentCommand + 1 < commands.size()) {
                        execCommand(finalAddedNewLine, finalDelim, finalIndentString, commands.get(currentCommand + 1), commands, currentCommand + 1, text, addedParen, start, addedCloseParen, newDeltaCaretPosition);
                    } else {
                        // last one
                        try {
                            onAfterAllLinesHandled(text, addedParen, start, readOnlyColumnsInCurrentBeforePrompt, addedCloseParen, finalIndentString[0], newDeltaCaretPosition);
                        } finally {
                            // We must disconnect
                            // reconnect with the document
                            stopDisconnected();
                        }
                    }
                }
            };
            RunInUiThread.async(runnable);
            return null;
        }
    };
    handler.beforeHandleCommand(commandLine, onResponseReceived);
    // Handle the command in a thread that doesn't block the U/I.
    Job j = new Job("PyDev Console Hander") {

        @Override
        protected IStatus run(IProgressMonitor monitor) {
            promptReady = false;
            handler.handleCommand(commandLine, onResponseReceived);
            return Status.OK_STATUS;
        }
    };
    j.setSystem(true);
    j.schedule();
}
Also used : InterpreterResponse(org.python.pydev.shared_interactive_console.console.InterpreterResponse) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) DocCmd(org.python.pydev.shared_core.utils.DocCmd) IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) ICallback(org.python.pydev.shared_core.callbacks.ICallback) Job(org.eclipse.core.runtime.jobs.Job) IDocument(org.eclipse.jface.text.IDocument)

Example 2 with InterpreterResponse

use of org.python.pydev.shared_interactive_console.console.InterpreterResponse in project Pydev by fabioz.

the class PydevConsoleCommunication method interrupt.

/**
 * Instructs the client to raise KeyboardInterrupt and return to a clean command prompt.  This can be
 * called to terminate:
 * - infinite or excessively long processing loops (CPU bound)
 * - I/O wait (e.g. urlopen, time.sleep)
 * - asking for input from the console i.e. input(); this is a special case of the above because PyDev
 *   is involved
 * - command prompt continuation processing, so that the user doesn't have to work out the exact
 *   sequence of close brackets required to get the prompt back
 * This requires the cooperation of the client (the call to interrupt must be processed by the XMLRPC
 * server) but in most cases is better than just terminating the process.
 */
@Override
public void interrupt() {
    Job job = new Job("Interrupt console process") {

        @Override
        protected IStatus run(IProgressMonitor monitor) {
            try {
                lastResponse = null;
                setNextResponse(new InterpreterResponse(false, false));
                moreBuffer.clear();
                PydevConsoleCommunication.this.client.execute("interrupt", new Object[0]);
                if (PydevConsoleCommunication.this.waitingForInput) {
                    PydevConsoleCommunication.this.inputReceived = "";
                    PydevConsoleCommunication.this.waitingForInput = false;
                }
            } catch (Exception e) {
                Log.log(IStatus.ERROR, "Problem interrupting python process", e);
            }
            return Status.OK_STATUS;
        }
    };
    job.schedule();
}
Also used : IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) InterpreterResponse(org.python.pydev.shared_interactive_console.console.InterpreterResponse) Job(org.eclipse.core.runtime.jobs.Job) CoreException(org.eclipse.core.runtime.CoreException) UserCanceledException(org.python.pydev.debug.newconsole.env.UserCanceledException) XmlRpcNoSuchHandlerException(org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 3 with InterpreterResponse

use of org.python.pydev.shared_interactive_console.console.InterpreterResponse in project Pydev by fabioz.

the class PydevConsoleCommunication method execInterpreter.

/**
 * Executes a given line in the interpreter.
 *
 * @param command the command to be executed in the client
 */
@Override
public void execInterpreter(String command, final ICallback<Object, InterpreterResponse> onResponseReceived) {
    setNextResponse(null);
    if (waitingForInput) {
        inputReceived = command;
        waitingForInput = false;
    // the thread that we started in the last exec is still alive if we were waiting for an input.
    } else {
        if (lastResponse != null && lastResponse.need_input == false && lastResponse.more) {
            if (command.trim().length() > 0 && Character.isWhitespace(command.charAt(0))) {
                moreBuffer.add(command);
                // Pass same response back again (we still need more input to try to do some evaluation).
                onResponseReceived.call(lastResponse);
                return;
            }
        }
        final String executeCommand;
        if (moreBuffer.size() > 0) {
            executeCommand = StringUtils.join("\n", moreBuffer) + "\n" + command;
            moreBuffer.clear();
        } else {
            executeCommand = command;
        }
        // create a thread that'll keep locked until an answer is received from the server.
        Job job = new Job("PyDev Console Communication") {

            /**
             * Executes the needed command
             *
             * @return a tuple with (null, more) or (error, false)
             *
             * @throws XmlRpcException
             */
            private boolean exec() throws XmlRpcException {
                if (client == null) {
                    return false;
                }
                Object ret = client.execute(executeCommand.contains("\n") ? "execMultipleLines" : "execLine", new Object[] { executeCommand });
                if (!(ret instanceof Boolean)) {
                    if (ret instanceof Object[]) {
                        Object[] objects = (Object[]) ret;
                        ret = StringUtils.join(" ", objects);
                    } else {
                        ret = "" + ret;
                    }
                    if (onContentsReceived != null) {
                        onContentsReceived.call(new Tuple<String, String>("", ret.toString()));
                    }
                    return false;
                }
                boolean more = (Boolean) ret;
                return more;
            }

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                final boolean needInput = false;
                try {
                    if (!firstCommWorked) {
                        throw new Exception("hello must be called successfully before execInterpreter can be used.");
                    }
                    finishedExecution.unset();
                    boolean more = exec();
                    if (!more) {
                        finishedExecution.waitForSet();
                    }
                    setNextResponse(new InterpreterResponse(more, needInput));
                } catch (Exception e) {
                    Log.log(e);
                    setNextResponse(new InterpreterResponse(false, needInput));
                }
                return Status.OK_STATUS;
            }
        };
        job.schedule();
    }
    // busy loop until we have a response
    InterpreterResponse waitForSet = nextResponse.waitForSet();
    lastResponse = waitForSet;
    onResponseReceived.call(waitForSet);
}
Also used : IProgressMonitor(org.eclipse.core.runtime.IProgressMonitor) InterpreterResponse(org.python.pydev.shared_interactive_console.console.InterpreterResponse) Job(org.eclipse.core.runtime.jobs.Job) CoreException(org.eclipse.core.runtime.CoreException) UserCanceledException(org.python.pydev.debug.newconsole.env.UserCanceledException) XmlRpcNoSuchHandlerException(org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 4 with InterpreterResponse

use of org.python.pydev.shared_interactive_console.console.InterpreterResponse in project Pydev by fabioz.

the class PydevConsoleCommunication method requestInput.

private Object requestInput() {
    waitingForInput = true;
    inputReceived = null;
    boolean needInput = true;
    // let the busy loop from execInterpreter free and enter a busy loop
    // in this function until execInterpreter gives us an input
    setNextResponse(new InterpreterResponse(false, needInput));
    // busy loop until we have an input
    while (inputReceived == null) {
        synchronized (lock) {
            try {
                lock.wait(10);
            } catch (InterruptedException e) {
                Log.log(e);
            }
        }
    }
    return inputReceived;
}
Also used : InterpreterResponse(org.python.pydev.shared_interactive_console.console.InterpreterResponse)

Example 5 with InterpreterResponse

use of org.python.pydev.shared_interactive_console.console.InterpreterResponse in project Pydev by fabioz.

the class ScriptConsoleDocumentListenerTest method setUp.

@Override
protected void setUp() throws Exception {
    super.setUp();
    this.doc = new Document();
    final List<String> commandsHandled = new ArrayList<String>();
    ScriptConsolePrompt prompt = new ScriptConsolePrompt(">>> ", "... ");
    listener = new ScriptConsoleDocumentListener(new IScriptConsoleViewer2ForDocumentListener() {

        @Override
        public IDocument getDocument() {
            return doc;
        }

        @Override
        public IConsoleStyleProvider getStyleProvider() {
            return null;
        }

        @Override
        public void revealEndOfDocument() {
        // do nothing
        }

        @Override
        public void setCaretOffset(int length, boolean async) {
        // do nothing
        }

        @Override
        public int getCommandLineOffset() {
            return 0;
        }

        @Override
        public int getConsoleWidthInCharacters() {
            return 0;
        }

        @Override
        public int getCaretOffset() {
            return 0;
        }

        @Override
        public IScriptConsoleSession getConsoleSession() {
            return null;
        }
    }, new ICommandHandler() {

        @Override
        public void beforeHandleCommand(String userInput, ICallback<Object, InterpreterResponse> onResponseReceived) {
            commandsHandled.add(userInput);
        }

        @Override
        public void handleCommand(String userInput, ICallback<Object, InterpreterResponse> onResponseReceived) {
            boolean more = false;
            if (userInput.endsWith(":") || userInput.endsWith("\\")) {
                more = true;
            }
            onResponseReceived.call(new InterpreterResponse(more, false));
        }

        @Override
        public ICompletionProposalHandle[] getTabCompletions(String commandLine, int cursorPosition) {
            return null;
        }

        @Override
        public void setOnContentsReceivedCallback(ICallback<Object, Tuple<String, String>> onContentsReceived) {
        }

        @Override
        public boolean isOnStateWhereCommandHandlingShouldStop(String commandLine) {
            return false;
        }
    }, prompt, new ScriptConsoleHistory(), new ArrayList<IConsoleLineTracker>(), "", new PyAutoIndentStrategy(new IAdaptable() {

        @Override
        public <T> T getAdapter(Class<T> adapter) {
            return null;
        }
    }));
    PyAutoIndentStrategy strategy = (PyAutoIndentStrategy) listener.getIndentStrategy();
    strategy.setIndentPrefs(new TestIndentPrefs(true, 4));
    listener.setDocument(doc);
}
Also used : IScriptConsoleViewer2ForDocumentListener(org.python.pydev.shared_interactive_console.console.ui.internal.IScriptConsoleViewer2ForDocumentListener) ScriptConsolePrompt(org.python.pydev.shared_interactive_console.console.ScriptConsolePrompt) IAdaptable(org.eclipse.core.runtime.IAdaptable) InterpreterResponse(org.python.pydev.shared_interactive_console.console.InterpreterResponse) ScriptConsoleHistory(org.python.pydev.shared_interactive_console.console.ScriptConsoleHistory) ArrayList(java.util.ArrayList) ScriptConsoleDocumentListener(org.python.pydev.shared_interactive_console.console.ui.internal.ScriptConsoleDocumentListener) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) ICommandHandler(org.python.pydev.shared_interactive_console.console.ui.internal.ICommandHandler) ICallback(org.python.pydev.shared_core.callbacks.ICallback) ICompletionProposalHandle(org.python.pydev.shared_core.code_completion.ICompletionProposalHandle) TestIndentPrefs(org.python.pydev.core.autoedit.TestIndentPrefs) PyAutoIndentStrategy(org.python.pydev.core.autoedit.PyAutoIndentStrategy)

Aggregations

InterpreterResponse (org.python.pydev.shared_interactive_console.console.InterpreterResponse)7 IProgressMonitor (org.eclipse.core.runtime.IProgressMonitor)4 Job (org.eclipse.core.runtime.jobs.Job)4 CoreException (org.eclipse.core.runtime.CoreException)3 IOException (java.io.IOException)2 MalformedURLException (java.net.MalformedURLException)2 XmlRpcException (org.apache.xmlrpc.XmlRpcException)2 XmlRpcNoSuchHandlerException (org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException)2 Document (org.eclipse.jface.text.Document)2 IDocument (org.eclipse.jface.text.IDocument)2 UserCanceledException (org.python.pydev.debug.newconsole.env.UserCanceledException)2 ICallback (org.python.pydev.shared_core.callbacks.ICallback)2 ArrayList (java.util.ArrayList)1 IAdaptable (org.eclipse.core.runtime.IAdaptable)1 PyAutoIndentStrategy (org.python.pydev.core.autoedit.PyAutoIndentStrategy)1 TestIndentPrefs (org.python.pydev.core.autoedit.TestIndentPrefs)1 PyStackFrame (org.python.pydev.debug.model.PyStackFrame)1 ICompletionProposalHandle (org.python.pydev.shared_core.code_completion.ICompletionProposalHandle)1 Tuple (org.python.pydev.shared_core.structure.Tuple)1 DocCmd (org.python.pydev.shared_core.utils.DocCmd)1