Skip to content

Commit

Permalink
Add support for escape() vim function
Browse files Browse the repository at this point in the history
  • Loading branch information
jphalip committed Dec 5, 2024
1 parent a005eb0 commit ba47cf4
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2003-2024 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

import org.jetbrains.plugins.ideavim.VimTestCase
import org.junit.jupiter.api.Test


class EscapeFunctionTest : VimTestCase() {
@Test
fun `test escape windows path with spaces`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('c:\program files\vim', ' \')"""))
assertExOutput("""c:\\program\ files\\vim""")
}

@Test
fun `test escape multiple special characters`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('special chars: #$^', '#$^')"""))
assertExOutput("""special chars: \#\$\^""")
}

@Test
fun `test escape when no escaping needed`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('no escaping needed', 'xyz')"""))
assertExOutput("no escaping needed")
}

@Test
fun `test escape empty strings`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('', '')"""))
assertExOutput("")
}

@Test
fun `test escape consecutive special characters`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('$$$$', '$')"""))
assertExOutput("""\$\$\$\$""")
}

@Test
fun `test escape with double backslashes`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('test\\here', '\\')"""))
assertExOutput("""test\\\\here""")
}

@Test
fun `test escape with unicode characters`() {
configureByText("\n")
typeText(commandToKeys("""echo escape('Hello 👋 #world', '#')"""))
assertExOutput("""Hello 👋 \#world""")

typeText(commandToKeys("""echo escape('🎉$🎊$', '$')"""))
assertExOutput("""🎉\$🎊\$""")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.maddyhome.idea.vim.vimscript.model.functions.handlers

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.vimscript.model.VimLContext
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimDataType
import com.maddyhome.idea.vim.vimscript.model.datatypes.VimString
import com.maddyhome.idea.vim.vimscript.model.expressions.Expression
import com.maddyhome.idea.vim.vimscript.model.functions.FunctionHandler

/**
* Implementation of Vim's escape() function.
* Escapes characters specified in the second argument that occur in the first
* argument with a backslash.
* Example: escape('c:\program files\vim', ' \') returns 'c:\\program\ files\\vim'
*/
@VimscriptFunction(name = "escape")
internal class EscapeFunctionHandler : FunctionHandler() {
override val minimumNumberOfArguments = 2
override val maximumNumberOfArguments = 2

override fun doFunction(
argumentValues: List<Expression>,
editor: VimEditor,
context: ExecutionContext,
vimContext: VimLContext,
): VimDataType {
// Get the input string and characters to escape
val string = argumentValues[0].evaluate(editor, context, vimContext).asString()
val charsToEscape = argumentValues[1].evaluate(editor, context, vimContext).asString()

// Process each character in the input string
val result = StringBuilder()
for (c in string) {
// If the current character should be escaped, add a backslash before it
if (c in charsToEscape) {
result.append('\\')
}
result.append(c)
}

return VimString(result.toString())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"abs": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.AbsFunctionHandler",
"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",
"exists": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.ExistsFunctionHandler",
"funcref": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.FuncrefFunctionHandler",
"function": "com.maddyhome.idea.vim.vimscript.model.functions.handlers.FunctionFunctionHandler",
Expand Down

0 comments on commit ba47cf4

Please sign in to comment.