void (final ConsoleCodeFragment command, final Function<InterpreterResponse, Object> onResponseReceived) { if (myDebugCommunication != null && myDebugCommunication.isSuspended()) { myDebugCommunication.execInterpreter(command, onResponseReceived); return; //TODO: handle text input and other cases } nextResponse = null; if (waitingForInput && myConsoleView != null && myConsoleView.isInitialized()) { inputReceived = command.getText(); waitingForInput = false; //the thread that we started in the last exec is still alive if we were waiting for an input. } else { //create a thread that'll keep locked until an answer is received from the server. new Task.Backgroundable(myProject, PyBundle.message("console.waiting.execution.result"), false) { @Override public void run(@NotNull ProgressIndicator indicator) { try { if (indicator.isCanceled()) return; Pair<String, Boolean> executed = exec(command); nextResponse = new InterpreterResponse(executed.second, false); } catch (ProcessCanceledException e) { //ignore } catch (PythonUnhandledException e) { LOG.error("Error in execInterpreter():" + e.traceback); nextResponse = new InterpreterResponse(false, false); notifyCommandExecuted(true); } catch (Exception e) { nextResponse = new InterpreterResponse(false, false); notifyCommandExecuted(true); } finally { InterpreterResponse response = nextResponse; if (response != null && response.more) { myNeedsMore = true; } onResponseReceived.fun(response); } } }.queue(); } }