mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-17 16:31:45 +02:00
Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c8c42cc4b2 | ||
![]() |
0b22b454e6 | ||
![]() |
f4fe03c582 | ||
![]() |
964e87fd6a | ||
![]() |
ec4c0a0d0d | ||
![]() |
f9cf62472c | ||
![]() |
ace584d294 | ||
![]() |
5cd669202b | ||
![]() |
4a09848720 | ||
![]() |
f998f1be9f | ||
![]() |
3352bdfabb | ||
![]() |
ce43a9648f | ||
![]() |
440a0bf393 | ||
![]() |
64a7555f42 | ||
![]() |
3aa6fe3dc0 | ||
![]() |
3522228d45 | ||
![]() |
9b42d9a5c6 | ||
![]() |
4e8d98f956 | ||
![]() |
f6c3d27bbc | ||
![]() |
21daf83fbd | ||
![]() |
7f1203c207 | ||
![]() |
89b1f90973 | ||
![]() |
8002a5497f | ||
![]() |
770d12d79b | ||
![]() |
7e4ac22d23 | ||
![]() |
4f4b26d3e1 | ||
![]() |
4ea7c421a8 | ||
![]() |
3c8b7e2de4 | ||
![]() |
b13acaf823 | ||
![]() |
709cd6ad6e | ||
![]() |
1316ccc56f | ||
![]() |
881ddd0e11 | ||
![]() |
49611ee6b9 | ||
![]() |
539465bb56 | ||
![]() |
bc54a73d69 | ||
![]() |
5eb12f5d14 | ||
![]() |
557e47650f | ||
![]() |
f50753bfd7 | ||
![]() |
7a164d6d5f | ||
![]() |
60bc936cd9 | ||
![]() |
d097e636ea | ||
![]() |
3ce2bbb624 | ||
![]() |
4926d2554e | ||
![]() |
eae135acba | ||
![]() |
8ce3801b87 | ||
![]() |
0c7c11f817 | ||
![]() |
b3a39c05d7 | ||
![]() |
7370012667 | ||
![]() |
412838fd4b | ||
![]() |
273a614389 | ||
![]() |
3944c80ae2 | ||
![]() |
726ab3f91b | ||
![]() |
ab307dd78f | ||
![]() |
e3079912ae | ||
![]() |
52da3ed0e4 | ||
![]() |
cda85169ea | ||
![]() |
978d1df598 | ||
![]() |
f90d22cc20 | ||
![]() |
bae69d92ae | ||
![]() |
b910239825 | ||
![]() |
6421a5969a | ||
![]() |
5c9faba7f4 | ||
![]() |
c1af738cc5 | ||
![]() |
23a80a9260 | ||
![]() |
d9d92f7eee | ||
![]() |
c8be6c203e | ||
![]() |
612c599d9b | ||
![]() |
1292c7d1ae | ||
![]() |
69f07967b5 | ||
![]() |
aedd427c07 | ||
![]() |
9b6c3dc511 | ||
![]() |
b4fa7f4317 | ||
![]() |
f053d305d5 | ||
![]() |
1d95b7ddf7 | ||
![]() |
01a6964d68 | ||
![]() |
d661f96a9b | ||
![]() |
c79fae8ab3 | ||
![]() |
121f130893 | ||
![]() |
da9a0a414a | ||
![]() |
e0732e041b | ||
![]() |
6fc5b3189a | ||
![]() |
2a0c9cb749 | ||
![]() |
7ad131b448 | ||
![]() |
3e7186bd60 | ||
![]() |
132f8cce53 | ||
![]() |
5c07f42afb | ||
![]() |
1f7a2594c8 | ||
![]() |
ec64d19a36 | ||
![]() |
5cb67470d5 | ||
![]() |
c03f01a96a | ||
![]() |
26b67a43ae | ||
![]() |
a93ca3a205 | ||
![]() |
dcc647ba3c | ||
![]() |
fe44f59239 | ||
![]() |
80dba0babf | ||
![]() |
34acf9a91e | ||
![]() |
cb859dbb7b | ||
![]() |
20c04b1e62 | ||
![]() |
69eaf8ed0c | ||
![]() |
62c828d722 | ||
![]() |
251e8e8ff4 | ||
![]() |
acc41ec72e | ||
![]() |
f9ebcf2ee4 | ||
![]() |
f3df231dc2 | ||
![]() |
75a1bb7cc5 | ||
![]() |
7d6a64315a | ||
![]() |
2758071d31 |
@@ -9,6 +9,7 @@
|
|||||||
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
||||||
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int></ID>
|
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int></ID>
|
||||||
<ID>ComplexMethod:SearchHelperKt.kt$// bounds are considered inside corresponding quotes fun checkInString(chars: CharSequence, currentPos: Int, str: Boolean): Boolean</ID>
|
<ID>ComplexMethod:SearchHelperKt.kt$// bounds are considered inside corresponding quotes fun checkInString(chars: CharSequence, currentPos: Int, str: Boolean): Boolean</ID>
|
||||||
|
<ID>ComplexMethod:SearchHighlightsHelper.kt$ private fun updateSearchHighlights( pattern: String?, shouldIgnoreSmartCase: Boolean, showHighlights: Boolean, initialOffset: Int, searchRange: LineRange?, forwards: Boolean, forceUpdate: Boolean ): Int</ID>
|
||||||
<ID>ComplexMethod:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
<ID>ComplexMethod:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
||||||
<ID>ComplexMethod:VimExchangeExtension.kt$VimExchangeExtension.Operator$private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult</ID>
|
<ID>ComplexMethod:VimExchangeExtension.kt$VimExchangeExtension.Operator$private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult</ID>
|
||||||
<ID>ComplexMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
<ID>ComplexMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
||||||
@@ -16,6 +17,8 @@
|
|||||||
<ID>LongMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
<ID>LongMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
||||||
<ID>LongMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
<ID>LongMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
||||||
<ID>LongMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
<ID>LongMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
||||||
|
<ID>LongMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
||||||
|
<ID>LoopWithTooManyJumpStatements:SearchHighlightsHelper.kt$for (project in projectManager.openProjects) { val current = FileEditorManager.getInstance(project).selectedTextEditor ?: continue // [VERSION UPDATE] 202+ Use editors val editors = EditorFactory.getInstance().getEditors(current.document, project) ?: continue for (editor in editors) { // Try to keep existing highlights if possible. Update if hlsearch has changed or if the pattern has changed. // Force update for the situations where the text is the same, but the ignore case values have changed. // E.g. Use `*` to search for a word (which ignores smartcase), then use `/<Up>` to search for the same pattern, // which will match smartcase. Or changing the smartcase/ignorecase settings if (shouldRemoveSearchHighlights(editor, pattern, showHighlights) || forceUpdate) { removeSearchHighlights(editor) } if (pattern == null) continue if (shouldAddAllSearchHighlights(editor, pattern, showHighlights)) { // hlsearch (+ incsearch/noincsearch) val startLine = searchRange?.startLine ?: 0 val endLine = searchRange?.endLine ?: -1 val results = SearchGroup.findAll(editor, pattern, startLine, endLine, shouldIgnoreCase(pattern, shouldIgnoreSmartCase)) if (results.isNotEmpty()) { currentMatchOffset = findClosestMatch(editor, results, initialOffset, forwards) highlightSearchResults(editor, pattern, results, currentMatchOffset) } editor.vimLastSearch = pattern } else if (shouldAddCurrentMatchSearchHighlight(pattern, showHighlights, initialOffset)) { // nohlsearch + incsearch val searchOptions = EnumSet.of(SearchOptions.WHOLE_FILE) if (wrapscan.isSet) searchOptions.add(SearchOptions.WRAP) if (shouldIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE) if (!forwards) searchOptions.add(SearchOptions.BACKWARDS) val result = SearchGroup.findIt(editor, pattern, initialOffset, 1, searchOptions) if (result != null) { currentMatchOffset = result.startOffset val results = listOf(result) highlightSearchResults(editor, pattern, results, currentMatchOffset) } } else if (shouldMaintainCurrentMatchOffset(pattern, initialOffset)) { // incsearch. If nothing has changed (e.g. we've edited offset values in `/foo/e+2`) make sure we return the // current match offset so the caret remains at the current incsarch match val offset = editor.vimIncsearchCurrentMatchOffset if (offset != null) { currentMatchOffset = offset } } } }</ID>
|
||||||
<ID>MagicNumber:ActionListHandler.kt$ActionListHandler$50</ID>
|
<ID>MagicNumber:ActionListHandler.kt$ActionListHandler$50</ID>
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$0.9f</ID>
|
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$0.9f</ID>
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$1.75f</ID>
|
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$1.75f</ID>
|
||||||
@@ -50,6 +53,7 @@
|
|||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$19</ID>
|
<ID>MagicNumber:OptionsManager.kt$OptionsManager$19</ID>
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$20</ID>
|
<ID>MagicNumber:OptionsManager.kt$OptionsManager$20</ID>
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$3</ID>
|
<ID>MagicNumber:OptionsManager.kt$OptionsManager$3</ID>
|
||||||
|
<ID>MagicNumber:OptionsManager.kt$OptionsManager$50</ID>
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$80</ID>
|
<ID>MagicNumber:OptionsManager.kt$OptionsManager$80</ID>
|
||||||
<ID>MagicNumber:ProcessExEntryAction.kt$ProcessExEntryAction$0x0a</ID>
|
<ID>MagicNumber:ProcessExEntryAction.kt$ProcessExEntryAction$0x0a</ID>
|
||||||
<ID>MagicNumber:RegistersHandler.kt$RegistersHandler$200</ID>
|
<ID>MagicNumber:RegistersHandler.kt$RegistersHandler$200</ID>
|
||||||
@@ -61,6 +65,7 @@
|
|||||||
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$3</ID>
|
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$3</ID>
|
||||||
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$4</ID>
|
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$4</ID>
|
||||||
<ID>MatchingDeclarationName:CommandDefinition.kt$CommandName</ID>
|
<ID>MatchingDeclarationName:CommandDefinition.kt$CommandName</ID>
|
||||||
|
<ID>MatchingDeclarationName:SearchHelperKt.kt$Direction</ID>
|
||||||
<ID>MaxLineLength:ExBeanClass.kt$ExBeanClass$logger<ExBeanClass>().error("IdeaVim doesn't accept contributions to `vimActions` extension points. Please create a plugin using `VimExtension`. Plugin to blame: $pluginId")</ID>
|
<ID>MaxLineLength:ExBeanClass.kt$ExBeanClass$logger<ExBeanClass>().error("IdeaVim doesn't accept contributions to `vimActions` extension points. Please create a plugin using `VimExtension`. Plugin to blame: $pluginId")</ID>
|
||||||
<ID>MaxLineLength:ExRanges.kt$SearchRange$override</ID>
|
<ID>MaxLineLength:ExRanges.kt$SearchRange$override</ID>
|
||||||
<ID>MaxLineLength:NotificationService.kt$NotificationService$notification.addAction(AppendToIdeaVimRcAction(notification, "set clipboard+=ideaput", "ideaput") { OptionsManager.clipboard.append(ClipboardOptionsData.ideaput) })</ID>
|
<ID>MaxLineLength:NotificationService.kt$NotificationService$notification.addAction(AppendToIdeaVimRcAction(notification, "set clipboard+=ideaput", "ideaput") { OptionsManager.clipboard.append(ClipboardOptionsData.ideaput) })</ID>
|
||||||
@@ -79,67 +84,18 @@
|
|||||||
<ID>MaxLineLength:VimShortcutKeyAction.kt$VimShortcutKeyAction.Companion$ImmutableSet.builder<KeyStroke>().addAll(getKeyStrokes(KeyEvent.VK_ENTER, 0)).addAll(getKeyStrokes(KeyEvent.VK_ESCAPE, 0)) .addAll(getKeyStrokes(KeyEvent.VK_TAB, 0)).addAll(getKeyStrokes(KeyEvent.VK_BACK_SPACE, 0, InputEvent.CTRL_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_INSERT, 0)).addAll(getKeyStrokes(KeyEvent.VK_DELETE, 0, InputEvent.CTRL_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_UP, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK)).addAll(getKeyStrokes(KeyEvent.VK_DOWN, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_LEFT, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_RIGHT, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_HOME, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK))</ID>
|
<ID>MaxLineLength:VimShortcutKeyAction.kt$VimShortcutKeyAction.Companion$ImmutableSet.builder<KeyStroke>().addAll(getKeyStrokes(KeyEvent.VK_ENTER, 0)).addAll(getKeyStrokes(KeyEvent.VK_ESCAPE, 0)) .addAll(getKeyStrokes(KeyEvent.VK_TAB, 0)).addAll(getKeyStrokes(KeyEvent.VK_BACK_SPACE, 0, InputEvent.CTRL_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_INSERT, 0)).addAll(getKeyStrokes(KeyEvent.VK_DELETE, 0, InputEvent.CTRL_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_UP, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK)).addAll(getKeyStrokes(KeyEvent.VK_DOWN, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_LEFT, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_RIGHT, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK)) .addAll(getKeyStrokes(KeyEvent.VK_HOME, 0, InputEvent.CTRL_DOWN_MASK, InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK or InputEvent.SHIFT_DOWN_MASK))</ID>
|
||||||
<ID>MemberNameEqualsClassName:Ranges.kt$Ranges$private val ranges: MutableList<Range> = mutableListOf()</ID>
|
<ID>MemberNameEqualsClassName:Ranges.kt$Ranges$private val ranges: MutableList<Range> = mutableListOf()</ID>
|
||||||
<ID>NestedBlockDepth:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
<ID>NestedBlockDepth:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
||||||
<ID>ReturnCount:ActionBeanClass.kt$ActionBeanClass$fun getParsedModes(): Set<MappingMode>?</ID>
|
|
||||||
<ID>ReturnCount:Alias.kt$Alias$fun getCommand(input: String, count: Int): String</ID>
|
|
||||||
<ID>ReturnCount:CmdFilterHandler.kt$CmdFilterHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
<ID>ReturnCount:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
||||||
<ID>ReturnCount:CommandGroup.kt$CommandGroup$fun isAlias(command: String): Boolean</ID>
|
|
||||||
<ID>ReturnCount:DeleteJoinLinesAction.kt$DeleteJoinLinesAction$override fun execute(editor: Editor, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Boolean</ID>
|
|
||||||
<ID>ReturnCount:DeleteJoinLinesSpacesAction.kt$DeleteJoinLinesSpacesAction$override fun execute(editor: Editor, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Boolean</ID>
|
|
||||||
<ID>ReturnCount:DeleteJoinVisualLinesAction.kt$DeleteJoinVisualLinesAction$override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean</ID>
|
|
||||||
<ID>ReturnCount:DeleteJoinVisualLinesSpacesAction.kt$DeleteJoinVisualLinesSpacesAction$override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean</ID>
|
|
||||||
<ID>ReturnCount:DeleteMotionAction.kt$DeleteMotionAction$override fun execute(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Boolean</ID>
|
|
||||||
<ID>ReturnCount:EditFileHandler.kt$EditFileHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:EditorHelper.kt$ fun Editor.isPrimaryEditor(): Boolean</ID>
|
|
||||||
<ID>ReturnCount:ExRanges.kt$Range.Companion$ @JvmStatic fun createRange(str: String, offset: Int, move: Boolean): Array<Range>?</ID>
|
<ID>ReturnCount:ExRanges.kt$Range.Companion$ @JvmStatic fun createRange(str: String, offset: Int, move: Boolean): Array<Range>?</ID>
|
||||||
<ID>ReturnCount:FilterMotionAction.kt$FilterMotionAction$override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean</ID>
|
|
||||||
<ID>ReturnCount:GotoCharacterHandler.kt$GotoCharacterHandler$override fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:Helper.kt$@Suppress("IncorrectParentDisposable") fun Editor.isTemplateActive(): Boolean</ID>
|
|
||||||
<ID>ReturnCount:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:IdeaSelectionControl.kt$IdeaSelectionControl$ fun predictMode(editor: Editor, selectionSource: VimListenerManager.SelectionSource): CommandState.Mode</ID>
|
|
||||||
<ID>ReturnCount:MapHandler.kt$MapHandler$@Throws(ExException::class) private fun executeCommand(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
|
||||||
<ID>ReturnCount:Marks.kt$IntellijMark$private fun getProject(): Project?</ID>
|
|
||||||
<ID>ReturnCount:Marks.kt$VimMark.Companion$@JvmStatic fun create(key: Char?, logicalLine: Int?, col: Int?, filename: String?, protocol: String?): VimMark?</ID>
|
|
||||||
<ID>ReturnCount:ModalEntry.kt$ModalEntry.<no name provided>$override fun dispatchKeyEvent(e: KeyEvent): Boolean</ID>
|
|
||||||
<ID>ReturnCount:MotionScrollLastScreenLinePageStartAction.kt$MotionScrollLastScreenLinePageStartAction$override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean</ID>
|
|
||||||
<ID>ReturnCount:OperatorAction.kt$OperatorAction$override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean</ID>
|
|
||||||
<ID>ReturnCount:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
|
||||||
<ID>ReturnCount:PutGroup.kt$PutGroup$private fun getProviderForPasteViaIde(context: DataContext, typeInRegister: SelectionType, data: PutData): PasteProvider?</ID>
|
|
||||||
<ID>ReturnCount:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets(editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any>): List<Int></ID>
|
|
||||||
<ID>ReturnCount:PutLinesHandler.kt$PutLinesHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:ReloadVimRc.kt$VimRcFileState$fun equalTo(document: Document): Boolean</ID>
|
|
||||||
<ID>ReturnCount:RepeatHandler.kt$RepeatHandler$@Throws(ExException::class) override fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ReturnCount:SelectMotionRightAction.kt$SelectMotionRightAction$override fun getOffset(editor: Editor, caret: Caret, context: DataContext, count: Int, rawCount: Int, argument: Argument?): Int</ID>
|
|
||||||
<ID>ReturnCount:ShowCmd.kt$ShowCmd$fun getFullText(editor: Editor?): String</ID>
|
|
||||||
<ID>ReturnCount:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
|
||||||
<ID>ReturnCount:TextObjectActionHandler.kt$TextObjectActionHandler$ final override fun baseExecute(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean</ID>
|
|
||||||
<ID>ReturnCount:UndoRedoHelper.kt$UndoRedoHelper$fun redo(context: DataContext): Boolean</ID>
|
|
||||||
<ID>ReturnCount:UndoRedoHelper.kt$UndoRedoHelper$fun undo(context: DataContext): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VimExchangeExtension.kt$VimExchangeExtension.Operator$override fun apply(editor: Editor, context: DataContext, selectionType: SelectionType): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VimExtensionFacade.kt$VimExtensionFacade$ @JvmStatic fun inputString(editor: Editor, prompt: String, finishOn: Char?): String</ID>
|
|
||||||
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.AllOccurrencesHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.AllOccurrencesHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
||||||
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
||||||
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.SkipOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>ReturnCount:VimScriptParser.kt$VimScriptParser$@Throws(ExException::class) fun evaluate(expression: String, globals: Map<String?, Any?>): Any</ID>
|
|
||||||
<ID>ReturnCount:VimScriptParser.kt$VimScriptParser$fun findOrCreateIdeaVimRc(): File?</ID>
|
|
||||||
<ID>ReturnCount:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun getKeyStroke(e: AnActionEvent): KeyStroke?</ID>
|
|
||||||
<ID>ReturnCount:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
<ID>ReturnCount:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
||||||
<ID>ReturnCount:VimSurroundExtension.kt$VimSurroundExtension.CSurroundHandler$override fun execute(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>ReturnCount:VimSurroundExtension.kt$VimSurroundExtension.Operator$override fun apply(editor: Editor, context: DataContext, selectionType: SelectionType): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualBlockAppendAction.kt$VisualBlockAppendAction$override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualBlockInsertAction.kt$VisualBlockInsertAction$override fun executeForAllCarets(editor: Editor, context: DataContext, cmd: Command, caretsAndSelections: Map<Caret, VimSelection>): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$ fun toggleVisual(editor: Editor, count: Int, rawCount: Int, subMode: CommandState.SubMode): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$fun autodetectVisualSubmode(editor: Editor): CommandState.SubMode</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$fun selectPreviousVisualMode(editor: Editor): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$fun swapVisualSelections(editor: Editor): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$private fun seemsLikeBlockMode(editor: Editor): Boolean</ID>
|
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$private fun seemsLikeBlockMode(editor: Editor): Boolean</ID>
|
||||||
<ID>ReturnCount:VisualOperatorActionHandler.kt$VisualOperatorActionHandler$final override fun baseExecute(editor: Editor, caret: Caret, context: DataContext, cmd: Command): Boolean</ID>
|
|
||||||
<ID>ReturnCount:YankGroup.kt$YankGroup$ fun yankMotion(editor: Editor, context: DataContext, count: Int, rawCount: Int, argument: Argument): Boolean</ID>
|
|
||||||
<ID>ThrowsCount:CommandHandler.kt$CommandHandler$private fun checkArgs(cmd: ExCommand)</ID>
|
<ID>ThrowsCount:CommandHandler.kt$CommandHandler$private fun checkArgs(cmd: ExCommand)</ID>
|
||||||
<ID>TooManyFunctions:CommandBuilder.kt$CommandBuilder</ID>
|
<ID>TooManyFunctions:CommandBuilder.kt$CommandBuilder</ID>
|
||||||
<ID>TooManyFunctions:CommandState.kt$CommandState</ID>
|
<ID>TooManyFunctions:CommandState.kt$CommandState</ID>
|
||||||
<ID>TooManyFunctions:PutGroup.kt$PutGroup</ID>
|
<ID>TooManyFunctions:PutGroup.kt$PutGroup</ID>
|
||||||
<ID>TooManyFunctions:Ranges.kt$Ranges</ID>
|
<ID>TooManyFunctions:Ranges.kt$Ranges</ID>
|
||||||
|
<ID>TooManyFunctions:SearchHighlightsHelper.kt$com.maddyhome.idea.vim.helper.SearchHighlightsHelper.kt</ID>
|
||||||
<ID>TooManyFunctions:VisualGroup.kt$com.maddyhome.idea.vim.group.visual.VisualGroup.kt</ID>
|
<ID>TooManyFunctions:VisualGroup.kt$com.maddyhome.idea.vim.group.visual.VisualGroup.kt</ID>
|
||||||
<ID>TooManyFunctions:VisualMotionGroup.kt$VisualMotionGroup</ID>
|
<ID>TooManyFunctions:VisualMotionGroup.kt$VisualMotionGroup</ID>
|
||||||
</CurrentIssues>
|
</CurrentIssues>
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,6 +6,8 @@
|
|||||||
!/.idea/copyright
|
!/.idea/copyright
|
||||||
!/.idea/icon.png
|
!/.idea/icon.png
|
||||||
!/.idea/inspectionProfiles
|
!/.idea/inspectionProfiles
|
||||||
|
!/.idea/fileTemplates
|
||||||
|
!/.idea/runConfigurations
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
/out/
|
/out/
|
||||||
|
1
.idea/fileTemplates/code/I18nized Concatenation.java
generated
Normal file
1
.idea/fileTemplates/code/I18nized Concatenation.java
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
com.maddyhome.idea.vim.helper.MessageHelper.message("${PROPERTY_KEY}", ${PARAMETERS})
|
1
.idea/fileTemplates/code/I18nized Expression.java
generated
Normal file
1
.idea/fileTemplates/code/I18nized Expression.java
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
com.maddyhome.idea.vim.helper.MessageHelper.message("${PROPERTY_KEY}")
|
27
.idea/inspectionProfiles/Project_Default.xml
generated
27
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,9 +1,34 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<scope name="Production" level="WARNING" enabled="false">
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="true" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</scope>
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="false" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_requireAnnotationsFirst" value="true" />
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PluginXmlI18n" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
26
.idea/inspectionProfiles/Qodana.xml
generated
26
.idea/inspectionProfiles/Qodana.xml
generated
@@ -8,6 +8,30 @@
|
|||||||
<option name="REPORT_FIELDS" value="true" />
|
<option name="REPORT_FIELDS" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="GrUnresolvedAccess" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="GrUnresolvedAccess" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<scope name="Production" level="WARNING" enabled="false">
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="true" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</scope>
|
||||||
|
<option name="ignoreForAssertStatements" value="true" />
|
||||||
|
<option name="ignoreForExceptionConstructors" value="true" />
|
||||||
|
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
|
||||||
|
<option name="ignoreForJUnitAsserts" value="true" />
|
||||||
|
<option name="ignoreForClassReferences" value="true" />
|
||||||
|
<option name="ignoreForPropertyKeyReferences" value="true" />
|
||||||
|
<option name="ignoreForNonAlpha" value="true" />
|
||||||
|
<option name="ignoreAssignedToConstants" value="false" />
|
||||||
|
<option name="ignoreToString" value="false" />
|
||||||
|
<option name="nonNlsCommentPattern" value="NON-NLS" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_requireAnnotationsFirst" value="true" />
|
<option name="m_requireAnnotationsFirst" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
@@ -17,7 +41,7 @@
|
|||||||
<option name="processLiterals" value="true" />
|
<option name="processLiterals" value="true" />
|
||||||
<option name="processComments" value="true" />
|
<option name="processComments" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="StaticMethodOnlyUsedInOneClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
20
.teamcity/_Self/Project.kt
vendored
20
.teamcity/_Self/Project.kt
vendored
@@ -13,10 +13,12 @@ import _Self.buildTypes.TestsForIntelliJ20192
|
|||||||
import _Self.buildTypes.TestsForIntelliJ20193
|
import _Self.buildTypes.TestsForIntelliJ20193
|
||||||
import _Self.buildTypes.TestsForIntelliJ20201
|
import _Self.buildTypes.TestsForIntelliJ20201
|
||||||
import _Self.buildTypes.TestsForIntelliJ20202
|
import _Self.buildTypes.TestsForIntelliJ20202
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20203
|
||||||
import _Self.buildTypes.TestsForIntelliJEAP
|
import _Self.buildTypes.TestsForIntelliJEAP
|
||||||
import _Self.vcsRoots.Branch_181
|
import _Self.vcsRoots.Branch_181
|
||||||
import _Self.vcsRoots.Branch_183
|
import _Self.vcsRoots.Branch_183
|
||||||
import _Self.vcsRoots.Branch_191_193
|
import _Self.vcsRoots.Branch_191_193
|
||||||
|
import _Self.vcsRoots.Branch_201
|
||||||
import _Self.vcsRoots.GitHubPullRequest
|
import _Self.vcsRoots.GitHubPullRequest
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
@@ -25,11 +27,22 @@ object Project : Project({
|
|||||||
|
|
||||||
vcsRoot(Branch_183)
|
vcsRoot(Branch_183)
|
||||||
vcsRoot(Branch_181)
|
vcsRoot(Branch_181)
|
||||||
vcsRoot(GitHubPullRequest)
|
|
||||||
vcsRoot(Branch_191_193)
|
vcsRoot(Branch_191_193)
|
||||||
|
vcsRoot(Branch_201)
|
||||||
|
vcsRoot(GitHubPullRequest)
|
||||||
|
|
||||||
buildType(GitHubPullRequests)
|
buildType(GitHubPullRequests)
|
||||||
|
|
||||||
buildType(Release)
|
buildType(Release)
|
||||||
|
buildType(ReleaseEap)
|
||||||
|
|
||||||
|
buildType(TestsForIntelliJ20202)
|
||||||
|
buildType(TestsForIntelliJ20203)
|
||||||
|
buildType(TestsForIntelliJEAP)
|
||||||
|
|
||||||
|
buildType(Nvim)
|
||||||
|
buildType(PluginVerifier)
|
||||||
|
|
||||||
buildType(TestsForIntelliJ20201)
|
buildType(TestsForIntelliJ20201)
|
||||||
buildType(TestsForIntelliJ20191)
|
buildType(TestsForIntelliJ20191)
|
||||||
buildType(TestsForIntelliJ20181)
|
buildType(TestsForIntelliJ20181)
|
||||||
@@ -37,11 +50,6 @@ object Project : Project({
|
|||||||
buildType(TestsForIntelliJ20182)
|
buildType(TestsForIntelliJ20182)
|
||||||
buildType(TestsForIntelliJ20193)
|
buildType(TestsForIntelliJ20193)
|
||||||
buildType(TestsForIntelliJ20183)
|
buildType(TestsForIntelliJ20183)
|
||||||
buildType(Nvim)
|
|
||||||
buildType(ReleaseEap)
|
|
||||||
buildType(TestsForIntelliJ20202)
|
|
||||||
buildType(TestsForIntelliJEAP)
|
|
||||||
buildType(PluginVerifier)
|
|
||||||
|
|
||||||
features {
|
features {
|
||||||
feature {
|
feature {
|
||||||
|
2
.teamcity/_Self/buildTypes/ActiveTests.kt
vendored
2
.teamcity/_Self/buildTypes/ActiveTests.kt
vendored
@@ -41,5 +41,5 @@ sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
|
|||||||
})
|
})
|
||||||
|
|
||||||
object TestsForIntelliJEAP : ActiveTests("Tests for IntelliJ Latest EAP", "LATEST-EAP-SNAPSHOT")
|
object TestsForIntelliJEAP : ActiveTests("Tests for IntelliJ Latest EAP", "LATEST-EAP-SNAPSHOT")
|
||||||
|
object TestsForIntelliJ20203 : ActiveTests("Tests for IntelliJ 2020.3", "2020.3")
|
||||||
object TestsForIntelliJ20202 : ActiveTests("Tests for IntelliJ 2020.2", "2020.2")
|
object TestsForIntelliJ20202 : ActiveTests("Tests for IntelliJ 2020.2", "2020.2")
|
||||||
object TestsForIntelliJ20201 : ActiveTests("Tests for IntelliJ 2020.1", "2020.1")
|
|
||||||
|
@@ -16,7 +16,7 @@ object GitHubPullRequests : BuildType({
|
|||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.1")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.3")
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
.teamcity/_Self/buildTypes/Release.kt
vendored
2
.teamcity/_Self/buildTypes/Release.kt
vendored
@@ -10,7 +10,7 @@ object Release : BuildType({
|
|||||||
description = "Build and publish IdeaVim plugin"
|
description = "Build and publish IdeaVim plugin"
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
artifactRules = "build/distributions/*"
|
||||||
buildNumberPattern = "0.61"
|
buildNumberPattern = "0.63"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
||||||
|
2
.teamcity/_Self/buildTypes/ReleaseEap.kt
vendored
2
.teamcity/_Self/buildTypes/ReleaseEap.kt
vendored
@@ -13,7 +13,7 @@ object ReleaseEap : BuildType({
|
|||||||
description = "Build and publish EAP of IdeaVim plugin"
|
description = "Build and publish EAP of IdeaVim plugin"
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
artifactRules = "build/distributions/*"
|
||||||
buildNumberPattern = "0.61.%build.counter%"
|
buildNumberPattern = "0.63.%build.counter%"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
||||||
|
46
.teamcity/_Self/buildTypes/TestsForIntelliJ_201.kt
vendored
Normal file
46
.teamcity/_Self/buildTypes/TestsForIntelliJ_201.kt
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
sealed class TestsForIntelliJ_201_branch(private val version: String) : BuildType({
|
||||||
|
name = "Tests for IntelliJ $version"
|
||||||
|
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-$version")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(_Self.vcsRoots.Branch_201)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.ON_SERVER
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean test"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
object TestsForIntelliJ20201 : TestsForIntelliJ_201_branch("2020.1")
|
12
.teamcity/_Self/vcsRoots/Branch_201.kt
vendored
Normal file
12
.teamcity/_Self/vcsRoots/Branch_201.kt
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.vcsRoots
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
|
object Branch_201 : GitVcsRoot({
|
||||||
|
name = "https://github.com/JetBrains/ideavim (branch 201)"
|
||||||
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
|
branch = "201"
|
||||||
|
useMirrors = false
|
||||||
|
})
|
16
AUTHORS.md
16
AUTHORS.md
@@ -323,6 +323,22 @@ Contributors:
|
|||||||
[![icon][github]](https://github.com/i-e-b)
|
[![icon][github]](https://github.com/i-e-b)
|
||||||
|
|
||||||
Iain Ballard
|
Iain Ballard
|
||||||
|
* [![icon][mail]](mailto:brandoncc@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/brandoncc)
|
||||||
|
|
||||||
|
Brandon Conway
|
||||||
|
* [![icon][mail]](mailto:ga@anadoxin.org)
|
||||||
|
[![icon][github]](https://github.com/antekone)
|
||||||
|
|
||||||
|
Grzegorz Antoniak
|
||||||
|
* [![icon][mail]](mailto:shaunpatterson@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/shaunpatterson)
|
||||||
|
|
||||||
|
Shaun Patterson
|
||||||
|
* [![icon][mail]](mailto:vladimir.petrenko@jetbrains.com)
|
||||||
|
[![icon][github]](https://github.com/vladimir-petrenko)
|
||||||
|
|
||||||
|
Vladimir Petrenko
|
||||||
|
|
||||||
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 maintainers.
|
contact the maintainers.
|
||||||
|
39
CHANGES.md
39
CHANGES.md
@@ -22,9 +22,44 @@ It is important to distinguish EAP from traditional pre-release software.
|
|||||||
Please note that the quality of EAP versions may at times be way below even
|
Please note that the quality of EAP versions may at times be way below even
|
||||||
usual beta standards.
|
usual beta standards.
|
||||||
|
|
||||||
## To Be Released
|
## 0.63, 2020-12-16
|
||||||
|
|
||||||
...
|
### Changes:
|
||||||
|
* Update the minimal required IJ version: 2020.2+
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [CWM-927](https://youtrack.jetbrains.com/issue/CWM-927) Fix typing for CodeWithMe and IdeaVim
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [259](https://github.com/JetBrains/ideavim/pull/259) by [Vladimir Petrenko](https://github.com/vladimir-petrenko): CWM-927 disable vim for client's hidden editor on host
|
||||||
|
|
||||||
|
## 0.62, 2020-12-15
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support `unmap` and `mapclear` commands [VIM-1491](https://youtrack.jetbrains.com/issue/VIM-1491)
|
||||||
|
* Support mappings in ex panel (`cmap`) [VIM-1227](https://youtrack.jetbrains.com/issue/VIM-1227)
|
||||||
|
|
||||||
|
### Changes:
|
||||||
|
* `octal` is now disabled by default for `nrformats`. [VIM-2181](https://youtrack.jetbrains.com/issue/VIM-2181)
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2113](https://youtrack.jetbrains.com/issue/VIM-2113) Fix `cit` for empty tags
|
||||||
|
* [VIM-2114](https://youtrack.jetbrains.com/issue/VIM-2114) Unnamed register isn't changed after deleting empty tag
|
||||||
|
* [VIM-1475](https://youtrack.jetbrains.com/issue/VIM-1475) Enable block caret to be used in insert mode.
|
||||||
|
* [VIM-2170](https://youtrack.jetbrains.com/issue/VIM-2170) Fix an alternative range format for `s` command
|
||||||
|
* [VIM-1913](https://youtrack.jetbrains.com/issue/VIM-1913)
|
||||||
|
[VIM-2154](https://youtrack.jetbrains.com/issue/VIM-2154) Several fixes for AppCode templates
|
||||||
|
* [VIM-1756](https://youtrack.jetbrains.com/issue/VIM-1756) Fix startsel from insert mode
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [249](https://github.com/JetBrains/ideavim/pull/249) by [Jan Palus](https://github.com/jpalus): VIM-2113 Increase tag range only in visual mode
|
||||||
|
* [250](https://github.com/JetBrains/ideavim/pull/250) by [Jan Palus](https://github.com/jpalus): VIM-2114 Do not override registers when deleting empty range
|
||||||
|
* [256](https://github.com/JetBrains/ideavim/pull/256) by [Brandon Conway](https://github.com/brandoncc): Fix typo
|
||||||
|
* [254](https://github.com/JetBrains/ideavim/pull/254) by [Grzegorz Antoniak](https://github.com/antekone): VIM-1475: Add an option to use block caret in insert mode
|
||||||
|
* [225](https://github.com/JetBrains/ideavim/pull/225) by [sumoooru2](https://github.com/sumoooru2): Implement cmap
|
||||||
|
* [258](https://github.com/JetBrains/ideavim/pull/258) by [Matt Ellis](https://github.com/citizenmatt): Show the correct handler class in :map
|
||||||
|
* [257](https://github.com/JetBrains/ideavim/pull/257) by [Matt Ellis](https://github.com/citizenmatt): Extract SearchHighlightsHelper from SearchGroup
|
||||||
|
* [251](https://github.com/JetBrains/ideavim/pull/251) by [Shaun Patterson](https://github.com/shaunpatterson): VIM-1756: startSel works in insert mode
|
||||||
|
|
||||||
## 0.61, 2020-11-12
|
## 0.61, 2020-11-12
|
||||||
|
|
||||||
|
65
README.md
65
README.md
@@ -144,28 +144,45 @@ set idearefactormode=keep
|
|||||||
map <leader>f <Plug>(easymotion-s)
|
map <leader>f <Plug>(easymotion-s)
|
||||||
map <leader>e <Plug>(easymotion-f)
|
map <leader>e <Plug>(easymotion-f)
|
||||||
|
|
||||||
map <leader>d :action Debug<CR>
|
map <leader>d <Action>(Debug)
|
||||||
map <leader>r :action RenameElement<CR>
|
map <leader>r <Action>(RenameElement)
|
||||||
map <leader>c :action Stop<CR>
|
map <leader>c <Action>(Stop)
|
||||||
map <leader>z :action ToggleDistractionFreeMode<CR>
|
map <leader>z <Action>(ToggleDistractionFreeMode)
|
||||||
|
|
||||||
map <leader>s :action SelectInProjectView<CR>
|
map <leader>s <Action>(SelectInProjectView)
|
||||||
map <leader>a :action Annotate<CR>
|
map <leader>a <Action>(Annotate)
|
||||||
map <leader>h :action Vcs.ShowTabbedFileHistory<CR>
|
map <leader>h <Action>(Vcs.ShowTabbedFileHistory)
|
||||||
map <S-Space> :action GotoNextError<CR>
|
map <S-Space> <Action>(GotoNextError)
|
||||||
|
|
||||||
map <leader>b :action ToggleLineBreakpoint<CR>
|
map <leader>b <Action>(ToggleLineBreakpoint)
|
||||||
map <leader>o :action FileStructurePopup<CR>
|
map <leader>o <Action>(FileStructurePopup)
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><strong>Suggested options</strong> (click to see)</summary>
|
||||||
|
|
||||||
|
Here is also a list of the suggested options from [defaults.vim](https://github.com/vim/vim/blob/master/runtime/defaults.vim)
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" Show a few lines of context around the cursor. Note that this makes the
|
||||||
|
" text scroll if you mouse-click near the start or end of the window.
|
||||||
|
set scrolloff=5
|
||||||
|
|
||||||
|
" Do incremental searching
|
||||||
|
set incsearch
|
||||||
|
|
||||||
|
" Don't use Ex mode, use Q for formatting.
|
||||||
|
map Q gq
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
You can read your `~/.vimrc` file from `~/.ideavimrc` with this command:
|
You can read your `~/.vimrc` file from `~/.ideavimrc` with this command:
|
||||||
|
|
||||||
source ~/.vimrc
|
source ~/.vimrc
|
||||||
|
|
||||||
Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
> :warning: Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
||||||
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
||||||
of VimL files.
|
of VimL files.
|
||||||
|
|
||||||
@@ -183,10 +200,8 @@ Emulated Vim Plugins
|
|||||||
|
|
||||||
See [doc/emulated-plugins.md](doc/emulated-plugins.md)
|
See [doc/emulated-plugins.md](doc/emulated-plugins.md)
|
||||||
|
|
||||||
Changes to the IDE
|
Executing IDE Actions
|
||||||
------------------
|
---------------------
|
||||||
|
|
||||||
### Executing IDE Actions
|
|
||||||
|
|
||||||
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
||||||
Ex commands or via `:map` command mappings:
|
Ex commands or via `:map` command mappings:
|
||||||
@@ -205,7 +220,7 @@ Ex commands or via `:map` command mappings:
|
|||||||
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`).
|
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`).
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>"Track aciton Ids" Details</strong> (click to see)</summary>
|
<summary><strong>"Track action Ids" Details</strong> (click to see)</summary>
|
||||||
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@@ -222,24 +237,6 @@ Examples:
|
|||||||
:map \b <Action>(ToggleLineBreakpoint)
|
:map \b <Action>(ToggleLineBreakpoint)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Undo/Redo
|
|
||||||
|
|
||||||
The IdeaVim plugin uses the undo/redo functionality of the IntelliJ Platform,
|
|
||||||
so the behavior of the `u` and `<C-R>` commands may differ from the original
|
|
||||||
Vim. Vim compatibility of undo/redo may be improved in future releases.
|
|
||||||
|
|
||||||
See also [unresolved undo issues](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+Help+topic%3A+u).
|
|
||||||
|
|
||||||
### Escape
|
|
||||||
|
|
||||||
Using `<Esc>` in dialog windows remains problematic. For most dialog windows,
|
|
||||||
the Vim emulator is put into insert mode with `<Esc>` not working. You
|
|
||||||
should use `<C-c>` or `<C-[>` instead. In some dialog windows, the normal mode is
|
|
||||||
switched by default. The usage of the Vim emulator in dialog windows is an area for
|
|
||||||
improvement.
|
|
||||||
|
|
||||||
See also [unresolved escape issues](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+Help+topic%3A+i_Esc).
|
|
||||||
|
|
||||||
:gem: Contributing
|
:gem: Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
26
build.gradle
26
build.gradle
@@ -13,7 +13,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'org.jetbrains.intellij' version '0.6.2'
|
id 'org.jetbrains.intellij' version '0.6.5'
|
||||||
id 'io.gitlab.arturbosch.detekt' version '1.14.1'
|
id 'io.gitlab.arturbosch.detekt' version '1.14.1'
|
||||||
id "org.jetbrains.changelog" version "0.6.2"
|
id "org.jetbrains.changelog" version "0.6.2"
|
||||||
}
|
}
|
||||||
@@ -45,6 +45,8 @@ intellij {
|
|||||||
intellijRepo = "https://www.jetbrains.com/intellij-repository"
|
intellijRepo = "https://www.jetbrains.com/intellij-repository"
|
||||||
plugins = ['java']
|
plugins = ['java']
|
||||||
|
|
||||||
|
downloadRobotServerPlugin.version = "0.10.0"
|
||||||
|
|
||||||
publishPlugin {
|
publishPlugin {
|
||||||
channels publishChannels.split(',')
|
channels publishChannels.split(',')
|
||||||
username publishUsername
|
username publishUsername
|
||||||
@@ -52,8 +54,12 @@ intellij {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runIdeForUiTests {
|
||||||
|
systemProperty "robot-server.port", "8082"
|
||||||
|
}
|
||||||
|
|
||||||
runPluginVerifier {
|
runPluginVerifier {
|
||||||
ideVersions = ["IC-2020.1.4", "IC-2020.2.3"]
|
ideVersions = ["IC-2020.2.3", "IC-2020.3"]
|
||||||
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
||||||
teamCityOutputFormat = true
|
teamCityOutputFormat = true
|
||||||
}
|
}
|
||||||
@@ -61,14 +67,18 @@ runPluginVerifier {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven { url = "https://jetbrains.bintray.com/intellij-third-party-dependencies" }
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
||||||
compileOnly "org.jetbrains:annotations:19.0.0"
|
compileOnly "org.jetbrains:annotations:20.1.0"
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
||||||
compile group: 'com.ensarsarajcic.neovim.java', name: 'neovim-api', version: '0.1.16'
|
testImplementation("com.ensarsarajcic.neovim.java:neovim-api:0.1.16")
|
||||||
|
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-robot:0.10.0")
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-fixtures:1.1.18")
|
||||||
}
|
}
|
||||||
|
|
||||||
compileKotlin {
|
compileKotlin {
|
||||||
@@ -113,6 +123,14 @@ changelog {
|
|||||||
// version = "0.60"
|
// version = "0.60"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task getUnreleasedChangelog() {
|
||||||
|
group = "changelog"
|
||||||
|
doLast {
|
||||||
|
def log = changelog.getUnreleased().toHTML()
|
||||||
|
println log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks.register("slackEapNotification") {
|
tasks.register("slackEapNotification") {
|
||||||
doLast {
|
doLast {
|
||||||
if (!slackUrl) return
|
if (!slackUrl) return
|
||||||
|
@@ -28,9 +28,9 @@
|
|||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionRightMatchCharAction" mappingModes="NXO" keys="f"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionRightMatchCharAction" mappingModes="NXO" keys="f"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionRightTillMatchCharAction" mappingModes="NXO" keys="t"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionRightTillMatchCharAction" mappingModes="NXO" keys="t"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionHomeAction" mappingModes="NV" keys="«Home»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionHomeAction" mappingModes="NV" keys="«Home»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftHomeAction" mappingModes="NV" keys="«S-Home»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftHomeAction" mappingModes="INV" keys="«S-Home»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionEndAction" mappingModes="NVO" keys="«End»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionEndAction" mappingModes="NVO" keys="«End»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftEndAction" mappingModes="NV" keys="«S-End»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftEndAction" mappingModes="INV" keys="«S-End»"/>
|
||||||
<!-- Up/Down -->
|
<!-- Up/Down -->
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionDownAction" mappingModes="NXO" keys="j"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionDownAction" mappingModes="NXO" keys="j"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionDownCtrlNAction" mappingModes="NXO" keys="«C-N»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionDownCtrlNAction" mappingModes="NXO" keys="«C-N»"/>
|
||||||
@@ -152,10 +152,10 @@
|
|||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollColumnRightAction" mappingModes="NXO" keys="zh,z«Left»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollColumnRightAction" mappingModes="NXO" keys="zh,z«Left»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollHalfWidthLeftAction" mappingModes="NXO" keys="zL"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollHalfWidthLeftAction" mappingModes="NXO" keys="zL"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollHalfWidthRightAction" mappingModes="NXO" keys="zH"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.scroll.MotionScrollHalfWidthRightAction" mappingModes="NXO" keys="zH"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionShiftDownAction" mappingModes="NV" keys="«S-Down»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionShiftDownAction" mappingModes="INV" keys="«S-Down»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionShiftUpAction" mappingModes="NV" keys="«S-Up»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.updown.MotionShiftUpAction" mappingModes="INV" keys="«S-Up»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftRightAction" mappingModes="NV" keys="«S-Right»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftRightAction" mappingModes="INV" keys="«S-Right»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftLeftAction" mappingModes="NV" keys="«S-Left»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.leftright.MotionShiftLeftAction" mappingModes="INV" keys="«S-Left»"/>
|
||||||
<!-- Visual -->
|
<!-- Visual -->
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.visual.VisualExitModeAction" mappingModes="X" keys="«Esc»,«C-[»,«C-C»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.visual.VisualExitModeAction" mappingModes="X" keys="«Esc»,«C-[»,«C-C»"/>
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.motion.visual.VisualToggleCharacterModeAction" mappingModes="NX" keys="v"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.motion.visual.VisualToggleCharacterModeAction" mappingModes="NX" keys="v"/>
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JoinLinesHandler" names="j[oin]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JoinLinesHandler" names="j[oin]"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JumpsHandler" names="ju[mps]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JumpsHandler" names="ju[mps]"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.LetHandler" names="let"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.LetHandler" names="let"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MapHandler"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapHandler"/>
|
||||||
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.UnMapHandler"/>
|
||||||
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapClearHandler"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarkHandler" names="ma[rk],k"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarkHandler" names="ma[rk],k"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarksHandler" names="marks"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarksHandler" names="marks"/>
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MoveTextHandler" names="m[ove]"/>
|
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MoveTextHandler" names="m[ove]"/>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<idea-plugin>
|
<idea-plugin>
|
||||||
<applicationListeners>
|
<applicationListeners>
|
||||||
<listener class="com.maddyhome.idea.vim.ui.ExEntryPanel$LafListener"
|
<listener class="com.maddyhome.idea.vim.ui.ex.ExEntryPanel$LafListener"
|
||||||
topic="com.intellij.ide.ui.LafManagerListener"/>
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
<listener class="com.maddyhome.idea.vim.extension.highlightedyank.HighlightColorResetter"
|
<listener class="com.maddyhome.idea.vim.extension.highlightedyank.HighlightColorResetter"
|
||||||
topic="com.intellij.ide.ui.LafManagerListener"/>
|
topic="com.intellij.ide.ui.LafManagerListener"/>
|
||||||
|
@@ -1,47 +1,66 @@
|
|||||||
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
|
<idea-plugin url="https://plugins.jetbrains.com/plugin/164" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
<name>IdeaVim</name>
|
<name>IdeaVim</name>
|
||||||
<id>IdeaVIM</id>
|
<id>IdeaVIM</id>
|
||||||
<change-notes>
|
<change-notes><![CDATA[
|
||||||
<h3>Features:</h3>
|
<h3>Features:</h3>
|
||||||
<br/>
|
<ul>
|
||||||
<ul><li>Ability to map IDE actions via the <code>&lt;Action&gt;</code> keyword. E.g.
|
<li>Support <code>unmap</code> and <code>mapclear</code> commands <a
|
||||||
<code>map &lt;C-K&gt; &lt;Action&gt;(CommentByLineComment)</code>.
|
href="https://youtrack.jetbrains.com/issue/VIM-1491">VIM-1491</a></li>
|
||||||
Check out <code>README.md</code> for the details.</li><li><code>IdeaVim: track action
|
<li>Support mappings in ex panel (<code>cmap</code>) <a
|
||||||
Ids</code> command to find action ids for the <code>:action</code> command.
|
href="https://youtrack.jetbrains.com/issue/VIM-1227">VIM-1227</a></li>
|
||||||
Enable this option in &quot;Search everywhere&quot; (double shift).</li><li>Ability to enable
|
</ul>
|
||||||
extensions using <code>vim-plug</code> or <code>vundle</code> syntax.<br />
|
|
||||||
E.g. to enable commentary extension you can use one of the following commands:<pre><code
|
|
||||||
class="language-vim">set commentary
|
|
||||||
Plug 'tpope/vim-commentary'
|
|
||||||
Plug 'https://github.com/tpope/vim-commentary'
|
|
||||||
Plugin 'tpope/vim-commentary'
|
|
||||||
...
|
|
||||||
</code></pre><p>This approach is especially handy if you have <code>.vimrc</code> with
|
|
||||||
plugins registered via <code>vim-plug</code> or <code>vundle</code>.</p></li></ul>
|
|
||||||
|
|
||||||
|
<h3>Changes:</h3>
|
||||||
|
<ul>
|
||||||
|
<li><code>octal</code> is now disabled by default for <code>nrformats</code>. <a
|
||||||
|
href="https://youtrack.jetbrains.com/issue/VIM-2181">VIM-2181</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<br/>
|
<h3>Fixes:</h3>
|
||||||
<h3>Changes:</h3>
|
<ul>
|
||||||
<br/>
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-2113">VIM-2113</a> Fix <code>cit</code> for empty tags</li>
|
||||||
<ul><li>Fix <code>&lt;Esc&gt;</code> for dialogs. Now <code>&lt;Esc&gt;</code>
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-2114">VIM-2114</a> Unnamed register isn't changed after deleting
|
||||||
will exit insert / visual mode and close the dialog from normal mode.</li><li>Add option to disable
|
empty tag
|
||||||
IdeaVim in dialogs / single line editors. <a href="https://youtrack.jetbrains.com/issue/VIM-765">VIM-765</a><br
|
</li>
|
||||||
/>
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-1475">VIM-1475</a> Enable block caret to be used in insert mode.
|
||||||
Use <code>set ideavimsupport=</code> to disable IdeaVim in dialog editors. </li><li>Reposition
|
</li>
|
||||||
cursor when <code>scrolloff</code> changes</li></ul>
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-2170">VIM-2170</a> Fix an alternative range format for
|
||||||
|
<code>s</code> command
|
||||||
|
</li>
|
||||||
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-1913">VIM-1913</a>
|
||||||
|
<a href="https://youtrack.jetbrains.com/issue/VIM-2154">VIM-2154</a> Several fixes for AppCode templates
|
||||||
|
</li>
|
||||||
|
<li><a href="https://youtrack.jetbrains.com/issue/VIM-1756">VIM-1756</a> Fix startsel from insert mode</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<br/>
|
<h3>Merged PRs:</h3>
|
||||||
<h3>Fixes:</h3>
|
<ul>
|
||||||
<br/>
|
<li><a href="https://github.com/JetBrains/ideavim/pull/249">249</a> by <a href="https://github.com/jpalus">Jan
|
||||||
<ul><li><a href="https://youtrack.jetbrains.com/issue/VIM-2150">VIM-2150</a> <code>Shift-D</code>
|
Palus</a>: VIM-2113 Increase tag range only in visual mode
|
||||||
should not delete an empty line</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2157">VIM-2157</a>
|
</li>
|
||||||
Fix tab with an active template</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2156">VIM-2156</a>
|
<li><a href="https://github.com/JetBrains/ideavim/pull/250">250</a> by <a href="https://github.com/jpalus">Jan
|
||||||
Correct up/down motions with inlays</li><li><a href="https://youtrack.jetbrains.com/issue/VIM-2144">VIM-2144</a>
|
Palus</a>: VIM-2114 Do not override registers when deleting empty range
|
||||||
Correct text position after block insert with inlays</li><li><a
|
</li>
|
||||||
href="https://youtrack.jetbrains.com/issue/VIM-2158">VIM-2158</a> Fix scrolling when <code>scrolloff</code>
|
<li><a href="https://github.com/JetBrains/ideavim/pull/256">256</a> by <a href="https://github.com/brandoncc">Brandon
|
||||||
is over half screen height, but less than full height</li></ul>
|
Conway</a>: Fix typo
|
||||||
<br/>
|
</li>
|
||||||
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
<li><a href="https://github.com/JetBrains/ideavim/pull/254">254</a> by <a href="https://github.com/antekone">Grzegorz
|
||||||
|
Antoniak</a>: VIM-1475: Add an option to use block caret in insert mode
|
||||||
|
</li>
|
||||||
|
<li><a href="https://github.com/JetBrains/ideavim/pull/225">225</a> by <a href="https://github.com/sumoooru2">sumoooru2</a>:
|
||||||
|
Implement cmap
|
||||||
|
</li>
|
||||||
|
<li><a href="https://github.com/JetBrains/ideavim/pull/258">258</a> by <a href="https://github.com/citizenmatt">Matt
|
||||||
|
Ellis</a>: Show the correct handler class in :map
|
||||||
|
</li>
|
||||||
|
<li><a href="https://github.com/JetBrains/ideavim/pull/257">257</a> by <a href="https://github.com/citizenmatt">Matt
|
||||||
|
Ellis</a>: Extract SearchHighlightsHelper from SearchGroup
|
||||||
|
</li>
|
||||||
|
<li><a href="https://github.com/JetBrains/ideavim/pull/251">251</a> by <a href="https://github.com/shaunpatterson">Shaun
|
||||||
|
Patterson</a>: VIM-1756: startSel works in insert mode
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
]]>
|
||||||
</change-notes>
|
</change-notes>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
<p>Vim emulation plugin for IntelliJ Platform-based IDEs.</p>
|
<p>Vim emulation plugin for IntelliJ Platform-based IDEs.</p>
|
||||||
@@ -60,11 +79,11 @@
|
|||||||
|
|
||||||
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
<!-- Please search for "[VERSION UPDATE]" in project in case you update the since-build version -->
|
||||||
<!-- Check for [Version Update] tag in YouTrack as well -->
|
<!-- Check for [Version Update] tag in YouTrack as well -->
|
||||||
<idea-version since-build="201.5985.32"/>
|
<idea-version since-build="202"/>
|
||||||
|
|
||||||
<!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform -->
|
<!-- Mark the plugin as compatible with RubyMine and other products based on the IntelliJ platform -->
|
||||||
<depends>com.intellij.modules.lang</depends>
|
<depends>com.intellij.modules.lang</depends>
|
||||||
<resource-bundle xmlns="">messages</resource-bundle>
|
<resource-bundle>messages.IdeaVimBundle</resource-bundle>
|
||||||
|
|
||||||
<application-components>
|
<application-components>
|
||||||
<component>
|
<component>
|
||||||
@@ -94,7 +113,6 @@
|
|||||||
<statusBarWidgetFactory implementation="com.maddyhome.idea.vim.ui.StatusBarIconFactory"/>
|
<statusBarWidgetFactory implementation="com.maddyhome.idea.vim.ui.StatusBarIconFactory"/>
|
||||||
<statusBarWidgetFactory implementation="com.maddyhome.idea.vim.ui.ShowCmdStatusBarWidgetFactory" order="first"/>
|
<statusBarWidgetFactory implementation="com.maddyhome.idea.vim.ui.ShowCmdStatusBarWidgetFactory" order="first"/>
|
||||||
|
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.config.VimLocalConfig"/>
|
|
||||||
<applicationService serviceImplementation="com.maddyhome.idea.vim.VimPlugin"/>
|
<applicationService serviceImplementation="com.maddyhome.idea.vim.VimPlugin"/>
|
||||||
|
|
||||||
<!-- Initialise as early as possible so that we're ready to edit quickly. This is especially important for Rider,
|
<!-- Initialise as early as possible so that we're ready to edit quickly. This is especially important for Rider,
|
||||||
@@ -111,7 +129,7 @@
|
|||||||
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimListeners.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
|
|
||||||
<actions>
|
<actions resource-bundle="messages.IdeaVimBundle">
|
||||||
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction">
|
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction">
|
||||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||||
</action>
|
</action>
|
||||||
@@ -137,8 +155,6 @@
|
|||||||
</action>
|
</action>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<action id="VimFindActionIdAction"
|
<action id="VimFindActionIdAction" class="com.maddyhome.idea.vim.listener.FindActionIdAction"/>
|
||||||
class="com.maddyhome.idea.vim.listener.FindActionIdAction" text="IdeaVim: Track Action Ids"
|
|
||||||
description="Starts tracking ids of executed actions"/>
|
|
||||||
</actions>
|
</actions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
@@ -72,8 +72,54 @@ E475=E475: Invalid argument: {0}
|
|||||||
E774=E774: 'operatorfunc' is empty
|
E774=E774: 'operatorfunc' is empty
|
||||||
|
|
||||||
action.VimPluginToggle.text=Vim Emulator
|
action.VimPluginToggle.text=Vim Emulator
|
||||||
description.VimPluginToggle.description=Toggle the vim plugin On/off
|
action.VimPluginToggle.description=Toggle the vim plugin On/Off
|
||||||
|
action.VimPluginToggle.enabled=Enabled
|
||||||
|
action.VimPluginToggle.enable=Enable
|
||||||
|
|
||||||
action.VimShortcutKeyAction.text=Shortcuts
|
action.VimShortcutKeyAction.text=Shortcuts
|
||||||
|
|
||||||
action.VimActions.text=Vim Actions
|
action.VimActions.text=Vim Actions
|
||||||
|
action.not.found.0=Action not found: {0}
|
||||||
|
|
||||||
|
action.VimFindActionIdAction.text=IdeaVim: Track Action Ids
|
||||||
|
action.VimFindActionIdAction.description=Starts tracking ids of executed actions
|
||||||
|
|
||||||
|
ex.show.all.actions.0.1=--- Actions ---{0}{1}
|
||||||
|
e471.argument.required=E471: Argument required
|
||||||
|
|
||||||
|
buffer.0.does.not.exist=Buffer {0} does not exist
|
||||||
|
no.matching.buffer.for.0=No matching buffer for {0}
|
||||||
|
no.write.since.last.change.add.to.override=No write since last change (add ! to override)
|
||||||
|
more.than.one.match.for.0=More than one match for {0}
|
||||||
|
e176.invalid.number.of.arguments=E176: Invalid number of arguments
|
||||||
|
e183.user.defined.commands.must.start.with.an.uppercase.letter=E183: User defined commands must start with an uppercase letter
|
||||||
|
e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
|
||||||
|
e174.command.already.exists.add.to.replace.it=E174: Command already exists: add ! to replace it
|
||||||
|
recursion.detected.maximum.alias.depth.reached=Recursion detected, maximum alias depth reached.
|
||||||
|
show.mode.recording=recording
|
||||||
|
e184.no.such.user.defined.command.0=E184: No such user-defined command: {0}
|
||||||
|
unable.to.find.0=Unable to find {0}
|
||||||
|
more.ret.line.space.page.d.half.page.q.quit=-- MORE -- (RET: line, SPACE: page, d: half page, q: quit)
|
||||||
|
hit.enter.or.type.command.to.continue=Hit ENTER or type command to continue
|
||||||
|
ex.output.panel.more=-- MORE --
|
||||||
|
command.name.vim.macro.playback=Vim Macro Playback
|
||||||
|
action.no.changes.text=No Changes
|
||||||
|
action.reload.text=Reload
|
||||||
|
replace.with.0=Replace with {0} (y/n/a/q/l)?
|
||||||
|
error.invalid.command.argument=Error: invalid command argument
|
||||||
|
argtextobj.invalid.value.of.g.argtextobj.pairs.0=argtextobj: Invalid value of g:argtextobj_pairs -- {0}
|
||||||
|
highlightedyank.invalid.value.of.0.1=highlightedyank: Invalid value of {0} -- {1}
|
||||||
|
could.not.find.file.0=Could not find file: {0}
|
||||||
|
popup.advertisement.version=Version {0}
|
||||||
|
action.eap.choice.active.text=EAP{0, choice, 0# (Active)|1#}
|
||||||
|
action.about.eap.text=About EAP...
|
||||||
|
action.contacts.help.text=Contacts && Help
|
||||||
|
action.contact.on.twitter.text=Contact on Twitter
|
||||||
|
action.create.issue.text=Create an Issue
|
||||||
|
action.contribute.on.github.text=Contribute on GitHub
|
||||||
|
action.settings.text=Settings...
|
||||||
|
action.finish.eap.text=Finish EAP
|
||||||
|
action.subscribe.to.eap.text=Subscribe to EAP
|
||||||
|
configurable.name.vim.emulation=Vim Emulation
|
||||||
|
border.title.shortcut.conflicts.for.active.keymap=Shortcut Conflicts for Active Keymap
|
||||||
|
message.no.more.matches=No more matches
|
@@ -140,6 +140,6 @@ public class EventFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private @NotNull TypedAction getTypedAction() {
|
private @NotNull TypedAction getTypedAction() {
|
||||||
return EditorActionManager.getInstance().getTypedAction();
|
return TypedAction.getInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,10 +26,8 @@ import com.intellij.openapi.application.ApplicationManager;
|
|||||||
import com.intellij.openapi.application.ModalityState;
|
import com.intellij.openapi.application.ModalityState;
|
||||||
import com.intellij.openapi.command.CommandProcessor;
|
import com.intellij.openapi.command.CommandProcessor;
|
||||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||||
import com.intellij.openapi.editor.Caret;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.editor.actionSystem.ActionPlan;
|
import com.intellij.openapi.editor.actionSystem.ActionPlan;
|
||||||
import com.intellij.openapi.editor.actionSystem.CaretSpecificDataContext;
|
|
||||||
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
|
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
|
||||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
@@ -40,17 +38,14 @@ import com.maddyhome.idea.vim.action.change.insert.InsertCompletedDigraphAction;
|
|||||||
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction;
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction;
|
||||||
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
||||||
import com.maddyhome.idea.vim.command.*;
|
import com.maddyhome.idea.vim.command.*;
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
|
||||||
import com.maddyhome.idea.vim.group.ChangeGroup;
|
import com.maddyhome.idea.vim.group.ChangeGroup;
|
||||||
import com.maddyhome.idea.vim.group.RegisterGroup;
|
import com.maddyhome.idea.vim.group.RegisterGroup;
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection;
|
|
||||||
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
import com.maddyhome.idea.vim.key.*;
|
import com.maddyhome.idea.vim.key.*;
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.ui.ShowCmd;
|
import com.maddyhome.idea.vim.ui.ShowCmd;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
@@ -59,13 +54,12 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
|
import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
|
||||||
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
||||||
@@ -599,6 +593,22 @@ public class KeyHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DigraphResult res = editorState.processDigraphKey(key, editor);
|
DigraphResult res = editorState.processDigraphKey(key, editor);
|
||||||
|
if (ExEntryPanel.getInstance().isActive()) {
|
||||||
|
switch (res.getResult()) {
|
||||||
|
case DigraphResult.RES_HANDLED:
|
||||||
|
setPromptCharacterEx(commandBuilder.isPuttingLiteral() ? '^' : key.getKeyChar());
|
||||||
|
break;
|
||||||
|
case DigraphResult.RES_DONE:
|
||||||
|
case DigraphResult.RES_BAD:
|
||||||
|
if (key.getKeyCode() == KeyEvent.VK_C && (key.getModifiers() & InputEvent.CTRL_DOWN_MASK) != 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
ExEntryPanel.getInstance().getEntry().clearCurrentAction();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (res.getResult()) {
|
switch (res.getResult()) {
|
||||||
case DigraphResult.RES_HANDLED:
|
case DigraphResult.RES_HANDLED:
|
||||||
editorState.getCommandBuilder().addKey(key);
|
editorState.getCommandBuilder().addKey(key);
|
||||||
@@ -753,8 +763,10 @@ public class KeyHandler {
|
|||||||
// the key handler when it's complete.
|
// the key handler when it's complete.
|
||||||
if (action instanceof InsertCompletedDigraphAction) {
|
if (action instanceof InsertCompletedDigraphAction) {
|
||||||
editorState.startDigraphSequence();
|
editorState.startDigraphSequence();
|
||||||
|
setPromptCharacterEx('?');
|
||||||
} else if (action instanceof InsertCompletedLiteralAction) {
|
} else if (action instanceof InsertCompletedLiteralAction) {
|
||||||
editorState.startLiteralSequence();
|
editorState.startLiteralSequence();
|
||||||
|
setPromptCharacterEx('^');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EX_STRING:
|
case EX_STRING:
|
||||||
@@ -777,7 +789,7 @@ public class KeyHandler {
|
|||||||
* @param name The name of the action to execute
|
* @param name The name of the action to execute
|
||||||
* @param context The context to run it in
|
* @param context The context to run it in
|
||||||
*/
|
*/
|
||||||
public static boolean executeAction(@NotNull String name, @NotNull DataContext context) {
|
public static boolean executeAction(@NotNull @NonNls String name, @NotNull DataContext context) {
|
||||||
ActionManager aMgr = ActionManager.getInstance();
|
ActionManager aMgr = ActionManager.getInstance();
|
||||||
AnAction action = aMgr.getAction(name);
|
AnAction action = aMgr.getAction(name);
|
||||||
return action != null && executeAction(action, context);
|
return action != null && executeAction(action, context);
|
||||||
@@ -849,6 +861,13 @@ public class KeyHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setPromptCharacterEx(final char promptCharacter) {
|
||||||
|
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstance();
|
||||||
|
if (exEntryPanel.isActive()) {
|
||||||
|
exEntryPanel.getEntry().setCurrentActionPromptCharacter(promptCharacter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
||||||
private static final class DialogAwareDataContext implements DataContext {
|
private static final class DialogAwareDataContext implements DataContext {
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@@ -915,9 +934,12 @@ public class KeyHandler {
|
|||||||
if (editorState.getSubMode() == CommandState.SubMode.SINGLE_COMMAND &&
|
if (editorState.getSubMode() == CommandState.SubMode.SINGLE_COMMAND &&
|
||||||
(!cmd.getFlags().contains(CommandFlags.FLAG_EXPECT_MORE))) {
|
(!cmd.getFlags().contains(CommandFlags.FLAG_EXPECT_MORE))) {
|
||||||
editorState.popModes();
|
editorState.popModes();
|
||||||
|
VisualGroupKt.resetShape(CommandStateHelper.getMode(editor), editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyHandler.getInstance().reset(editor);
|
if (editorState.getCommandBuilder().isDone()) {
|
||||||
|
KeyHandler.getInstance().reset(editor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Editor editor;
|
private final Editor editor;
|
||||||
|
@@ -19,12 +19,16 @@ package com.maddyhome.idea.vim;
|
|||||||
|
|
||||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||||
import com.intellij.ide.plugins.PluginManager;
|
import com.intellij.ide.plugins.PluginManager;
|
||||||
|
import com.intellij.ide.plugins.PluginManagerCore;
|
||||||
import com.intellij.notification.Notification;
|
import com.intellij.notification.Notification;
|
||||||
import com.intellij.notification.NotificationListener;
|
import com.intellij.notification.NotificationListener;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.application.Application;
|
import com.intellij.openapi.application.Application;
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.components.*;
|
import com.intellij.openapi.components.PersistentStateComponent;
|
||||||
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
|
import com.intellij.openapi.components.State;
|
||||||
|
import com.intellij.openapi.components.Storage;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.extensions.PluginId;
|
import com.intellij.openapi.extensions.PluginId;
|
||||||
import com.intellij.openapi.keymap.Keymap;
|
import com.intellij.openapi.keymap.Keymap;
|
||||||
@@ -37,7 +41,6 @@ import com.intellij.openapi.ui.Messages;
|
|||||||
import com.intellij.openapi.util.SystemInfo;
|
import com.intellij.openapi.util.SystemInfo;
|
||||||
import com.intellij.openapi.wm.StatusBar;
|
import com.intellij.openapi.wm.StatusBar;
|
||||||
import com.intellij.openapi.wm.WindowManager;
|
import com.intellij.openapi.wm.WindowManager;
|
||||||
import com.maddyhome.idea.vim.config.VimLocalConfig;
|
|
||||||
import com.maddyhome.idea.vim.config.VimState;
|
import com.maddyhome.idea.vim.config.VimState;
|
||||||
import com.maddyhome.idea.vim.config.migration.ApplicationConfigurationMigrator;
|
import com.maddyhome.idea.vim.config.migration.ApplicationConfigurationMigrator;
|
||||||
import com.maddyhome.idea.vim.ex.CommandParser;
|
import com.maddyhome.idea.vim.ex.CommandParser;
|
||||||
@@ -50,7 +53,7 @@ import com.maddyhome.idea.vim.group.visual.VisualMotionGroup;
|
|||||||
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
import com.maddyhome.idea.vim.helper.MacKeyRepeat;
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
import com.maddyhome.idea.vim.listener.VimListenerManager;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
import com.maddyhome.idea.vim.ui.StatusBarIconFactory;
|
||||||
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
import com.maddyhome.idea.vim.ui.VimEmulationConfigurable;
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState;
|
import com.maddyhome.idea.vim.ui.VimRcFileState;
|
||||||
@@ -102,11 +105,6 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
LOG.debug("initComponent");
|
LOG.debug("initComponent");
|
||||||
|
|
||||||
// Initialize a legacy local config.
|
|
||||||
if (previousStateVersion == 5) {
|
|
||||||
//noinspection deprecation
|
|
||||||
VimLocalConfig.Companion.initialize();
|
|
||||||
}
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
Application application = ApplicationManager.getApplication();
|
Application application = ApplicationManager.getApplication();
|
||||||
if (application.isUnitTestMode()) {
|
if (application.isUnitTestMode()) {
|
||||||
@@ -165,7 +163,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable RegisterGroup getRegisterIfCreated() {
|
public static @Nullable RegisterGroup getRegisterIfCreated() {
|
||||||
return ServiceManager.getServiceIfCreated(RegisterGroup.class);
|
return ApplicationManager.getApplication().getServiceIfCreated(RegisterGroup.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull FileGroup getFile() {
|
public static @NotNull FileGroup getFile() {
|
||||||
@@ -177,7 +175,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable SearchGroup getSearchIfCreated() {
|
public static @Nullable SearchGroup getSearchIfCreated() {
|
||||||
return ServiceManager.getServiceIfCreated(SearchGroup.class);
|
return ApplicationManager.getApplication().getServiceIfCreated(SearchGroup.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull ProcessGroup getProcess() {
|
public static @NotNull ProcessGroup getProcess() {
|
||||||
@@ -201,7 +199,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable KeyGroup getKeyIfCreated() {
|
public static @Nullable KeyGroup getKeyIfCreated() {
|
||||||
return ServiceManager.getServiceIfCreated(KeyGroup.class);
|
return ApplicationManager.getApplication().getServiceIfCreated(KeyGroup.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull WindowGroup getWindow() {
|
public static @NotNull WindowGroup getWindow() {
|
||||||
@@ -213,7 +211,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable EditorGroup getEditorIfCreated() {
|
public static @Nullable EditorGroup getEditorIfCreated() {
|
||||||
return ServiceManager.getServiceIfCreated(EditorGroup.class);
|
return ApplicationManager.getApplication().getServiceIfCreated(EditorGroup.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull VisualMotionGroup getVisualMotion() {
|
public static @NotNull VisualMotionGroup getVisualMotion() {
|
||||||
@@ -260,7 +258,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull String getVersion() {
|
public static @NotNull String getVersion() {
|
||||||
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(getPluginId());
|
final IdeaPluginDescriptor plugin = PluginManagerCore.getPlugin(getPluginId());
|
||||||
if (!ApplicationManager.getApplication().isInternal()) {
|
if (!ApplicationManager.getApplication().isInternal()) {
|
||||||
return plugin != null ? plugin.getVersion() : "SNAPSHOT";
|
return plugin != null ? plugin.getVersion() : "SNAPSHOT";
|
||||||
}
|
}
|
||||||
@@ -324,7 +322,7 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
|
|||||||
showMessage(msg);
|
showMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showMessage(@Nls @Nullable String msg) {
|
public static void showMessage(@Nls(capitalization = Nls.Capitalization.Sentence) @Nullable String msg) {
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
getInstance().message = msg;
|
getInstance().message = msg;
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ package com.maddyhome.idea.vim.action
|
|||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
import com.intellij.openapi.project.DumbAwareToggleAction
|
import com.intellij.openapi.project.DumbAwareToggleAction
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.ui.VimActions
|
import com.maddyhome.idea.vim.ui.VimActions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +39,7 @@ class VimPluginToggleAction : DumbAwareToggleAction() {
|
|||||||
super.update(e)
|
super.update(e)
|
||||||
|
|
||||||
e.presentation.text = if (VimActions.actionPlace == e.place) {
|
e.presentation.text = if (VimActions.actionPlace == e.place) {
|
||||||
if (VimPlugin.isEnabled()) "Enabled" else "Enable"
|
if (VimPlugin.isEnabled()) MessageHelper.message("action.VimPluginToggle.enabled") else MessageHelper.message("action.VimPluginToggle.enable")
|
||||||
} else "Vim Emulator"
|
} else MessageHelper.message("action.VimPluginToggle.text")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@ import com.maddyhome.idea.vim.helper.isIdeaVimDisabledHere
|
|||||||
import com.maddyhome.idea.vim.helper.isPrimaryEditor
|
import com.maddyhome.idea.vim.helper.isPrimaryEditor
|
||||||
import com.maddyhome.idea.vim.helper.isTemplateActive
|
import com.maddyhome.idea.vim.helper.isTemplateActive
|
||||||
import com.maddyhome.idea.vim.key.ShortcutOwner
|
import com.maddyhome.idea.vim.key.ShortcutOwner
|
||||||
|
import com.maddyhome.idea.vim.listener.IdeaSpecifics.AppCodeTemplates.appCodeTemplateCaptured
|
||||||
import com.maddyhome.idea.vim.listener.IdeaSpecifics.aceJumpActive
|
import com.maddyhome.idea.vim.listener.IdeaSpecifics.aceJumpActive
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
import java.awt.event.InputEvent
|
import java.awt.event.InputEvent
|
||||||
@@ -99,6 +100,8 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
|||||||
|
|
||||||
if (keyCode == KeyEvent.VK_TAB && editor.isTemplateActive()) return false
|
if (keyCode == KeyEvent.VK_TAB && editor.isTemplateActive()) return false
|
||||||
|
|
||||||
|
if ((keyCode == KeyEvent.VK_TAB || keyCode == KeyEvent.VK_ENTER) && editor.appCodeTemplateCaptured()) return false
|
||||||
|
|
||||||
if (editor.inInsertMode) { // XXX: <Tab> won't be recorded in macros
|
if (editor.inInsertMode) { // XXX: <Tab> won't be recorded in macros
|
||||||
if (keyCode == KeyEvent.VK_TAB) {
|
if (keyCode == KeyEvent.VK_TAB) {
|
||||||
VimPlugin.getChange().tabAction = true
|
VimPlugin.getChange().tabAction = true
|
||||||
|
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.VisualPosition
|
import com.intellij.openapi.editor.VisualPosition
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
@@ -43,7 +44,10 @@ class AddInlineInlaysAction : AnAction() {
|
|||||||
val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine))
|
val lineLength = EditorHelper.getLineLength(editor, EditorHelper.visualLineToLogicalLine(editor, currentVisualLine))
|
||||||
while (i < lineLength) {
|
while (i < lineLength) {
|
||||||
val relatesToPrecedingText = random.nextInt(10) > 7
|
val relatesToPrecedingText = random.nextInt(10) > 7
|
||||||
|
|
||||||
|
@VimNlsSafe
|
||||||
val text = "a".repeat(max(1, random.nextInt(7)))
|
val text = "a".repeat(max(1, random.nextInt(7)))
|
||||||
|
|
||||||
val offset = EditorHelper.visualPositionToOffset(editor, VisualPosition(currentVisualLine, i))
|
val offset = EditorHelper.visualPositionToOffset(editor, VisualPosition(currentVisualLine, i))
|
||||||
// We don't need a custom renderer, just use the standard parameter hint renderer
|
// We don't need a custom renderer, just use the standard parameter hint renderer
|
||||||
inlayModel.addInlineElement(offset, relatesToPrecedingText, HintRenderer(if (relatesToPrecedingText) ":$text" else "$text:"))
|
inlayModel.addInlineElement(offset, relatesToPrecedingText, HintRenderer(if (relatesToPrecedingText) ":$text" else "$text:"))
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.ex.CommandParser
|
import com.maddyhome.idea.vim.ex.CommandParser
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
|
import com.maddyhome.idea.vim.group.RegisterGroup
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
|
|
||||||
class PlaybackRegisterAction : VimActionHandler.SingleExecution() {
|
class PlaybackRegisterAction : VimActionHandler.SingleExecution() {
|
||||||
@@ -44,7 +45,7 @@ class PlaybackRegisterAction : VimActionHandler.SingleExecution() {
|
|||||||
'@' -> {
|
'@' -> {
|
||||||
application.runWriteAction { res.set(VimPlugin.getMacro().playbackLastRegister(editor, context, project, cmd.count)) }
|
application.runWriteAction { res.set(VimPlugin.getMacro().playbackLastRegister(editor, context, project, cmd.count)) }
|
||||||
}
|
}
|
||||||
':' -> { // No write action
|
RegisterGroup.LAST_COMMAND_REGISTER -> { // No write action
|
||||||
try {
|
try {
|
||||||
res.set(CommandParser.getInstance().processLastCommand(editor, context, cmd.count))
|
res.set(CommandParser.getInstance().processLastCommand(editor, context, cmd.count))
|
||||||
} catch (e: ExException) {
|
} catch (e: ExException) {
|
||||||
|
@@ -47,9 +47,7 @@ class MotionScrollPageDownAction : VimActionHandler.SingleExecution() {
|
|||||||
class MotionScrollPageDownInsertModeAction : VimActionHandler.SingleExecution(), ComplicatedKeysAction {
|
class MotionScrollPageDownInsertModeAction : VimActionHandler.SingleExecution(), ComplicatedKeysAction {
|
||||||
|
|
||||||
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0))
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.SHIFT_DOWN_MASK)),
|
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, KeyEvent.SHIFT_DOWN_MASK))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override val type: Command.Type = Command.Type.OTHER_READONLY
|
override val type: Command.Type = Command.Type.OTHER_READONLY
|
||||||
|
@@ -47,9 +47,7 @@ class MotionScrollPageUpAction : VimActionHandler.SingleExecution() {
|
|||||||
class MotionScrollPageUpInsertModeAction : VimActionHandler.SingleExecution(), ComplicatedKeysAction {
|
class MotionScrollPageUpInsertModeAction : VimActionHandler.SingleExecution(), ComplicatedKeysAction {
|
||||||
|
|
||||||
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0))
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.SHIFT_DOWN_MASK)),
|
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, KeyEvent.SHIFT_DOWN_MASK))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override val type: Command.Type = Command.Type.OTHER_READONLY
|
override val type: Command.Type = Command.Type.OTHER_READONLY
|
||||||
|
@@ -25,6 +25,7 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
import com.maddyhome.idea.vim.command.MotionType
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.Direction
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ class SearchWholeWordBackwardAction : MotionActionHandler.ForEachCaret() {
|
|||||||
count: Int,
|
count: Int,
|
||||||
rawCount: Int,
|
rawCount: Int,
|
||||||
argument: Argument?): Int {
|
argument: Argument?): Int {
|
||||||
return VimPlugin.getSearch().searchWord(editor, caret, count, true, -1)
|
return VimPlugin.getSearch().searchWord(editor, caret, count, true, Direction.BACKWARDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||||
|
@@ -25,6 +25,7 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
import com.maddyhome.idea.vim.command.MotionType
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.Direction
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ class SearchWholeWordForwardAction : MotionActionHandler.ForEachCaret() {
|
|||||||
count: Int,
|
count: Int,
|
||||||
rawCount: Int,
|
rawCount: Int,
|
||||||
argument: Argument?): Int {
|
argument: Argument?): Int {
|
||||||
return VimPlugin.getSearch().searchWord(editor, caret, count, true, 1)
|
return VimPlugin.getSearch().searchWord(editor, caret, count, true, Direction.FORWARDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||||
|
@@ -25,6 +25,7 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
import com.maddyhome.idea.vim.command.MotionType
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.Direction
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ class SearchWordBackwardAction : MotionActionHandler.ForEachCaret() {
|
|||||||
count: Int,
|
count: Int,
|
||||||
rawCount: Int,
|
rawCount: Int,
|
||||||
argument: Argument?): Int {
|
argument: Argument?): Int {
|
||||||
return VimPlugin.getSearch().searchWord(editor, caret, count, false, -1)
|
return VimPlugin.getSearch().searchWord(editor, caret, count, false, Direction.BACKWARDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||||
|
@@ -25,6 +25,7 @@ import com.maddyhome.idea.vim.command.Argument
|
|||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
import com.maddyhome.idea.vim.command.CommandFlags
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
import com.maddyhome.idea.vim.command.MotionType
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.Direction
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ class SearchWordForwardAction : MotionActionHandler.ForEachCaret() {
|
|||||||
count: Int,
|
count: Int,
|
||||||
rawCount: Int,
|
rawCount: Int,
|
||||||
argument: Argument?): Int {
|
argument: Argument?): Int {
|
||||||
return VimPlugin.getSearch().searchWord(editor, caret, count, false, 1)
|
return VimPlugin.getSearch().searchWord(editor, caret, count, false, Direction.FORWARDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
import com.maddyhome.idea.vim.group.visual.vimSetSystemSelectionSilently
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
import com.maddyhome.idea.vim.helper.vimLastColumn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -23,10 +23,10 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Command
|
import com.maddyhome.idea.vim.command.Command
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.group.visual.updateCaretState
|
import com.maddyhome.idea.vim.group.visual.updateCaretState
|
||||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Plate
|
* @author Alex Plate
|
||||||
|
@@ -51,9 +51,7 @@ class MotionWordLeftInsertAction : MotionActionHandler.ForEachCaret(), Complicat
|
|||||||
|
|
||||||
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.CTRL_DOWN_MASK)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.CTRL_DOWN_MASK)),
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, KeyEvent.CTRL_DOWN_MASK)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, KeyEvent.CTRL_DOWN_MASK))
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.SHIFT_DOWN_MASK)),
|
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, KeyEvent.SHIFT_DOWN_MASK))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_STROKE)
|
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_STROKE)
|
||||||
|
@@ -51,9 +51,7 @@ class MotionWordRightInsertAction : MotionActionHandler.ForEachCaret(), Complica
|
|||||||
|
|
||||||
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
override val keyStrokesSet: Set<List<KeyStroke>> = setOf(
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.CTRL_DOWN_MASK)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.CTRL_DOWN_MASK)),
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, KeyEvent.CTRL_DOWN_MASK)),
|
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, KeyEvent.CTRL_DOWN_MASK))
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.SHIFT_DOWN_MASK)),
|
|
||||||
listOf(KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, KeyEvent.SHIFT_DOWN_MASK))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_STROKE)
|
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_STROKE)
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package com.maddyhome.idea.vim.command
|
package com.maddyhome.idea.vim.command
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.action.DuplicableOperatorAction
|
import com.maddyhome.idea.vim.action.DuplicableOperatorAction
|
||||||
|
import com.maddyhome.idea.vim.action.ResetModeAction
|
||||||
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedDigraphAction
|
||||||
|
import com.maddyhome.idea.vim.action.change.insert.InsertCompletedLiteralAction
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.key.CommandPartNode
|
||||||
import com.maddyhome.idea.vim.key.Node
|
import com.maddyhome.idea.vim.key.Node
|
||||||
@@ -24,6 +27,9 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
var expectedArgumentType: Argument.Type? = null
|
var expectedArgumentType: Argument.Type? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var prevExpectedArgumentType: Argument.Type? = null
|
||||||
|
private set
|
||||||
|
|
||||||
val isReady get() = commandState == CurrentCommandState.READY
|
val isReady get() = commandState == CurrentCommandState.READY
|
||||||
val isBad get() = commandState == CurrentCommandState.BAD_COMMAND
|
val isBad get() = commandState == CurrentCommandState.BAD_COMMAND
|
||||||
val isEmpty get() = commandParts.isEmpty()
|
val isEmpty get() = commandParts.isEmpty()
|
||||||
@@ -38,6 +44,7 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
|
|
||||||
fun pushCommandPart(action: EditorActionHandlerBase) {
|
fun pushCommandPart(action: EditorActionHandlerBase) {
|
||||||
commandParts.add(Command(count, action, action.type, action.flags))
|
commandParts.add(Command(count, action, action.type, action.flags))
|
||||||
|
prevExpectedArgumentType = expectedArgumentType
|
||||||
expectedArgumentType = action.argumentType
|
expectedArgumentType = action.argumentType
|
||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
@@ -106,6 +113,14 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
return currentCommandPartNode !is RootNode
|
return currentCommandPartNode !is RootNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isPuttingLiteral(): Boolean {
|
||||||
|
return !commandParts.isEmpty() && commandParts.last.action is InsertCompletedLiteralAction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isDone(): Boolean {
|
||||||
|
return commandParts.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
fun completeCommandPart(argument: Argument) {
|
fun completeCommandPart(argument: Argument) {
|
||||||
commandParts.peekLast().argument = argument
|
commandParts.peekLast().argument = argument
|
||||||
commandState = CurrentCommandState.READY
|
commandState = CurrentCommandState.READY
|
||||||
@@ -121,6 +136,11 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildCommand(): Command {
|
fun buildCommand(): Command {
|
||||||
|
if (commandParts.last.action is InsertCompletedDigraphAction || commandParts.last.action is ResetModeAction) {
|
||||||
|
expectedArgumentType = prevExpectedArgumentType
|
||||||
|
prevExpectedArgumentType = null
|
||||||
|
return commandParts.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
var command: Command = commandParts.removeFirst()
|
var command: Command = commandParts.removeFirst()
|
||||||
while (commandParts.size > 0) {
|
while (commandParts.size > 0) {
|
||||||
@@ -147,6 +167,7 @@ class CommandBuilder(private var currentCommandPartNode: CommandPartNode) {
|
|||||||
commandParts.clear()
|
commandParts.clear()
|
||||||
keyList.clear()
|
keyList.clear()
|
||||||
expectedArgumentType = null
|
expectedArgumentType = null
|
||||||
|
prevExpectedArgumentType = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetInProgressCommandPart(commandPartNode: CommandPartNode) {
|
fun resetInProgressCommandPart(commandPartNode: CommandPartNode) {
|
||||||
|
@@ -23,6 +23,8 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.helper.DigraphResult
|
import com.maddyhome.idea.vim.helper.DigraphResult
|
||||||
import com.maddyhome.idea.vim.helper.DigraphSequence
|
import com.maddyhome.idea.vim.helper.DigraphSequence
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe
|
||||||
import com.maddyhome.idea.vim.helper.noneOfEnum
|
import com.maddyhome.idea.vim.helper.noneOfEnum
|
||||||
import com.maddyhome.idea.vim.helper.vimCommandState
|
import com.maddyhome.idea.vim.helper.vimCommandState
|
||||||
import com.maddyhome.idea.vim.key.CommandPartNode
|
import com.maddyhome.idea.vim.key.CommandPartNode
|
||||||
@@ -232,6 +234,7 @@ class CommandState private constructor() {
|
|||||||
* be added. It's better not to compare the whole string but only
|
* be added. It's better not to compare the whole string but only
|
||||||
* the leading character(s).
|
* the leading character(s).
|
||||||
*/
|
*/
|
||||||
|
@VimNlsSafe
|
||||||
fun toVimNotation(): String {
|
fun toVimNotation(): String {
|
||||||
return when (mode) {
|
return when (mode) {
|
||||||
Mode.COMMAND -> "n"
|
Mode.COMMAND -> "n"
|
||||||
@@ -266,7 +269,7 @@ class CommandState private constructor() {
|
|||||||
if (msg.isNotEmpty()) {
|
if (msg.isNotEmpty()) {
|
||||||
msg.append(" - ")
|
msg.append(" - ")
|
||||||
}
|
}
|
||||||
msg.append("recording")
|
msg.append(MessageHelper.message("show.mode.recording"))
|
||||||
}
|
}
|
||||||
VimPlugin.showMode(msg.toString())
|
VimPlugin.showMode(msg.toString())
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
package com.maddyhome.idea.vim.common
|
package com.maddyhome.idea.vim.common
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
@@ -39,10 +41,10 @@ class Alias(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val LessThan = "<lt>"
|
@NonNls const val LessThan = "<lt>"
|
||||||
const val Count = "<count>"
|
@NonNls const val Count = "<count>"
|
||||||
const val Arguments = "<args>"
|
@NonNls const val Arguments = "<args>"
|
||||||
const val QuotedArguments = "<q-args>"
|
@NonNls const val QuotedArguments = "<q-args>"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCommand(input: String, count: Int): String {
|
fun getCommand(input: String, count: Int): String {
|
||||||
@@ -52,7 +54,7 @@ class Alias(
|
|||||||
var compiledCommand = this.command
|
var compiledCommand = this.command
|
||||||
val cleanedInput = input.trim().removePrefix(name).trim()
|
val cleanedInput = input.trim().removePrefix(name).trim()
|
||||||
if (minimumNumberOfArguments > 0 && cleanedInput.isEmpty()) {
|
if (minimumNumberOfArguments > 0 && cleanedInput.isEmpty()) {
|
||||||
VimPlugin.showMessage("E471: Argument required")
|
VimPlugin.showMessage(MessageHelper.message("e471.argument.required"))
|
||||||
VimPlugin.indicateError()
|
VimPlugin.indicateError()
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import com.intellij.ide.bookmarks.Bookmark
|
|||||||
import com.intellij.ide.bookmarks.BookmarkManager
|
import com.intellij.ide.bookmarks.BookmarkManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.maddyhome.idea.vim.group.MarkGroup
|
import com.maddyhome.idea.vim.group.MarkGroup
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
interface Mark {
|
interface Mark {
|
||||||
@@ -35,7 +36,7 @@ interface Mark {
|
|||||||
fun clear()
|
fun clear()
|
||||||
|
|
||||||
object KeySorter : Comparator<Mark> {
|
object KeySorter : Comparator<Mark> {
|
||||||
private const val ORDER = "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"[]^.<>"
|
@NonNls private const val ORDER = "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"[]^.<>"
|
||||||
|
|
||||||
override fun compare(o1: Mark, o2: Mark): Int {
|
override fun compare(o1: Mark, o2: Mark): Int {
|
||||||
return ORDER.indexOf(o1.key) - ORDER.indexOf(o2.key)
|
return ORDER.indexOf(o1.key) - ORDER.indexOf(o2.key)
|
||||||
|
@@ -20,8 +20,8 @@ package com.maddyhome.idea.vim.common
|
|||||||
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
import com.intellij.codeInsight.editorActions.TextBlockTransferableData
|
||||||
import com.maddyhome.idea.vim.command.SelectionType
|
import com.maddyhome.idea.vim.command.SelectionType
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper
|
import com.maddyhome.idea.vim.helper.StringHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import java.util.*
|
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
class Register {
|
class Register {
|
||||||
@@ -81,7 +81,7 @@ class Register {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object KeySorter : Comparator<Register> {
|
object KeySorter : Comparator<Register> {
|
||||||
private const val ORDER = "\"0123456789abcdefghijklmnopqrstuvwxyz-*+.:%#/="
|
@NonNls private const val ORDER = "\"0123456789abcdefghijklmnopqrstuvwxyz-*+.:%#/="
|
||||||
|
|
||||||
override fun compare(o1: Register, o2: Register): Int {
|
override fun compare(o1: Register, o2: Register): Int {
|
||||||
return ORDER.indexOf(o1.name.toLowerCase()) - ORDER.indexOf(o2.name.toLowerCase())
|
return ORDER.indexOf(o1.name.toLowerCase()) - ORDER.indexOf(o2.name.toLowerCase())
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
package com.maddyhome.idea.vim.common
|
package com.maddyhome.idea.vim.common
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract
|
import org.jetbrains.annotations.Contract
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -85,7 +86,7 @@ class TextRange(val startOffsets: IntArray, val endOffsets: IntArray) {
|
|||||||
operator fun contains(offset: Int): Boolean = if (isMultiple) false else offset in startOffset until endOffset
|
operator fun contains(offset: Int): Boolean = if (isMultiple) false else offset in startOffset until endOffset
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val sb = StringBuilder()
|
@NonNls val sb = StringBuilder()
|
||||||
sb.append("TextRange")
|
sb.append("TextRange")
|
||||||
sb.append("{starts=")
|
sb.append("{starts=")
|
||||||
|
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2020 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.config
|
|
||||||
|
|
||||||
import com.intellij.openapi.components.PersistentStateComponent
|
|
||||||
import com.intellij.openapi.components.RoamingType
|
|
||||||
import com.intellij.openapi.components.ServiceManager
|
|
||||||
import com.intellij.openapi.components.State
|
|
||||||
import com.intellij.openapi.components.Storage
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import org.jdom.Element
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Alex Plate
|
|
||||||
*/
|
|
||||||
|
|
||||||
@State(name = "VimLocalSettings", storages = [
|
|
||||||
Storage("\$APP_CONFIG$$/vim_local_settings.xml", roamingType = RoamingType.DISABLED, deprecated = true),
|
|
||||||
Storage("\$APP_CONFIG$/vim_local_settings.xml", roamingType = RoamingType.DISABLED, deprecated = true)
|
|
||||||
])
|
|
||||||
@Deprecated("The data from this class will be stored in vim_settings")
|
|
||||||
class VimLocalConfig : PersistentStateComponent<Element> {
|
|
||||||
override fun getState(): Element? = null
|
|
||||||
|
|
||||||
override fun loadState(state: Element) {
|
|
||||||
// This is initialization of state from the legacy configuration structure.
|
|
||||||
// This code should be performed only once on settings migration.
|
|
||||||
// After the migration is done, the file with settings gets removed and this method won't be called again.
|
|
||||||
VimPlugin.getMark().readData(state)
|
|
||||||
VimPlugin.getRegister().readData(state)
|
|
||||||
VimPlugin.getSearch().readData(state)
|
|
||||||
VimPlugin.getHistory().readData(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun initialize() {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
ServiceManager.getService(VimLocalConfig::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -60,7 +60,7 @@ class MigrationComponents(
|
|||||||
@Service
|
@Service
|
||||||
class ApplicationConfigurationMigrator(migrationComponents: MigrationComponents) {
|
class ApplicationConfigurationMigrator(migrationComponents: MigrationComponents) {
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "HardCodedStringLiteral")
|
||||||
constructor() : this(productionMigrationComponents)
|
constructor() : this(productionMigrationComponents)
|
||||||
|
|
||||||
private val migrators = migrationComponents.groupedMigrators
|
private val migrators = migrationComponents.groupedMigrators
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
package com.maddyhome.idea.vim.config.migration
|
package com.maddyhome.idea.vim.config.migration
|
||||||
|
|
||||||
import com.intellij.openapi.application.PathManager
|
import com.intellij.openapi.application.PathManager
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
interface VersionDetector {
|
interface VersionDetector {
|
||||||
fun extractVersion(): Int?
|
fun extractVersion(): Int?
|
||||||
@@ -28,7 +29,7 @@ interface VersionDetector {
|
|||||||
|
|
||||||
object `Detect versions 3, 4, 5, 6` : VersionDetector {
|
object `Detect versions 3, 4, 5, 6` : VersionDetector {
|
||||||
|
|
||||||
val pattern = "state version=\"(.)\"".toRegex()
|
@NonNls val pattern = "state version=\"(.)\"".toRegex()
|
||||||
|
|
||||||
override fun extractVersion(): Int? {
|
override fun extractVersion(): Int? {
|
||||||
val configFile = PathManager.getOptionsFile("vim_settings")
|
val configFile = PathManager.getOptionsFile("vim_settings")
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.ex
|
package com.maddyhome.idea.vim.ex
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class CommandNode(command: ExBeanClass? = null) {
|
class CommandNode(command: ExBeanClass? = null) {
|
||||||
|
|
||||||
var commandHandler: ExBeanClass? = command
|
var commandHandler: ExBeanClass? = command
|
||||||
|
@@ -26,11 +26,11 @@ import com.intellij.openapi.util.ThrowableComputable;
|
|||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
import com.maddyhome.idea.vim.command.SelectionType;
|
import com.maddyhome.idea.vim.command.SelectionType;
|
||||||
import com.maddyhome.idea.vim.common.Register;
|
import com.maddyhome.idea.vim.common.Register;
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
|
||||||
import com.maddyhome.idea.vim.ex.handler.GotoLineHandler;
|
import com.maddyhome.idea.vim.ex.handler.GotoLineHandler;
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Range;
|
import com.maddyhome.idea.vim.ex.ranges.Range;
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Ranges;
|
import com.maddyhome.idea.vim.ex.ranges.Ranges;
|
||||||
import com.maddyhome.idea.vim.group.HistoryGroup;
|
import com.maddyhome.idea.vim.group.HistoryGroup;
|
||||||
|
import com.maddyhome.idea.vim.group.RegisterGroup;
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper;
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.Msg;
|
import com.maddyhome.idea.vim.helper.Msg;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -150,7 +150,7 @@ public class CommandParser {
|
|||||||
}
|
}
|
||||||
processCommand(editor, context, commandAlias, count, aliasCountdown - 1);
|
processCommand(editor, context, commandAlias, count, aliasCountdown - 1);
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.showMessage("Recursion detected, maximum alias depth reached.");
|
VimPlugin.showMessage(MessageHelper.message("recursion.detected.maximum.alias.depth.reached"));
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
logger.warn("Recursion detected, maximum alias depth reached. ");
|
logger.warn("Recursion detected, maximum alias depth reached. ");
|
||||||
}
|
}
|
||||||
@@ -177,8 +177,7 @@ public class CommandParser {
|
|||||||
ThrowableComputable<Object, ExException> runCommand = () -> {
|
ThrowableComputable<Object, ExException> runCommand = () -> {
|
||||||
boolean ok = handler.process(editor, context, command, count);
|
boolean ok = handler.process(editor, context, command, count);
|
||||||
if (ok && !handler.getArgFlags().getFlags().contains(CommandHandler.Flag.DONT_SAVE_LAST)) {
|
if (ok && !handler.getArgFlags().getFlags().contains(CommandHandler.Flag.DONT_SAVE_LAST)) {
|
||||||
VimPlugin.getRegister().storeTextInternal(editor, new TextRange(-1, -1), cmd,
|
VimPlugin.getRegister().storeTextSpecial(RegisterGroup.LAST_COMMAND_REGISTER, cmd);
|
||||||
SelectionType.CHARACTER_WISE, ':', false);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@@ -307,6 +306,10 @@ public class CommandParser {
|
|||||||
state = State.RANGE_SHORT_PATTERN;
|
state = State.RANGE_SHORT_PATTERN;
|
||||||
reprocess = false;
|
reprocess = false;
|
||||||
}
|
}
|
||||||
|
else if (ch == ',') {
|
||||||
|
location.append('.');
|
||||||
|
state = State.RANGE_MAYBE_DONE;
|
||||||
|
}
|
||||||
else if (ch == '/' || ch == '?') {
|
else if (ch == '/' || ch == '?') {
|
||||||
location.append(ch);
|
location.append(ch);
|
||||||
patternType = ch;
|
patternType = ch;
|
||||||
|
@@ -33,6 +33,7 @@ import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_OPTIONAL
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.runAfterGotFocus
|
import com.maddyhome.idea.vim.helper.runAfterGotFocus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +46,7 @@ class ActionHandler : CommandHandler.SingleExecution() {
|
|||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
val actionName = cmd.argument.trim()
|
val actionName = cmd.argument.trim()
|
||||||
val action = ActionManager.getInstance().getAction(actionName) ?: run {
|
val action = ActionManager.getInstance().getAction(actionName) ?: run {
|
||||||
VimPlugin.showMessage("Action not found: $actionName")
|
VimPlugin.showMessage(MessageHelper.message("action.not.found.0", actionName))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val application = ApplicationManager.getApplication()
|
val application = ApplicationManager.getApplication()
|
||||||
|
@@ -30,6 +30,7 @@ import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
import com.maddyhome.idea.vim.ex.ExOutputModel
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper
|
import com.maddyhome.idea.vim.helper.StringHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,7 +56,7 @@ class ActionListHandler : CommandHandler.SingleExecution() {
|
|||||||
.joinToString(lineSeparator)
|
.joinToString(lineSeparator)
|
||||||
|
|
||||||
|
|
||||||
ExOutputModel.getInstance(editor).output("--- Actions ---$lineSeparator$actions")
|
ExOutputModel.getInstance(editor).output(MessageHelper.message("ex.show.all.actions.0.1", lineSeparator, actions))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.ex.CommandHandler
|
|||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles buffer, buf, bu, b.
|
* Handles buffer, buf, bu, b.
|
||||||
@@ -47,7 +48,7 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
val bufNum = buffer.toInt() - 1
|
val bufNum = buffer.toInt() - 1
|
||||||
|
|
||||||
if (!VimPlugin.getFile().selectFile(bufNum, context)) {
|
if (!VimPlugin.getFile().selectFile(bufNum, context)) {
|
||||||
VimPlugin.showMessage("Buffer $bufNum does not exist")
|
VimPlugin.showMessage(MessageHelper.message("buffer.0.does.not.exist", bufNum))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -55,12 +56,12 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
|
|
||||||
when(editors.size) {
|
when(editors.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
VimPlugin.showMessage("No matching buffer for $buffer")
|
VimPlugin.showMessage(MessageHelper.message("no.matching.buffer.for.0", buffer))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
if (EditorHelper.hasUnsavedChanges(editor) && !overrideModified) {
|
if (EditorHelper.hasUnsavedChanges(editor) && !overrideModified) {
|
||||||
VimPlugin.showMessage("No write since last change (add ! to override)")
|
VimPlugin.showMessage(MessageHelper.message("no.write.since.last.change.add.to.override"))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -68,7 +69,7 @@ class BufferHandler : CommandHandler.SingleExecution() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
VimPlugin.showMessage("More than one match for $buffer")
|
VimPlugin.showMessage(MessageHelper.message("more.than.one.match.for.0", buffer))
|
||||||
result = false
|
result = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
import com.maddyhome.idea.vim.ex.ExOutputModel
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +116,7 @@ class BufferListHandler : CommandHandler.SingleExecution() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getBufferStatus(editor: Editor, file: VirtualFile, currentFile: VirtualFile, previousFile: VirtualFile?): String {
|
private fun getBufferStatus(editor: Editor, file: VirtualFile, currentFile: VirtualFile, previousFile: VirtualFile?): String {
|
||||||
val bufStatus = StringBuilder()
|
@NonNls val bufStatus = StringBuilder()
|
||||||
|
|
||||||
when(file) {
|
when(file) {
|
||||||
currentFile -> bufStatus.append("%a ")
|
currentFile -> bufStatus.append("%a ")
|
||||||
|
@@ -32,6 +32,8 @@ import com.maddyhome.idea.vim.ex.ExOutputModel
|
|||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
import com.maddyhome.idea.vim.group.CommandGroup.Companion.BLACKLISTED_ALIASES
|
import com.maddyhome.idea.vim.group.CommandGroup.Companion.BLACKLISTED_ALIASES
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
@@ -42,16 +44,13 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// Static definitions needed for aliases.
|
// Static definitions needed for aliases.
|
||||||
private companion object {
|
private companion object {
|
||||||
const val overridePrefix = "!"
|
const val overridePrefix = "!"
|
||||||
const val argsPrefix = "-nargs"
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls const val argsPrefix = "-nargs"
|
||||||
|
|
||||||
const val anyNumberOfArguments = "*"
|
const val anyNumberOfArguments = "*"
|
||||||
const val zeroOrOneArguments = "?"
|
const val zeroOrOneArguments = "?"
|
||||||
const val moreThanZeroArguments = "+"
|
const val moreThanZeroArguments = "+"
|
||||||
|
|
||||||
const val errorInvalidNumberOfArguments = "E176: Invalid number of arguments"
|
|
||||||
const val errorCannotStartWithLowercase = "E183: User defined commands must start with an uppercase letter"
|
|
||||||
const val errorReservedName = "E841: Reserved name, cannot be used for user defined command"
|
|
||||||
const val errorCommandAlreadyExists = "E174: Command already exists: add ! to replace it"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute(cmd: ExCommand) {
|
override fun execute(cmd: ExCommand) {
|
||||||
@@ -95,7 +94,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// in the actual alias being created, and we don't want to parse that one.
|
// in the actual alias being created, and we don't want to parse that one.
|
||||||
val trimmedInput = argument.takeWhile { it != ' ' }
|
val trimmedInput = argument.takeWhile { it != ' ' }
|
||||||
val pattern = Regex("(?>-nargs=((|[-])\\d+|[?]|[+]|[*]))").find(trimmedInput) ?: run {
|
val pattern = Regex("(?>-nargs=((|[-])\\d+|[?]|[+]|[*]))").find(trimmedInput) ?: run {
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val nargForTrim = pattern.groupValues[0]
|
val nargForTrim = pattern.groupValues[0]
|
||||||
@@ -118,7 +117,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// I missed something, since the regex limits the value to be ? + * or
|
// I missed something, since the regex limits the value to be ? + * or
|
||||||
// a valid number, its not possible (as far as I know) to have another value
|
// a valid number, its not possible (as far as I know) to have another value
|
||||||
// that regex would accept that is not valid.
|
// that regex would accept that is not valid.
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +125,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// Not sure why this isn't documented, but if you try to create a command in vim
|
// Not sure why this isn't documented, but if you try to create a command in vim
|
||||||
// with an explicit number of arguments greater than 1 it returns this error.
|
// with an explicit number of arguments greater than 1 it returns this error.
|
||||||
if (argNum > 1 || argNum < 0) {
|
if (argNum > 1 || argNum < 0) {
|
||||||
VimPlugin.showMessage(errorInvalidNumberOfArguments)
|
VimPlugin.showMessage(MessageHelper.message("e176.invalid.number.of.arguments"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
minNumberOfArgs = argNum
|
minNumberOfArgs = argNum
|
||||||
@@ -148,12 +147,12 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
|
|
||||||
// User-aliases need to begin with an uppercase character.
|
// User-aliases need to begin with an uppercase character.
|
||||||
if (!alias[0].isUpperCase()) {
|
if (!alias[0].isUpperCase()) {
|
||||||
VimPlugin.showMessage(errorCannotStartWithLowercase)
|
VimPlugin.showMessage(MessageHelper.message("e183.user.defined.commands.must.start.with.an.uppercase.letter"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alias in BLACKLISTED_ALIASES) {
|
if (alias in BLACKLISTED_ALIASES) {
|
||||||
VimPlugin.showMessage(errorReservedName)
|
VimPlugin.showMessage(MessageHelper.message("e841.reserved.name.cannot.be.used.for.user.defined.command"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +168,7 @@ class CmdHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|||||||
// If we are not over-writing existing aliases, and an alias with the same command
|
// If we are not over-writing existing aliases, and an alias with the same command
|
||||||
// already exists then we want to do nothing.
|
// already exists then we want to do nothing.
|
||||||
if (!overrideAlias && VimPlugin.getCommand().hasAlias(alias)) {
|
if (!overrideAlias && VimPlugin.getCommand().hasAlias(alias)) {
|
||||||
VimPlugin.showMessage(errorCommandAlreadyExists)
|
VimPlugin.showMessage(MessageHelper.message("e174.command.already.exists.add.to.replace.it"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,12 +24,13 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
class DelCmdHandler : CommandHandler.SingleExecution() {
|
class DelCmdHandler : CommandHandler.SingleExecution() {
|
||||||
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_REQUIRED, Access.READ_ONLY)
|
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_REQUIRED, Access.READ_ONLY)
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
if (!VimPlugin.getCommand().hasAlias(cmd.argument)) {
|
if (!VimPlugin.getCommand().hasAlias(cmd.argument)) {
|
||||||
VimPlugin.showMessage("E184: No such user-defined command: ${cmd.argument}")
|
VimPlugin.showMessage(MessageHelper.message("e184.no.such.user.defined.command.0", cmd.argument))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.UnsupportedEncodingException
|
import java.io.UnsupportedEncodingException
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class HelpHandler : CommandHandler.SingleExecution() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
private fun helpTopicUrl(topic: String): String {
|
private fun helpTopicUrl(topic: String): String {
|
||||||
if (topic.isBlank()) return HELP_ROOT_URL
|
if (topic.isBlank()) return HELP_ROOT_URL
|
||||||
|
|
||||||
|
@@ -36,7 +36,6 @@ import com.maddyhome.idea.vim.helper.EditorHelper
|
|||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.Msg
|
import com.maddyhome.idea.vim.helper.Msg
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class MoveTextHandler : CommandHandler.SingleExecution() {
|
class MoveTextHandler : CommandHandler.SingleExecution() {
|
||||||
|
@@ -28,9 +28,8 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
import com.maddyhome.idea.vim.helper.inBlockSubMode
|
||||||
import java.util.*
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Alex Selesse
|
* @author Alex Selesse
|
||||||
|
@@ -24,11 +24,14 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
class SplitHandler : CommandHandler.SingleExecution() {
|
class SplitHandler : CommandHandler.SingleExecution() {
|
||||||
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY)
|
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY)
|
||||||
|
@NonNls private val visualSplitPrefix = "v"
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
||||||
if (cmd.command.startsWith("v")) {
|
if (cmd.command.startsWith(visualSplitPrefix)) {
|
||||||
VimPlugin.getWindow().splitWindowVertical(context, cmd.argument)
|
VimPlugin.getWindow().splitWindowVertical(context, cmd.argument)
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.getWindow().splitWindowHorizontal(context, cmd.argument)
|
VimPlugin.getWindow().splitWindowHorizontal(context, cmd.argument)
|
||||||
|
@@ -26,6 +26,7 @@ import com.maddyhome.idea.vim.VimPlugin
|
|||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rieon Ke
|
* @author Rieon Ke
|
||||||
@@ -51,7 +52,7 @@ class TabCloseHandler : CommandHandler.SingleExecution() {
|
|||||||
val select = if (index == current) index + 1 else current
|
val select = if (index == current) index + 1 else current
|
||||||
tabbedPane.removeTabAt(index, select)
|
tabbedPane.removeTabAt(index, select)
|
||||||
} else {
|
} else {
|
||||||
VimPlugin.showMessage("Error: invalid command argument")
|
VimPlugin.showMessage(MessageHelper.message("error.invalid.command.argument"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
31
src/com/maddyhome/idea/vim/ex/handler/mapping/CommandInfo.kt
Normal file
31
src/com/maddyhome/idea/vim/ex/handler/mapping/CommandInfo.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
internal class CommandInfo(
|
||||||
|
@NonNls val prefix: String,
|
||||||
|
@NonNls suffix: String,
|
||||||
|
val mappingModes: Set<MappingMode>,
|
||||||
|
val isRecursive: Boolean
|
||||||
|
) {
|
||||||
|
val command = if (suffix.isBlank()) prefix else "$prefix[$suffix]"
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandName
|
||||||
|
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
|
|
||||||
|
class MapClearHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, ComplicatedNameExCommand {
|
||||||
|
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_FORBIDDEN, READ_ONLY)
|
||||||
|
override val names: Array<CommandName> = COMMAND_NAMES
|
||||||
|
|
||||||
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean = executeCommand(cmd)
|
||||||
|
|
||||||
|
override fun execute(cmd: ExCommand) {
|
||||||
|
executeCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeCommand(cmd: ExCommand): Boolean {
|
||||||
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
|
|
||||||
|
VimPlugin.getKey().removeKeyMapping(commandInfo.mappingModes)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMMAND_INFOS = arrayOf(
|
||||||
|
CommandInfo("mapc", "lear", MappingMode.NVO, false),
|
||||||
|
CommandInfo("nmapc", "lear", MappingMode.N, false),
|
||||||
|
CommandInfo("vmapc", "lear", MappingMode.V, false),
|
||||||
|
CommandInfo("xmapc", "lear", MappingMode.X, false),
|
||||||
|
CommandInfo("smapc", "lear", MappingMode.S, false),
|
||||||
|
CommandInfo("omapc", "lear", MappingMode.O, false),
|
||||||
|
CommandInfo("imapc", "lear", MappingMode.I, false),
|
||||||
|
CommandInfo("cmapc", "lear", MappingMode.C, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val COMMAND_NAMES = commands(*COMMAND_INFOS.map { it.command }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
@@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
@@ -30,11 +30,12 @@ import com.maddyhome.idea.vim.ex.ExCommand
|
|||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ex.commands
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
import com.maddyhome.idea.vim.ex.handler.MapHandler.SpecialArgument.EXPR
|
import com.maddyhome.idea.vim.ex.handler.mapping.MapHandler.SpecialArgument.EXPR
|
||||||
import com.maddyhome.idea.vim.ex.handler.MapHandler.SpecialArgument.SCRIPT
|
import com.maddyhome.idea.vim.ex.handler.mapping.MapHandler.SpecialArgument.SCRIPT
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
@@ -57,34 +58,32 @@ class MapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, Co
|
|||||||
|
|
||||||
@Throws(ExException::class)
|
@Throws(ExException::class)
|
||||||
private fun executeCommand(cmd: ExCommand, editor: Editor?): Boolean {
|
private fun executeCommand(cmd: ExCommand, editor: Editor?): Boolean {
|
||||||
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) }
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
if (commandInfo != null) {
|
val argument = cmd.argument
|
||||||
val argument = cmd.argument
|
val modes = commandInfo.mappingModes
|
||||||
val modes = commandInfo.mappingModes
|
|
||||||
if (argument.isEmpty()) {
|
|
||||||
return editor != null && VimPlugin.getKey().showKeyMappings(modes, editor)
|
|
||||||
} else {
|
|
||||||
val arguments = try {
|
|
||||||
parseCommandArguments(argument)
|
|
||||||
} catch (ignored: IllegalArgumentException) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments != null) {
|
if (argument.isEmpty()) return editor != null && VimPlugin.getKey().showKeyMappings(modes, editor)
|
||||||
for (unsupportedArgument in UNSUPPORTED_SPECIAL_ARGUMENTS) {
|
|
||||||
if (unsupportedArgument in arguments.specialArguments) {
|
val arguments = try {
|
||||||
throw ExException("Unsupported map argument: $unsupportedArgument")
|
parseCommandArguments(argument) ?: return false
|
||||||
}
|
} catch (ignored: IllegalArgumentException) {
|
||||||
}
|
return false
|
||||||
VimPlugin.getKey().putKeyMapping(modes, arguments.fromKeys, MappingOwner.IdeaVim, arguments.toKeys, commandInfo.isRecursive)
|
}
|
||||||
return true
|
|
||||||
}
|
for (unsupportedArgument in UNSUPPORTED_SPECIAL_ARGUMENTS) {
|
||||||
|
if (unsupportedArgument in arguments.specialArguments) {
|
||||||
|
throw ExException("Unsupported map argument: $unsupportedArgument")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
|
VimPlugin.getKey()
|
||||||
|
.putKeyMapping(modes, arguments.fromKeys, MappingOwner.IdeaVim, arguments.toKeys, commandInfo.isRecursive)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@NonNls
|
||||||
private enum class SpecialArgument(val myName: String) {
|
private enum class SpecialArgument(val myName: String) {
|
||||||
BUFFER("<buffer>"),
|
BUFFER("<buffer>"),
|
||||||
NOWAIT("<nowait>"),
|
NOWAIT("<nowait>"),
|
||||||
@@ -113,10 +112,6 @@ class MapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, Co
|
|||||||
private class CommandArguments(val specialArguments: Set<SpecialArgument>, val fromKeys: List<KeyStroke>,
|
private class CommandArguments(val specialArguments: Set<SpecialArgument>, val fromKeys: List<KeyStroke>,
|
||||||
val toKeys: List<KeyStroke>)
|
val toKeys: List<KeyStroke>)
|
||||||
|
|
||||||
private class CommandInfo(val prefix: String, suffix: String, val mappingModes: Set<MappingMode>, val isRecursive: Boolean) {
|
|
||||||
val command = if (suffix.isBlank()) prefix else "$prefix[$suffix]"
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CTRL_V = '\u0016'
|
private const val CTRL_V = '\u0016'
|
||||||
private val COMMAND_INFOS = arrayOf(
|
private val COMMAND_INFOS = arrayOf(
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||||
|
* Copyright (C) 2003-2020 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.maddyhome.idea.vim.ex.handler.mapping
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
|
import com.maddyhome.idea.vim.command.MappingMode
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_REQUIRED
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
||||||
|
import com.maddyhome.idea.vim.ex.CommandName
|
||||||
|
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.ExCommand
|
||||||
|
import com.maddyhome.idea.vim.ex.commands
|
||||||
|
import com.maddyhome.idea.vim.ex.flags
|
||||||
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
||||||
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
|
|
||||||
|
class UnMapHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler, ComplicatedNameExCommand {
|
||||||
|
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_REQUIRED, READ_ONLY)
|
||||||
|
override val names: Array<CommandName> = COMMAND_NAMES
|
||||||
|
|
||||||
|
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean = executeCommand(cmd)
|
||||||
|
|
||||||
|
override fun execute(cmd: ExCommand) {
|
||||||
|
executeCommand(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun executeCommand(cmd: ExCommand): Boolean {
|
||||||
|
val commandInfo = COMMAND_INFOS.find { cmd.command.startsWith(it.prefix) } ?: return false
|
||||||
|
val argument = cmd.argument
|
||||||
|
|
||||||
|
if (argument.isEmpty()) return false
|
||||||
|
|
||||||
|
val parsedKeys = parseKeys(argument.trimStart())
|
||||||
|
|
||||||
|
VimPlugin.getKey().removeKeyMapping(commandInfo.mappingModes, parsedKeys)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMMAND_INFOS = arrayOf(
|
||||||
|
CommandInfo("unm", "ap", MappingMode.NVO, false),
|
||||||
|
CommandInfo("nun", "map", MappingMode.N, false),
|
||||||
|
CommandInfo("vu", "nmap", MappingMode.V, false),
|
||||||
|
CommandInfo("xu", "nmap", MappingMode.X, false),
|
||||||
|
CommandInfo("sunm", "ap", MappingMode.S, false),
|
||||||
|
CommandInfo("ou", "nmap", MappingMode.O, false),
|
||||||
|
CommandInfo("iu", "nmap", MappingMode.I, false),
|
||||||
|
CommandInfo("cu", "nmap", MappingMode.C, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val COMMAND_NAMES = commands(*COMMAND_INFOS.map { it.command }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
@@ -24,6 +24,7 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,6 +180,7 @@ class Ranges {
|
|||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
override fun toString(): String = "Ranges[ranges=$ranges]"
|
override fun toString(): String = "Ranges[ranges=$ranges]"
|
||||||
|
|
||||||
private var startLine = 0
|
private var startLine = 0
|
||||||
|
@@ -20,6 +20,7 @@ package com.maddyhome.idea.vim.ex.vimscript
|
|||||||
import com.maddyhome.idea.vim.ex.CommandParser
|
import com.maddyhome.idea.vim.ex.CommandParser
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
import com.maddyhome.idea.vim.ex.ExException
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState
|
import com.maddyhome.idea.vim.ui.VimRcFileState
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@@ -30,8 +31,14 @@ import java.util.regex.Pattern
|
|||||||
* @author vlan
|
* @author vlan
|
||||||
*/
|
*/
|
||||||
object VimScriptParser {
|
object VimScriptParser {
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val VIMRC_FILE_NAME = "ideavimrc"
|
private const val VIMRC_FILE_NAME = "ideavimrc"
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private val HOME_VIMRC_PATHS = arrayOf(".$VIMRC_FILE_NAME", "_$VIMRC_FILE_NAME")
|
private val HOME_VIMRC_PATHS = arrayOf(".$VIMRC_FILE_NAME", "_$VIMRC_FILE_NAME")
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private val XDG_VIMRC_PATH = "ideavim" + File.separator + VIMRC_FILE_NAME
|
private val XDG_VIMRC_PATH = "ideavim" + File.separator + VIMRC_FILE_NAME
|
||||||
private val DOUBLE_QUOTED_STRING = Pattern.compile("\"([^\"]*)\"")
|
private val DOUBLE_QUOTED_STRING = Pattern.compile("\"([^\"]*)\"")
|
||||||
private val SINGLE_QUOTED_STRING = Pattern.compile("'([^']*)'")
|
private val SINGLE_QUOTED_STRING = Pattern.compile("'([^']*)'")
|
||||||
|
@@ -21,7 +21,6 @@ package com.maddyhome.idea.vim.extension
|
|||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
||||||
import com.intellij.util.xmlb.annotations.Attribute
|
import com.intellij.util.xmlb.annotations.Attribute
|
||||||
import com.intellij.util.xmlb.annotations.CollectionBean
|
|
||||||
import com.intellij.util.xmlb.annotations.Tag
|
import com.intellij.util.xmlb.annotations.Tag
|
||||||
import com.intellij.util.xmlb.annotations.XCollection
|
import com.intellij.util.xmlb.annotations.XCollection
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
@@ -20,6 +20,7 @@ package com.maddyhome.idea.vim.extension;
|
|||||||
|
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
|
import com.maddyhome.idea.vim.helper.VimNlsSafe;
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner;
|
import com.maddyhome.idea.vim.key.MappingOwner;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -36,6 +37,7 @@ public interface VimExtension {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ApiStatus.ScheduledForRemoval(inVersion = "0.65")
|
@ApiStatus.ScheduledForRemoval(inVersion = "0.65")
|
||||||
|
@VimNlsSafe
|
||||||
@NotNull String getName();
|
@NotNull String getName();
|
||||||
|
|
||||||
default MappingOwner getOwner() {
|
default MappingOwner getOwner() {
|
||||||
|
@@ -30,7 +30,7 @@ import com.maddyhome.idea.vim.helper.TestInputModel
|
|||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
import com.maddyhome.idea.vim.key.MappingOwner
|
import com.maddyhome.idea.vim.key.MappingOwner
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel
|
||||||
import com.maddyhome.idea.vim.ui.ModalEntry
|
import com.maddyhome.idea.vim.ui.ModalEntry
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
@@ -12,12 +12,16 @@ import com.maddyhome.idea.vim.extension.VimExtension;
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
||||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
||||||
import com.maddyhome.idea.vim.helper.InlayHelperKt;
|
import com.maddyhome.idea.vim.helper.InlayHelperKt;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
import com.maddyhome.idea.vim.listener.SelectionVimListenerSuppressor;
|
||||||
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
import com.maddyhome.idea.vim.listener.VimListenerSuppressor;
|
||||||
|
import org.jetbrains.annotations.Nls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
|
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping;
|
||||||
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
|
import static com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping;
|
||||||
@@ -183,7 +187,8 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
try {
|
try {
|
||||||
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
bracketPairs = BracketPairs.fromBracketPairList(bracketPairsVar);
|
||||||
} catch (BracketPairs.ParseException parseException) {
|
} catch (BracketPairs.ParseException parseException) {
|
||||||
VimPlugin.showMessage("argtextobj: Invalid value of g:argtextobj_pairs -- " + parseException.getMessage());
|
VimPlugin.showMessage(
|
||||||
|
MessageHelper.message("argtextobj.invalid.value.of.g.argtextobj.pairs.0", parseException.getMessage()));
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -259,7 +264,7 @@ public class VimArgTextObjExtension implements VimExtension {
|
|||||||
private int rightBound = Integer.MIN_VALUE;
|
private int rightBound = Integer.MIN_VALUE;
|
||||||
private int leftBracket;
|
private int leftBracket;
|
||||||
private int rightBracket;
|
private int rightBracket;
|
||||||
private String error = null;
|
private @Nls String error = null;
|
||||||
private static final String QUOTES = "\"'";
|
private static final String QUOTES = "\"'";
|
||||||
|
|
||||||
private static final int MAX_SEARCH_LINES = 10;
|
private static final int MAX_SEARCH_LINES = 10;
|
||||||
|
@@ -51,6 +51,7 @@ import com.maddyhome.idea.vim.helper.moveToInlayAwareLogicalPosition
|
|||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This emulation misses:
|
* This emulation misses:
|
||||||
@@ -80,8 +81,11 @@ class VimExchangeExtension : VimExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_CMD = "<Plug>(Exchange)"
|
const val EXCHANGE_CMD = "<Plug>(Exchange)"
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_CLEAR_CMD = "<Plug>(ExchangeClear)"
|
const val EXCHANGE_CLEAR_CMD = "<Plug>(ExchangeClear)"
|
||||||
|
@NonNls
|
||||||
const val EXCHANGE_LINE_CMD = "<Plug>(ExchangeLine)"
|
const val EXCHANGE_LINE_CMD = "<Plug>(ExchangeLine)"
|
||||||
|
|
||||||
val EXCHANGE_KEY = Key<Exchange>("exchange")
|
val EXCHANGE_KEY = Key<Exchange>("exchange")
|
||||||
|
@@ -35,16 +35,21 @@ import com.maddyhome.idea.vim.VimProjectService
|
|||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment
|
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
import com.maddyhome.idea.vim.extension.VimExtension
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.listener.VimInsertListener
|
import com.maddyhome.idea.vim.listener.VimInsertListener
|
||||||
import com.maddyhome.idea.vim.listener.VimYankListener
|
import com.maddyhome.idea.vim.listener.VimYankListener
|
||||||
import com.maddyhome.idea.vim.option.StrictMode
|
import com.maddyhome.idea.vim.option.StrictMode
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
const val DEFAULT_HIGHLIGHT_DURATION: Long = 300
|
||||||
|
|
||||||
|
@NonNls
|
||||||
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
private const val HIGHLIGHT_DURATION_VARIABLE_NAME = "g:highlightedyank_highlight_duration"
|
||||||
|
@NonNls
|
||||||
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
private const val HIGHLIGHT_COLOR_VARIABLE_NAME = "g:highlightedyank_highlight_color"
|
||||||
private var defaultHighlightTextColor: Color? = null
|
private var defaultHighlightTextColor: Color? = null
|
||||||
|
|
||||||
@@ -197,7 +202,13 @@ class VimHighlightedYank: VimExtension, VimYankListener, VimInsertListener {
|
|||||||
extractFun(value)
|
extractFun(value)
|
||||||
}
|
}
|
||||||
catch (e: Exception){
|
catch (e: Exception){
|
||||||
VimPlugin.showMessage("highlightedyank: Invalid value of $variableName -- ${e.message}")
|
VimPlugin.showMessage(
|
||||||
|
MessageHelper.message(
|
||||||
|
"highlightedyank.invalid.value.of.0.1",
|
||||||
|
variableName,
|
||||||
|
e.message ?: ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
default
|
default
|
||||||
}
|
}
|
||||||
|
@@ -33,22 +33,41 @@ import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
|||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSelection
|
import com.maddyhome.idea.vim.group.visual.vimSetSelection
|
||||||
|
import com.maddyhome.idea.vim.helper.Direction
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper.findWordUnderCursor
|
import com.maddyhome.idea.vim.helper.SearchHelper.findWordUnderCursor
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
||||||
import com.maddyhome.idea.vim.helper.endOffsetInclusive
|
import com.maddyhome.idea.vim.helper.endOffsetInclusive
|
||||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
import com.maddyhome.idea.vim.helper.exitVisualMode
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
import com.maddyhome.idea.vim.helper.inVisualMode
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.lang.Integer.min
|
import java.lang.Integer.min
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.Comparator
|
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val NEXT_WHOLE_OCCURRENCE = "<Plug>NextWholeOccurrence"
|
private const val NEXT_WHOLE_OCCURRENCE = "<Plug>NextWholeOccurrence"
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val NEXT_OCCURRENCE = "<Plug>NextOccurrence"
|
private const val NEXT_OCCURRENCE = "<Plug>NextOccurrence"
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val SKIP_OCCURRENCE = "<Plug>SkipOccurrence"
|
private const val SKIP_OCCURRENCE = "<Plug>SkipOccurrence"
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val REMOVE_OCCURRENCE = "<Plug>RemoveOccurrence"
|
private const val REMOVE_OCCURRENCE = "<Plug>RemoveOccurrence"
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val ALL_WHOLE_OCCURRENCES = "<Plug>AllWholeOccurrences"
|
private const val ALL_WHOLE_OCCURRENCES = "<Plug>AllWholeOccurrences"
|
||||||
|
|
||||||
|
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
||||||
|
@NonNls
|
||||||
private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,11 +81,23 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(NEXT_WHOLE_OCCURRENCE), owner, NextOccurrenceHandler(), false)
|
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(NEXT_WHOLE_OCCURRENCE), owner, NextOccurrenceHandler(), false)
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(NEXT_OCCURRENCE), owner, NextOccurrenceHandler(whole = false), false)
|
putExtensionHandlerMapping(
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(ALL_WHOLE_OCCURRENCES), owner, AllOccurrencesHandler(), false )
|
MappingMode.NXO,
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(ALL_OCCURRENCES), owner, AllOccurrencesHandler(whole = false), false )
|
parseKeys(NEXT_OCCURRENCE),
|
||||||
putExtensionHandlerMapping(MappingMode.X, parseKeys(SKIP_OCCURRENCE), owner, SkipOccurrenceHandler(), false )
|
owner,
|
||||||
putExtensionHandlerMapping(MappingMode.X, parseKeys(REMOVE_OCCURRENCE), owner, RemoveOccurrenceHandler(), false )
|
NextOccurrenceHandler(whole = false),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(ALL_WHOLE_OCCURRENCES), owner, AllOccurrencesHandler(), false)
|
||||||
|
putExtensionHandlerMapping(
|
||||||
|
MappingMode.NXO,
|
||||||
|
parseKeys(ALL_OCCURRENCES),
|
||||||
|
owner,
|
||||||
|
AllOccurrencesHandler(whole = false),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
putExtensionHandlerMapping(MappingMode.X, parseKeys(SKIP_OCCURRENCE), owner, SkipOccurrenceHandler(), false)
|
||||||
|
putExtensionHandlerMapping(MappingMode.X, parseKeys(REMOVE_OCCURRENCE), owner, RemoveOccurrenceHandler(), false)
|
||||||
|
|
||||||
putKeyMapping(MappingMode.NXO, parseKeys("<A-n>"), owner, parseKeys(NEXT_WHOLE_OCCURRENCE), true)
|
putKeyMapping(MappingMode.NXO, parseKeys("<A-n>"), owner, parseKeys(NEXT_WHOLE_OCCURRENCE), true)
|
||||||
putKeyMapping(MappingMode.NXO, parseKeys("g<A-n>"), owner, parseKeys(NEXT_OCCURRENCE), true)
|
putKeyMapping(MappingMode.NXO, parseKeys("g<A-n>"), owner, parseKeys(NEXT_OCCURRENCE), true)
|
||||||
@@ -87,7 +118,8 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
inner class NextOccurrenceHandler(val whole: Boolean = true) : WriteActionHandler() {
|
inner class NextOccurrenceHandler(val whole: Boolean = true) : WriteActionHandler() {
|
||||||
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
||||||
val caretModel = editor.caretModel
|
val caretModel = editor.caretModel
|
||||||
val patternComparator = if (OptionsManager.ignorecase.isSet) String.CASE_INSENSITIVE_ORDER else Comparator(String::compareTo)
|
val patternComparator =
|
||||||
|
if (OptionsManager.ignorecase.isSet) String.CASE_INSENSITIVE_ORDER else Comparator(String::compareTo)
|
||||||
|
|
||||||
if (!editor.inVisualMode) {
|
if (!editor.inVisualMode) {
|
||||||
if (caretModel.caretCount > 1) return
|
if (caretModel.caretCount > 1) return
|
||||||
@@ -97,7 +129,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
if (range.startOffset > caret.offset) return
|
if (range.startOffset > caret.offset) return
|
||||||
|
|
||||||
val nextOffset = findNextOccurrence(editor, caret, range, whole)
|
val nextOffset = findNextOccurrence(editor, caret, range, whole)
|
||||||
if (nextOffset == caret.selectionStart) VimPlugin.showMessage("No more matches")
|
if (nextOffset == caret.selectionStart) VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
} else {
|
} else {
|
||||||
val newPositions = arrayListOf<VisualPosition>()
|
val newPositions = arrayListOf<VisualPosition>()
|
||||||
val patterns = sortedSetOf(patternComparator)
|
val patterns = sortedSetOf(patternComparator)
|
||||||
@@ -125,10 +157,18 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
val primaryCaret = editor.caretModel.primaryCaret
|
val primaryCaret = editor.caretModel.primaryCaret
|
||||||
val nextOffset = VimPlugin.getSearch().searchNextFromOffset(editor, primaryCaret.offset + 1, 1)
|
val nextOffset = VimPlugin.getSearch().searchNextFromOffset(editor, primaryCaret.offset + 1, 1)
|
||||||
val pattern = patterns.first()
|
val pattern = patterns.first()
|
||||||
if (nextOffset == -1 || patternComparator.compare(EditorHelper.getText(editor, nextOffset, nextOffset + pattern.length), pattern) != 0) {
|
if (nextOffset == -1 || patternComparator.compare(
|
||||||
|
EditorHelper.getText(
|
||||||
|
editor,
|
||||||
|
nextOffset,
|
||||||
|
nextOffset + pattern.length
|
||||||
|
), pattern
|
||||||
|
) != 0
|
||||||
|
) {
|
||||||
if (caretModel.caretCount > 1) return
|
if (caretModel.caretCount > 1) return
|
||||||
|
|
||||||
val newNextOffset = VimPlugin.getSearch().search(editor, pattern, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
val newNextOffset =
|
||||||
|
VimPlugin.getSearch().search(editor, pattern, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
||||||
|
|
||||||
if (newNextOffset != -1) {
|
if (newNextOffset != -1) {
|
||||||
val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(newNextOffset)) ?: return
|
val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(newNextOffset)) ?: return
|
||||||
@@ -140,7 +180,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
|
|
||||||
caretModel.allCarets.forEach {
|
caretModel.allCarets.forEach {
|
||||||
if (it.selectionStart == nextOffset) {
|
if (it.selectionStart == nextOffset) {
|
||||||
VimPlugin.showMessage("No more matches")
|
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +199,8 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
val primaryCaret = caretModel.primaryCaret
|
val primaryCaret = caretModel.primaryCaret
|
||||||
var nextOffset = if (editor.inVisualMode) {
|
var nextOffset = if (editor.inVisualMode) {
|
||||||
val selectedText = primaryCaret.selectedText ?: return
|
val selectedText = primaryCaret.selectedText ?: return
|
||||||
val nextOffset = VimPlugin.getSearch().search(editor, selectedText, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
val nextOffset =
|
||||||
|
VimPlugin.getSearch().search(editor, selectedText, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
||||||
nextOffset
|
nextOffset
|
||||||
} else {
|
} else {
|
||||||
val range = findWordUnderCursor(editor, primaryCaret) ?: return
|
val range = findWordUnderCursor(editor, primaryCaret) ?: return
|
||||||
@@ -194,7 +235,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
|
|
||||||
editor.caretModel.allCarets.forEach {
|
editor.caretModel.allCarets.forEach {
|
||||||
if (it.selectionStart == nextOffset) {
|
if (it.selectionStart == nextOffset) {
|
||||||
VimPlugin.showMessage("No more matches")
|
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +270,7 @@ class VimMultipleCursorsExtension : VimExtension {
|
|||||||
val wordRange = VimPlugin.getMotion().getWordRange(editor, caret, 1, false, false)
|
val wordRange = VimPlugin.getMotion().getWordRange(editor, caret, 1, false, false)
|
||||||
caret.vimSetSelection(wordRange.startOffset, wordRange.endOffsetInclusive, true)
|
caret.vimSetSelection(wordRange.startOffset, wordRange.endOffsetInclusive, true)
|
||||||
|
|
||||||
val offset = VimPlugin.getSearch().searchWord(editor, caret, 1, whole, 1)
|
val offset = VimPlugin.getSearch().searchWord(editor, caret, 1, whole, Direction.FORWARDS)
|
||||||
MotionGroup.moveCaret(editor, caret, range.endOffset - 1)
|
MotionGroup.moveCaret(editor, caret, range.endOffset - 1)
|
||||||
|
|
||||||
return offset
|
return offset
|
||||||
|
@@ -42,6 +42,7 @@ import com.maddyhome.idea.vim.helper.exitVisualMode
|
|||||||
import com.maddyhome.idea.vim.helper.subMode
|
import com.maddyhome.idea.vim.helper.subMode
|
||||||
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
import com.maddyhome.idea.vim.helper.vimForEachCaret
|
||||||
import com.maddyhome.idea.vim.key.OperatorFunction
|
import com.maddyhome.idea.vim.key.OperatorFunction
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
|
|
||||||
class ReplaceWithRegister : VimExtension {
|
class ReplaceWithRegister : VimExtension {
|
||||||
@@ -123,8 +124,11 @@ class ReplaceWithRegister : VimExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@NonNls
|
||||||
private const val RWR_OPERATOR = "<Plug>ReplaceWithRegisterOperator"
|
private const val RWR_OPERATOR = "<Plug>ReplaceWithRegisterOperator"
|
||||||
|
@NonNls
|
||||||
private const val RWR_LINE = "<Plug>ReplaceWithRegisterLine"
|
private const val RWR_LINE = "<Plug>ReplaceWithRegisterLine"
|
||||||
|
@NonNls
|
||||||
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
private const val RWR_VISUAL = "<Plug>ReplaceWithRegisterVisual"
|
||||||
|
|
||||||
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
|
private fun doReplace(editor: Editor, visualSelection: PutData.VisualSelection) {
|
||||||
|
@@ -69,6 +69,7 @@ import com.maddyhome.idea.vim.option.BoundListOption;
|
|||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.text.StringsKt;
|
import kotlin.text.StringsKt;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -93,6 +94,9 @@ public class ChangeGroup {
|
|||||||
private static final ImmutableSet<String> wordMotions =
|
private static final ImmutableSet<String> wordMotions =
|
||||||
ImmutableSet.of(VIM_MOTION_WORD_RIGHT, VIM_MOTION_BIG_WORD_RIGHT, VIM_MOTION_CAMEL_RIGHT);
|
ImmutableSet.of(VIM_MOTION_WORD_RIGHT, VIM_MOTION_BIG_WORD_RIGHT, VIM_MOTION_CAMEL_RIGHT);
|
||||||
|
|
||||||
|
@NonNls private static final String HEX_START = "0x";
|
||||||
|
@NonNls private static final String MAX_HEX_INTEGER = "ffffffffffffffff";
|
||||||
|
|
||||||
private @Nullable Command lastInsert;
|
private @Nullable Command lastInsert;
|
||||||
|
|
||||||
private List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
private List<VimInsertListener> insertListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||||
@@ -1940,7 +1944,7 @@ public class ChangeGroup {
|
|||||||
|
|
||||||
char ch = text.charAt(0);
|
char ch = text.charAt(0);
|
||||||
if (hex && SearchHelper.NumberType.HEX.equals(numberType)) {
|
if (hex && SearchHelper.NumberType.HEX.equals(numberType)) {
|
||||||
if (!text.toLowerCase().startsWith("0x")) throw new RuntimeException("Hex number should start with 0x: " + text);
|
if (!text.toLowerCase().startsWith(HEX_START)) throw new RuntimeException("Hex number should start with 0x: " + text);
|
||||||
for (int i = text.length() - 1; i >= 2; i--) {
|
for (int i = text.length() - 1; i >= 2; i--) {
|
||||||
int index = "abcdefABCDEF".indexOf(text.charAt(i));
|
int index = "abcdefABCDEF".indexOf(text.charAt(i));
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
@@ -1952,7 +1956,7 @@ public class ChangeGroup {
|
|||||||
BigInteger num = new BigInteger(text.substring(2), 16);
|
BigInteger num = new BigInteger(text.substring(2), 16);
|
||||||
num = num.add(BigInteger.valueOf(count));
|
num = num.add(BigInteger.valueOf(count));
|
||||||
if (num.compareTo(BigInteger.ZERO) < 0) {
|
if (num.compareTo(BigInteger.ZERO) < 0) {
|
||||||
num = new BigInteger("ffffffffffffffff", 16).add(BigInteger.ONE).add(num);
|
num = new BigInteger(MAX_HEX_INTEGER, 16).add(BigInteger.ONE).add(num);
|
||||||
}
|
}
|
||||||
number = num.toString(16);
|
number = num.toString(16);
|
||||||
number = StringsKt.padStart(number, text.length() - 2, '0');
|
number = StringsKt.padStart(number, text.length() - 2, '0');
|
||||||
|
@@ -19,13 +19,14 @@
|
|||||||
package com.maddyhome.idea.vim.group
|
package com.maddyhome.idea.vim.group
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.common.Alias
|
import com.maddyhome.idea.vim.common.Alias
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elliot Courant
|
* @author Elliot Courant
|
||||||
*/
|
*/
|
||||||
class CommandGroup {
|
class CommandGroup {
|
||||||
companion object {
|
companion object {
|
||||||
val BLACKLISTED_ALIASES = arrayOf("X", "Next", "Print")
|
@NonNls val BLACKLISTED_ALIASES = arrayOf("X", "Next", "Print")
|
||||||
private const val overridePrefix = "!"
|
private const val overridePrefix = "!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,14 +27,17 @@ import com.intellij.openapi.editor.*;
|
|||||||
import com.intellij.openapi.editor.event.CaretEvent;
|
import com.intellij.openapi.editor.event.CaretEvent;
|
||||||
import com.intellij.openapi.editor.event.CaretListener;
|
import com.intellij.openapi.editor.event.CaretListener;
|
||||||
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
||||||
|
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.maddyhome.idea.vim.KeyHandler;
|
import com.maddyhome.idea.vim.KeyHandler;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
|
import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
@State(name = "VimEditorSettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
||||||
public class EditorGroup implements PersistentStateComponent<Element> {
|
public class EditorGroup implements PersistentStateComponent<Element> {
|
||||||
private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
|
private static final boolean REFRAIN_FROM_SCROLLING_VIM_VALUE = true;
|
||||||
public static final String EDITOR_STORE_ELEMENT = "editor";
|
public static final @NonNls String EDITOR_STORE_ELEMENT = "editor";
|
||||||
|
|
||||||
private boolean isBlockCursor = false;
|
private boolean isBlockCursor = false;
|
||||||
private boolean isRefrainFromScrolling = false;
|
private boolean isRefrainFromScrolling = false;
|
||||||
@@ -203,6 +206,10 @@ public class EditorGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBarCursorSettings() {
|
||||||
|
return !EditorSettingsExternalizable.getInstance().isBlockCursor();
|
||||||
|
}
|
||||||
|
|
||||||
public void editorCreated(@NotNull Editor editor) {
|
public void editorCreated(@NotNull Editor editor) {
|
||||||
isBlockCursor = editor.getSettings().isBlockCursor();
|
isBlockCursor = editor.getSettings().isBlockCursor();
|
||||||
isRefrainFromScrolling = editor.getSettings().isRefrainFromScrolling();
|
isRefrainFromScrolling = editor.getSettings().isRefrainFromScrolling();
|
||||||
@@ -217,7 +224,7 @@ public class EditorGroup implements PersistentStateComponent<Element> {
|
|||||||
VimPlugin.getChange().insertBeforeCursor(editor, new EditorDataContext(editor, null));
|
VimPlugin.getChange().insertBeforeCursor(editor, new EditorDataContext(editor, null));
|
||||||
KeyHandler.getInstance().reset(editor);
|
KeyHandler.getInstance().reset(editor);
|
||||||
}
|
}
|
||||||
editor.getSettings().setBlockCursor(!CommandStateHelper.inInsertMode(editor));
|
VisualGroupKt.resetShape(CommandStateHelper.getMode(editor), editor);
|
||||||
editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
|
editor.getSettings().setRefrainFromScrolling(REFRAIN_FROM_SCROLLING_VIM_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,7 @@ import com.maddyhome.idea.vim.command.CommandState;
|
|||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper;
|
import com.maddyhome.idea.vim.helper.EditorHelper;
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelperRt;
|
import com.maddyhome.idea.vim.helper.EditorHelperRt;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper;
|
import com.maddyhome.idea.vim.helper.SearchHelper;
|
||||||
import com.maddyhome.idea.vim.option.IdeaWriteData;
|
import com.maddyhome.idea.vim.option.IdeaWriteData;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
@@ -85,7 +86,7 @@ public class FileGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VimPlugin.showMessage("Unable to find " + filename);
|
VimPlugin.showMessage(MessageHelper.message("unable.to.find.0", filename));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.helper.StringHelper;
|
|||||||
import com.maddyhome.idea.vim.option.NumberOption;
|
import com.maddyhome.idea.vim.option.NumberOption;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -39,10 +40,10 @@ import java.util.Map;
|
|||||||
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
||||||
})
|
})
|
||||||
public class HistoryGroup implements PersistentStateComponent<Element> {
|
public class HistoryGroup implements PersistentStateComponent<Element> {
|
||||||
public static final String SEARCH = "search";
|
public static final @NonNls String SEARCH = "search";
|
||||||
public static final String COMMAND = "cmd";
|
public static final @NonNls String COMMAND = "cmd";
|
||||||
public static final String EXPRESSION = "expr";
|
public static final @NonNls String EXPRESSION = "expr";
|
||||||
public static final String INPUT = "input";
|
public static final @NonNls String INPUT = "input";
|
||||||
|
|
||||||
public void addEntry(String key, @NotNull String text) {
|
public void addEntry(String key, @NotNull String text) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
@@ -47,6 +47,7 @@ import com.maddyhome.idea.vim.key.*;
|
|||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.text.StringsKt;
|
import kotlin.text.StringsKt;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -65,9 +66,9 @@ import static java.util.stream.Collectors.toList;
|
|||||||
*/
|
*/
|
||||||
@State(name = "VimKeySettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
@State(name = "VimKeySettings", storages = {@Storage(value = "$APP_CONFIG$/vim_settings.xml")})
|
||||||
public class KeyGroup implements PersistentStateComponent<Element> {
|
public class KeyGroup implements PersistentStateComponent<Element> {
|
||||||
public static final String SHORTCUT_CONFLICTS_ELEMENT = "shortcut-conflicts";
|
public static final @NonNls String SHORTCUT_CONFLICTS_ELEMENT = "shortcut-conflicts";
|
||||||
private static final String SHORTCUT_CONFLICT_ELEMENT = "shortcut-conflict";
|
private static final @NonNls String SHORTCUT_CONFLICT_ELEMENT = "shortcut-conflict";
|
||||||
private static final String OWNER_ATTRIBUTE = "owner";
|
private static final @NonNls String OWNER_ATTRIBUTE = "owner";
|
||||||
private static final String TEXT_ELEMENT = "text";
|
private static final String TEXT_ELEMENT = "text";
|
||||||
|
|
||||||
private static final Logger logger = Logger.getInstance(KeyGroup.class);
|
private static final Logger logger = Logger.getInstance(KeyGroup.class);
|
||||||
@@ -117,6 +118,14 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
unregisterKeyMapping(owner);
|
unregisterKeyMapping(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeKeyMapping(@NotNull Set<MappingMode> modes, @NotNull List<KeyStroke> keys) {
|
||||||
|
modes.stream().map(this::getKeyMapping).forEach(o -> o.delete(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeKeyMapping(@NotNull Set<MappingMode> modes) {
|
||||||
|
modes.stream().map(this::getKeyMapping).forEach(KeyMapping::delete);
|
||||||
|
}
|
||||||
|
|
||||||
public void putKeyMapping(@NotNull Set<MappingMode> modes,
|
public void putKeyMapping(@NotNull Set<MappingMode> modes,
|
||||||
@NotNull List<KeyStroke> fromKeys,
|
@NotNull List<KeyStroke> fromKeys,
|
||||||
@NotNull MappingOwner owner,
|
@NotNull MappingOwner owner,
|
||||||
@@ -467,7 +476,7 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NotNull String getModesStringCode(@NotNull Set<MappingMode> modes) {
|
private static @NotNull @NonNls String getModesStringCode(@NotNull Set<MappingMode> modes) {
|
||||||
if (modes.equals(MappingMode.NVO)) {
|
if (modes.equals(MappingMode.NVO)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -525,7 +534,7 @@ public class KeyGroup implements PersistentStateComponent<Element> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Element getState() {
|
public Element getState() {
|
||||||
Element element = new Element("key");
|
@NonNls Element element = new Element("key");
|
||||||
saveData(element);
|
saveData(element);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.maddyhome.idea.vim.KeyHandler;
|
import com.maddyhome.idea.vim.KeyHandler;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
import com.maddyhome.idea.vim.common.Register;
|
import com.maddyhome.idea.vim.common.Register;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper;
|
import com.maddyhome.idea.vim.helper.StringHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -130,7 +131,8 @@ public class MacroGroup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ApplicationManager.getApplication().invokeLater(
|
ApplicationManager.getApplication().invokeLater(
|
||||||
() -> CommandProcessor.getInstance().executeCommand(project, run, "Vim Macro Playback", keys.get(pos)));
|
() -> CommandProcessor.getInstance()
|
||||||
|
.executeCommand(project, run, MessageHelper.message("command.name.vim.macro.playback"), keys.get(pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postKey(@NotNull KeyStroke stroke, @NotNull Editor editor) {
|
public void postKey(@NotNull KeyStroke stroke, @NotNull Editor editor) {
|
||||||
|
@@ -48,6 +48,7 @@ import com.maddyhome.idea.vim.helper.SearchHelper;
|
|||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -811,7 +812,7 @@ public class MarkGroup implements PersistentStateComponent<Element> {
|
|||||||
private static final int SAVE_JUMP_COUNT = 100;
|
private static final int SAVE_JUMP_COUNT = 100;
|
||||||
|
|
||||||
public static final String WR_GLOBAL_MARKS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
public static final String WR_GLOBAL_MARKS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
public static final String WR_REGULAR_FILE_MARKS = "abcdefghijklmnopqrstuvwxyz";
|
public static final @NonNls String WR_REGULAR_FILE_MARKS = "abcdefghijklmnopqrstuvwxyz";
|
||||||
/** Marks: abcdefghijklmnopqrstuvwxyz' */
|
/** Marks: abcdefghijklmnopqrstuvwxyz' */
|
||||||
private static final String WR_FILE_MARKS = WR_REGULAR_FILE_MARKS + "'";
|
private static final String WR_FILE_MARKS = WR_REGULAR_FILE_MARKS + "'";
|
||||||
|
|
||||||
|
@@ -41,10 +41,11 @@ import com.maddyhome.idea.vim.group.visual.VisualGroupKt;
|
|||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler;
|
import com.maddyhome.idea.vim.handler.MotionActionHandler;
|
||||||
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
import com.maddyhome.idea.vim.handler.TextObjectActionHandler;
|
||||||
import com.maddyhome.idea.vim.helper.*;
|
import com.maddyhome.idea.vim.helper.*;
|
||||||
|
import com.maddyhome.idea.vim.listener.IdeaSpecifics;
|
||||||
import com.maddyhome.idea.vim.option.NumberOption;
|
import com.maddyhome.idea.vim.option.NumberOption;
|
||||||
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
import com.maddyhome.idea.vim.option.OptionChangeListener;
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager;
|
import com.maddyhome.idea.vim.option.OptionsManager;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import kotlin.ranges.IntProgression;
|
import kotlin.ranges.IntProgression;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
@@ -318,6 +319,8 @@ public class MotionGroup {
|
|||||||
else {
|
else {
|
||||||
ModeHelper.exitVisualMode(editor);
|
ModeHelper.exitVisualMode(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdeaSpecifics.AppCodeTemplates.onMovement(editor, caret, oldOffset < offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) {
|
private @Nullable Editor selectEditor(@NotNull Editor editor, @NotNull Mark mark) {
|
||||||
|
@@ -31,7 +31,7 @@ import com.maddyhome.idea.vim.common.TextRange;
|
|||||||
import com.maddyhome.idea.vim.ex.CommandParser;
|
import com.maddyhome.idea.vim.ex.CommandParser;
|
||||||
import com.maddyhome.idea.vim.ex.ExException;
|
import com.maddyhome.idea.vim.ex.ExException;
|
||||||
import com.maddyhome.idea.vim.helper.UiHelper;
|
import com.maddyhome.idea.vim.helper.UiHelper;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
package com.maddyhome.idea.vim.group;
|
package com.maddyhome.idea.vim.group;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor;
|
import com.intellij.codeInsight.editorActions.CopyPastePostProcessor;
|
||||||
import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
|
import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
|
||||||
import com.intellij.codeInsight.editorActions.TextBlockTransferable;
|
import com.intellij.codeInsight.editorActions.TextBlockTransferable;
|
||||||
@@ -62,6 +61,7 @@ import com.maddyhome.idea.vim.option.OptionsManager;
|
|||||||
import com.maddyhome.idea.vim.ui.ClipboardHandler;
|
import com.maddyhome.idea.vim.ui.ClipboardHandler;
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -80,18 +80,33 @@ import java.util.stream.Collectors;
|
|||||||
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
||||||
})
|
})
|
||||||
public class RegisterGroup implements PersistentStateComponent<Element> {
|
public class RegisterGroup implements PersistentStateComponent<Element> {
|
||||||
private static final String WRITABLE_REGISTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-*+_/\"";
|
public static final char UNNAMED_REGISTER = '"';
|
||||||
private static final String READONLY_REGISTERS = ":.%#=/";
|
public static final char LAST_SEARCH_REGISTER = '/'; // IdeaVim does not supporting writing to this register
|
||||||
private static final String RECORDABLE_REGISTER = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
public static final char LAST_COMMAND_REGISTER = ':';
|
||||||
private static final String PLAYBACK_REGISTER = RECORDABLE_REGISTER + "\".*+";
|
private static final char LAST_INSERTED_TEXT_REGISTER = '.';
|
||||||
|
public static final char SMALL_DELETION_REGISTER = '-';
|
||||||
|
private static final char BLACK_HOLE_REGISTER = '_';
|
||||||
|
private static final char ALTERNATE_BUFFER_REGISTER = '#'; // Not supported
|
||||||
|
private static final char EXPRESSION_BUFFER_REGISTER = '='; // Not supported
|
||||||
|
private static final char CURRENT_FILENAME_REGISTER = '%'; // Not supported
|
||||||
|
private static final @NonNls String CLIPBOARD_REGISTERS = "*+";
|
||||||
|
private static final @NonNls String NUMBERED_REGISTERS = "0123456789";
|
||||||
|
private static final @NonNls String NAMED_REGISTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
private static final @NonNls String WRITABLE_REGISTERS = NUMBERED_REGISTERS + NAMED_REGISTERS + CLIPBOARD_REGISTERS
|
||||||
|
+ SMALL_DELETION_REGISTER + BLACK_HOLE_REGISTER + UNNAMED_REGISTER + LAST_SEARCH_REGISTER;
|
||||||
|
private static final String READONLY_REGISTERS = ""
|
||||||
|
+ CURRENT_FILENAME_REGISTER + LAST_COMMAND_REGISTER + LAST_INSERTED_TEXT_REGISTER + ALTERNATE_BUFFER_REGISTER
|
||||||
|
+ EXPRESSION_BUFFER_REGISTER; // Expression buffer is not actually readonly
|
||||||
|
private static final @NonNls String RECORDABLE_REGISTERS = NUMBERED_REGISTERS + NAMED_REGISTERS;
|
||||||
|
private static final String PLAYBACK_REGISTERS = RECORDABLE_REGISTERS + UNNAMED_REGISTER + CLIPBOARD_REGISTERS + LAST_INSERTED_TEXT_REGISTER;
|
||||||
private static final String VALID_REGISTERS = WRITABLE_REGISTERS + READONLY_REGISTERS;
|
private static final String VALID_REGISTERS = WRITABLE_REGISTERS + READONLY_REGISTERS;
|
||||||
private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
|
|
||||||
private static final Logger logger = Logger.getInstance(RegisterGroup.class.getName());
|
private static final Logger logger = Logger.getInstance(RegisterGroup.class.getName());
|
||||||
|
|
||||||
public static final char UNNAMED_REGISTER = '"';
|
private final @NotNull HashMap<Character, Register> registers = new HashMap<>();
|
||||||
private char defaultRegister = UNNAMED_REGISTER;
|
private char defaultRegister = UNNAMED_REGISTER;
|
||||||
private char lastRegister = defaultRegister;
|
private char lastRegister = defaultRegister;
|
||||||
private final @NotNull HashMap<Character, Register> registers = new HashMap<>();
|
|
||||||
private char recordRegister = 0;
|
private char recordRegister = 0;
|
||||||
private @Nullable List<KeyStroke> recordList = null;
|
private @Nullable List<KeyStroke> recordList = null;
|
||||||
|
|
||||||
@@ -172,13 +187,43 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean storeTextInternal(@NotNull Editor editor, @NotNull TextRange range, @NotNull String text,
|
/**
|
||||||
@NotNull SelectionType type, char register, boolean isDelete) {
|
* Stores text, character wise, in the given special register
|
||||||
// Null register doesn't get saved
|
*
|
||||||
if (lastRegister == '_') return true;
|
* <p>This method is intended to support writing to registers when the text cannot be yanked from an editor. This is
|
||||||
|
* expected to only be used to update the search and command registers. It will not update named registers.</p>
|
||||||
|
*
|
||||||
|
* <p>While this method allows setting the unnamed register, this should only be done from tests, and only when it's
|
||||||
|
* not possible to yank or cut from the fixture editor. This method will skip additional text processing, and won't
|
||||||
|
* update other registers such as the small delete register or reorder the numbered registers. It is much more
|
||||||
|
* preferable to yank from the fixture editor.</p>
|
||||||
|
*
|
||||||
|
* @param register The register to use for storing the text. Cannot be a normal text register
|
||||||
|
* @param text The text to store, without further processing
|
||||||
|
* @return True if the text is stored, false if the passed register is not supported
|
||||||
|
*/
|
||||||
|
public boolean storeTextSpecial(char register, @NotNull String text) {
|
||||||
|
if (READONLY_REGISTERS.indexOf(register) == -1 && register != LAST_SEARCH_REGISTER
|
||||||
|
&& register != UNNAMED_REGISTER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
registers.put(register, new Register(register, SelectionType.CHARACTER_WISE, text, new ArrayList<>()));
|
||||||
|
if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + text + "\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean storeTextInternal(@NotNull Editor editor, @NotNull TextRange range, @NotNull String text,
|
||||||
|
@NotNull SelectionType type, char register, boolean isDelete) {
|
||||||
|
// Null register doesn't get saved, but acts like it was
|
||||||
|
if (lastRegister == BLACK_HOLE_REGISTER) return true;
|
||||||
|
|
||||||
int start = range.getStartOffset();
|
int start = range.getStartOffset();
|
||||||
int end = range.getEndOffset();
|
int end = range.getEndOffset();
|
||||||
|
|
||||||
|
if (isDelete && start == end) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Normalize the start and end
|
// Normalize the start and end
|
||||||
if (start > end) {
|
if (start > end) {
|
||||||
int t = start;
|
int t = start;
|
||||||
@@ -213,7 +258,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + processedText + "\"");
|
if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + processedText + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CLIPBOARD_REGISTERS.contains(register)) {
|
if (CLIPBOARD_REGISTERS.indexOf(register) >= 0) {
|
||||||
ClipboardHandler.setClipboardText(processedText, new ArrayList<>(transferableData), text);
|
ClipboardHandler.setClipboardText(processedText, new ArrayList<>(transferableData), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +287,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
// Deletes smaller than one line and without specified register go the the "-" register
|
// Deletes smaller than one line and without specified register go the the "-" register
|
||||||
if (smallInlineDeletion && register == defaultRegister) {
|
if (smallInlineDeletion && register == defaultRegister) {
|
||||||
registers.put('-', new Register('-', type, processedText, new ArrayList<>(transferableData)));
|
registers.put(SMALL_DELETION_REGISTER, new Register(SMALL_DELETION_REGISTER, type, processedText, new ArrayList<>(transferableData)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Yanks also go to register 0 if the default register was used
|
// Yanks also go to register 0 if the default register was used
|
||||||
@@ -332,7 +377,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Register getPlaybackRegister(char r) {
|
public @Nullable Register getPlaybackRegister(char r) {
|
||||||
if (PLAYBACK_REGISTER.indexOf(r) != 0) {
|
if (PLAYBACK_REGISTERS.indexOf(r) != 0) {
|
||||||
return getRegister(r);
|
return getRegister(r);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -345,7 +390,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
if (Character.isUpperCase(r)) {
|
if (Character.isUpperCase(r)) {
|
||||||
r = Character.toLowerCase(r);
|
r = Character.toLowerCase(r);
|
||||||
}
|
}
|
||||||
return CLIPBOARD_REGISTERS.contains(r) ? refreshClipboardRegister(r) : registers.get(r);
|
return CLIPBOARD_REGISTERS.indexOf(r) >= 0 ? refreshClipboardRegister(r) : registers.get(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveRegister(char r, Register register) {
|
public void saveRegister(char r, Register register) {
|
||||||
@@ -353,7 +398,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
if (Character.isUpperCase(r)) {
|
if (Character.isUpperCase(r)) {
|
||||||
r = Character.toLowerCase(r);
|
r = Character.toLowerCase(r);
|
||||||
}
|
}
|
||||||
if (CLIPBOARD_REGISTERS.contains(r)) {
|
if (CLIPBOARD_REGISTERS.indexOf(r) >= 0) {
|
||||||
ClipboardHandler.setClipboardText(register.getText(), new ArrayList<>(register.getTransferableData()), register.getRawText());
|
ClipboardHandler.setClipboardText(register.getText(), new ArrayList<>(register.getTransferableData()), register.getRawText());
|
||||||
}
|
}
|
||||||
registers.put(r, register);
|
registers.put(r, register);
|
||||||
@@ -377,7 +422,8 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
public @NotNull List<Register> getRegisters() {
|
public @NotNull List<Register> getRegisters() {
|
||||||
final List<Register> res = new ArrayList<>(registers.values());
|
final List<Register> res = new ArrayList<>(registers.values());
|
||||||
for (Character r : CLIPBOARD_REGISTERS) {
|
for (int i = 0; i < CLIPBOARD_REGISTERS.length(); i++) {
|
||||||
|
final char r = CLIPBOARD_REGISTERS.charAt(i);
|
||||||
final Register register = refreshClipboardRegister(r);
|
final Register register = refreshClipboardRegister(r);
|
||||||
if (register != null) {
|
if (register != null) {
|
||||||
res.add(register);
|
res.add(register);
|
||||||
@@ -388,7 +434,7 @@ public class RegisterGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean startRecording(Editor editor, char register) {
|
public boolean startRecording(Editor editor, char register) {
|
||||||
if (RECORDABLE_REGISTER.indexOf(register) != -1) {
|
if (RECORDABLE_REGISTERS.indexOf(register) != -1) {
|
||||||
CommandState.getInstance(editor).setRecording(true);
|
CommandState.getInstance(editor).setRecording(true);
|
||||||
recordRegister = register;
|
recordRegister = register;
|
||||||
recordList = new ArrayList<>();
|
recordList = new ArrayList<>();
|
||||||
|
@@ -25,20 +25,15 @@ import com.intellij.openapi.components.State;
|
|||||||
import com.intellij.openapi.components.Storage;
|
import com.intellij.openapi.components.Storage;
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.editor.*;
|
import com.intellij.openapi.editor.*;
|
||||||
import com.intellij.openapi.editor.colors.EditorColors;
|
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
|
||||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||||
import com.intellij.openapi.editor.event.DocumentListener;
|
import com.intellij.openapi.editor.event.DocumentListener;
|
||||||
import com.intellij.openapi.editor.markup.*;
|
import com.intellij.openapi.editor.markup.*;
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
|
||||||
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
|
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.project.ProjectManager;
|
import com.intellij.openapi.project.ProjectManager;
|
||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
import com.intellij.ui.ColorUtil;
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags;
|
import com.maddyhome.idea.vim.command.CommandFlags;
|
||||||
import com.maddyhome.idea.vim.command.SelectionType;
|
|
||||||
import com.maddyhome.idea.vim.common.CharacterPosition;
|
import com.maddyhome.idea.vim.common.CharacterPosition;
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.ex.ranges.LineRange;
|
import com.maddyhome.idea.vim.ex.ranges.LineRange;
|
||||||
@@ -49,20 +44,24 @@ import com.maddyhome.idea.vim.option.OptionsManager;
|
|||||||
import com.maddyhome.idea.vim.regexp.CharPointer;
|
import com.maddyhome.idea.vim.regexp.CharPointer;
|
||||||
import com.maddyhome.idea.vim.regexp.CharacterClasses;
|
import com.maddyhome.idea.vim.regexp.CharacterClasses;
|
||||||
import com.maddyhome.idea.vim.regexp.RegExp;
|
import com.maddyhome.idea.vim.regexp.RegExp;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
|
||||||
import com.maddyhome.idea.vim.ui.ModalEntry;
|
import com.maddyhome.idea.vim.ui.ModalEntry;
|
||||||
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.*;
|
|
||||||
|
import static com.maddyhome.idea.vim.helper.SearchHelperKtKt.shouldIgnoreCase;
|
||||||
|
|
||||||
@State(name = "VimSearchSettings", storages = {
|
@State(name = "VimSearchSettings", storages = {
|
||||||
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
@Storage(value = "$APP_CONFIG$/vim_settings_local.xml", roamingType = RoamingType.DISABLED)
|
||||||
@@ -81,9 +80,6 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
options.getIgnorecase().addOptionChangeListener(updateHighlightsIfVisible);
|
options.getIgnorecase().addOptionChangeListener(updateHighlightsIfVisible);
|
||||||
|
|
||||||
// It appears that when changing smartcase, Vim only redraws the highlights when the screen is redrawn. We can't
|
|
||||||
// reliably copy that, so do the most intuitive thing
|
|
||||||
options.getSmartcase().addOptionChangeListener(updateHighlightsIfVisible);
|
options.getSmartcase().addOptionChangeListener(updateHighlightsIfVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +100,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
// This method is used in AceJump integration plugin
|
// This method is used in AceJump integration plugin
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public int getLastDir() {
|
public int getLastDir() {
|
||||||
return lastDir;
|
return lastDir.toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String getLastPattern() {
|
public @Nullable String getLastPattern() {
|
||||||
@@ -114,15 +110,13 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
public void resetState() {
|
public void resetState() {
|
||||||
lastSearch = lastPattern = lastSubstitute = lastReplace = lastOffset = null;
|
lastSearch = lastPattern = lastSubstitute = lastReplace = lastOffset = null;
|
||||||
lastIgnoreSmartCase = false;
|
lastIgnoreSmartCase = false;
|
||||||
lastDir = 0;
|
lastDir = Direction.UNSET;
|
||||||
resetShowSearchHighlight();
|
resetShowSearchHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLastPattern(@NotNull Editor editor, @NotNull String lastPattern) {
|
private void setLastPattern(@NotNull String lastPattern) {
|
||||||
this.lastPattern = lastPattern;
|
this.lastPattern = lastPattern;
|
||||||
VimPlugin.getRegister().storeTextInternal(editor, new TextRange(-1, -1),
|
VimPlugin.getRegister().storeTextSpecial(RegisterGroup.LAST_SEARCH_REGISTER, lastPattern);
|
||||||
lastPattern, SelectionType.CHARACTER_WISE, '/', false);
|
|
||||||
|
|
||||||
VimPlugin.getHistory().addEntry(HistoryGroup.SEARCH, lastPattern);
|
VimPlugin.getHistory().addEntry(HistoryGroup.SEARCH, lastPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +203,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
else {
|
else {
|
||||||
// XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method
|
// XXX: The Ex entry panel is used only for UI here, its logic might be inappropriate for this method
|
||||||
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts();
|
final ExEntryPanel exEntryPanel = ExEntryPanel.getInstanceWithoutShortcuts();
|
||||||
exEntryPanel.activate(editor, new EditorDataContext(editor, null), "Replace with " + match + " (y/n/a/q/l)?", "", 1);
|
exEntryPanel.activate(editor, new EditorDataContext(editor, null), MessageHelper.message("replace.with.0", match), "", 1);
|
||||||
MotionGroup.moveCaret(editor, caret, startoff);
|
MotionGroup.moveCaret(editor, caret, startoff);
|
||||||
ModalEntry.INSTANCE.activate(keyStrokeProcessor);
|
ModalEntry.INSTANCE.activate(keyStrokeProcessor);
|
||||||
exEntryPanel.deactivate(true, false);
|
exEntryPanel.deactivate(true, false);
|
||||||
@@ -217,13 +211,6 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
return result.get();
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldIgnoreCase(@NotNull String pattern, boolean ignoreSmartCase) {
|
|
||||||
boolean sc = !ignoreSmartCase && OptionsManager.INSTANCE.getSmartcase().isSet();
|
|
||||||
boolean ic = OptionsManager.INSTANCE.getIgnorecase().isSet();
|
|
||||||
|
|
||||||
return ic && !(sc && StringHelper.containsUpperCase(pattern));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int search(@NotNull Editor editor, @NotNull String command, int count, EnumSet<CommandFlags> flags, boolean moveCursor) {
|
public int search(@NotNull Editor editor, @NotNull String command, int count, EnumSet<CommandFlags> flags, boolean moveCursor) {
|
||||||
return search(editor, editor.getCaretModel().getPrimaryCaret(), command, count, flags, moveCursor);
|
return search(editor, editor.getCaretModel().getPrimaryCaret(), command, count, flags, moveCursor);
|
||||||
}
|
}
|
||||||
@@ -241,12 +228,12 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int search(@NotNull Editor editor, @NotNull String command, int startOffset, int count, @NotNull EnumSet<CommandFlags> flags) {
|
public int search(@NotNull Editor editor, @NotNull String command, int startOffset, int count, @NotNull EnumSet<CommandFlags> flags) {
|
||||||
int dir = DIR_FORWARDS;
|
Direction dir = Direction.FORWARDS;
|
||||||
char type = '/';
|
char type = '/';
|
||||||
String pattern = lastSearch;
|
String pattern = lastSearch;
|
||||||
String offset = lastOffset;
|
String offset = lastOffset;
|
||||||
if (flags.contains(CommandFlags.FLAG_SEARCH_REV)) {
|
if (flags.contains(CommandFlags.FLAG_SEARCH_REV)) {
|
||||||
dir = DIR_BACKWARDS;
|
dir = Direction.BACKWARDS;
|
||||||
type = '?';
|
type = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +270,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
lastSearch = pattern;
|
lastSearch = pattern;
|
||||||
lastIgnoreSmartCase = false;
|
lastIgnoreSmartCase = false;
|
||||||
if (pattern != null) {
|
if (pattern != null) {
|
||||||
setLastPattern(editor, pattern);
|
setLastPattern(pattern);
|
||||||
}
|
}
|
||||||
lastOffset = offset;
|
lastOffset = offset;
|
||||||
lastDir = dir;
|
lastDir = dir;
|
||||||
@@ -300,7 +287,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
return findItOffset(editor, startOffset, count, lastDir);
|
return findItOffset(editor, startOffset, count, lastDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int searchWord(@NotNull Editor editor, @NotNull Caret caret, int count, boolean whole, int dir) {
|
public int searchWord(@NotNull Editor editor, @NotNull Caret caret, int count, boolean whole, Direction dir) {
|
||||||
TextRange range = SearchHelper.findWordUnderCursor(editor, caret);
|
TextRange range = SearchHelper.findWordUnderCursor(editor, caret);
|
||||||
if (range == null) {
|
if (range == null) {
|
||||||
logger.warn("No range was found");
|
logger.warn("No range was found");
|
||||||
@@ -320,7 +307,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
lastSearch = pattern.toString();
|
lastSearch = pattern.toString();
|
||||||
lastIgnoreSmartCase = true;
|
lastIgnoreSmartCase = true;
|
||||||
setLastPattern(editor, lastSearch);
|
setLastPattern(lastSearch);
|
||||||
lastOffset = "";
|
lastOffset = "";
|
||||||
lastDir = dir;
|
lastDir = dir;
|
||||||
|
|
||||||
@@ -335,16 +322,16 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int searchPrevious(@NotNull Editor editor, @NotNull Caret caret, int count) {
|
public int searchPrevious(@NotNull Editor editor, @NotNull Caret caret, int count) {
|
||||||
return searchNextWithDirection(editor, caret, count, -lastDir);
|
return searchNextWithDirection(editor, caret, count, lastDir.reverse());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int searchNextFromOffset(@NotNull Editor editor, int offset, int count) {
|
public int searchNextFromOffset(@NotNull Editor editor, int offset, int count) {
|
||||||
resetShowSearchHighlight();
|
resetShowSearchHighlight();
|
||||||
updateSearchHighlights();
|
updateSearchHighlights();
|
||||||
return findItOffset(editor, offset, count, 1);
|
return findItOffset(editor, offset, count, Direction.FORWARDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int searchNextWithDirection(@NotNull Editor editor, @NotNull Caret caret, int count, int dir) {
|
private int searchNextWithDirection(@NotNull Editor editor, @NotNull Caret caret, int count, Direction dir) {
|
||||||
resetShowSearchHighlight();
|
resetShowSearchHighlight();
|
||||||
updateSearchHighlights();
|
updateSearchHighlights();
|
||||||
final int startOffset = caret.getOffset();
|
final int startOffset = caret.getOffset();
|
||||||
@@ -368,163 +355,25 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void forceUpdateSearchHighlights() {
|
private void forceUpdateSearchHighlights() {
|
||||||
updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, true);
|
SearchHighlightsHelper.updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSearchHighlights() {
|
private void updateSearchHighlights() {
|
||||||
updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, false);
|
SearchHighlightsHelper.updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetIncsearchHighlights() {
|
public void resetIncsearchHighlights() {
|
||||||
updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, true);
|
SearchHighlightsHelper.updateSearchHighlights(lastSearch, lastIgnoreSmartCase, showSearchHighlight, true);
|
||||||
}
|
|
||||||
|
|
||||||
public int updateIncsearchHighlights(@NotNull Editor editor, @NotNull String pattern, boolean forwards, int caretOffset, @Nullable LineRange searchRange) {
|
|
||||||
final int searchStartOffset = searchRange != null ? EditorHelper.getLineStartOffset(editor, searchRange.startLine) : caretOffset;
|
|
||||||
final boolean showHighlights = OptionsManager.INSTANCE.getHlsearch().isSet();
|
|
||||||
return updateSearchHighlights(pattern, false, showHighlights, searchStartOffset, searchRange, forwards, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSearchHighlights(@Nullable String pattern, boolean shouldIgnoreSmartCase, boolean showHighlights, boolean forceUpdate) {
|
|
||||||
updateSearchHighlights(pattern, shouldIgnoreSmartCase, showHighlights, -1, null, true, forceUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refreshes current search highlights for all editors of currently active text editor/document
|
|
||||||
*/
|
|
||||||
private int updateSearchHighlights(@Nullable String pattern, boolean shouldIgnoreSmartCase, boolean showHighlights,
|
|
||||||
int initialOffset, @Nullable LineRange searchRange, boolean forwards, boolean forceUpdate) {
|
|
||||||
int currentMatchOffset = -1;
|
|
||||||
|
|
||||||
ProjectManager projectManager = ProjectManager.getInstanceIfCreated();
|
|
||||||
if (projectManager == null) return currentMatchOffset;
|
|
||||||
Project[] projects = projectManager.getOpenProjects();
|
|
||||||
for (Project project : projects) {
|
|
||||||
Editor current = FileEditorManager.getInstance(project).getSelectedTextEditor();
|
|
||||||
Editor[] editors = current == null ? null : EditorFactory.getInstance().getEditors(current.getDocument(), project);
|
|
||||||
if (editors == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Editor editor : editors) {
|
|
||||||
// Force update for the situations where the text is the same, but the ignore case values have changed.
|
|
||||||
// E.g. Use `*` to search for a word (which ignores smartcase), then use `/<Up>` to search for the same pattern,
|
|
||||||
// which will match smartcase. Or changing the smartcase/ignorecase settings
|
|
||||||
if (shouldRemoveSearchHighlight(editor, pattern, showHighlights) || forceUpdate) {
|
|
||||||
removeSearchHighlight(editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldAddAllSearchHighlights(editor, pattern, showHighlights)) {
|
|
||||||
final int startLine = searchRange == null ? 0 : searchRange.startLine;
|
|
||||||
final int endLine = searchRange == null ? -1 : searchRange.endLine;
|
|
||||||
List<TextRange> results = findAll(editor, pattern, startLine, endLine, shouldIgnoreCase(pattern, shouldIgnoreSmartCase));
|
|
||||||
if (!results.isEmpty()) {
|
|
||||||
currentMatchOffset = findClosestMatch(editor, results, initialOffset, forwards);
|
|
||||||
highlightSearchResults(editor, pattern, results, currentMatchOffset);
|
|
||||||
}
|
|
||||||
UserDataManager.setVimLastSearch(editor, pattern);
|
|
||||||
}
|
|
||||||
else if (shouldAddCurrentMatchSearchHighlight(pattern, showHighlights, initialOffset)) {
|
|
||||||
final boolean wrap = OptionsManager.INSTANCE.getWrapscan().isSet();
|
|
||||||
final EnumSet<SearchOptions> searchOptions = EnumSet.of(SearchOptions.WHOLE_FILE);
|
|
||||||
if (wrap) searchOptions.add(SearchOptions.WRAP);
|
|
||||||
if (shouldIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE);
|
|
||||||
if (!forwards) searchOptions.add(SearchOptions.BACKWARDS);
|
|
||||||
final TextRange result = findIt(editor, pattern, initialOffset, 1, searchOptions);
|
|
||||||
if (result != null && pattern != null) {
|
|
||||||
currentMatchOffset = result.getStartOffset();
|
|
||||||
final List<TextRange> results = Collections.singletonList(result);
|
|
||||||
highlightSearchResults(editor, pattern, results, currentMatchOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (shouldMaintainCurrentMatchOffset(pattern, initialOffset)) {
|
|
||||||
final Integer offset = UserDataManager.getVimIncsearchCurrentMatchOffset(editor);
|
|
||||||
if (offset != null) {
|
|
||||||
currentMatchOffset = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentMatchOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove current search highlights if hlSearch is false, or if the pattern is changed
|
|
||||||
*/
|
|
||||||
@Contract("_, _, false -> true; _, null, true -> false")
|
|
||||||
private boolean shouldRemoveSearchHighlight(@NotNull Editor editor, String newPattern, boolean hlSearch) {
|
|
||||||
return !hlSearch || (newPattern != null && !newPattern.equals(UserDataManager.getVimLastSearch(editor)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add search highlights if hlSearch is true and the pattern is changed
|
|
||||||
*/
|
|
||||||
@Contract("_, _, false -> false; _, null, true -> false")
|
|
||||||
private boolean shouldAddAllSearchHighlights(@NotNull Editor editor, @Nullable String newPattern, boolean hlSearch) {
|
|
||||||
return hlSearch && newPattern != null && !newPattern.equals(UserDataManager.getVimLastSearch(editor)) && !Objects.equals(newPattern, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add search highlight for current match if hlsearch is false and we're performing incsearch highlights
|
|
||||||
*/
|
|
||||||
@Contract("_, true, _ -> false")
|
|
||||||
private boolean shouldAddCurrentMatchSearchHighlight(@Nullable String pattern, boolean hlSearch, int initialOffset) {
|
|
||||||
return !hlSearch && isIncrementalSearchHighlights(initialOffset) && pattern != null && pattern.length() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keep the current match offset if the pattern is still valid and we're performing incremental search highlights
|
|
||||||
* This will keep the caret position when editing the offset in e.g. `/foo/e+1`
|
|
||||||
*/
|
|
||||||
@Contract("null, _ -> false")
|
|
||||||
private boolean shouldMaintainCurrentMatchOffset(@Nullable String pattern, int initialOffset) {
|
|
||||||
return pattern != null && pattern.length() > 0 && isIncrementalSearchHighlights(initialOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* initialOffset is only valid if we're highlighting incsearch
|
|
||||||
*/
|
|
||||||
@Contract(pure = true)
|
|
||||||
private boolean isIncrementalSearchHighlights(int initialOffset) {
|
|
||||||
return initialOffset != -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void highlightSearchLines(@NotNull Editor editor, int startLine, int endLine) {
|
private void highlightSearchLines(@NotNull Editor editor, int startLine, int endLine) {
|
||||||
if (lastSearch != null) {
|
if (lastSearch != null) {
|
||||||
final List<TextRange> results = findAll(editor, lastSearch, startLine, endLine, shouldIgnoreCase(lastSearch, lastIgnoreSmartCase));
|
final List<TextRange> results = findAll(editor, lastSearch, startLine, endLine,
|
||||||
highlightSearchResults(editor, lastSearch, results, -1);
|
shouldIgnoreCase(lastSearch, lastIgnoreSmartCase));
|
||||||
|
SearchHighlightsHelper.highlightSearchResults(editor, lastSearch, results, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findClosestMatch(@NotNull Editor editor, @NotNull List<TextRange> results, int initialOffset, boolean forwards) {
|
|
||||||
if (results.isEmpty() || initialOffset == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int size = EditorHelperRt.getFileSize(editor);
|
|
||||||
final TextRange max = Collections.max(results, (r1, r2) -> {
|
|
||||||
final int d1 = distance(r1, initialOffset, forwards, size);
|
|
||||||
final int d2 = distance(r2, initialOffset, forwards, size);
|
|
||||||
if (d1 < 0 && d2 >= 0) {
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
return d2 - d1;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!OptionsManager.INSTANCE.getWrapscan().isSet()) {
|
|
||||||
final int start = max.getStartOffset();
|
|
||||||
if (forwards && start < initialOffset) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (start >= initialOffset) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return max.getStartOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable TextRange getNextSearchRange(@NotNull Editor editor, int count, boolean forwards) {
|
public @Nullable TextRange getNextSearchRange(@NotNull Editor editor, int count, boolean forwards) {
|
||||||
editor.getCaretModel().removeSecondaryCarets();
|
editor.getCaretModel().removeSecondaryCarets();
|
||||||
TextRange current = findUnderCaret(editor);
|
TextRange current = findUnderCaret(editor);
|
||||||
@@ -574,23 +423,13 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
return findIt(editor, lastSearch, startOffset, 1, searchOptions);
|
return findIt(editor, lastSearch, startOffset, 1, searchOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int distance(@NotNull TextRange range, int pos, boolean forwards, int size) {
|
public static TextRange findIt(@NotNull Editor editor, @Nullable String pattern, int startOffset, int count, EnumSet<SearchOptions> searchOptions) {
|
||||||
final int start = range.getStartOffset();
|
|
||||||
if (start <= pos) {
|
|
||||||
return forwards ? size - pos + start : pos - start;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return forwards ? start - pos : pos + size - start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextRange findIt(@NotNull Editor editor, @Nullable String pattern, int startOffset, int count, EnumSet<SearchOptions> searchOptions) {
|
|
||||||
if (pattern == null || pattern.length() == 0) {
|
if (pattern == null || pattern.length() == 0) {
|
||||||
logger.warn("Pattern is null or empty. Cannot perform search");
|
logger.warn("Pattern is null or empty. Cannot perform search");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dir = searchOptions.contains(SearchOptions.BACKWARDS) ? DIR_BACKWARDS : DIR_FORWARDS;
|
Direction dir = searchOptions.contains(SearchOptions.BACKWARDS) ? Direction.BACKWARDS : Direction.FORWARDS;
|
||||||
|
|
||||||
//RE sp;
|
//RE sp;
|
||||||
RegExp sp;
|
RegExp sp;
|
||||||
@@ -628,7 +467,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
int loop;
|
int loop;
|
||||||
RegExp.lpos_T start_pos;
|
RegExp.lpos_T start_pos;
|
||||||
boolean at_first_line;
|
boolean at_first_line;
|
||||||
int extra_col = dir == DIR_FORWARDS ? 1 : 0;
|
int extra_col = dir == Direction.FORWARDS ? 1 : 0;
|
||||||
boolean match_ok;
|
boolean match_ok;
|
||||||
long nmatched;
|
long nmatched;
|
||||||
//int submatch = 0;
|
//int submatch = 0;
|
||||||
@@ -652,7 +491,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
* Start searching in current line, unless searching backwards and
|
* Start searching in current line, unless searching backwards and
|
||||||
* we're in column 0.
|
* we're in column 0.
|
||||||
*/
|
*/
|
||||||
if (dir == DIR_BACKWARDS && start_pos.col == 0) {
|
if (dir == Direction.BACKWARDS && start_pos.col == 0) {
|
||||||
lnum = pos.lnum - 1;
|
lnum = pos.lnum - 1;
|
||||||
at_first_line = false;
|
at_first_line = false;
|
||||||
}
|
}
|
||||||
@@ -666,7 +505,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
startLine = lnum;
|
startLine = lnum;
|
||||||
endLine = lnum + 1;
|
endLine = lnum + 1;
|
||||||
}
|
}
|
||||||
for (; lnum >= startLine && lnum < endLine; lnum += dir, at_first_line = false) {
|
for (; lnum >= startLine && lnum < endLine; lnum += dir.toInt(), at_first_line = false) {
|
||||||
/*
|
/*
|
||||||
* Look for a match somewhere in the line.
|
* Look for a match somewhere in the line.
|
||||||
*/
|
*/
|
||||||
@@ -683,7 +522,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
* the start position. If not, continue at the end of the
|
* the start position. If not, continue at the end of the
|
||||||
* match (this is vi compatible) or on the next char.
|
* match (this is vi compatible) or on the next char.
|
||||||
*/
|
*/
|
||||||
if (dir == DIR_FORWARDS && at_first_line) {
|
if (dir == Direction.FORWARDS && at_first_line) {
|
||||||
match_ok = true;
|
match_ok = true;
|
||||||
/*
|
/*
|
||||||
* When match lands on a NUL the cursor will be put
|
* When match lands on a NUL the cursor will be put
|
||||||
@@ -721,7 +560,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dir == DIR_BACKWARDS) {
|
if (dir == Direction.BACKWARDS) {
|
||||||
/*
|
/*
|
||||||
* Now, if there are multiple matches on this line,
|
* Now, if there are multiple matches on this line,
|
||||||
* we have to get the last one. Or the last one before
|
* we have to get the last one. Or the last one before
|
||||||
@@ -815,7 +654,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
* is redrawn. The keep_msg is cleared whenever another message is
|
* is redrawn. The keep_msg is cleared whenever another message is
|
||||||
* written.
|
* written.
|
||||||
*/
|
*/
|
||||||
if (dir == DIR_BACKWARDS) /* start second loop at the other end */ {
|
if (dir == Direction.BACKWARDS) /* start second loop at the other end */ {
|
||||||
lnum = lineCount - 1;
|
lnum = lineCount - 1;
|
||||||
//if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
//if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
|
||||||
// give_warning((char_u *)_(top_bot_msg), TRUE);
|
// give_warning((char_u *)_(top_bot_msg), TRUE);
|
||||||
@@ -855,24 +694,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
new CharacterPosition(endpos.lnum, endpos.col).toOffset(editor));
|
new CharacterPosition(endpos.lnum, endpos.col).toOffset(editor));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void highlightSearchResults(@NotNull Editor editor, @NotNull String pattern, List<TextRange> results,
|
private int findItOffset(@NotNull Editor editor, int startOffset, int count, Direction dir) {
|
||||||
int currentMatchOffset) {
|
|
||||||
Collection<RangeHighlighter> highlighters = UserDataManager.getVimLastHighlighters(editor);
|
|
||||||
if (highlighters == null) {
|
|
||||||
highlighters = new ArrayList<>();
|
|
||||||
UserDataManager.setVimLastHighlighters(editor, highlighters);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TextRange range : results) {
|
|
||||||
final boolean current = range.getStartOffset() == currentMatchOffset;
|
|
||||||
final RangeHighlighter highlighter = highlightMatch(editor, range.getStartOffset(), range.getEndOffset(), current, pattern);
|
|
||||||
highlighters.add(highlighter);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserDataManager.setVimIncsearchCurrentMatchOffset(editor, currentMatchOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int findItOffset(@NotNull Editor editor, int startOffset, int count, int dir) {
|
|
||||||
boolean wrap = OptionsManager.INSTANCE.getWrapscan().isSet();
|
boolean wrap = OptionsManager.INSTANCE.getWrapscan().isSet();
|
||||||
logger.debug("Perform search. Direction: " + dir + " wrap: " + wrap);
|
logger.debug("Perform search. Direction: " + dir + " wrap: " + wrap);
|
||||||
|
|
||||||
@@ -935,7 +757,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EnumSet<SearchOptions> searchOptions = EnumSet.of(SearchOptions.SHOW_MESSAGES, SearchOptions.WHOLE_FILE);
|
EnumSet<SearchOptions> searchOptions = EnumSet.of(SearchOptions.SHOW_MESSAGES, SearchOptions.WHOLE_FILE);
|
||||||
if (dir == DIR_BACKWARDS) searchOptions.add(SearchOptions.BACKWARDS);
|
if (dir == Direction.BACKWARDS) searchOptions.add(SearchOptions.BACKWARDS);
|
||||||
if (lastIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE);
|
if (lastIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE);
|
||||||
if (wrap) searchOptions.add(SearchOptions.WRAP);
|
if (wrap) searchOptions.add(SearchOptions.WRAP);
|
||||||
if (hasEndOffset) searchOptions.add(SearchOptions.WANT_ENDPOS);
|
if (hasEndOffset) searchOptions.add(SearchOptions.WANT_ENDPOS);
|
||||||
@@ -983,7 +805,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
|
|
||||||
@RWLockLabel.SelfSynchronized
|
@RWLockLabel.SelfSynchronized
|
||||||
public boolean searchAndReplace(@NotNull Editor editor, @NotNull Caret caret, @NotNull LineRange range,
|
public boolean searchAndReplace(@NotNull Editor editor, @NotNull Caret caret, @NotNull LineRange range,
|
||||||
@NotNull String excmd, String exarg) {
|
@NotNull @NonNls String excmd, @NonNls String exarg) {
|
||||||
// Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
|
// Explicitly exit visual mode here, so that visual mode marks don't change when we move the cursor to a match.
|
||||||
if (CommandStateHelper.inVisualMode(editor)) {
|
if (CommandStateHelper.inVisualMode(editor)) {
|
||||||
ModeHelper.exitVisualMode(editor);
|
ModeHelper.exitVisualMode(editor);
|
||||||
@@ -1164,7 +986,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
lastSubstitute = pattern;
|
lastSubstitute = pattern;
|
||||||
lastSearch = pattern;
|
lastSearch = pattern;
|
||||||
if (pattern != null) {
|
if (pattern != null) {
|
||||||
setLastPattern(editor, pattern);
|
setLastPattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
int start = editor.getDocument().getLineStartOffset(line1);
|
int start = editor.getDocument().getLineStartOffset(line1);
|
||||||
@@ -1247,7 +1069,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
if (do_all || line != lastLine) {
|
if (do_all || line != lastLine) {
|
||||||
boolean doReplace = true;
|
boolean doReplace = true;
|
||||||
if (do_ask) {
|
if (do_ask) {
|
||||||
RangeHighlighter hl = highlightConfirm(editor, startoff, endoff);
|
RangeHighlighter hl = SearchHighlightsHelper.addSubstitutionConfirmationHighlight(editor, startoff, endoff);
|
||||||
final ReplaceConfirmationChoice choice = confirmChoice(editor, match, caret, startoff);
|
final ReplaceConfirmationChoice choice = confirmChoice(editor, match, caret, startoff);
|
||||||
editor.getMarkupModel().removeHighlighter(hl);
|
editor.getMarkupModel().removeHighlighter(hl);
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
@@ -1318,65 +1140,6 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NotNull RangeHighlighter highlightConfirm(@NotNull Editor editor, int start, int end) {
|
|
||||||
TextAttributes color = new TextAttributes(
|
|
||||||
editor.getColorsScheme().getColor(EditorColors.SELECTION_FOREGROUND_COLOR),
|
|
||||||
editor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR),
|
|
||||||
editor.getColorsScheme().getColor(EditorColors.CARET_COLOR),
|
|
||||||
EffectType.ROUNDED_BOX, Font.PLAIN
|
|
||||||
);
|
|
||||||
return editor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.SELECTION,
|
|
||||||
color, HighlighterTargetArea.EXACT_RANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @NotNull RangeHighlighter highlightMatch(@NotNull Editor editor, int start, int end, boolean current, String tooltip) {
|
|
||||||
TextAttributes attributes = editor.getColorsScheme().getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
|
|
||||||
if (current) {
|
|
||||||
// This mimics what IntelliJ does with the Find live preview
|
|
||||||
attributes = attributes.clone();
|
|
||||||
attributes.setEffectType(EffectType.ROUNDED_BOX);
|
|
||||||
attributes.setEffectColor(editor.getColorsScheme().getColor(EditorColors.CARET_COLOR));
|
|
||||||
}
|
|
||||||
if (attributes.getErrorStripeColor() == null) {
|
|
||||||
attributes.setErrorStripeColor(getFallbackErrorStripeColor(attributes, editor.getColorsScheme()));
|
|
||||||
}
|
|
||||||
final RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.SELECTION - 1,
|
|
||||||
attributes, HighlighterTargetArea.EXACT_RANGE);
|
|
||||||
highlighter.setErrorStripeTooltip(tooltip);
|
|
||||||
return highlighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a valid error stripe colour based on editor background
|
|
||||||
*
|
|
||||||
* Based on HighlightManager#addRangeHighlight behaviour, which we can't use because it will hide highlights when
|
|
||||||
* hitting Escape
|
|
||||||
*/
|
|
||||||
private static @Nullable Color getFallbackErrorStripeColor(TextAttributes attributes, EditorColorsScheme colorsScheme) {
|
|
||||||
if (attributes.getBackgroundColor() != null) {
|
|
||||||
boolean isDark = ColorUtil.isDark(colorsScheme.getDefaultBackground());
|
|
||||||
return isDark ? attributes.getBackgroundColor().brighter() : attributes.getBackgroundColor().darker();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void removeSearchHighlight(@NotNull Editor editor) {
|
|
||||||
UserDataManager.setVimLastSearch(editor, null);
|
|
||||||
|
|
||||||
Collection<RangeHighlighter> ehl = UserDataManager.getVimLastHighlighters(editor);
|
|
||||||
if (ehl == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RangeHighlighter rh : ehl) {
|
|
||||||
editor.getMarkupModel().removeHighlighter(rh);
|
|
||||||
}
|
|
||||||
|
|
||||||
ehl.clear();
|
|
||||||
|
|
||||||
UserDataManager.setVimLastHighlighters(editor, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveData(@NotNull Element element) {
|
public void saveData(@NotNull Element element) {
|
||||||
logger.debug("saveData");
|
logger.debug("saveData");
|
||||||
Element search = new Element("search");
|
Element search = new Element("search");
|
||||||
@@ -1396,7 +1159,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
search.addContent(createElementWithText("last-substitute", lastSubstitute));
|
search.addContent(createElementWithText("last-substitute", lastSubstitute));
|
||||||
}
|
}
|
||||||
Element text = new Element("last-dir");
|
Element text = new Element("last-dir");
|
||||||
text.addContent(Integer.toString(lastDir));
|
text.addContent(Integer.toString(lastDir.toInt()));
|
||||||
search.addContent(text);
|
search.addContent(text);
|
||||||
|
|
||||||
text = new Element("show-last");
|
text = new Element("show-last");
|
||||||
@@ -1425,7 +1188,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
lastSubstitute = getSafeChildText(search, "last-substitute");
|
lastSubstitute = getSafeChildText(search, "last-substitute");
|
||||||
|
|
||||||
Element dir = search.getChild("last-dir");
|
Element dir = search.getChild("last-dir");
|
||||||
lastDir = Integer.parseInt(dir.getText());
|
lastDir = Direction.Companion.fromInt(Integer.parseInt(dir.getText()));
|
||||||
|
|
||||||
Element show = search.getChild("show-last");
|
Element show = search.getChild("show-last");
|
||||||
final ListOption vimInfo = OptionsManager.INSTANCE.getViminfo();
|
final ListOption vimInfo = OptionsManager.INSTANCE.getViminfo();
|
||||||
@@ -1522,7 +1285,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
SUBSTITUTE_ALL,
|
SUBSTITUTE_ALL,
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum SearchOptions {
|
public enum SearchOptions {
|
||||||
BACKWARDS,
|
BACKWARDS,
|
||||||
WANT_ENDPOS,
|
WANT_ENDPOS,
|
||||||
WRAP,
|
WRAP,
|
||||||
@@ -1537,7 +1300,7 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
private @Nullable String lastReplace;
|
private @Nullable String lastReplace;
|
||||||
private @Nullable String lastOffset;
|
private @Nullable String lastOffset;
|
||||||
private boolean lastIgnoreSmartCase;
|
private boolean lastIgnoreSmartCase;
|
||||||
private int lastDir;
|
private @NotNull Direction lastDir = Direction.FORWARDS;
|
||||||
private boolean showSearchHighlight = OptionsManager.INSTANCE.getHlsearch().isSet();
|
private boolean showSearchHighlight = OptionsManager.INSTANCE.getHlsearch().isSet();
|
||||||
|
|
||||||
private boolean do_all = false; /* do multiple substitutions per line */
|
private boolean do_all = false; /* do multiple substitutions per line */
|
||||||
@@ -1550,8 +1313,5 @@ public class SearchGroup implements PersistentStateComponent<Element> {
|
|||||||
private static final int RE_SEARCH = 2;
|
private static final int RE_SEARCH = 2;
|
||||||
private static final int RE_SUBST = 3;
|
private static final int RE_SUBST = 3;
|
||||||
|
|
||||||
private static final int DIR_FORWARDS = 1;
|
|
||||||
private static final int DIR_BACKWARDS = -1;
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getInstance(SearchGroup.class.getName());
|
private static final Logger logger = Logger.getInstance(SearchGroup.class.getName());
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
import com.maddyhome.idea.vim.VimPlugin;
|
||||||
|
import com.maddyhome.idea.vim.helper.MessageHelper;
|
||||||
import com.maddyhome.idea.vim.helper.RWLockLabel;
|
import com.maddyhome.idea.vim.helper.RWLockLabel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -158,7 +159,7 @@ public class WindowGroup {
|
|||||||
if (filename.length() > 0) {
|
if (filename.length() > 0) {
|
||||||
virtualFile = VimPlugin.getFile().findFile(filename, project);
|
virtualFile = VimPlugin.getFile().findFile(filename, project);
|
||||||
if (virtualFile == null) {
|
if (virtualFile == null) {
|
||||||
VimPlugin.showMessage("Could not find file: " + filename);
|
VimPlugin.showMessage(MessageHelper.message("could.not.find.file.0", filename));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,9 +46,9 @@ import com.maddyhome.idea.vim.common.TextRange
|
|||||||
import com.maddyhome.idea.vim.group.MarkGroup
|
import com.maddyhome.idea.vim.group.MarkGroup
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
import com.maddyhome.idea.vim.group.MotionGroup
|
||||||
import com.maddyhome.idea.vim.group.visual.VimSelection
|
import com.maddyhome.idea.vim.group.visual.VimSelection
|
||||||
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
|
import com.maddyhome.idea.vim.helper.moveToInlayAwareOffset
|
||||||
import com.maddyhome.idea.vim.option.ClipboardOptionsData
|
import com.maddyhome.idea.vim.option.ClipboardOptionsData
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@@ -32,7 +32,6 @@ import com.maddyhome.idea.vim.helper.EditorHelper
|
|||||||
import com.maddyhome.idea.vim.helper.fileSize
|
import com.maddyhome.idea.vim.helper.fileSize
|
||||||
import com.maddyhome.idea.vim.listener.VimYankListener
|
import com.maddyhome.idea.vim.listener.VimYankListener
|
||||||
import org.jetbrains.annotations.Contract
|
import org.jetbrains.annotations.Contract
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class YankGroup {
|
class YankGroup {
|
||||||
|
@@ -27,6 +27,7 @@ import com.maddyhome.idea.vim.command.SelectionType.CHARACTER_WISE
|
|||||||
import com.maddyhome.idea.vim.command.SelectionType.LINE_WISE
|
import com.maddyhome.idea.vim.command.SelectionType.LINE_WISE
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
import com.maddyhome.idea.vim.common.TextRange
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ sealed class VimSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNls
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val startLogPosition = editor.offsetToLogicalPosition(vimStart)
|
val startLogPosition = editor.offsetToLogicalPosition(vimStart)
|
||||||
val endLogPosition = editor.offsetToLogicalPosition(vimEnd)
|
val endLogPosition = editor.offsetToLogicalPosition(vimEnd)
|
||||||
|
@@ -163,7 +163,7 @@ fun updateCaretState(editor: Editor) {
|
|||||||
|
|
||||||
fun CommandState.Mode.resetShape(editor: Editor) = when (this) {
|
fun CommandState.Mode.resetShape(editor: Editor) = when (this) {
|
||||||
CommandState.Mode.COMMAND, CommandState.Mode.VISUAL, CommandState.Mode.REPLACE -> ChangeGroup.resetCaret(editor, false)
|
CommandState.Mode.COMMAND, CommandState.Mode.VISUAL, CommandState.Mode.REPLACE -> ChangeGroup.resetCaret(editor, false)
|
||||||
CommandState.Mode.SELECT, CommandState.Mode.INSERT -> ChangeGroup.resetCaret(editor, true)
|
CommandState.Mode.SELECT, CommandState.Mode.INSERT -> ChangeGroup.resetCaret(editor, VimPlugin.getEditor().isBarCursorSettings)
|
||||||
CommandState.Mode.CMD_LINE, CommandState.Mode.OP_PENDING -> Unit
|
CommandState.Mode.CMD_LINE, CommandState.Mode.OP_PENDING -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ import com.maddyhome.idea.vim.helper.StringHelper
|
|||||||
import com.maddyhome.idea.vim.helper.commandState
|
import com.maddyhome.idea.vim.helper.commandState
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
||||||
import com.maddyhome.idea.vim.helper.noneOfEnum
|
import com.maddyhome.idea.vim.helper.noneOfEnum
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
@@ -103,14 +104,17 @@ abstract class EditorActionHandlerBase(private val myRunForEachCaret: Boolean) {
|
|||||||
fun parseKeysSet(keyStrings: List<String>) = keyStrings.map { StringHelper.parseKeys(it) }.toSet()
|
fun parseKeysSet(keyStrings: List<String>) = keyStrings.map { StringHelper.parseKeys(it) }.toSet()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun parseKeysSet(vararg keyStrings: String): Set<List<KeyStroke>> = List(keyStrings.size) {
|
fun parseKeysSet(@NonNls vararg keyStrings: String): Set<List<KeyStroke>> = List(keyStrings.size) {
|
||||||
StringHelper.parseKeys(keyStrings[it])
|
StringHelper.parseKeys(keyStrings[it])
|
||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
|
@NonNls private const val VimActionPrefix = "Vim"
|
||||||
|
|
||||||
|
@NonNls
|
||||||
fun getActionId(classFullName: String): String {
|
fun getActionId(classFullName: String): String {
|
||||||
return classFullName
|
return classFullName
|
||||||
.takeLastWhile { it != '.' }
|
.takeLastWhile { it != '.' }
|
||||||
.let { if (it.startsWith("Vim", true)) it else "Vim$it" }
|
.let { if (it.startsWith(VimActionPrefix, true)) it else "$VimActionPrefix$it" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,6 +50,8 @@ object CharacterHelper {
|
|||||||
CharacterType.KATAKANA
|
CharacterType.KATAKANA
|
||||||
} else if (isHalfWidthKatakanaLetter(ch)) {
|
} else if (isHalfWidthKatakanaLetter(ch)) {
|
||||||
CharacterType.HALF_WIDTH_KATAKANA
|
CharacterType.HALF_WIDTH_KATAKANA
|
||||||
|
} else if (block == UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS) {
|
||||||
|
CharacterType.CJK_UNIFIED_IDEOGRAPHS
|
||||||
} else if (punctuationAsLetters || iskeyword.isKeyword(ch)) {
|
} else if (punctuationAsLetters || iskeyword.isKeyword(ch)) {
|
||||||
CharacterType.KEYWORD
|
CharacterType.KEYWORD
|
||||||
} else {
|
} else {
|
||||||
@@ -89,6 +91,6 @@ object CharacterHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class CharacterType {
|
enum class CharacterType {
|
||||||
KEYWORD, HIRAGANA, KATAKANA, HALF_WIDTH_KATAKANA, PUNCTUATION, WHITESPACE
|
KEYWORD, HIRAGANA, KATAKANA, HALF_WIDTH_KATAKANA, CJK_UNIFIED_IDEOGRAPHS, PUNCTUATION, WHITESPACE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,9 +21,11 @@
|
|||||||
package com.maddyhome.idea.vim.helper
|
package com.maddyhome.idea.vim.helper
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.maddyhome.idea.vim.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
import com.maddyhome.idea.vim.command.CommandState
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
import com.maddyhome.idea.vim.option.OptionsManager
|
||||||
|
|
||||||
|
@get:VimNlsSafe
|
||||||
val usesVirtualSpace
|
val usesVirtualSpace
|
||||||
get() = OptionsManager.virtualedit.value == "onemore"
|
get() = OptionsManager.virtualedit.value == "onemore"
|
||||||
|
|
||||||
@@ -39,12 +41,23 @@ val CommandState.Mode.isEndAllowedIgnoringOnemore: Boolean
|
|||||||
CommandState.Mode.COMMAND, CommandState.Mode.CMD_LINE, CommandState.Mode.REPLACE, CommandState.Mode.OP_PENDING -> false
|
CommandState.Mode.COMMAND, CommandState.Mode.CMD_LINE, CommandState.Mode.REPLACE, CommandState.Mode.OP_PENDING -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
val CommandState.Mode.isBlockCaret
|
/**
|
||||||
|
* Should this caret behave like the block caret?
|
||||||
|
* Keep in mind that in insert mode the caret can have a block shape, but it doesn't behave like the block one
|
||||||
|
* If you're looking for a shape, check [isBlockCaretShape]
|
||||||
|
*/
|
||||||
|
val CommandState.Mode.isBlockCaretBehaviour
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
CommandState.Mode.VISUAL, CommandState.Mode.COMMAND, CommandState.Mode.OP_PENDING -> true
|
CommandState.Mode.VISUAL, CommandState.Mode.COMMAND, CommandState.Mode.OP_PENDING -> true
|
||||||
CommandState.Mode.INSERT, CommandState.Mode.CMD_LINE, CommandState.Mode.REPLACE, CommandState.Mode.SELECT -> false
|
CommandState.Mode.INSERT, CommandState.Mode.CMD_LINE, CommandState.Mode.REPLACE, CommandState.Mode.SELECT -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val CommandState.Mode.isBlockCaretShape
|
||||||
|
get() = when (this) {
|
||||||
|
CommandState.Mode.VISUAL, CommandState.Mode.COMMAND, CommandState.Mode.OP_PENDING -> true
|
||||||
|
CommandState.Mode.INSERT, CommandState.Mode.CMD_LINE, CommandState.Mode.REPLACE, CommandState.Mode.SELECT -> !VimPlugin.getEditor().isBarCursorSettings
|
||||||
|
}
|
||||||
|
|
||||||
val CommandState.Mode.hasVisualSelection
|
val CommandState.Mode.hasVisualSelection
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
CommandState.Mode.VISUAL, CommandState.Mode.SELECT -> true
|
CommandState.Mode.VISUAL, CommandState.Mode.SELECT -> true
|
||||||
|
@@ -27,7 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||||||
import com.intellij.testFramework.LightVirtualFile;
|
import com.intellij.testFramework.LightVirtualFile;
|
||||||
import com.maddyhome.idea.vim.common.IndentConfig;
|
import com.maddyhome.idea.vim.common.IndentConfig;
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
import com.maddyhome.idea.vim.common.TextRange;
|
||||||
import com.maddyhome.idea.vim.ui.ExEntryPanel;
|
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user