mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-22 08:53:28 +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
|
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,
|
# Wrap Vimscript for using in lua,
|
||||||
# but only if the string contains something other than whitespaces
|
# but only if the string contains something other than whitespaces
|
||||||
# TODO: account for a possible ']]' in the string
|
|
||||||
wrapVimscriptForLua =
|
wrapVimscriptForLua =
|
||||||
string:
|
string: lib.optionalString (hasContent string) "vim.cmd(${toLuaLongLiteral string})";
|
||||||
lib.optionalString (hasContent string) ''
|
|
||||||
vim.cmd([[
|
|
||||||
${string}
|
|
||||||
]])
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Wrap lua script for using in Vimscript,
|
# Wrap lua script for using in Vimscript,
|
||||||
# but only if the string contains something other than whitespaces
|
# but only if the string contains something other than whitespaces
|
||||||
# TODO: account for a possible 'EOF' if the string
|
|
||||||
wrapLuaForVimscript =
|
wrapLuaForVimscript =
|
||||||
string:
|
string: lib.optionalString (hasContent string) "lua ${toVimscriptHeredoc string}";
|
||||||
lib.optionalString (hasContent string) ''
|
|
||||||
lua << EOF
|
|
||||||
${string}
|
|
||||||
EOF
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Split a list into a several sub-list, each with a max-size of `size`
|
# Split a list into a several sub-list, each with a max-size of `size`
|
||||||
groupListBySize =
|
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
|
in
|
||||||
if results == [ ] then
|
if results == [ ] then
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue