Sublime Text 3 构建系统:JSON 中的反斜杠

Sublime Text 3 Build System: Backslash in a JSON

我想用MinGW通过Sublime Text编译一个c程序。 我需要 运行 的命令是:

gcc "${file}" -o "${file_path}${file_base_name}.exe"

(注意文件路径中的\)

我需要将此字符串作为值写入 JSON 文件中。所以,我尝试转换有问题的字符:

" => \"
\ => \
...

" 字符没有问题,它可以正确转换 - 反斜杠的行为很奇怪。 这是我尝试通过 Sublime 编译时 运行s 的命令:

gcc C:\Users\omer\Desktop${file_base_name}.c -o C:\Users\omer\Desktop${file_base_name}.exe

转换\ => \不正确?我错过了什么?

编辑:这是完整的构建系统 JSON。

{
"shell_cmd": "gcc \"${file}\" -o \"${file_path}\${file_base_name}.exe\"",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"working_dir": "${file_path}",
"selector": "source.c",

"variants":
[
    {
        "name": "Run",
        "shell_cmd": "gcc \"${file}\" -o \"${file_path}\${file_base_name}.exe\" && \"${file_path}\${file_base_name}.exe\""
    }
]

}

对您的问题的简短回答是,您需要进行一些但不是全部所需的转义,因为您需要应对 JSON 转义字符和 Sublime 转义字符,因此结果你被 Sublime 的一个功能所吸引。

我猜你在 Windows 上,因为你使用 \ 作为路径分隔符; Windows 还允许 / 也用作路径分隔符,因此您可以通过将所有 \ 序列替换为 / 来解决您的问题(这也可能整体看起来更干净了)。

下面是较长版本的答案,它解释了正在发生的事情(以及另一种解决视觉上更混乱的问题的方法)。


你确实是正确的,在 JSON\ 字符是特殊的并且引入了一个转义序列,所以为了在 [=14= 中有一个文字 \ 字符] 字符串,您需要将其写为 \

但是,Sublime 也支持它自己的 \ 转义序列,因此在某些情况下,您需要在输入文件中使用比您预期更多的转义字符才能获得您想要的结果想要。

sublime-build 文件中,Sublime 将任何以 $ 为前缀的单词扩展为变量,并用它的值替换整个变量(例如 $file 替换为名称当前文件)。这也适用于任何以 $ 为前缀的序列,例如 $test;在这种情况下,变量的值是空字符串,因此整个变量被替换为空字符串。

此外,Sublime 还在内部处理 \ 字符作为意思 "the next character is not special"。因此,如果您需要在构建命令中的某处使用 $ 字符(可能作为命令行参数等),您需要将其引用为 $ 以告诉 Sublime 不要特殊对待它。

这就是您在上面的输出中看到的;执行的命令包含文本 ${file_base_name} 因为 Sublime 看到字符串的方式告诉它它不应该扩展变量。

也许最好用一些例子来说明原因:

"shell_cmd": "echo ${file}"

这将在构建输出中显示当前文件的名称

"shell_cmd": "echo ${file}

在这里,如果您尝试 运行 构建,什么也不会发生,但状态栏会显示 No Build System。想法是告诉 Sublime 不要扩展变量,但实际上这是无效的 JSON 因为当处理为 JSON 数据时, $ 不是有效的转义序列。因此文件加载失败并且 运行.

没有构建系统
"shell_cmd": "echo \${file}

当它被读取为 JSON 时,\ 被替换为 \,而 Sublime 将字符串视为 ${file}。当它执行构建时,Sublime 本身将 $ 替换为 $,构建输出面板中的输出字面意思是 ${file}(即没有展开)。

最后一个示例显示了您遇到的情况,\ 告诉 JSON 加载器这应该是单个 \ 字符,这就是发生的情况。然而,Sublime 随后将 $ 视为特殊的。

为了扩展文件路径和基本名称之间带有文字 \ 的内容,您需要执行以下操作:

"shell_cmd": "echo ${file_path}\\${file_base_name}"

事件的顺序是这样的:

  1. JSON加载器加载字符串并转换转义序列,因此每个\被转换为单个\,留下Sublime看到的字符串作为 echo "${file_path}\${file_base_name}".

  2. 当 Sublime 执行构建时,它将 \ 视为单个 \,将完整处理的字符串保留为 echo "${file_path}${file_base_name}"

  3. 变量被展开,你最终得到C:\Users\Me\Desktop\MyFile(或者你有什么),这就是你想要的。

因此,解决问题的一种方法是将所有 \ 序列加倍,使它们成为 \\;然后 JSON 处理器会在加载文件时将其转换为您当前拥有的内容,而 Sublime 将按照您期望的方式处理它。

总的来说这很麻烦,但事实证明,在 Windows 上你可以使用 / 作为路径分隔符,它在内部的处理方式与其他任何东西一样,所以一个更快的解决方案是更换\/ 相反,这应该为您提供相同的工作解决方案,而不是看起来那么混乱。