1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-17 16:31:45 +02:00

Compare commits

...

24 Commits
0.35 ... 0.36

Author SHA1 Message Date
Andrey Vlasovskikh
969ca0119a Bumped version to 0.36 2014-10-14 14:22:38 +04:00
Andrey Vlasovskikh
6a1c792cda VIM-171 Added support for window navigation commands: left/right/up/down 2014-10-13 23:08:56 +04:00
Andrey Vlasovskikh
c0ba39ab40 Use multi-caret API available from branches 135+ 2014-10-09 18:33:07 +04:00
Andrey Vlasovskikh
3e0e08c5e1 VIM-632 Restored visual block mode that was broken due to multiple carets support
Vim actions with multiple carets in modes other than visual block are
not supported yet. It will be a separate feature. The idea behind this
commit is to fix the regression in visual block mode.

Bounds of visual selection are no longer reversed if they are
overlapped, this fixes expanding the block selection in all directions.

IdeaVim no longer uses SelectionModel.hasBlockSelection() since it
always returns 'true' now.

There are a couple of places where we remove secondary carets when
moving the primary caret or re-setting visual mode. It may be
incompatible with the forthcoming support for multi-caret Vim actions.
2014-10-09 18:01:47 +04:00
Andrey Vlasovskikh
3d64373c22 Updated the changelog 2014-10-07 15:24:45 +04:00
Andrey Vlasovskikh
2557688657 Added Alexey Shmalko to the list of contributors 2014-10-07 15:11:55 +04:00
Andrey Vlasovskikh
fcc564df25 Cleanup 2014-10-07 14:29:30 +04:00
Andrey Vlasovskikh
4ecbb93d01 Converted window actions into subclasses of VimCommandAction 2014-10-07 13:52:46 +04:00
Alexey Shmalko
9bdc9b3634 VIM-171 Add checks for that window is not null 2014-10-04 01:29:41 +03:00
Alexey Shmalko
f46c3b0aa9 VIM-171 Add support for window cycling
Adds following keystrokes:
<C-W>w <C-W><C-W> next window
<C-W>W            previous window

With number both commands go to window with specified index.
2014-10-04 00:52:24 +03:00
Alexey Shmalko
095fdf07c5 VIM-171 Add support for closing all windows except current
Adds <C-W>o, <C-W><C-O> keystrokes.
2014-10-04 00:02:15 +03:00
Alexey Shmalko
648e988b64 VIM-171 Add support for closing window
Adds <C-W>c keystroke.
2014-10-03 23:41:53 +03:00
Alexey Shmalko
b1add735d6 Add split action
This patch adds following keystrokes:
<C-W>s <C-W>S <C-W><C-S> horizontal split
<C-W>v <C-W><C-V>        vertical split
2014-10-02 20:52:13 +03:00
Andrey Vlasovskikh
3f5882118e Compatibility with builds 133+ / IntelliJ 13+ 2014-09-10 15:03:01 +04:00
Andrey Vlasovskikh
4e83f56696 Merge branch 'vim-265'
Conflicts:
	AUTHORS.md
2014-09-10 13:58:29 +04:00
Andrey Vlasovskikh
ab250f1d9c Added salaam to the list of contributors 2014-09-10 13:57:40 +04:00
Andrey Vlasovskikh
4672dece51 VIM-770 Close the current tab on :quit instead of all tabs with the current file 2014-09-10 13:52:00 +04:00
Andrey Vlasovskikh
a632de9214 Cleanup 2014-09-09 18:30:21 +04:00
Andrey Vlasovskikh
e8ebba8b3d Removed unused declarations 2014-09-09 18:25:45 +04:00
Andrey Vlasovskikh
5cf8181474 Added Dathan Bennett to the list of contributors 2014-09-09 00:38:42 +04:00
Andrey Vlasovskikh
a717e4785d VIM-569 Fixed <C-W> when the caret is at the end of a line 2014-09-09 00:36:39 +04:00
Dathan Bennett
16ce16c632 Add test for VIM-569 fix 2014-09-06 02:59:49 -07:00
Dathan Bennett
8d7bf2661a Set isChange to true when calling deleteRange from ctrl-w handler 2014-09-06 01:07:03 -07:00
salaam
9e1b026a88 VIM-265 Add window split commands
Conflicts:
	src/com/maddyhome/idea/vim/VimPlugin.java
	src/com/maddyhome/idea/vim/ex/CommandParser.java
2014-08-31 23:57:22 -05:00
28 changed files with 1159 additions and 118 deletions

View File

@@ -24,6 +24,9 @@ Contributors:
* [John Lindquist](mailto:johnlindquist@gmail.com) * [John Lindquist](mailto:johnlindquist@gmail.com)
* [Ira Klotzko](mailto:iklotzko@ltech.com) * [Ira Klotzko](mailto:iklotzko@ltech.com)
* [Alex Selesse](mailto:alex@selesse.com) * [Alex Selesse](mailto:alex@selesse.com)
* [Dathan Bennett](mailto:dbennett@palantir.com)
* [salaam](mailto:kphayen@gmail.com)
* [Alexey Shmalko](mailto:rasen.dubi@gmail.com)
If you are a contributor and your name is not listed here, feel free to If you are a contributor and your name is not listed here, feel free to
contact the maintainer. contact the maintainer.

View File

@@ -4,6 +4,26 @@ The Changelog
History of changes in IdeaVim for the IntelliJ platform. History of changes in IdeaVim for the IntelliJ platform.
0.36, 2014-10-14
----------------
Added support for common window splitting and navigation commands. Various bug
fixes.
Features:
* VIM-171 Window `<C-W>` commands: split, close, next/previous windows,
left/right/up/down windows
* VIM-265 Window `:split` and `:vsplit` commands
Bug fixes:
* VIM-632 Restored visual block mode that was broken due to multiple carets support
* VIM-770 Close the current tab on `:quit` instead of all tabs with the current
file
* VIM-569 Fixed `<C-W>` when the caret is at the end of a line
0.35, 2014-05-15 0.35, 2014-05-15
---------------- ----------------

