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

Compare commits

...

31 Commits
0.35 ... 0.37

Author SHA1 Message Date
Andrey Vlasovskikh
26b49b1a0c Made the description shorter 2014-10-15 15:22:40 +04:00
Andrey Vlasovskikh
ef32648ddc Bumped version to 0.37 2014-10-15 15:17:42 +04:00
Andrey Vlasovskikh
c873524cb1 VIM-784 Fixed visual line selection where start > end of the selection range
It was a regression introduced by the fix of VIM-632.
2014-10-15 15:10:22 +04:00
Andrey Vlasovskikh
2d11561041 Added Andrew Brookins to the list of contributors 2014-10-14 15:28:23 +04:00
Andrey Vlasovskikh
f7643b6bb3 Updated changelist 2014-10-14 15:28:07 +04:00
Andrey Vlasovskikh
d3afd83e8e Merge branch 'VIM-407' 2014-10-14 15:25:43 +04:00
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
Andrew Brookins
19365effa9 VIM-407 Add tests. Only skip the ending line if it is empty.
Conflicts:
	src/com/maddyhome/idea/vim/group/ChangeGroup.java
	test/org/jetbrains/plugins/ideavim/action/ShiftRightLinesActionTest.java
2014-05-22 22:04:14 -07:00
30 changed files with 1266 additions and 147 deletions

View File

@@ -24,6 +24,10 @@ Contributors:
* [John Lindquist](mailto:johnlindquist@gmail.com)
* [Ira Klotzko](mailto:iklotzko@ltech.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)
* [Andrew Brookins](mailto:a.m.brookins@gmail.com)
If you are a contributor and your name is not listed here, feel free to
contact the maintainer.

View File

@@ -4,6 +4,39 @@ The Changelog
History of changes in IdeaVim for the IntelliJ platform.
0.37, 2014-10-15
----------------
A bugfix release.
Bug fixes:
* VIM-784 Fixed visual line selection where the start of the selection range
was greater than its end
* VIM-407 Fixed `>>` to work if a line contains only one character
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
----------------

View File

@@ -17,7 +17,7 @@ IdeaVim
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,
AppCode and Android Studio.
AppCode, CLion and Android Studio.
Resources:
@@ -63,18 +63,17 @@ Supported:
* Macros
* Digraphs
* Command line and search history
* Window commands
* Vim web help
Not supported (yet):
* Window commands
* Jump lists
* Various less used commands
See also:
* [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)
@@ -135,7 +134,7 @@ in the issue tracker.
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".
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
platform-version:120.0
idea.download.url=http://download.jetbrains.com/idea/ideaIU-13.zip
version-id:0.37
platform-version:135.0
idea.download.url=http://download.jetbrains.com/idea/ideaIU-13.1.zip
build.number=dev

View File

@@ -3,6 +3,17 @@
<id>IdeaVIM</id>
<change-notes>
<![CDATA[
<p>0.37:</p>
<ul>
<li>Various bug fixes</li>
</ul>
<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>
<ul>
<li><code>~/.vimrc</code> is no longer read by default, use <code>~/.ideavimrc</code> instead</li>
@@ -24,42 +35,15 @@
<ul>
<li>Fixed API compatibility with IntelliJ platform builds 132.1052+</li>
</ul>
<p>0.31:</p>
<ul>
<li>Various bug fixes</li>
</ul>
<p>0.30:</p>
<ul>
<li>Support for a separate <code>.ideavimrc</code> config file</li>
<li>Fixed long-standing issues with merged undo/redo commands and <code>&lt;Esc&gt;</code> during completion</li>
<li>Various bug fixes</li>
</ul>
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
]]>
</change-notes>
<description>
<![CDATA[
<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>Supported functionality:</p>
<ul>
<li>Motion keys</li>
<li>Deletion/Changing</li>
<li>Insert mode commands</li>
<li>Marks</li>
<li>Registers</li>
<li>Undo/redo</li>
<li>Visual mode commands</li>
<li>Some Ex commands</li>
<li>Some :set options</li>
<li>Full Vim regexps for search and search/replace</li>
<li>Key mappings</li>
<li>Configuration via ~/.ideavimrc</li>
<li>Macros</li>
<li>Digraphs</li>
<li>Command line and search history</li>
<li>Vim web help</li>
</ul>
<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>IdeaVim supports many Vim features including normal/insert/visual modes, motion keys, deletion/changing, marks, registers, some Ex commands, Vim regexps, configuration via ~/.ideavimrc, macros, window commands, etc.</p>
<p>See the <a href="https://github.com/JetBrains/ideavim">JetBrains/ideavim</a> on GitHub for more details.</p>
]]>
</description>
<version>@VERSION@</version>
@@ -316,6 +300,18 @@
<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"/>
<!-- 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 -->
<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"/>

