I'm working on a Visual Studio Code extension. The extension is supposed to act on the text that is currently selected in the editor window and send it to an external command (lein-cljfmt in my case, but I think that's unrelated to my question). When the external command is done processing the text I want to replace the current editor selector with the result returned from the command line tool.
Before sending the string I escape it like this:
contents
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n');
The result in being unescaped like:
contents
.replace(/\\n/g, '\n')
.replace(/\\"/g, '"')
.replace(/\\\\/g, '\\');
This works in all but one case: when the selection that is being processed contains a string literal that contains a newline literal, the unescaping will instead turn this into a linebreak, thus breaking the code in the editor.
This is an example of a snippet that breaks my escaping:
(defn join
[a b]
(str a "\n" b))
I tried quite some regexp black magic like
.replace(/(?!\B"[^"]*)\\n(?![^"]*"\B)/g, '\n')
by now, but couldn't find a solution that does not have edge cases. Is there a way to do this that I am missing? I also wonder if there is a VSCode extension API that could handle that as it seems to be a common scenario to me.