1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-02-28 02:45:59 +01:00

Added 'execute' command

This commit is contained in:
lippfi 2021-08-07 00:03:21 +03:00
parent 509a202f93
commit 73c1dc8118
5 changed files with 107 additions and 1 deletions
src
com/maddyhome/idea/vim/vimscript
main/antlr
test/org/jetbrains/plugins/ideavim/ex/handler

View File

@ -40,7 +40,9 @@ object Executor {
var executingVimScript = false
@kotlin.jvm.Throws(ExException::class)
fun execute(scriptString: String, editor: Editor, context: DataContext, skipHistory: Boolean, indicateErrors: Boolean = true) {
fun execute(scriptString: String, editor: Editor, context: DataContext, skipHistory: Boolean, indicateErrors: Boolean = true): ExecutionResult {
var finalResult: ExecutionResult = ExecutionResult.Success
val script = VimscriptParser.parse(scriptString)
val vimContext = VimContext()
@ -48,9 +50,11 @@ object Executor {
try {
val result = unit.execute(editor, context, vimContext)
if (result is ExecutionResult.Error) {
finalResult = ExecutionResult.Error
VimPlugin.indicateError()
}
} catch (e: ExException) {
finalResult = ExecutionResult.Error
if (indicateErrors) {
VimPlugin.showMessage(e.message)
VimPlugin.indicateError()
@ -66,6 +70,7 @@ object Executor {
VimPlugin.getRegister().storeTextSpecial(RegisterGroup.LAST_COMMAND_REGISTER, scriptString)
}
}
return finalResult
}
fun execute(scriptString: String, skipHistory: Boolean = true) {

View File

@ -0,0 +1,36 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2021 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.vimscript.model.commands
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.maddyhome.idea.vim.ex.ranges.Ranges
import com.maddyhome.idea.vim.vimscript.Executor
import com.maddyhome.idea.vim.vimscript.model.ExecutionResult
import com.maddyhome.idea.vim.vimscript.model.VimContext
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
class ExecuteCommand(val ranges: Ranges, val expressions: List<Expression>) : Command.SingleExecution(ranges) {
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.SELF_SYNCHRONIZED)
override fun processCommand(editor: Editor, context: DataContext, vimContext: VimContext): ExecutionResult {
val command = expressions.joinToString(separator = " ") { it.evaluate(editor, context, vimContext).asString() }
return Executor.execute(command, editor, context, skipHistory = true, indicateErrors = true)
}
}

View File

@ -22,6 +22,7 @@ import com.maddyhome.idea.vim.vimscript.model.commands.DigraphCommand
import com.maddyhome.idea.vim.vimscript.model.commands.DumpLineCommand
import com.maddyhome.idea.vim.vimscript.model.commands.EchoCommand
import com.maddyhome.idea.vim.vimscript.model.commands.EditFileCommand
import com.maddyhome.idea.vim.vimscript.model.commands.ExecuteCommand
import com.maddyhome.idea.vim.vimscript.model.commands.ExitCommand
import com.maddyhome.idea.vim.vimscript.model.commands.FileCommand
import com.maddyhome.idea.vim.vimscript.model.commands.FindClassCommand
@ -648,6 +649,16 @@ object CommandVisitor : VimscriptBaseVisitor<Command>() {
return MapClearCommand(ranges, argument, cmd)
}
override fun visitExecuteCommand(ctx: VimscriptParser.ExecuteCommandContext): ExecuteCommand {
val ranges = parseRanges(ctx.range())
val expressions = ctx.expr().stream()
.map { tree: ExprContext ->
expressionVisitor.visit(tree)
}
.collect(Collectors.toList())
return ExecuteCommand(ranges, expressions)
}
override fun visitOtherCommand(ctx: OtherCommandContext): UnknownCommand {
val ranges: Ranges = parseRanges(ctx.range())
val name = ctx.commandName().text

View File

@ -303,6 +303,9 @@ command:
range? ws_cols MAP_CLEAR (WS* commandArgument)?
#MapClearCommand|
range? ws_cols EXECUTE WS+ (expr WS*)*
#ExecuteCommand|
range? ws_cols UNMAP (WS* commandArgument)?
#UnmapCommand|
@ -638,6 +641,7 @@ existingCommands: RETURN
| MAP
| MAP_CLEAR
| UNMAP
| EXECUTE
;
ws_cols: (WS | COLON)*;
@ -814,6 +818,7 @@ UNMAP: 'unm' | 'nun' | 'vu' | 'xu' | 'sunm' | 'ou' | 'iu' | 'cu
| 'nunm' | 'vunm' | 'xunm' | 'ounm' | 'iunm' | 'cunm'
| 'unma' | 'nunma' | 'vunma' | 'xunma' | 'sunma' | 'ounma' | 'iunma' | 'cunma'
| 'unmap' | 'nunmap' | 'vunmap' | 'xunmap' | 'sunmap' | 'ounmap' | 'iunmap' | 'cunmap';
EXECUTE: 'exe' | 'exec' | 'execu' | 'execut' | 'execute';
// Types
DIGIT: [0-9];

View File

@ -0,0 +1,49 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2021 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 org.jetbrains.plugins.ideavim.ex.handler
import org.jetbrains.plugins.ideavim.VimTestCase
class ExecuteCommandTest : VimTestCase() {
fun `test execute with one expression`() {
configureByText("\n")
typeText(commandToKeys("execute 'echo 42'"))
assertExOutput("42\n")
}
fun `test execute with range`() {
configureByText("\n")
typeText(commandToKeys("1,2execute 'echo 42'"))
assertNoExOutput()
assertPluginError(true)
}
fun `test execute multiple expressions`() {
configureByText("\n")
typeText(commandToKeys("execute 'echo' 4 + 2 * 3"))
assertExOutput("10\n")
}
fun `test execute adds space between expressions if missing`() {
configureByText("\n")
typeText(commandToKeys("execute 'echo ' . \"'result =\"4+2*3.\"'\""))
assertExOutput("result = 10\n")
}
}