mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-20 16:15:43 +02:00
lib: fix escaping bugs in wrapVimscriptForLua and wrapLuaForVimscript
These functions had very similar bugs: they didn't check if their chosen "close token" was already present in the string they're escaping. I went ahead and did the work implied by the TODOs: search for a "close token" that is *not* in the original string. Pretty simple concept, but it turned into an annoying amount of code. I couldn't find anything in upstream nixpkgs lib, or some clever insight about lua/vimscript that makes this work unecessary, but I'll be thrilled (and a little bummed about a wasted afternoon) to learn about something.
This commit is contained in:
parent
2df1bdd14d
commit
400d1d927d
2 changed files with 120 additions and 14 deletions
|
@ -125,27 +125,98 @@ rec {
|
|||
end
|
||||
'';
|
||||
|
||||
/**
|
||||
Convert the given String to a Lua [long literal].
|
||||
For example, you could use this to safely pass a Vimscript string to the
|
||||
`vim.cmd` function.
|
||||
|
||||
[long literal]: https://www.lua.org/manual/5.4/manual.html#3.1
|
||||
|
||||
# Examples
|
||||
|
||||
```nix
|
||||
nix-repl> toLuaLongLiteral "simple"
|
||||
"[[simple]]"
|
||||
```
|
||||
|
||||
```nix
|
||||
nix-repl> toLuaLongLiteral "]]"
|
||||
"[=[]]]=]"
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
toLuaLongLiteral :: String -> String
|
||||
```
|
||||
*/
|
||||
toLuaLongLiteral =
|
||||
string:
|
||||
let
|
||||
findTokens =
|
||||
depth:
|
||||
let
|
||||
infix = lib.strings.replicate depth "=";
|
||||
tokens.open = "[${infix}[";
|
||||
tokens.close = "]${infix}]";
|
||||
in
|
||||
if lib.hasInfix tokens.close string then findTokens (depth + 1) else tokens;
|
||||
|
||||
tokens = findTokens 0;
|
||||
in
|
||||
tokens.open + string + tokens.close;
|
||||
|
||||
/**
|
||||
Convert the given String into a Vimscript [:let-heredoc].
|
||||
For example, you could use this to invoke [:lua].
|
||||
|
||||
[:let-heredoc]: https://neovim.io/doc/user/eval.html#%3Alet-heredoc
|
||||
[:lua]: https://neovim.io/doc/user/lua.html#%3Alua-heredoc
|
||||
|
||||
# Examples
|
||||
|
||||
```nix
|
||||
toVimscriptHeredoc "simple"
|
||||
=> "<< EOF\nsimple\nEOF"
|
||||
```
|
||||
|
||||
```nix
|
||||
toVimscriptHeredoc "EOF"
|
||||
=> "<< EOFF\nEOF\nEOFF"
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
toVimscriptHeredoc :: String -> String
|
||||
```
|
||||
*/
|
||||
toVimscriptHeredoc =
|
||||
string:
|
||||
let
|
||||
findToken =
|
||||
depth:
|
||||
let
|
||||
token = "EOF" + lib.strings.replicate depth "F";
|
||||
in
|
||||
if lib.hasInfix token string then findToken (depth + 1) else token;
|
||||
|
||||
token = findToken 0;
|
||||
in
|
||||
''
|
||||
<< ${token}
|
||||
${string}
|
||||
${token}'';
|
||||
|
||||
# Wrap Vimscript for using in lua,
|
||||
# but only if the string contains something other than whitespaces
|
||||
# TODO: account for a possible ']]' in the string
|
||||
wrapVimscriptForLua =
|
||||
string:
|
||||
lib.optionalString (hasContent string) ''
|
||||
vim.cmd([[
|
||||
${string}
|
||||
]])
|
||||
'';
|
||||
string: lib.optionalString (hasContent string) "vim.cmd(${toLuaLongLiteral string})";
|
||||
|
||||
# Wrap lua script for using in Vimscript,
|
||||
# but only if the string contains something other than whitespaces
|
||||
# TODO: account for a possible 'EOF' if the string
|
||||
wrapLuaForVimscript =
|
||||
string:
|
||||
lib.optionalString (hasContent string) ''
|
||||
lua << EOF
|
||||
${string}
|
||||
EOF
|
||||
'';
|
||||
string: lib.optionalString (hasContent string) "lua ${toVimscriptHeredoc string}";
|
||||
|
||||
# Split a list into a several sub-list, each with a max-size of `size`
|
||||
groupListBySize =
|
||||
|
|
|
@ -374,6 +374,41 @@ let
|
|||
];
|
||||
};
|
||||
};
|
||||
|
||||
testEscapeStringForLua = {
|
||||
expr = lib.mapAttrs (_: helpers.utils.toLuaLongLiteral) {
|
||||
simple = "simple";
|
||||
depth-one = " ]] ";
|
||||
depth-two = " ]] ]=] ";
|
||||
};
|
||||
expected = {
|
||||
simple = "[[simple]]";
|
||||
depth-one = "[=[ ]] ]=]";
|
||||
depth-two = "[==[ ]] ]=] ]==]";
|
||||
};
|
||||
};
|
||||
|
||||
testEscapeStringForVimscript = {
|
||||
expr = lib.mapAttrs (_: helpers.utils.toVimscriptHeredoc) {
|
||||
simple = "simple";
|
||||
depth-one = "EOF";
|
||||
depth-two = "EOF EOFF";
|
||||
};
|
||||
expected = {
|
||||
simple = ''
|
||||
<< EOF
|
||||
simple
|
||||
EOF'';
|
||||
depth-one = ''
|
||||
<< EOFF
|
||||
EOF
|
||||
EOFF'';
|
||||
depth-two = ''
|
||||
<< EOFFF
|
||||
EOF EOFF
|
||||
EOFFF'';
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
if results == [ ] then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue