diff --git a/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java b/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java index 850efcade..e75b43bf2 100644 --- a/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java +++ b/src/com/maddyhome/idea/vim/ex/handler/SubstituteHandler.java @@ -21,10 +21,17 @@ package com.maddyhome.idea.vim.ex.handler; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Editor; -import com.maddyhome.idea.vim.KeyHandler; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.diagnostic.Logger; import com.maddyhome.idea.vim.ex.CommandHandler; import com.maddyhome.idea.vim.ex.ExCommand; import com.maddyhome.idea.vim.ex.ExException; +import com.maddyhome.idea.vim.ex.InvalidArgumentException; +import com.maddyhome.idea.vim.ex.CommandName; +import com.maddyhome.idea.vim.group.CommandGroups; +import com.maddyhome.idea.vim.group.SearchGroup; +import java.util.StringTokenizer; +import java.util.NoSuchElementException; /** * @@ -33,13 +40,87 @@ public class SubstituteHandler extends CommandHandler { public SubstituteHandler() { - super("s", "ubstitute", 0); + super(new CommandName[] { + new CommandName("s", "ubstitute"), + new CommandName("&", ""), + new CommandName("~", "") + }, WRITABLE); } public boolean execute(Editor editor, DataContext context, ExCommand cmd) throws ExException { - KeyHandler.executeAction("Replace", context); + String arg = cmd.getArgument(); + logger.debug("arg="+arg); + String pattern = ""; + String replace = "~"; + String args = ""; + String count = ""; + // Are there any aruments at all? + if (arg.length() > 0) + { + // Are there flags and possible count? + if (Character.isLetter(arg.charAt(0)) || arg.charAt(0) == '&') + { + StringTokenizer tokenizer = new StringTokenizer(arg, " "); + args = tokenizer.nextToken(); + if (tokenizer.hasMoreTokens()) + { + count = tokenizer.nextToken(); + } + } + // Is there just a count? + else if (Character.isDigit(arg.charAt(0))) + { + count = arg; + } + // We have a pattern and maybe flags and a count + else + { + if (arg.length() < 3) + { + throw new InvalidArgumentException(); + } + StringTokenizer tokenizer = new StringTokenizer(arg.substring(1), Character.toString(arg.charAt(0))); + if (tokenizer.countTokens() < 2) + { + throw new InvalidArgumentException(); + } - return true; + pattern = tokenizer.nextToken(); + replace = tokenizer.nextToken(); + try + { + args = tokenizer.nextToken(" " + arg.charAt(0)); + count = tokenizer.nextToken(" "); + } + catch (NoSuchElementException e) + { + } + + if (args.length() > 0 && Character.isDigit(args.charAt(0))) + { + args = ""; + count = args; + } + } + } + + logger.debug("pattern="+pattern); + logger.debug("replace="+replace); + logger.debug("args="+args); + logger.debug("count="+count); + + cmd.setArgument(count); + TextRange range = cmd.getTextRange(editor, context, count.length() > 0); + + int sflags = SearchGroup.argsToFlags(args); + if (cmd.getCommand().equals("~")) + { + sflags |= SearchGroup.REUSE; + } + + return CommandGroups.getInstance().getSearch().searchAndReplace(editor, context, range, pattern, replace, sflags); } + + private static Logger logger = Logger.getInstance(SubstituteHandler.class.getName()); }