View File

@@ -17,7 +17,7 @@ IdeaVim
IdeaVim is a Vim emulation plug-in for IDEs based on the IntelliJ platform. IdeaVim is a Vim emulation plug-in for IDEs based on the IntelliJ platform.
IdeaVim can be used with IntelliJ IDEA, RubyMine, PyCharm, PhpStorm, WebStorm, IdeaVim can be used with IntelliJ IDEA, RubyMine, PyCharm, PhpStorm, WebStorm,
AppCode and Android Studio. AppCode, CLion and Android Studio.
Resources: Resources:
@@ -63,18 +63,17 @@ Supported:
* Macros * Macros
* Digraphs * Digraphs
* Command line and search history * Command line and search history
* Window commands
* Vim web help * Vim web help
Not supported (yet): Not supported (yet):
* Window commands
* Jump lists * Jump lists
* Various less used commands * Various less used commands
See also: See also:
* [List of recently added commands](https://github.com/JetBrains/ideavim/blob/master/src/com/maddyhome/idea/vim/package-info.java) * [List of recently added commands](https://github.com/JetBrains/ideavim/blob/master/src/com/maddyhome/idea/vim/package-info.java)
* [List of commands covered with tests](https://github.com/JetBrains/ideavim/blob/master/index.txt)
* [Top features and bugs](http://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+sort+by%3A+votes) * [Top features and bugs](http://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+sort+by%3A+votes)
@@ -135,7 +134,7 @@ in the issue tracker.
1. Fork IdeaVim on GitHub and clone the repository on your local machine. 1. Fork IdeaVim on GitHub and clone the repository on your local machine.
2. Open the project in IntelliJ IDEA 12+ (Community or Ultimate) using "File | 2. Open the project in IntelliJ IDEA 13.1+ (Community or Ultimate) using "File |
Open... | /path/to/ideavim". Open... | /path/to/ideavim".
3. Set up a JDK if you haven't got it yet. Use "File | Project Structure | SDKs 3. Set up a JDK if you haven't got it yet. Use "File | Project Structure | SDKs

View File

@@ -1,4 +1,4 @@
version-id:0.35 version-id:0.36
platform-version:120.0 platform-version:135.0
idea.download.url=http://download.jetbrains.com/idea/ideaIU-13.zip idea.download.url=http://download.jetbrains.com/idea/ideaIU-13.1.zip
build.number=dev build.number=dev

View File

@@ -3,6 +3,13 @@
<id>IdeaVIM</id> <id>IdeaVIM</id>
<change-notes> <change-notes>
<![CDATA[ <![CDATA[
<p>0.36:</p>
<ul>
<li>Window commands from the <code>&lt;C-W&gt;</code> family</li>
<li>Support for <code>:split</code>/<code>:vsplit</code> commands</li>
<li>Fixed visual block selection mode</li>
<li>Various bug fixes</li>
</ul>
<p>0.35:</p> <p>0.35:</p>
<ul> <ul>
<li><code>~/.vimrc</code> is no longer read by default, use <code>~/.ideavimrc</code> instead</li> <li><code>~/.vimrc</code> is no longer read by default, use <code>~/.ideavimrc</code> instead</li>
@@ -40,11 +47,11 @@
<description> <description>
<![CDATA[ <![CDATA[
<p>Build @VERSION@-@BUILD-NUMBER@</p> <p>Build @VERSION@-@BUILD-NUMBER@</p>
<p>Vim emulation plug-in for IDEs based on the IntelliJ platform. IdeaVim can be used with IntelliJ IDEA, RubyMine, PyCharm, PhpStorm, WebStorm, AppCode and Android Studio.</p> <p>Vim emulation plug-in for IDEs based on the IntelliJ platform. IdeaVim can be used with IntelliJ IDEA, RubyMine, PyCharm, PhpStorm, WebStorm, AppCode, CLion and Android Studio.</p>
<p>Supported functionality:</p> <p>Supported functionality:</p>
<ul> <ul>
<li>Motion keys</li> <li>Motion keys</li>
<li>Deletion/Changing</li> <li>Deletion/changing</li>
<li>Insert mode commands</li> <li>Insert mode commands</li>
<li>Marks</li> <li>Marks</li>
<li>Registers</li> <li>Registers</li>
@@ -58,6 +65,7 @@
<li>Macros</li> <li>Macros</li>
<li>Digraphs</li> <li>Digraphs</li>
<li>Command line and search history</li> <li>Command line and search history</li>
<li>Window commands</li>
<li>Vim web help</li> <li>Vim web help</li>
</ul> </ul>
]]> ]]>
@@ -316,6 +324,18 @@
<action id="VimFileGetFileInfo" class="com.maddyhome.idea.vim.action.file.FileGetFileInfoAction" text="Get File Info"/> <action id="VimFileGetFileInfo" class="com.maddyhome.idea.vim.action.file.FileGetFileInfoAction" text="Get File Info"/>
<action id="VimFileGetLocationInfo" class="com.maddyhome.idea.vim.action.file.FileGetLocationInfoAction" text="Get Location Info"/> <action id="VimFileGetLocationInfo" class="com.maddyhome.idea.vim.action.file.FileGetLocationInfoAction" text="Get Location Info"/>
<!-- Window -->
<action id="VimWindowSplitVertical" class="com.maddyhome.idea.vim.action.window.VerticalSplitAction" text="Split window vertically"/>
<action id="VimWindowSplitHorizontal" class="com.maddyhome.idea.vim.action.window.HorizontalSplitAction" text="Split window horizontally"/>
<action id="VimWindowClose" class="com.maddyhome.idea.vim.action.window.CloseWindowAction" text="Close current window"/>
<action id="VimWindowOnly" class="com.maddyhome.idea.vim.action.window.WindowOnlyAction" text="Close all windows except current"/>
<action id="VimWindowNext" class="com.maddyhome.idea.vim.action.window.WindowNextAction" text="Select next window"/>
<action id="VimWindowPrev" class="com.maddyhome.idea.vim.action.window.WindowPrevAction" text="Select previous window"/>
<action id="VimWindowLeft" class="com.maddyhome.idea.vim.action.window.WindowLeftAction" text="Go to left window"/>
<action id="VimWindowRight" class="com.maddyhome.idea.vim.action.window.WindowRightAction" text="Go to right window"/>
<action id="VimWindowUp" class="com.maddyhome.idea.vim.action.window.WindowUpAction" text="Go to window up"/>
<action id="VimWindowDown" class="com.maddyhome.idea.vim.action.window.WindowDownAction" text="Go to window down"/>
<!-- Search --> <!-- Search -->
<action id="VimSearchFwdEntry" class="com.maddyhome.idea.vim.action.motion.search.SearchEntryFwdAction" text="Search Forward"/> <action id="VimSearchFwdEntry" class="com.maddyhome.idea.vim.action.motion.search.SearchEntryFwdAction" text="Search Forward"/>
<action id="VimSearchRevEntry" class="com.maddyhome.idea.vim.action.motion.search.SearchEntryRevAction" text="Search Backward"/> <action id="VimSearchRevEntry" class="com.maddyhome.idea.vim.action.motion.search.SearchEntryRevAction" text="Search Backward"/>

View File

@@ -657,9 +657,6 @@ public class RegisterActions {
parser.registerAction(MappingMode.N, "VimFileGetFileInfo", Command.Type.OTHER_READONLY, parser.registerAction(MappingMode.N, "VimFileGetFileInfo", Command.Type.OTHER_READONLY,
new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_MASK))); new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_MASK)));
// Window Actions
// TODO - CTRL-W commands: +, -, =, S, s, _, b, c, n, o, q, s, t, <up>, <down>
// Macro Actions // Macro Actions
parser.registerAction(MappingMode.N, "VimPlaybackLastRegister", Command.Type.OTHER_WRITABLE, parser.registerAction(MappingMode.N, "VimPlaybackLastRegister", Command.Type.OTHER_WRITABLE,
new Shortcut("@@")); new Shortcut("@@"));

View File

@@ -119,6 +119,7 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
@NotNull private final DigraphGroup digraph; @NotNull private final DigraphGroup digraph;
@NotNull private final HistoryGroup history; @NotNull private final HistoryGroup history;
@NotNull private final KeyGroup key; @NotNull private final KeyGroup key;
@NotNull private WindowGroup window;
public VimPlugin(final Application app) { public VimPlugin(final Application app) {
myApp = app; myApp = app;
@@ -135,6 +136,7 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
digraph = new DigraphGroup(); digraph = new DigraphGroup();
history = new HistoryGroup(); history = new HistoryGroup();
key = new KeyGroup(); key = new KeyGroup();
window = new WindowGroup();
LOG.debug("VimPlugin ctr"); LOG.debug("VimPlugin ctr");
} }
@@ -290,6 +292,11 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
return getInstance().key; return getInstance().key;
} }
@NotNull
public static WindowGroup getWindow() {
return getInstance().window;
}
@NotNull @NotNull
public static PluginId getPluginId() { public static PluginId getPluginId() {
return PluginId.getId(IDEAVIM_PLUGIN_ID); return PluginId.getId(IDEAVIM_PLUGIN_ID);

View File

@@ -0,0 +1,64 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author rasendubi
*/
public class CloseWindowAction extends VimCommandAction {
public CloseWindowAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().closeCurrentWindow(context);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>c");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,64 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author rasendubi
*/
public class HorizontalSplitAction extends VimCommandAction {
public HorizontalSplitAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().splitWindowHorizontal(context, "");
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>s", "<C-W>S", "<C-W><C-S>");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,64 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author rasendubi
*/
public class VerticalSplitAction extends VimCommandAction {
public VerticalSplitAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().splitWindowVertical(context, "");
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>v", "<C-W><C-V>");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,65 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author vlan
*/
public class WindowDownAction extends VimCommandAction {
public WindowDownAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().selectWindowInRow(context, cmd.getCount(), true);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>j");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,65 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author vlan
*/
public class WindowLeftAction extends VimCommandAction {
public WindowLeftAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().selectWindowInRow(context, cmd.getCount() * -1, false);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>h");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,68 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author rasendubi
*/
public class WindowNextAction extends VimCommandAction {
public WindowNextAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
if (cmd.getRawCount() == 0) {
VimPlugin.getWindow().selectNextWindow(context);
} else {
VimPlugin.getWindow().selectWindow(context, cmd.getCount());
}
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>w", "<C-W><C-W>");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,64 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author rasendubi
*/
public class WindowOnlyAction extends VimCommandAction {
public WindowOnlyAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().closeAllExceptCurrent(context);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>o", "<C-W><C-O>");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,65 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
public class WindowPrevAction extends VimCommandAction {
public WindowPrevAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
if (cmd.getRawCount() == 0) {
VimPlugin.getWindow().selectPreviousWindow(context);
} else {
VimPlugin.getWindow().selectWindow(context, cmd.getCount());
}
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>W");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,65 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author vlan
*/
public class WindowRightAction extends VimCommandAction {
public WindowRightAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().selectWindowInRow(context, cmd.getCount(), false);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>l");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -0,0 +1,65 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.action.window;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.action.VimCommandAction;
import com.maddyhome.idea.vim.command.Command;
import com.maddyhome.idea.vim.command.MappingMode;
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.List;
import java.util.Set;
/**
* @author vlan
*/
public class WindowUpAction extends VimCommandAction {
public WindowUpAction() {
super(new EditorActionHandlerBase() {
@Override
protected boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull Command cmd) {
VimPlugin.getWindow().selectWindowInRow(context, cmd.getCount() * -1, true);
return true;
}
});
}
@NotNull
@Override
public Set<MappingMode> getMappingModes() {
return MappingMode.N;
}
@NotNull
@Override
public Set<List<KeyStroke>> getKeyStrokesSet() {
return parseKeysSet("<C-W>k");
}
@NotNull
@Override
public Command.Type getType() {
return Command.Type.OTHER_READONLY;
}
}

View File

@@ -110,6 +110,7 @@ public class CommandParser {
new ShiftRightHandler(); new ShiftRightHandler();
new SourceHandler(); new SourceHandler();
new SortHandler(); new SortHandler();
new SplitHandler();
new SubstituteHandler(); new SubstituteHandler();
new UndoHandler(); new UndoHandler();
new WriteAllHandler(); new WriteAllHandler();

View File

@@ -0,0 +1,49 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.ex.handler;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.VimPlugin;
import com.maddyhome.idea.vim.ex.CommandHandler;
import com.maddyhome.idea.vim.ex.CommandName;
import com.maddyhome.idea.vim.ex.ExCommand;
import org.jetbrains.annotations.NotNull;
/**
*
*/
public class SplitHandler extends CommandHandler {
public SplitHandler() {
super(new CommandName[]{
new CommandName("vs", "plit"),
new CommandName("sp", "lit")
}, RANGE_FORBIDDEN | ARGUMENT_OPTIONAL | DONT_REOPEN);
}
public boolean execute(@NotNull Editor editor, @NotNull DataContext context, @NotNull ExCommand cmd) {
if (cmd.getCommand().startsWith("v")) {
VimPlugin.getWindow().splitWindowVertical(context, cmd.getArgument());
} else {
VimPlugin.getWindow().splitWindowHorizontal(context, cmd.getArgument());
}
return true;
}
}

View File

@@ -323,7 +323,7 @@ public class ChangeGroup {
return false; return false;
} }
final TextRange range = new TextRange(deleteTo, editor.getCaretModel().getOffset()); final TextRange range = new TextRange(deleteTo, editor.getCaretModel().getOffset());
deleteRange(editor, range, SelectionType.CHARACTER_WISE, false); deleteRange(editor, range, SelectionType.CHARACTER_WISE, true);
return true; return true;
} }

View File

@@ -26,6 +26,9 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.EditorTabbedContainer;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
@@ -60,36 +63,7 @@ public class FileGroup {
} }
Project proj = PlatformDataKeys.PROJECT.getData(context); // API change - don't merge Project proj = PlatformDataKeys.PROJECT.getData(context); // API change - don't merge
VirtualFile found = null; VirtualFile found = findFile(filename, proj);
if (filename.length() > 2 && filename.charAt(0) == '~' && filename.charAt(1) == File.separatorChar) {
String homefile = filename.substring(2);
String dir = System.getProperty("user.home");
if (logger.isDebugEnabled()) {
logger.debug("home dir file");
logger.debug("looking for " + homefile + " in " + dir);
}
found = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(dir, homefile));
}
else {
if (proj == null) {
return false;
}
ProjectRootManager prm = ProjectRootManager.getInstance(proj);
VirtualFile[] roots = prm.getContentRoots();
for (int i = 0; i < roots.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("root[" + i + "] = " + roots[i].getPath());
}
found = findFile(roots[i], filename);
if (found != null) {
break;
}
}
if (found == null) {
found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename));
}
}
if (found != null) { if (found != null) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
@@ -117,6 +91,42 @@ public class FileGroup {
} }
} }
@Nullable
public VirtualFile findFile(@NotNull String filename, @NotNull Project proj) {
VirtualFile found = null;
if (filename.length() > 2 && filename.charAt(0) == '~' && filename.charAt(1) == File.separatorChar) {
String homefile = filename.substring(2);
String dir = System.getProperty("user.home");
if (logger.isDebugEnabled()) {
logger.debug("home dir file");
logger.debug("looking for " + homefile + " in " + dir);
}
found = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(dir, homefile));
}
else {
if (proj == null) {
return null;
}
ProjectRootManager prm = ProjectRootManager.getInstance(proj);
VirtualFile[] roots = prm.getContentRoots();
for (int i = 0; i < roots.length; i++) {
if (logger.isDebugEnabled()) {
logger.debug("root[" + i + "] = " + roots[i].getPath());
}
found = findFile(roots[i], filename);
if (found != null) {
break;
}
}
if (found == null) {
found = LocalFileSystem.getInstance().findFileByIoFile(new File(filename));
}
}
return found;
}
@Nullable @Nullable
private VirtualFile findFile(@NotNull VirtualFile root, @NotNull String filename) { private VirtualFile findFile(@NotNull VirtualFile root, @NotNull String filename) {
VirtualFile res = root.findFileByRelativePath(filename); VirtualFile res = root.findFileByRelativePath(filename);
@@ -146,11 +156,26 @@ public class FileGroup {
* @param context The data context * @param context The data context
*/ */
public void closeFile(@NotNull Editor editor, @NotNull DataContext context) { public void closeFile(@NotNull Editor editor, @NotNull DataContext context) {
Project proj = PlatformDataKeys.PROJECT.getData(context); final Project project = PlatformDataKeys.PROJECT.getData(context);
FileEditorManager fem = FileEditorManager.getInstance(proj); // API change - don't merge if (project != null) {
VirtualFile vf = EditorData.getVirtualFile(editor); final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
if (vf != null) { final EditorWindow window = fileEditorManager.getCurrentWindow();
fem.closeFile(vf); final EditorTabbedContainer tabbedPane = window.getTabbedPane();
if (tabbedPane != null) {
if (tabbedPane.getTabCount() > 1) {
final int index = tabbedPane.getSelectedIndex();
tabbedPane.removeTabAt(index, index + 1);
}
else {
tabbedPane.close();
}
}
else {
VirtualFile virtualFile = EditorData.getVirtualFile(editor);
if (virtualFile != null) {
fileEditorManager.closeFile(virtualFile);
}
}
} }
} }

View File

@@ -1187,13 +1187,18 @@ public class MotionGroup {
public static void moveCaret(@NotNull Editor editor, int offset) { public static void moveCaret(@NotNull Editor editor, int offset) {
if (offset >= 0 && offset <= editor.getDocument().getTextLength()) { if (offset >= 0 && offset <= editor.getDocument().getTextLength()) {
final boolean keepVisual = keepVisual(editor);
if (editor.getCaretModel().getOffset() != offset) { if (editor.getCaretModel().getOffset() != offset) {
if (!keepVisual) {
// XXX: Hack for preventing the merge multiple carets that results in loosing the primary caret for |v_d|
editor.getCaretModel().removeSecondaryCarets();
}
editor.getCaretModel().moveToOffset(offset); editor.getCaretModel().moveToOffset(offset);
EditorData.setLastColumn(editor, editor.getCaretModel().getVisualPosition().column); EditorData.setLastColumn(editor, editor.getCaretModel().getVisualPosition().column);
scrollCaretIntoView(editor); scrollCaretIntoView(editor);
} }
if (keepVisual(editor)) { if (keepVisual) {
VimPlugin.getMotion().updateSelection(editor, offset); VimPlugin.getMotion().updateSelection(editor, offset);
} }
else { else {
@@ -1518,6 +1523,7 @@ public class MotionGroup {
} }
if (removeSelection) { if (removeSelection) {
editor.getSelectionModel().removeSelection(); editor.getSelectionModel().removeSelection();
editor.getCaretModel().removeSecondaryCarets();
} }
CommandState.getInstance(editor).setSubMode(CommandState.SubMode.NONE); CommandState.getInstance(editor).setSubMode(CommandState.SubMode.NONE);
} }
@@ -1566,29 +1572,21 @@ public class MotionGroup {
@NotNull @NotNull
public TextRange getVisualRange(@NotNull Editor editor) { public TextRange getVisualRange(@NotNull Editor editor) {
if (editor.getSelectionModel().hasBlockSelection()) { final TextRange res = new TextRange(editor.getSelectionModel().getBlockSelectionStarts(),
TextRange res = new TextRange(editor.getSelectionModel().getBlockSelectionStarts(), editor.getSelectionModel().getBlockSelectionEnds());
editor.getSelectionModel().getBlockSelectionEnds()); // If the last left/right motion was the $ command, simulate each line being selected to end-of-line
// If the last left/right motion was the $ command, simulate each line being selected to end-of-line final CommandState.SubMode subMode = CommandState.getInstance(editor).getSubMode();
if (EditorData.getLastColumn(editor) >= MotionGroup.LAST_COLUMN) { if (subMode == CommandState.SubMode.VISUAL_BLOCK && EditorData.getLastColumn(editor) >= MotionGroup.LAST_COLUMN) {
int[] starts = res.getStartOffsets(); final int[] starts = res.getStartOffsets();
int[] ends = res.getEndOffsets(); final int[] ends = res.getEndOffsets();
for (int i = 0; i < starts.length; i++) {
for (int i = 0; i < starts.length; i++) { if (ends[i] > starts[i]) {
if (ends[i] > starts[i]) { ends[i] = EditorHelper.getLineEndForOffset(editor, starts[i]);
ends[i] = EditorHelper.getLineEndForOffset(editor, starts[i]);
}
} }
res = new TextRange(starts, ends);
} }
return new TextRange(starts, ends);
return res;
}
else {
return new TextRange(editor.getSelectionModel().getSelectionStart(),
editor.getSelectionModel().getSelectionEnd());
} }
return res;
} }
@NotNull @NotNull
@@ -1601,31 +1599,29 @@ public class MotionGroup {
visualOffset = offset; visualOffset = offset;
int start = visualStart; int start = visualStart;
int end = visualEnd; int end = visualEnd;
if (start > end) { final CommandState.SubMode subMode = CommandState.getInstance(editor).getSubMode();
int t = start;
start = end;
end = t;
}
if (CommandState.getInstance(editor).getSubMode() == CommandState.SubMode.VISUAL_CHARACTER) { if (subMode == CommandState.SubMode.VISUAL_CHARACTER) {
BoundStringOption opt = (BoundStringOption)Options.getInstance().getOption("selection"); if (start > end) {
int lineEnd = EditorHelper.getLineEndForOffset(editor, end); int t = start;
int adj = 1; start = end;
if (opt.getValue().equals("exclusive") || end == lineEnd) { end = t;
adj = 0;
} }
final BoundStringOption opt = (BoundStringOption)Options.getInstance().getOption("selection");
int lineEnd = EditorHelper.getLineEndForOffset(editor, end);
final int adj = opt.getValue().equals("exclusive") || end == lineEnd ? 0 : 1;
end = Math.min(EditorHelper.getFileSize(editor), end + adj); end = Math.min(EditorHelper.getFileSize(editor), end + adj);
editor.getSelectionModel().setSelection(start, end); editor.getSelectionModel().setSelection(start, end);
} }
else if (CommandState.getInstance(editor).getSubMode() == CommandState.SubMode.VISUAL_LINE) { else if (subMode == CommandState.SubMode.VISUAL_LINE) {
start = EditorHelper.getLineStartForOffset(editor, start); start = EditorHelper.getLineStartForOffset(editor, start);
end = EditorHelper.getLineEndForOffset(editor, end); end = EditorHelper.getLineEndForOffset(editor, end);
editor.getSelectionModel().setSelection(start, end); editor.getSelectionModel().setSelection(start, end);
} }
else { else if (subMode == CommandState.SubMode.VISUAL_BLOCK) {
LogicalPosition lineStart = editor.offsetToLogicalPosition(start); final LogicalPosition lineStart = editor.offsetToLogicalPosition(start);
LogicalPosition lend = editor.offsetToLogicalPosition(end); final LogicalPosition lineEnd = editor.offsetToLogicalPosition(end);
editor.getSelectionModel().setBlockSelection(lineStart, lend); editor.getSelectionModel().setBlockSelection(lineStart, lineEnd);
} }
VimPlugin.getMark().setVisualSelectionMarks(editor, new TextRange(start, end)); VimPlugin.getMark().setVisualSelectionMarks(editor, new TextRange(start, end));

View File

@@ -0,0 +1,178 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2014 The IdeaVim authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.maddyhome.idea.vim.group;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.maddyhome.idea.vim.VimPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
public class WindowGroup {
public WindowGroup() {
}
public void closeCurrentWindow(@NotNull DataContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow window = fileEditorManager.getSplitters().getCurrentWindow();
if (window != null) {
window.closeAllExcept(null);
}
}
public void closeAllExceptCurrent(@NotNull DataContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow current = fileEditorManager.getCurrentWindow();
for (final EditorWindow window : fileEditorManager.getWindows()) {
if (window != current) {
window.closeAllExcept(null);
}
}
}
public void selectNextWindow(@NotNull DataContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow current = fileEditorManager.getCurrentWindow();
if (current != null) {
fileEditorManager.getNextWindow(current).setAsCurrentWindow(true);
}
}
public void selectPreviousWindow(@NotNull DataContext context) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow current = fileEditorManager.getCurrentWindow();
if (current != null) {
fileEditorManager.getPrevWindow(current).setAsCurrentWindow(true);
}
}
public void selectWindow(@NotNull DataContext context, int index) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow[] windows = fileEditorManager.getWindows();
if (index - 1 < windows.length) {
windows[index - 1].setAsCurrentWindow(true);
}
}
public void splitWindowHorizontal(@NotNull DataContext context, @NotNull String filename) {
splitWindow(SwingConstants.HORIZONTAL, context, filename);
}
public void splitWindowVertical(@NotNull DataContext context, @NotNull String filename) {
splitWindow(SwingConstants.VERTICAL, context, filename);
}
public void selectWindowInRow(@NotNull DataContext context, int relativePosition, boolean vertical) {
final FileEditorManagerEx fileEditorManager = getFileEditorManager(context);
final EditorWindow currentWindow = fileEditorManager.getCurrentWindow();
if (currentWindow != null) {
final EditorWindow[] windows = fileEditorManager.getWindows();
final List<EditorWindow> row = findWindowsInRow(currentWindow, Arrays.asList(windows), vertical);
selectWindow(currentWindow, row, relativePosition);
}
}
private void selectWindow(@NotNull EditorWindow currentWindow, @NotNull List<EditorWindow> windows,
int relativePosition) {
final int pos = windows.indexOf(currentWindow);
final int selected = pos + relativePosition;
final int normalized = Math.max(0, Math.min(selected, windows.size() - 1));
windows.get(normalized).setAsCurrentWindow(true);
}
@NotNull
private static List<EditorWindow> findWindowsInRow(@NotNull EditorWindow anchor,
@NotNull List<EditorWindow> windows, final boolean vertical) {
final Rectangle anchorRect = getEditorWindowRectangle(anchor);
if (anchorRect != null) {
final List<EditorWindow> result = new ArrayList<EditorWindow>();
final double coord = vertical ? anchorRect.getX() : anchorRect.getY();
for (EditorWindow window : windows) {
final Rectangle rect = getEditorWindowRectangle(window);
if (rect != null) {
final double min = vertical ? rect.getX() : rect.getY();
final double max = min + (vertical ? rect.getWidth() : rect.getHeight());
if (coord >= min && coord <= max) {
result.add(window);
}
}
}
Collections.sort(result, new Comparator<EditorWindow>() {
@Override
public int compare(EditorWindow window1, EditorWindow window2) {
final Rectangle rect1 = getEditorWindowRectangle(window1);
final Rectangle rect2 = getEditorWindowRectangle(window2);
if (rect1 != null && rect2 != null) {
final double diff = vertical ? (rect1.getY() - rect2.getY()) : (rect1.getX() - rect2.getX());
return diff < 0 ? -1 : diff > 0 ? 1 : 0;
}
return 0;
}
});
return result;
}
return Collections.singletonList(anchor);
}
@NotNull
private static FileEditorManagerEx getFileEditorManager(@NotNull DataContext context) {
final Project project = PlatformDataKeys.PROJECT.getData(context);
return FileEditorManagerEx.getInstanceEx(project);
}
private void splitWindow(int orientation, @NotNull DataContext context, @NotNull String filename) {
final Project project = PlatformDataKeys.PROJECT.getData(context);
final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
VirtualFile virtualFile = null;
if (filename.length() > 0 && project != null) {
virtualFile = VimPlugin.getFile().findFile(filename, project);
if (virtualFile == null) {
VimPlugin.showMessage("Could not find file: " + filename);
return;
}
}
final EditorWindow editorWindow = fileEditorManager.getSplitters().getCurrentWindow();
if (editorWindow != null) {
editorWindow.split(orientation, true, virtualFile, true);
}
}
@Nullable
private static Rectangle getEditorWindowRectangle(@NotNull EditorWindow window) {
final EditorWithProviderComposite editor = window.getSelectedEditor();
if (editor != null) {
final Point point = editor.getComponent().getLocationOnScreen();
final Dimension dimension = editor.getComponent().getSize();
return new Rectangle(point, dimension);
}
return null;
}
}

View File

@@ -524,7 +524,7 @@ public class SearchHelper {
private static int findNextWordOne(@NotNull CharSequence chars, int pos, int size, int step, boolean bigWord, boolean spaceWords) { private static int findNextWordOne(@NotNull CharSequence chars, int pos, int size, int step, boolean bigWord, boolean spaceWords) {
boolean found = false; boolean found = false;
pos = pos < size ? pos : size - 1; pos = pos < size ? pos : Math.min(size, chars.length() - 1);
// For back searches, skip any current whitespace so we start at the end of a word // For back searches, skip any current whitespace so we start at the end of a word
if (step < 0 && pos > 0) { if (step < 0 && pos > 0) {
if (CharacterHelper.charType(chars.charAt(pos - 1), bigWord) == CharacterHelper.CharacterType.WHITESPACE && !spaceWords) { if (CharacterHelper.charType(chars.charAt(pos - 1), bigWord) == CharacterHelper.CharacterType.WHITESPACE && !spaceWords) {

View File

@@ -42,6 +42,53 @@
* |gv| {@link com.maddyhome.idea.vim.action.motion.visual.VisualSelectPreviousAction} * |gv| {@link com.maddyhome.idea.vim.action.motion.visual.VisualSelectPreviousAction}
* *
* *
* 2.2. Window commands
*
* tag action
* ---------------------------------------------------------------------------------------------------------------------
*
* |CTRL-W_+| TODO
* |CTRL-W_-| TODO
* |CTRL-W_<| TODO
* |CTRL-W_=| TODO
* |CTRL-W_>| TODO
* |CTRL-W_H| TODO
* |CTRL-W_J| TODO
* |CTRL-W_K| TODO
* |CTRL-W_L| TODO
* |CTRL-W_R| TODO
* |CTRL-W_W| {@link com.maddyhome.idea.vim.action.window.WindowPrevAction}
* |CTRL-W_]| TODO
* |CTRL-W_^| TODO
* |CTRL-W__| TODO
* |CTRL-W_b| TODO
* |CTRL-W_c| {@link com.maddyhome.idea.vim.action.window.CloseWindowAction}
* |CTRL-W_h| {@link com.maddyhome.idea.vim.action.window.WindowLeftAction}
* |CTRL-W_<Left>| ...
* |CTRL-W_j| {@link com.maddyhome.idea.vim.action.window.WindowDownAction}
* |CTRL-W_<Down>| ...
* |CTRL-W_k| {@link com.maddyhome.idea.vim.action.window.WindowUpAction}
* |CTRL-W_<Up>| ...
* |CTRL-W_l| {@link com.maddyhome.idea.vim.action.window.WindowRightAction}
* |CTRL-W_<Right>| ...
* |CTRL-W_n| TODO
* |CTRL-W_o| {@link com.maddyhome.idea.vim.action.window.WindowOnlyAction}
* |CTRL-W_CTRL-O| ...
* |CTRL-W_p| TODO
* |CTRL-W_q| TODO
* |CTRL-W_r| TODO
* |CTRL-W_s| {@link com.maddyhome.idea.vim.action.window.HorizontalSplitAction}
* |CTRL-W_S| ...
* |CTRL-W_CTRL-S| ...
* |CTRL-W_t| TODO
* |CTRL-W_v| {@link com.maddyhome.idea.vim.action.window.VerticalSplitAction}
* |CTRL-W_CTRL-V| ...
* |CTRL-W_w| {@link com.maddyhome.idea.vim.action.window.WindowNextAction}
* |CTRL-W_CTRL-W| ...
* |CTRL-W_z| TODO
* |CTRL-W_bar| TODO
*
*
* 3. Visual mode * 3. Visual mode
* *
* tag action * tag action

View File

@@ -1,6 +1,7 @@
package org.jetbrains.plugins.ideavim; package org.jetbrains.plugins.ideavim;
import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
@@ -22,6 +23,7 @@ import com.maddyhome.idea.vim.helper.StringHelper;
import com.maddyhome.idea.vim.option.Options; import com.maddyhome.idea.vim.option.Options;
import com.maddyhome.idea.vim.ui.ExEntryPanel; import com.maddyhome.idea.vim.ui.ExEntryPanel;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*; import javax.swing.*;
import java.util.ArrayList; import java.util.ArrayList;
@@ -113,9 +115,12 @@ public abstract class VimTestCase extends UsefulTestCase {
return keys; return keys;
} }
public void assertOffset(int expectedOffset) { public void assertOffset(int... expectedOffsets) {
final int offset = myFixture.getEditor().getCaretModel().getOffset(); final List<Caret> carets = myFixture.getEditor().getCaretModel().getAllCarets();
assertEquals(expectedOffset, offset); assertEquals("Wrong amount of carets", expectedOffsets.length, carets.size());
for (int i = 0; i < expectedOffsets.length; i++) {
assertEquals(expectedOffsets[i], carets.get(i).getOffset());
}
} }
public void assertMode(@NotNull CommandState.Mode expectedMode) { public void assertMode(@NotNull CommandState.Mode expectedMode) {
@@ -123,7 +128,7 @@ public abstract class VimTestCase extends UsefulTestCase {
assertEquals(expectedMode, mode); assertEquals(expectedMode, mode);
} }
public void assertSelection(@NotNull String expected) { public void assertSelection(@Nullable String expected) {
final String selected = myFixture.getEditor().getSelectionModel().getSelectedText(); final String selected = myFixture.getEditor().getSelectionModel().getSelectedText();
assertEquals(expected, selected); assertEquals(expected, selected);
} }

View File

@@ -54,9 +54,7 @@ public class ChangeActionTest extends VimTestCase {
// VIM-321 |d| |count| // VIM-321 |d| |count|
public void testDeleteEmptyRange() { public void testDeleteEmptyRange() {
doTest(parseKeys("d0"), doTest(parseKeys("d0"), "<caret>hello\n", "hello\n");
"<caret>hello\n",
"hello\n");
} }
// VIM-112 |i| |i_CTRL-W| // VIM-112 |i| |i_CTRL-W|
@@ -64,8 +62,7 @@ public class ChangeActionTest extends VimTestCase {
typeTextInFile(parseKeys("i", "one two three", "<C-W>"), typeTextInFile(parseKeys("i", "one two three", "<C-W>"),
"hello\n" + "hello\n" +
"<caret>\n"); "<caret>\n");
myFixture.checkResult("hello\n" + myFixture.checkResult("hello\n" + "one two \n");
"one two \n");
} }
// VIM-157 |~| // VIM-157 |~|
@@ -84,13 +81,11 @@ public class ChangeActionTest extends VimTestCase {
// VIM-85 |i| |gi| |gg| // VIM-85 |i| |gi| |gg|
public void testInsertAtPreviousAction() { public void testInsertAtPreviousAction() {
doTest(parseKeys("i", "hello", "<Esc>", "gg", "gi", " world! "), doTest(parseKeys("i", "hello", "<Esc>", "gg", "gi", " world! "), "one\n" +
"one\n" + "two <caret>three\n" +
"two <caret>three\n" + "four\n", "one\n" +
"four\n", "two hello world! three\n" +
"one\n" + "four\n");
"two hello world! three\n" +
"four\n");
} }
// VIM-312 |d| |w| // VIM-312 |d| |w|
@@ -114,13 +109,11 @@ public class ChangeActionTest extends VimTestCase {
// VIM-105 |d| |w| // VIM-105 |d| |w|
public void testDeleteLastWordBeforeEOLs() { public void testDeleteLastWordBeforeEOLs() {
doTest(parseKeys("dw"), doTest(parseKeys("dw"), "one <caret>two\n" +
"one <caret>two\n" + "\n" +
"\n" + "three\n", "one \n" +
"three\n", "\n" +
"one \n" + "three\n");
"\n" +
"three\n");
} }
// VIM-105 |d| |w| // VIM-105 |d| |w|
@@ -150,9 +143,7 @@ public class ChangeActionTest extends VimTestCase {
// VIM-300 |c| |w| // VIM-300 |c| |w|
public void testChangeWordTwoWordsWithoutWhitespace() { public void testChangeWordTwoWordsWithoutWhitespace() {
doTest(parseKeys("cw"), doTest(parseKeys("cw"), "<caret>$value\n", "value\n");
"<caret>$value\n",
"value\n");
} }
// VIM-296 |cc| // VIM-296 |cc|
@@ -176,11 +167,7 @@ public class ChangeActionTest extends VimTestCase {
// |d| |v_aw| // |d| |v_aw|
public void testDeleteLastWordAfterPunctuation() { public void testDeleteLastWordAfterPunctuation() {
doTest(parseKeys("daw"), doTest(parseKeys("daw"), "foo(<caret>bar\n" + "baz\n", "foo(\n" + "baz\n");
"foo(<caret>bar\n" +
"baz\n",
"foo(\n" +
"baz\n");
} }
// VIM-244 |d| |l| // VIM-244 |d| |l|
@@ -244,6 +231,51 @@ public class ChangeActionTest extends VimTestCase {
"fooar\n"); "fooar\n");
} }
// VIM-569 |a| |i_CTRL-W|
public void testDeletePreviousWordDotEOL() {
doTest(parseKeys("a", "<C-W>"),
"this is a sentence<caret>.\n",
"this is a sentence<caret>\n");
}
// VIM-569 |a| |i_CTRL-W|
public void testDeletePreviousWordLastAfterWhitespace() {
doTest(parseKeys("A", "<C-W>"),
"<caret>this is a sentence\n",
"this is a <caret>\n");
}
// VIM-513 |A| |i_CTRL-W|
public void testDeletePreviousWordEOL() {
doTest(parseKeys("A", "<C-W>"),
"<caret>$variable\n",
"$<caret>\n");
}
// VIM-632 |CTRL-V| |v_b_I|
public void testChangeVisualBlock() {
doTest(parseKeys("<C-V>", "j", "I", "quux ", "<Esc>"),
"foo bar\n" +
"<caret>baz quux\n" +
"spam eggs\n",
"foo bar\n" +
"<caret>quux baz quux\n" +
"quux spam eggs\n");
}
// VIM-632 |CTRL-V| |v_d|
public void testDeleteVisualBlock() {
doTest(parseKeys("<C-V>", "jjl", "d"),
"<caret>foo\n" +
"bar\n" +
"baz\n" +
"quux\n",
"<caret>oo\n" +
"ar\n" +
"az\n" +
"quux\n");
}
private void doTest(final List<KeyStroke> keys, String before, String after) { private void doTest(final List<KeyStroke> keys, String before, String after) {
myFixture.configureByText("a.java", before); myFixture.configureByText("a.java", before);
final Editor editor = myFixture.getEditor(); final Editor editor = myFixture.getEditor();

View File

@@ -1,6 +1,7 @@
package org.jetbrains.plugins.ideavim.action; package org.jetbrains.plugins.ideavim.action;
import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Editor;
import com.maddyhome.idea.vim.command.CommandState;
import org.jetbrains.plugins.ideavim.VimTestCase; import org.jetbrains.plugins.ideavim.VimTestCase;
import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys; import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
@@ -82,7 +83,7 @@ public class CopyActionTest extends VimTestCase {
assertEquals(0, editor.getCaretModel().getOffset()); assertEquals(0, editor.getCaretModel().getOffset());
} }
// |v_y| // VIM-632 |CTRL-V| |v_y| |p|
public void testYankVisualBlock() { public void testYankVisualBlock() {
typeTextInFile(parseKeys("<C-V>", "jl", "yl", "p"), typeTextInFile(parseKeys("<C-V>", "jl", "yl", "p"),
"<caret>* one\n" + "<caret>* one\n" +
@@ -98,5 +99,17 @@ public class CopyActionTest extends VimTestCase {
myFixture.checkResult("* *one\n" + myFixture.checkResult("* *one\n" +
"* *two\n"); "* *two\n");
assertSelection(null);
assertOffset(2);
}
// VIM-632 |CTRL-V| |v_y|
public void testStateAfterYankVisualBlock() {
typeTextInFile(parseKeys("<C-V>", "jl", "y"),
"<caret>foo\n" +
"bar\n");
assertOffset(0);
assertMode(CommandState.Mode.COMMAND);
assertSelection(null);
} }
} }