예제 #1
0
  public boolean processExKey(Editor editor, @NotNull KeyStroke stroke, boolean charOnly) {
    // This will only get called if somehow the key focus ended up in the editor while the ex entry
    // window
    // is open. So I'll put focus back in the editor and process the key.

    ExEntryPanel panel = ExEntryPanel.getInstance();
    if (panel.isActive()) {
      panel.requestFocus();
      panel.handleKey(stroke);

      return true;
    } else {
      CommandState.getInstance(editor).popState();
      KeyHandler.getInstance().reset(editor);
      return false;
    }

    /*
    if (!charOnly || stroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED && ExEntryPanel.getInstance().isActive())
    {
        ExEntryPanel panel = ExEntryPanel.getInstance();
        panel.handleKey(stroke);

        return true;
    }
    else
    {
        return false;
    }
    */
  }
예제 #2
0
 public void startFilterCommand(
     @NotNull Editor editor, DataContext context, @NotNull Command cmd) {
   String initText = getRange(editor, cmd) + "!";
   CommandState.getInstance(editor)
       .pushState(
           CommandState.Mode.EX_ENTRY, CommandState.SubMode.NONE, KeyParser.MAPPING_CMD_LINE);
   ExEntryPanel panel = ExEntryPanel.getInstance();
   panel.activate(editor, context, ":", initText, 1);
 }
예제 #3
0
  public void startExCommand(@NotNull Editor editor, DataContext context, @NotNull Command cmd) {
    if (editor.isOneLineMode()) // Don't allow ex commands in one line editors
    {
      return;
    }

    String initText = getRange(editor, cmd);
    CommandState.getInstance(editor)
        .pushState(
            CommandState.Mode.EX_ENTRY, CommandState.SubMode.NONE, KeyParser.MAPPING_CMD_LINE);
    ExEntryPanel panel = ExEntryPanel.getInstance();
    panel.activate(editor, context, ":", initText, 1);
  }
예제 #4
0
  @NotNull
  private String getRange(Editor editor, @NotNull Command cmd) {
    String initText = "";
    if (CommandState.getInstance(editor).getMode() == CommandState.Mode.VISUAL) {
      initText = "'<,'>";
    } else if (cmd.getRawCount() > 0) {
      if (cmd.getCount() == 1) {
        initText = ".";
      } else {
        initText = ".,.+" + (cmd.getCount() - 1);
      }
    }

    return initText;
  }
예제 #5
0
  public boolean cancelExEntry(@NotNull final Editor editor, @NotNull final DataContext context) {
    CommandState.getInstance(editor).popState();
    KeyHandler.getInstance().reset(editor);
    ExEntryPanel panel = ExEntryPanel.getInstance();
    panel.deactivate();
    final Project project = PlatformDataKeys.PROJECT.getData(context); // API change - don't merge
    SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            // editor.getContentComponent().requestFocus();
            VirtualFile vf = EditorData.getVirtualFile(editor);
            if (vf != null) {
              FileEditorManager.getInstance(project)
                  .openFile(EditorData.getVirtualFile(editor), true);
            }
          }
        });

    return true;
  }
예제 #6
0
 private void record(Editor editor, @NotNull String text) {
   if (CommandState.getInstance(editor).isRecording()) {
     CommandGroups.getInstance().getRegister().recordText(text);
   }
 }
