Пример #1
0
  @Override
  protected SourceViewerConfiguration createSourceViewerConfiguration() {
    PyContentAssistant contentAssist = new PyContentAssistant();
    IContentAssistProcessor processor = createConsoleCompletionProcessor(contentAssist);
    contentAssist.setContentAssistProcessor(
        processor, JSScriptConsoleSourceViewerConfiguration.PARTITION_TYPE);

    contentAssist.enableAutoActivation(true);
    contentAssist.enableAutoInsert(false);
    contentAssist.setAutoActivationDelay(PyCodeCompletionPreferencesPage.getAutocompleteDelay());

    PyCorrectionAssistant quickAssist = new PyCorrectionAssistant();
    // next create a content assistant processor to populate the completions window
    IQuickAssistProcessor quickAssistProcessor = createConsoleQuickAssistProcessor(quickAssist);

    // Correction assist works on all
    quickAssist.setQuickAssistProcessor(quickAssistProcessor);

    SourceViewerConfiguration cfg =
        new JSScriptConsoleSourceViewerConfiguration(createHover(), contentAssist, quickAssist);
    return cfg;
  }
Пример #2
0
  /**
   * This method creates the python server process and starts the sockets, so that we can talk with
   * the server.
   *
   * @param milisSleep: time to wait after creating the process.
   * @throws IOException is some error happens creating the sockets - the process is terminated.
   * @throws JDTNotAvailableException
   * @throws CoreException
   * @throws CoreException
   * @throws MisconfigurationException
   */
  /*package*/ void startIt(IInterpreterInfo interpreter)
      throws IOException, JDTNotAvailableException, CoreException, MisconfigurationException {

    int milisSleep = AbstractShell.DEFAULT_SLEEP_BETWEEN_ATTEMPTS;
    synchronized (ioLock) {
      this.shellInterpreter = interpreter;
      if (inStart || isConnected) {
        // it is already in the process of starting, so, if we are in another thread, just forget
        // about it.
        return;
      }
      inStart = true;
      try {
        if (finishedForGood) {
          throw new RuntimeException(
              "Shells are already finished for good, so, it is an invalid state to try to restart it.");
        }

        ProcessCreationInfo processInfo = null;
        try {

          serverSocketChannel = ServerSocketChannel.open();
          serverSocketChannel.configureBlocking(false);
          serverSocketChannel.bind(new InetSocketAddress(0));

          serverSocket = serverSocketChannel.socket();
          int port = serverSocket.getLocalPort();
          SocketUtil.checkValidPort(port);

          if (process != null) {
            endIt(); // end the current process
          }

          processInfo = createServerProcess(interpreter, port);
          dbg("executed: " + processInfo.getProcessLog(), 1);

          sleepALittle(200); // Give it some time to warmup.
          if (process == null) {
            String msg =
                "Error creating python process - got null process.\n" + processInfo.getProcessLog();
            dbg(msg, 1);
            Log.log(msg);
            throw new CoreException(PydevPlugin.makeStatus(IStatus.ERROR, msg, new Exception(msg)));
          }
          try {
            int exitVal =
                process
                    .exitValue(); // should throw exception saying that it still is not
                                  // terminated...
            String msg =
                "Error creating python process - exited before creating sockets - exitValue = ("
                    + exitVal
                    + ").\n"
                    + processInfo.getProcessLog();
            dbg(msg, 1);
            Log.log(msg);
            throw new CoreException(PydevPlugin.makeStatus(IStatus.ERROR, msg, new Exception(msg)));
          } catch (IllegalThreadStateException e2) { // this is ok
          }

          dbg("afterCreateProcess ", 1);
          // ok, process validated, so, let's get its output and store it for further use.

          boolean connected = false;
          int attempt = 0;

          dbg("connecting... ", 1);
          sleepALittle(milisSleep);
          int maxAttempts = PyCodeCompletionPreferencesPage.getNumberOfConnectionAttempts();

          dbg("maxAttempts: " + maxAttempts, 1);
          dbg("finishedForGood: " + finishedForGood, 1);

          while (!connected && attempt < maxAttempts && !finishedForGood) {
            attempt += 1;
            dbg("connecting attept..." + attempt, 1);
            try {

              try {
                dbg("serverSocket.accept()! ", 1);
                long initial = System.currentTimeMillis();
                SocketChannel accept = null;
                while (accept == null
                    && System.currentTimeMillis() - initial
                        < 5000) { // Each attempt is 5 seconds...
                  dbg(
                      "serverSocketChannel.accept(): waiting for python client to connect back to the eclipse java vm",
                      1);
                  accept = serverSocketChannel.accept();
                  if (accept == null) {
                    sleepALittle(500);
                  }
                }
                if (accept != null) {
                  socket = accept.socket();
                  dbg("socketToRead.setSoTimeout(5000) ", 1);
                  socket.setSoTimeout(5000); // let's give it a higher timeout
                  connected = true;
                  dbg("connected! ", 1);
                } else {
                  String msg =
                      "The python client still hasn't connected back to the eclipse java vm (will retry...)";
                  dbg(msg, 1);
                  Log.log(msg);
                }
              } catch (SocketTimeoutException e) {
                // that's ok, timeout for waiting connection expired, let's check it again in the
                // next loop
                dbg("SocketTimeoutException! ", 1);
              }
            } catch (IOException e1) {
              dbg("IOException! ", 1);
            }

            // if not connected, let's sleep a little for another attempt
            if (!connected) {
              if (attempt > 1) {
                // Don't log first failed attempt.
                String msg =
                    "Attempt: "
                        + attempt
                        + " of "
                        + maxAttempts
                        + " failed, trying again...(socket connected: "
                        + (socket == null ? "still null" : socket.isConnected())
                        + ")";

                dbg(msg, 1);
                Log.log(msg);
                sleepALittle(milisSleep);
              }
            }
          }

          if (!connected && !finishedForGood) {
            dbg("NOT connected ", 1);

            // what, after all this trouble we are still not connected????!?!?!?!
            // let's communicate this to the user...
            String isAlive;
            try {
              int exitVal =
                  process
                      .exitValue(); // should throw exception saying that it still is not
                                    // terminated...
              isAlive = " - the process in NOT ALIVE anymore (output=" + exitVal + ") - ";
            } catch (IllegalThreadStateException e2) { // this is ok
              isAlive = " - the process in still alive (killing it now)- ";
              process.destroy();
            }
            closeConn(); // make sure all connections are closed as we're not connected

            String msg =
                "Error connecting to python process (most likely cause for failure is a firewall blocking communication or a misconfigured network).\n"
                    + isAlive
                    + "\n"
                    + processInfo.getProcessLog();

            RuntimeException exception = new RuntimeException(msg);
            dbg(msg, 1);
            Log.log(exception);
            throw exception;
          }

        } catch (IOException e) {

          if (process != null) {
            process.destroy();
            process = null;
          }
          throw e;
        } finally {
          if (processInfo != null) {
            processInfo.stopGettingOutput();
            processInfo = null;
          }
        }
      } finally {
        this.inStart = false;
      }

      // if it got here, everything went ok (otherwise we would have gotten an exception).
      isConnected = true;
    }
    synchronized (lockLastPythonPath) {
      lastPythonPath = null;
    }
  }
  /** When a console page is initialized, */
  public void init(IPageBookViewPage page, final IConsole console) {
    if (!(console instanceof ProcessConsole)) {
      return;
    }
    ProcessConsole processConsole = (ProcessConsole) console;
    IProcess process = processConsole.getProcess();
    if (process == null) {
      return;
    }
    if (!PyCodeCompletionPreferencesPage.useCodeCompletion()
        || !PyCodeCompletionPreferencesPage.useCodeCompletionOnDebug()) {
      return;
    }
    String attribute = process.getAttribute(Constants.PYDEV_DEBUG_IPROCESS_ATTR);
    if (!Constants.PYDEV_DEBUG_IPROCESS_ATTR_TRUE.equals(attribute)) {
      // Only provide code-completion for pydev debug processes.
      return;
    }
    Control control = page.getControl();
    if (page instanceof IOConsolePage) {

      // Note that completions on "all letters and '_'" are already activated just by installing
      // the content assist, but the completions on the default keybinding is not, so, we have to
      // call it ourselves here.
      control.addKeyListener(
          new KeyListener() {
            public void keyPressed(KeyEvent e) {

              if (KeyBindingHelper.matchesContentAssistKeybinding(e)) {
                contentAssist.showPossibleCompletions();
              }
            }

            public void keyReleased(KeyEvent e) {}
          });

      IOConsolePage consolePage = (IOConsolePage) page;
      TextConsoleViewer viewer = consolePage.getViewer();

      contentAssist =
          new PyContentAssistant() {
            public String showPossibleCompletions() {
              // Only show completions if we're in a suspended console.
              if (getCurrentSuspendedPyStackFrame(console) == null) {
                return null;
              }
              return super.showPossibleCompletions();
            };
          };
      contentAssist.setInformationControlCreator(
          PyContentAssistant.createInformationControlCreator(viewer));
      ILaunch launch = process.getLaunch();
      IDebugTarget debugTarget = launch.getDebugTarget();
      IInterpreterInfo projectInterpreter = null;
      if (debugTarget instanceof PyDebugTarget) {
        PyDebugTarget pyDebugTarget = (PyDebugTarget) debugTarget;
        PythonNature nature = PythonNature.getPythonNature(pyDebugTarget.project);
        if (nature != null) {
          try {
            projectInterpreter = nature.getProjectInterpreter();
          } catch (Throwable e1) {
            Log.log(e1);
          }
        }
      }
      contentAssist.install(new ScriptConsoleViewerWrapper(viewer, projectInterpreter));

      PydevConsoleInterpreter interpreter = new PydevConsoleInterpreter();
      interpreter.setConsoleCommunication(new GetCompletionsInDebug());

      IContentAssistProcessor processor =
          new PydevConsoleCompletionProcessor(interpreter, contentAssist);
      contentAssist.setContentAssistProcessor(processor, IOConsolePartition.INPUT_PARTITION_TYPE);
      contentAssist.setContentAssistProcessor(processor, IOConsolePartition.OUTPUT_PARTITION_TYPE);

      contentAssist.enableAutoActivation(true);
      contentAssist.enableAutoInsert(false);
      contentAssist.setAutoActivationDelay(PyCodeCompletionPreferencesPage.getAutocompleteDelay());
    }
  }