mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-05-07 05:34:02 +02:00
Add bitwise functions
This commit is contained in:
parent
be86dc3c78
commit
23329cc522
src
main/resources/messages
test/java/org/jetbrains/plugins/ideavim/ex/implementation/functions/bitwiseFunctions
vim-engine/src/main
kotlin/com/maddyhome/idea/vim/vimscript/model/functions/handlers/bitwiseFunctions
resources/ksp-generated
@ -84,6 +84,7 @@ E546=E546: Illegal mode: {0}
|
||||
E548=E548: Digit expected: {0}
|
||||
E549=E549: Illegal percentage: {0}
|
||||
E774=E774: 'operatorfunc' is empty
|
||||
E805=E805: Using a Float as a Number
|
||||
e841.reserved.name.cannot.be.used.for.user.defined.command=E841: Reserved name, cannot be used for user defined command
|
||||
E939=E939: Positive count required
|
||||
E1214=E1214: Digraph must be just two characters: {0}
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.ideavim.ex.implementation.functions.bitwiseFunctions
|
||||
|
||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
|
||||
class AndFunctionTest : VimTestCase() {
|
||||
@BeforeEach
|
||||
override fun setUp(testInfo: TestInfo) {
|
||||
super.setUp(testInfo)
|
||||
configureByText("\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function bitwise ANDs two numbers`() {
|
||||
assertCommandOutput("echo and(2, 6)", "2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function bitwise ANDs two numbers with negative numbers`() {
|
||||
assertCommandOutput("echo and(-2, -6)", "-6")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function returns 0`() {
|
||||
assertCommandOutput("echo and(2, 4)", "0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function coerces string to number`() {
|
||||
assertCommandOutput("echo and('0xFF', '35')", "35")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function with list causes error`() {
|
||||
enterCommand("echo and([1, 2, 3], [2, 3, 4])")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E745: Using a List as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function with dict causes error`() {
|
||||
enterCommand("echo and({1: 2, 3: 4}, {3: 4, 5: 6})")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E728: Using a Dictionary as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test and function with float causes error`() {
|
||||
enterCommand("echo and(1.5, 2.5)")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E805: Using a Float as a Number")
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.ideavim.ex.implementation.functions.bitwiseFunctions
|
||||
|
||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
|
||||
class InvertFunctionTest : VimTestCase() {
|
||||
@BeforeEach
|
||||
override fun setUp(testInfo: TestInfo) {
|
||||
super.setUp(testInfo)
|
||||
configureByText("\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invert function inverts bits`() {
|
||||
// assertCommandOutput("echo invert(0b1010)", "-11")
|
||||
assertCommandOutput("echo invert(10)", "-11")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invert function with list causes error`() {
|
||||
enterCommand("echo invert([1, 2, 3])")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E745: Using a List as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invert function with dict causes error`() {
|
||||
enterCommand("echo invert({1: 2, 3: 4})")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E728: Using a Dictionary as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test invert function with float causes error`() {
|
||||
enterCommand("echo invert(1.5)")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E805: Using a Float as a Number")
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.ideavim.ex.implementation.functions.bitwiseFunctions
|
||||
|
||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
|
||||
class OrFunctionTest : VimTestCase() {
|
||||
@BeforeEach
|
||||
override fun setUp(testInfo: TestInfo) {
|
||||
super.setUp(testInfo)
|
||||
configureByText("\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function bitwise ORs two numbers`() {
|
||||
assertCommandOutput("echo or(2, 7)", "7")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function bitwise ORs two numbers with negative numbers`() {
|
||||
assertCommandOutput("echo or(-2, -6)", "-2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function returns 0`() {
|
||||
assertCommandOutput("echo or(0, 0)", "0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function coerces string to number`() {
|
||||
assertCommandOutput("echo or('0x07', '35')", "39")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function with list causes error`() {
|
||||
enterCommand("echo or([1, 2, 3], [2, 3, 4])")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E745: Using a List as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function with dict causes error`() {
|
||||
enterCommand("echo or({1: 2, 3: 4}, {3: 4, 5: 6})")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E728: Using a Dictionary as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test or function with float causes error`() {
|
||||
enterCommand("echo or(1.5, 2.5)")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E805: Using a Float as a Number")
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.ideavim.ex.implementation.functions.bitwiseFunctions
|
||||
|
||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
|
||||
class XorFunctionTest : VimTestCase() {
|
||||
@BeforeEach
|
||||
override fun setUp(testInfo: TestInfo) {
|
||||
super.setUp(testInfo)
|
||||
configureByText("\n")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function bitwise XORs two numbers`() {
|
||||
assertCommandOutput("echo xor(2, 7)", "5")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function bitwise XORs two numbers with negative numbers`() {
|
||||
assertCommandOutput("echo xor(-2, -6)", "4")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function returns 0`() {
|
||||
assertCommandOutput("echo xor(2, 2)", "0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function coerces string to number`() {
|
||||
assertCommandOutput("echo xor('0x07', '35')", "36")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function with list causes error`() {
|
||||
enterCommand("echo xor([1, 2, 3], [2, 3, 4])")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E745: Using a List as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function with dict causes error`() {
|
||||
enterCommand("echo xor({1: 2, 3: 4}, {3: 4, 5: 6})")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E728: Using a Dictionary as a Number")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test xor function with float causes error`() {
|
||||
enterCommand("echo xor(1.5, 2.5)")
|
||||
assertNoExOutput()
|
||||
assertPluginError(true)
|
||||
assertPluginErrorMessageContains("E805: Using a Float as a Number")
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions
|
||||
|
||||
import com.intellij.vim.annotations.VimscriptFunction
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.ex.exExceptionMessage
|
||||
import com.maddyhome.idea.vim.vimscript.model.VimLContext
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
|
||||
import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
|
||||
|
||||
internal abstract class BinaryBitwiseFunctionHandlerBase : FunctionHandler() {
|
||||
override val minimumNumberOfArguments = 2
|
||||
override val maximumNumberOfArguments = 2
|
||||
|
||||
override fun doFunction(
|
||||
argumentValues: List<Expression>,
|
||||
editor: VimEditor,
|
||||
context: ExecutionContext,
|
||||
vimContext: VimLContext,
|
||||
): VimDataType {
|
||||
val arg1 = argumentValues[0].evaluate(editor, context, vimContext)
|
||||
val arg2 = argumentValues[1].evaluate(editor, context, vimContext)
|
||||
|
||||
if (arg1 is VimFloat || arg2 is VimFloat) {
|
||||
throw exExceptionMessage("E805") // E805: Using a Float as a Number
|
||||
}
|
||||
|
||||
return VimInt(invoke(arg1.asDouble().toInt(), arg2.asDouble().toInt()))
|
||||
}
|
||||
|
||||
abstract fun invoke(a: Int, b: Int): Int
|
||||
}
|
||||
|
||||
@VimscriptFunction(name = "and")
|
||||
internal class AndFunctionHandler : BinaryBitwiseFunctionHandlerBase() {
|
||||
override fun invoke(a: Int, b: Int) = a and b
|
||||
}
|
||||
|
||||
@VimscriptFunction(name = "or")
|
||||
internal class OrFunctionHandler : BinaryBitwiseFunctionHandlerBase() {
|
||||
override fun invoke(a: Int, b: Int) = a or b
|
||||
}
|
||||
|
||||
@VimscriptFunction(name = "xor")
|
||||
internal class XorFunctionHandler : BinaryBitwiseFunctionHandlerBase() {
|
||||
override fun invoke(a: Int, b: Int) = a xor b
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2003-2025 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions
|
||||
|
||||
import com.intellij.vim.annotations.VimscriptFunction
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.ex.exExceptionMessage
|
||||
import com.maddyhome.idea.vim.vimscript.model.VimLContext
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimFloat
|
||||
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimInt
|
||||
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
|
||||
import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler
|
||||
|
||||
@VimscriptFunction(name = "invert")
|
||||
internal class InvertFunctionHandler : FunctionHandler() {
|
||||
override val minimumNumberOfArguments = 1
|
||||
override val maximumNumberOfArguments = 1
|
||||
|
||||
override fun doFunction(
|
||||
argumentValues: List<Expression>,
|
||||
editor: VimEditor,
|
||||
context: ExecutionContext,
|
||||
vimContext: VimLContext,
|
||||
): VimDataType {
|
||||
val arg1 = argumentValues[0].evaluate(editor, context, vimContext)
|
||||
if (arg1 is VimFloat) {
|
||||
throw exExceptionMessage("E805") // E805: Using a Float as a Number
|
||||
}
|
||||
|
||||
return VimInt(arg1.asDouble().toInt().inv())
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"abs": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.AbsFunctionHandler",
|
||||
"and": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.AndFunctionHandler",
|
||||
"col": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.ColFunctionHandler",
|
||||
"empty": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.EmptyFunctionHandler",
|
||||
"escape": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.EscapeFunctionHandler",
|
||||
@ -8,12 +9,15 @@
|
||||
"function": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.FunctionFunctionHandler",
|
||||
"get": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.GetFunctionHandler",
|
||||
"getcmdtype": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.GetCmdTypeFunctionHandler",
|
||||
"invert": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.InvertFunctionHandler",
|
||||
"join": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.JoinFunctionHandler",
|
||||
"len": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.LenFunctionHandler",
|
||||
"line": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.LineFunctionHandler",
|
||||
"or": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.OrFunctionHandler",
|
||||
"sin": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.SinFunctionHandler",
|
||||
"split": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.SplitFunctionHandler",
|
||||
"submatch": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.SubmatchFunctionHandler",
|
||||
"tolower": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.TolowerFunctionHandler",
|
||||
"toupper": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.ToupperFunctionHandler"
|
||||
"toupper": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.ToupperFunctionHandler",
|
||||
"xor": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.bitwiseFunctions.XorFunctionHandler"
|
||||
}
|
Loading…
Reference in New Issue
Block a user