예제 #7
0
  public boolean processExEntry(@NotNull final Editor editor, @NotNull final DataContext context) {
    ExEntryPanel panel = ExEntryPanel.getInstance();
    panel.deactivate();
    boolean res = true;
    int flags = 0;
    try {
      CommandState.getInstance(editor).popState();
      logger.debug("processing command");
      final String text = panel.getText();
      record(editor, text);
      if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread());
      if (panel.getLabel().equals(":")) {
        flags = CommandParser.getInstance().processCommand(editor, context, text, 1);
        if (logger.isDebugEnabled()) logger.debug("flags=" + flags);
        if (CommandState.getInstance(editor).getMode() == CommandState.Mode.VISUAL) {
          CommandGroups.getInstance().getMotion().exitVisual(editor, true);
        }
      } else {
        int pos =
            CommandGroups.getInstance()
                .getSearch()
                .search(
                    editor,
                    text,
                    panel.getCount(),
                    panel.getLabel().equals("/")
                        ? Command.FLAG_SEARCH_FWD
                        : Command.FLAG_SEARCH_REV,
                    true);
        if (pos == -1) {
          res = false;
        }
      }
    } catch (ExException ex) {
      // VimPlugin.showMessage(ex.getMessage());
      ProcessGroup.logger.info(ex.getMessage());
      VimPlugin.indicateError();
      res = false;
    } catch (Exception bad) {
      ProcessGroup.logger.error(bad);
      VimPlugin.indicateError();
      res = false;
    } finally {
      final int flg = flags;
      final Project project = PlatformDataKeys.PROJECT.getData(context); // API change - don't merge
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              // editor.getContentComponent().requestFocus();
              // Reopening the file was the only way I could solve the focus problem introduced in
              // IDEA at
              // version 1050.
              if (!ApplicationManager.getApplication().isUnitTestMode()
                  && (flg & CommandParser.RES_DONT_REOPEN) == 0) {
                VirtualFile vf = EditorData.getVirtualFile(editor);
                if (vf != null) {
                  FileEditorManager.getInstance(project)
                      .openFile(EditorData.getVirtualFile(editor), true);
                }
              }

              // If the result of the ex command is to display the "more" panel, show it here.
              if ((flg & CommandParser.RES_MORE_PANEL) != 0
                  && MorePanel.getInstance(editor).hasText()) {
                RunnableHelper.runReadCommand(
                    project,
                    new Runnable() {
                      public void run() {
                        MorePanel.getInstance(editor).activate();
                      }
                    },
                    "ShowMorePanel",
                    "ExCommand");
              }
            }
          });
    }

    return res;
  }
