Skip to content

Commit fbbd7a4

Browse files
authored
feat: insert " in bash command substitution and variable expansion (#535)
add special rules for insert " in bash files 1. command substitution: "$(|)" 2. variable expansion: "${|}" when insert char " in |, check rules for paired "" quotes will fail. Original behavior: Before Input After ------------------------------------ "$(|)" " "$("|)" "$("|)" " "$(""|")" "${|}" " "${"|}" "${"|}" " "${""|"}" New behavior: Before Input After ------------------------------------ "$(|)" " "$("|")" "$("|)" " "$(""|)" "${|}" " "${"|"}" "${"|}" " "${""|}"
1 parent c2a0dd0 commit fbbd7a4

File tree

3 files changed

+174
-1
lines changed

3 files changed

+174
-1
lines changed

lua/nvim-autopairs/rules/basic.lua

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,15 @@ local function setup(opt)
5858
quote("'", "'", "rust"):with_pair(cond.not_before_regex("[%w<&]")):with_pair(cond.not_after_text(">")),
5959
Rule("''", "''", 'nix'):with_move(cond.after_text("'")),
6060
quote("`", "`"),
61-
quote('"', '"', "-vim"),
61+
quote('"', '"', { "-vim", "-bash", "-sh" }),
62+
quote('"', '"', { "bash", "sh" }):with_pair(function(opts)
63+
-- add a constraint for quote check if input " in bash command
64+
-- substitution "$()", variable expansion "${}".
65+
local str = utils.get_shell_substitution_content_before_pos(opts.text, opts.col - 1)
66+
if str then
67+
return not utils.is_in_quotes(str, #str, '"')
68+
end
69+
end, 1),
6270
quote('"', '"', "vim"):with_pair(cond.not_before_regex("^%s*$", -1)),
6371
bracket("(", ")"),
6472
bracket("[", "]"),

lua/nvim-autopairs/utils.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,31 @@ M.get_prev_char = function(opt)
199199
return opt.line:sub(opt.col - 1, opt.col + #opt.rule.start_pair - 2)
200200
end
201201

202+
--- Get inner content of nearest bash substitution or variable expansion
203+
--- before cursor position
204+
--- eg:
205+
--- command substitution $(ab|c) -> ab
206+
--- variable expansion ${ab|c|} -> ab
207+
--- @param line string input line
208+
--- @param pos integer cursor pos (1-based)
209+
--- @return string | nil
210+
M.get_shell_substitution_content_before_pos = function(line, pos)
211+
local i = pos
212+
local char, prev2
213+
214+
while i > 1 do
215+
char = line:sub(i, i)
216+
if char == ')' or char == '}' then
217+
return nil
218+
end
219+
220+
prev2 = line:sub(i - 1, i)
221+
if prev2 == '$(' or prev2 == '${' then
222+
return line:sub(i + 1, pos)
223+
end
224+
225+
i = i - 1
226+
end
227+
end
228+
202229
return M

tests/nvim-autopairs_spec.lua

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,144 @@ local data = {
845845
"|```python"
846846
}
847847
},
848+
{
849+
name = [[add " in a bash-like command substitution, but not in a bash file]],
850+
key = [["]],
851+
before = [["$(|)"]],
852+
after = [["$("|)"]],
853+
},
854+
{
855+
name = [[add " in a bash-like variable expansion, but not in a bash file]],
856+
key = [["]],
857+
before = [["${|}"]],
858+
after = [["${"|}"]],
859+
},
860+
{
861+
name = [[add " in a bash command substitution]],
862+
key = [["]],
863+
before = [["$(|)"]],
864+
after = [["$("|")"]],
865+
filetype = "bash"
866+
},
867+
{
868+
name = [[add " in a bash command substitution, after a pair "]],
869+
key = [["]],
870+
before = [["$("$cmd" |)"]],
871+
after = [["$("$cmd" "|")"]],
872+
filetype = "bash"
873+
},
874+
{
875+
name = [[add " in a bash command substitution, after a open "]],
876+
key = [["]],
877+
before = [["$("|)"]],
878+
after = [["$(""|)"]],
879+
filetype = "bash"
880+
},
881+
{
882+
name = [[add " after a bash command substitution]],
883+
key = [["]],
884+
before = [["$("$var")" | ]],
885+
after = [["$("$var")" "|"]],
886+
filetype = "bash"
887+
},
888+
{
889+
name = [[add " in a variable command substitution]],
890+
key = [["]],
891+
before = [["${|}"]],
892+
after = [["${"|"}"]],
893+
filetype = "bash"
894+
},
895+
{
896+
name = [[add " in a bash variable expansion, after a pair "]],
897+
key = [["]],
898+
before = [["${"$cmd" |}"]],
899+
after = [["${"$cmd" "|"}"]],
900+
filetype = "bash"
901+
},
902+
{
903+
name = [[add " in a bash variable expansion, after a open "]],
904+
key = [["]],
905+
before = [["${"|}"]],
906+
after = [["${""|}"]],
907+
filetype = "bash"
908+
},
909+
{
910+
name = [[add " in a bash variable expansion, within array.]],
911+
key = [["]],
912+
before = [==["${arr[|]}"]==],
913+
after = [==["${arr["|"]}"]==],
914+
filetype = "bash"
915+
},
916+
{
917+
name = [[add " after a bash variable expansion]],
918+
key = [["]],
919+
before = [["${"$var"}" | ]],
920+
after = [["${"$var"}" "|"]],
921+
filetype = "bash"
922+
},
923+
{
924+
name = [[add " in a bash command substitution]],
925+
key = [["]],
926+
before = [["$(|)"]],
927+
after = [["$("|")"]],
928+
filetype = "sh"
929+
},
930+
{
931+
name = [[add " in a bash command substitution, after a pair "]],
932+
key = [["]],
933+
before = [["$("$cmd" |)"]],
934+
after = [["$("$cmd" "|")"]],
935+
filetype = "sh"
936+
},
937+
{
938+
name = [[add " in a bash command substitution, after a open "]],
939+
key = [["]],
940+
before = [["$("|)"]],
941+
after = [["$(""|)"]],
942+
filetype = "sh"
943+
},
944+
{
945+
name = [[add " after a bash command substitution]],
946+
key = [["]],
947+
before = [["$("$var")" | ]],
948+
after = [["$("$var")" "|"]],
949+
filetype = "sh"
950+
},
951+
{
952+
name = [[add " in a variable command substitution]],
953+
key = [["]],
954+
before = [["${|}"]],
955+
after = [["${"|"}"]],
956+
filetype = "sh"
957+
},
958+
{
959+
name = [[add " in a bash variable expansion, after a pair "]],
960+
key = [["]],
961+
before = [["${"$cmd" |}"]],
962+
after = [["${"$cmd" "|"}"]],
963+
filetype = "sh"
964+
},
965+
{
966+
name = [[add " in a bash variable expansion, after a open "]],
967+
key = [["]],
968+
before = [["${"|}"]],
969+
after = [["${""|}"]],
970+
filetype = "sh"
971+
},
972+
{
973+
name = [[add " after a bash variable expansion]],
974+
key = [["]],
975+
before = [["${"$var"}" | ]],
976+
after = [["${"$var"}" "|"]],
977+
filetype = "sh"
978+
},
979+
{
980+
name = [[add " in a bash variable expansion, within array.]],
981+
key = [["]],
982+
before = [==["${arr[|]}"]==],
983+
after = [==["${arr["|"]}"]==],
984+
filetype = "sh"
985+
},
848986
}
849987

850988
local run_data = _G.Test_filter(data)

0 commit comments

Comments
 (0)