View File

@@ -657,9 +657,6 @@ public class RegisterActions {
parser.registerAction(MappingMode.N, "VimFileGetFileInfo", Command.Type.OTHER_READONLY,
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
parser.registerAction(MappingMode.N, "VimPlaybackLastRegister", Command.Type.OTHER_WRITABLE,
new Shortcut("@@"));

View File

@@ -119,6 +119,7 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
@NotNull private final DigraphGroup digraph;
@NotNull private final HistoryGroup history;
@NotNull private final KeyGroup key;
@NotNull private WindowGroup window;
public VimPlugin(final Application app) {
myApp = app;
@@ -135,6 +136,7 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
digraph = new DigraphGroup();
history = new HistoryGroup();
key = new KeyGroup();
window = new WindowGroup();
LOG.debug("VimPlugin ctr");
}
@@ -290,6 +292,11 @@ public class VimPlugin implements ApplicationComponent, PersistentStateComponent
return getInstance().key;
}
@NotNull
public static WindowGroup getWindow() {
return getInstance().window;
}
@NotNull
public static PluginId getPluginId() {
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 SourceHandler();
new SortHandler();
new SplitHandler();
new SubstituteHandler();
new UndoHandler();
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;
}
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;
}
@@ -1338,7 +1338,9 @@ public class ChangeGroup {
int sline = editor.offsetToLogicalPosition(range.getStartOffset()).line;
int eline = editor.offsetToLogicalPosition(range.getEndOffset()).line;
int eoff = EditorHelper.getLineStartForOffset(editor, range.getEndOffset());
if (eoff == range.getEndOffset()) {
boolean elineIsEmpty = EditorHelper.getLineLength(editor, eline) == 0;
// Skip an empty ending line
if (eoff == range.getEndOffset() && elineIsEmpty) {
eline--;
}

View File

@@ -26,6 +26,9 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
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.FileTypeManager;
import com.intellij.openapi.project.Project;
@@ -60,36 +63,7 @@ public class FileGroup {
}
Project proj = PlatformDataKeys.PROJECT.getData(context); // API change - don't merge
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 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));
}
}
VirtualFile found = findFile(filename, proj);
if (found != null) {
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
private VirtualFile findFile(@NotNull VirtualFile root, @NotNull String filename) {
VirtualFile res = root.findFileByRelativePath(filename);
@@ -146,11 +156,26 @@ public class FileGroup {
* @param context The data context
*/
public void closeFile(@NotNull Editor editor, @NotNull DataContext context) {
Project proj = PlatformDataKeys.PROJECT.getData(context);
FileEditorManager fem = FileEditorManager.getInstance(proj); // API change - don't merge
VirtualFile vf = EditorData.getVirtualFile(editor);
if (vf != null) {
fem.closeFile(vf);
final Project project = PlatformDataKeys.PROJECT.getData(context);
if (project != null) {
final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
final EditorWindow window = fileEditorManager.getCurrentWindow();
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) {
if (offset >= 0 && offset <= editor.getDocument().getTextLength()) {
final boolean keepVisual = keepVisual(editor);
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);
EditorData.setLastColumn(editor, editor.getCaretModel().getVisualPosition().column);
scrollCaretIntoView(editor);
}
if (keepVisual(editor)) {
if (keepVisual) {
VimPlugin.getMotion().updateSelection(editor, offset);
}
else {
@@ -1518,6 +1523,7 @@ public class MotionGroup {
}
if (removeSelection) {
editor.getSelectionModel().removeSelection();
editor.getCaretModel().removeSecondaryCarets();
}
CommandState.getInstance(editor).setSubMode(CommandState.SubMode.NONE);
}
@@ -1566,29 +1572,21 @@ public class MotionGroup {
@NotNull
public TextRange getVisualRange(@NotNull Editor editor) {
if (editor.getSelectionModel().hasBlockSelection()) {
TextRange res = new TextRange(editor.getSelectionModel().getBlockSelectionStarts(),
editor.getSelectionModel().getBlockSelectionEnds());
// If the last left/right motion was the $ command, simulate each line being selected to end-of-line
if (EditorData.getLastColumn(editor) >= MotionGroup.LAST_COLUMN) {
int[] starts = res.getStartOffsets();
int[] ends = res.getEndOffsets();
for (int i = 0; i < starts.length; i++) {
if (ends[i] > starts[i]) {
ends[i] = EditorHelper.getLineEndForOffset(editor, starts[i]);
}
final TextRange res = new TextRange(editor.getSelectionModel().getBlockSelectionStarts(),
editor.getSelectionModel().getBlockSelectionEnds());
// 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 (subMode == CommandState.SubMode.VISUAL_BLOCK && EditorData.getLastColumn(editor) >= MotionGroup.LAST_COLUMN) {
final int[] starts = res.getStartOffsets();
final int[] ends = res.getEndOffsets();
for (int i = 0; i < starts.length; i++) {
if (ends[i] > starts[i]) {
ends[i] = EditorHelper.getLineEndForOffset(editor, starts[i]);
}
res = new TextRange(starts, ends);
}
return res;
}
else {
return new TextRange(editor.getSelectionModel().getSelectionStart(),
editor.getSelectionModel().getSelectionEnd());
return new TextRange(starts, ends);
}
return res;
}
@NotNull
@@ -1601,31 +1599,34 @@ public class MotionGroup {
visualOffset = offset;
int start = visualStart;
int end = visualEnd;
if (start > end) {
int t = start;
start = end;
end = t;
}
final CommandState.SubMode subMode = CommandState.getInstance(editor).getSubMode();
if (CommandState.getInstance(editor).getSubMode() == CommandState.SubMode.VISUAL_CHARACTER) {
BoundStringOption opt = (BoundStringOption)Options.getInstance().getOption("selection");
int lineEnd = EditorHelper.getLineEndForOffset(editor, end);
int adj = 1;
if (opt.getValue().equals("exclusive") || end == lineEnd) {
adj = 0;
if (subMode == CommandState.SubMode.VISUAL_CHARACTER) {
if (start > end) {
int t = start;
start = end;
end = t;
}
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);
editor.getSelectionModel().setSelection(start, end);
}
else if (CommandState.getInstance(editor).getSubMode() == CommandState.SubMode.VISUAL_LINE) {
else if (subMode == CommandState.SubMode.VISUAL_LINE) {
if (start > end) {
int t = start;
start = end;
end = t;
}
start = EditorHelper.getLineStartForOffset(editor, start);
end = EditorHelper.getLineEndForOffset(editor, end);
editor.getSelectionModel().setSelection(start, end);
}
else {
LogicalPosition lineStart = editor.offsetToLogicalPosition(start);
LogicalPosition lend = editor.offsetToLogicalPosition(end);
editor.getSelectionModel().setBlockSelection(lineStart, lend);
else if (subMode == CommandState.SubMode.VISUAL_BLOCK) {
final LogicalPosition lineStart = editor.offsetToLogicalPosition(start);
final LogicalPosition lineEnd = editor.offsetToLogicalPosition(end);
editor.getSelectionModel().setBlockSelection(lineStart, lineEnd);
}
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) {
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
if (step < 0 && pos > 0) {
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}
*
*
* 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
*
* tag action

View File

@@ -1,6 +1,7 @@
package org.jetbrains.plugins.ideavim;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.PlainTextFileType;
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.ui.ExEntryPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
@@ -113,9 +115,12 @@ public abstract class VimTestCase extends UsefulTestCase {
return keys;
}
public void assertOffset(int expectedOffset) {
final int offset = myFixture.getEditor().getCaretModel().getOffset();
assertEquals(expectedOffset, offset);
public void assertOffset(int... expectedOffsets) {
final List<Caret> carets = myFixture.getEditor().getCaretModel().getAllCarets();
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) {
@@ -123,7 +128,7 @@ public abstract class VimTestCase extends UsefulTestCase {
assertEquals(expectedMode, mode);
}
public void assertSelection(@NotNull String expected) {
public void assertSelection(@Nullable String expected) {
final String selected = myFixture.getEditor().getSelectionModel().getSelectedText();
assertEquals(expected, selected);
}

View File

@@ -54,9 +54,7 @@ public class ChangeActionTest extends VimTestCase {
// VIM-321 |d| |count|
public void testDeleteEmptyRange() {
doTest(parseKeys("d0"),
"<caret>hello\n",
"hello\n");
doTest(parseKeys("d0"), "<caret>hello\n", "hello\n");
}
// VIM-112 |i| |i_CTRL-W|
@@ -64,8 +62,7 @@ public class ChangeActionTest extends VimTestCase {
typeTextInFile(parseKeys("i", "one two three", "<C-W>"),
"hello\n" +
"<caret>\n");
myFixture.checkResult("hello\n" +
"one two \n");
myFixture.checkResult("hello\n" + "one two \n");
}
// VIM-157 |~|
@@ -84,13 +81,11 @@ public class ChangeActionTest extends VimTestCase {
// VIM-85 |i| |gi| |gg|
public void testInsertAtPreviousAction() {
doTest(parseKeys("i", "hello", "<Esc>", "gg", "gi", " world! "),
"one\n" +
"two <caret>three\n" +
"four\n",
"one\n" +
"two hello world! three\n" +
"four\n");
doTest(parseKeys("i", "hello", "<Esc>", "gg", "gi", " world! "), "one\n" +
"two <caret>three\n" +
"four\n", "one\n" +
"two hello world! three\n" +
"four\n");
}
// VIM-312 |d| |w|
@@ -114,13 +109,11 @@ public class ChangeActionTest extends VimTestCase {
// VIM-105 |d| |w|
public void testDeleteLastWordBeforeEOLs() {
doTest(parseKeys("dw"),
"one <caret>two\n" +
"\n" +
"three\n",
"one \n" +
"\n" +
"three\n");
doTest(parseKeys("dw"), "one <caret>two\n" +
"\n" +
"three\n", "one \n" +
"\n" +
"three\n");
}
// VIM-105 |d| |w|
@@ -150,9 +143,7 @@ public class ChangeActionTest extends VimTestCase {
// VIM-300 |c| |w|
public void testChangeWordTwoWordsWithoutWhitespace() {
doTest(parseKeys("cw"),
"<caret>$value\n",
"value\n");
doTest(parseKeys("cw"), "<caret>$value\n", "value\n");
}
// VIM-296 |cc|
@@ -176,11 +167,7 @@ public class ChangeActionTest extends VimTestCase {
// |d| |v_aw|
public void testDeleteLastWordAfterPunctuation() {
doTest(parseKeys("daw"),
"foo(<caret>bar\n" +
"baz\n",
"foo(\n" +
"baz\n");
doTest(parseKeys("daw"), "foo(<caret>bar\n" + "baz\n", "foo(\n" + "baz\n");
}
// VIM-244 |d| |l|
@@ -244,6 +231,51 @@ public class ChangeActionTest extends VimTestCase {
"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) {
myFixture.configureByText("a.java", before);
final Editor editor = myFixture.getEditor();

View File

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

View File

@@ -6,6 +6,7 @@ import com.maddyhome.idea.vim.VimPlugin;
import org.jetbrains.plugins.ideavim.VimTestCase;
import static com.maddyhome.idea.vim.command.CommandState.Mode.COMMAND;
import static com.maddyhome.idea.vim.command.CommandState.Mode.VISUAL;
import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
import static com.maddyhome.idea.vim.helper.StringHelper.stringToKeys;
@@ -593,4 +594,29 @@ public class MotionActionTest extends VimTestCase {
" bar\n" +
" baz");
}
public void testVisualLineSelectDown() {
typeTextInFile(parseKeys("Vj"),
"foo\n" +
"<caret>bar\n" +
"baz\n" +
"quux\n");
assertMode(VISUAL);
assertSelection("bar\n" +
"baz");
assertOffset(8);
}
// VIM-784
public void testVisualLineSelectUp() {
typeTextInFile(parseKeys("Vk"),
"foo\n" +
"bar\n" +
"<caret>baz\n" +
"quux\n");
assertMode(VISUAL);
assertSelection("bar\n" +
"baz");
assertOffset(4);
}
}

View File

@@ -0,0 +1,55 @@
package org.jetbrains.plugins.ideavim.action;
import org.jetbrains.plugins.ideavim.VimTestCase;
import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
/**
* @author abrookins
*/
public class ShiftRightLinesActionTest extends VimTestCase {
// VIM-407
public void testShiftShiftsOneCharacterSingleLine() {
myFixture.configureByText("a.txt", "<caret>w\n");
typeText(parseKeys(">>"));
myFixture.checkResult(" w\n");
}
// VIM-407
public void testShiftShiftsOneCharacterMultiLine() {
myFixture.configureByText("a.txt", "Hello\n<caret>w\nWorld");
typeText(parseKeys(">>"));
myFixture.checkResult("Hello\n w\nWorld");
}
public void testShiftShiftsMultipleCharactersOneLine() {
myFixture.configureByText("a.txt", "<caret>Hello, world!\n");
typeText(parseKeys(">>"));
myFixture.checkResult(" Hello, world!\n");
}
public void testShiftShiftsMultipleCharactersMultipleLines() {
myFixture.configureByText("a.txt", "<caret>Hello,\nworld!\n");
typeText(parseKeys("j>>"));
myFixture.checkResult("Hello,\n world!\n");
}
public void testShiftsSingleLineSelection() {
myFixture.configureByText("a.txt", "<caret>Hello,\nworld!\n");
typeText(parseKeys("jv$>>"));
myFixture.checkResult("Hello,\n world!\n");
}
public void testShiftsMultiLineSelection() {
myFixture.configureByText("a.txt", "<caret>Hello,\nworld!\n");
typeText(parseKeys("vj$>>"));
myFixture.checkResult(" Hello,\n world!\n");
}
public void testShiftsMultiLineSelectionSkipsNewline() {
myFixture.configureByText("a.txt", "<caret>Hello,\nworld!\n\n");
typeText(parseKeys("vG$>>"));
myFixture.checkResult(" Hello,\n world!\n\n");
}
}