예제 #8
0
  public boolean searchAndReplace(
      @NotNull Editor editor, @NotNull LineRange range, @NotNull String excmd, String exarg) {
    boolean res = true;

    // Explicitly exit visual mode here, so that visual mode marks don't change when we move the
    // cursor to a match.
    if (CommandState.getInstance(editor).getMode() == CommandState.Mode.VISUAL) {
      VimPlugin.getMotion().exitVisual(editor);
    }

    CharPointer cmd = new CharPointer(new StringBuffer(exarg));
    // sub_nsubs = 0;
    // sub_nlines = 0;

    int which_pat;
    if (excmd.equals("~")) {
      which_pat = RE_LAST; /* use last used regexp */
    } else {
      which_pat = RE_SUBST; /* use last substitute regexp */
    }

    CharPointer pat;
    CharPointer sub;
    char delimiter;
    /* new pattern and substitution */
    if (excmd.charAt(0) == 's'
        && !cmd.isNul()
        && !Character.isWhitespace(cmd.charAt())
        && "0123456789cegriIp|\"".indexOf(cmd.charAt()) == -1) {
      /* don't accept alphanumeric for separator */
      if (CharacterClasses.isAlpha(cmd.charAt())) {
        VimPlugin.showMessage(MessageHelper.message(Msg.E146));
        return false;
      }
      /*
       * undocumented vi feature:
       *  "\/sub/" and "\?sub?" use last used search pattern (almost like
       *  //sub/r).  "\&sub&" use last substitute pattern (like //sub/).
       */
      if (cmd.charAt() == '\\') {
        cmd.inc();
        if ("/?&".indexOf(cmd.charAt()) == -1) {
          VimPlugin.showMessage(MessageHelper.message(Msg.e_backslash));
          return false;
        }
        if (cmd.charAt() != '&') {
          which_pat = RE_SEARCH; /* use last '/' pattern */
        }
        pat = new CharPointer(""); /* empty search pattern */
        delimiter = cmd.charAt(); /* remember delimiter character */
        cmd.inc();
      } else /* find the end of the regexp */ {
        which_pat = RE_LAST; /* use last used regexp */
        delimiter = cmd.charAt(); /* remember delimiter character */
        cmd.inc();
        pat = cmd.ref(0); /* remember start of search pat */
        cmd = RegExp.skip_regexp(cmd, delimiter, true);
        if (cmd.charAt() == delimiter) /* end delimiter found */ {
          cmd.set('\u0000').inc(); /* replace it with a NUL */
        }
      }

      /*
       * Small incompatibility: vi sees '\n' as end of the command, but in
       * Vim we want to use '\n' to find/substitute a NUL.
       */
      sub = cmd.ref(0); /* remember the start of the substitution */

      while (!cmd.isNul()) {
        if (cmd.charAt() == delimiter) /* end delimiter found */ {
          cmd.set('\u0000').inc(); /* replace it with a NUL */
          break;
        }
        if (cmd.charAt(0) == '\\' && cmd.charAt(1) != 0) /* skip escaped characters */ {
          cmd.inc();
        }
        cmd.inc();
      }
    } else /* use previous pattern and substitution */ {
      if (lastReplace == null) /* there is no previous command */ {
        VimPlugin.showMessage(MessageHelper.message(Msg.e_nopresub));
        return false;
      }
      pat = null; /* search_regcomp() will use previous pattern */
      sub = new CharPointer(lastReplace);
    }

    /*
     * Find trailing options.  When '&' is used, keep old options.
     */
    if (cmd.charAt() == '&') {
      cmd.inc();
    } else {
      do_all = Options.getInstance().isSet("gdefault");
      do_ask = false;
      do_error = true;
      // do_print = false;
      do_ic = 0;
    }
    while (!cmd.isNul()) {
      /*
       * Note that 'g' and 'c' are always inverted, also when p_ed is off.
       * 'r' is never inverted.
       */
      if (cmd.charAt() == 'g') {
        do_all = !do_all;
      } else if (cmd.charAt() == 'c') {
        do_ask = !do_ask;
      } else if (cmd.charAt() == 'e') {
        do_error = !do_error;
      } else if (cmd.charAt() == 'r') /* use last used regexp */ {
        which_pat = RE_LAST;
      } else if (cmd.charAt() == 'i') /* ignore case */ {
        do_ic = 'i';
      } else if (cmd.charAt() == 'I') /* don't ignore case */ {
        do_ic = 'I';
      } else if (cmd.charAt() != 'p') {
        break;
      }
      cmd.inc();
    }

    int line1 = range.getStartLine();
    int line2 = range.getEndLine();

    /*
     * check for a trailing count
     */
    cmd = CharHelper.skipwhite(cmd);
    if (CharacterClasses.isDigit(cmd.charAt())) {
      int i = CharHelper.getdigits(cmd);
      if (i <= 0 && do_error) {
        VimPlugin.showMessage(MessageHelper.message(Msg.e_zerocount));
        return false;
      }
      line1 = line2;
      line2 = EditorHelper.normalizeLine(editor, line1 + i - 1);
    }

    /*
     * check for trailing command or garbage
     */
    cmd = CharHelper.skipwhite(cmd);
    if (!cmd.isNul() && cmd.charAt() != '"') /* if not end-of-line or comment */ {
      VimPlugin.showMessage(MessageHelper.message(Msg.e_trailing));
      return false;
    }

    String pattern = "";
    if (pat == null || pat.isNul()) {
      switch (which_pat) {
        case RE_LAST:
          pattern = lastPattern;
          break;
        case RE_SEARCH:
          pattern = lastSearch;
          break;
        case RE_SUBST:
          pattern = lastSubstitute;
          break;
      }
    } else {
      pattern = pat.toString();
    }

    lastSubstitute = pattern;
    if (pattern != null) {
      setLastPattern(editor, pattern);
    }

    // int start = editor.logicalPositionToOffset(new LogicalPosition(line1, 0));
    // int end = editor.logicalPositionToOffset(new LogicalPosition(line2,
    // EditorHelper.getLineLength(editor, line2)));
    int start = editor.getDocument().getLineStartOffset(line1);
    int end = editor.getDocument().getLineEndOffset(line2);

    RegExp sp;
    RegExp.regmmatch_T regmatch = new RegExp.regmmatch_T();
    sp = new RegExp();
    regmatch.regprog = sp.vim_regcomp(pattern, 1);
    if (regmatch.regprog == null) {
      if (do_error) {
        VimPlugin.showMessage(MessageHelper.message(Msg.e_invcmd));
      }
      return false;
    }

    /* the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase' */
    if (do_ic == 'i') {
      regmatch.rmm_ic = true;
    } else if (do_ic == 'I') {
      regmatch.rmm_ic = false;
    }

    /*
     * ~ in the substitute pattern is replaced with the old pattern.
     * We do it here once to avoid it to be replaced over and over again.
     * But don't do it when it starts with "\=", then it's an expression.
     */
    if (!(sub.charAt(0) == '\\' && sub.charAt(1) == '=') && lastReplace != null) {
      StringBuffer tmp = new StringBuffer(sub.toString());
      int pos = 0;
      while ((pos = tmp.indexOf("~", pos)) != -1) {
        if (pos == 0 || tmp.charAt(pos - 1) != '\\') {
          tmp.replace(pos, pos + 1, lastReplace);
          pos += lastReplace.length();
        }
        pos++;
      }
      sub = new CharPointer(tmp);
    }

    lastReplace = sub.toString();

    searchHighlight(false);

    if (logger.isDebugEnabled()) {
      logger.debug("search range=[" + start + "," + end + "]");
      logger.debug("pattern=" + pattern + ", replace=" + sub);
    }
    int lastMatch = -1;
    int lastLine = -1;
    int searchcol = 0;
    boolean firstMatch = true;
    boolean got_quit = false;
    int lcount = EditorHelper.getLineCount(editor);
    for (int lnum = line1; lnum <= line2 && !got_quit; ) {
      CharacterPosition newpos = null;
      int nmatch = sp.vim_regexec_multi(regmatch, editor, lcount, lnum, searchcol);
      if (nmatch > 0) {
        if (firstMatch) {
          VimPlugin.getMark().saveJumpLocation(editor);
          firstMatch = false;
        }

        String match = sp.vim_regsub_multi(regmatch, lnum, sub, 1, false);
        // logger.debug("found match[" + spos + "," + epos + "] - replace " + match);

        int line = lnum + regmatch.startpos[0].lnum;
        CharacterPosition startpos =
            new CharacterPosition(lnum + regmatch.startpos[0].lnum, regmatch.startpos[0].col);
        CharacterPosition endpos =
            new CharacterPosition(lnum + regmatch.endpos[0].lnum, regmatch.endpos[0].col);
        int startoff = EditorHelper.characterPositionToOffset(editor, startpos);
        int endoff = EditorHelper.characterPositionToOffset(editor, endpos);
        int newend = startoff + match.length();

        if (do_all || line != lastLine) {
          boolean doReplace = true;
          if (do_ask) {
            // editor.getSelectionModel().setSelection(startoff, endoff);
            RangeHighlighter hl = highlightConfirm(editor, startoff, endoff);
            int choice = getConfirmChoice(match);
            // editor.getSelectionModel().removeSelection();
            editor.getMarkupModel().removeHighlighter(hl);
            switch (choice) {
              case 0: // Yes
                doReplace = true;
                break;
              case 1: // No
                doReplace = false;
                break;
              case 2: // All
                do_ask = false;
                break;
              case JOptionPane.CLOSED_OPTION:
              case 3: // Quit
                doReplace = false;
                got_quit = true;
                break;
              case 4: // Last
                do_all = false;
                line2 = lnum;
                doReplace = true;
                break;
            }
          }

          if (doReplace) {
            editor.getDocument().replaceString(startoff, endoff, match);
            lastMatch = startoff;
            newpos = EditorHelper.offsetToCharacterPosition(editor, newend);

            lnum += newpos.line - endpos.line;
            line2 += newpos.line - endpos.line;
          }
        }

        lastLine = line;

        lnum += nmatch - 1;
        if (do_all && startoff != endoff) {
          if (newpos != null) {
            lnum = newpos.line;
            searchcol = newpos.column;
          } else {
            searchcol = endpos.column;
          }
        } else {
          searchcol = 0;
          lnum++;
        }
      } else {
        lnum++;
        searchcol = 0;
      }
    }

    if (lastMatch != -1) {
      MotionGroup.moveCaret(
          editor,
          VimPlugin.getMotion()
              .moveCaretToLineStartSkipLeading(
                  editor, editor.offsetToLogicalPosition(lastMatch).line));
    } else {
      VimPlugin.showMessage(MessageHelper.message(Msg.e_patnotf2, pattern));
    }

    return res;
  }