SublimeText构建系统简介及若干配置示例
作者:互联网
有兄弟来问关于\(Sublime\ Text\)构建系统配置的问题,本文进行一些整理并给出一些例子
\(Sublime\ Text\)构建系统简介
\(Sublime\ Text\)提供构建系统(\(Build\ Systems\))以允许用户运行外部程序,构建系统通过\(json\)的形式指定并保存在\(sublime-build\)文件中,功能包括:根据文件类型自动选择构建系统、记住上次使用的构建系统、构建系统结果的导航、取消执行构建
\(Sublime\ Text\)中,用户新增构建系统的方式为工具-构建系统-新建构建系统,新建的构建系统位于:
- 安装目录下
Data/Packages/User
中(\(Windows\)下) - 用户文件夹下
.config/sublime-text-3/Packages/User
中(\(Linux\)下)
下文主要整理一些关键/常用/官方文档没有详细涉及的内容,\(Sublime\ Text\)构建系统的完整介绍可参考官方文档
修改\(Sublime\ Text\)内置构建系统
\(Sublime\ Text\)内置了一些常见语言的构建系统,内置的构建系统使用\(Sublime\ Text\)提供的控制台,其不同于\(VSCode\),无法处理用户输入,可能的解决方案包括:
- 使用\(Sublime\ REPL\)插件,其性能较差,个人不是很推荐
- 修改内置构建系统,改为使用其它终端,例如\(cmd\)、\(gnome-terminal\)、\(kconsole\)等
\(Sublime\ Text\)内置的构建系统位于\(Sublime\ Text\)安装目录下\(Packages\)目录中的\(sublime-package\)文件内,\(sublime-package\)文件实质上是压缩文件,用解压软件打开即可修改其中的\(sublime-build\)文件,这样就无需通过新建一个构建系统的方式“曲线救国”
需要注意的是\(C\)和\(C++\)的配置均位于\(C++.sublime-package\)中,此外如果一个\(sublime-package\)文件中没有对应的\(sublime-build\)文件,向其中添加\(sublime-build\)文件后,该\(sublime-build\)文件对应的构建系统可以正常加载
个人建议长期使用的构建系统以内置构建系统的方式存储,临时使用的构建系统使用工具-构建系统-新建构建系统的方式添加
\(sublime-build\)部分字段解释
cmd
字段shell_cmd
字段为空时需要,会被shell_cmd
字段覆盖cmd
字段在\(Sublime\ Text\)中的执行方式是subprocess.Popen(cmd)
shell_cmd
字段cmd
字段为空时需要,会覆盖cmd
字段cmd
字段在\(Sublime\ Text\)中的执行方式是subprocess.Popen(shell_cmd, shell=True)
shell
字段shell_cmd
字段为空时有效,用来影响cmd
字段- 设置此字段时,
cmd
字段中的命令将通过\(Shell\)运行,似乎可以认为cmd + shell = shell_cmd
file_regex
字段- 用于获取构建时的报错,从而在代码中高亮标注出来
- 可捕获“文件名”、“行号”、“行内偏移”、“错误信息”中的部分或全部内容,详见官方文档
selector
字段- 设置了工具-构建系统-自动之后,根据此字段选择使用的构建系统
- 需要注意的是,这个字段对应的不是文件扩展名,而是视图-语法中的语法名
variants
字段- 用于在一个\(sublime-build\)中设置多个构建选项,可以通过工具-用...构建选择
- 非首次使用时,工具-构建会使用上一次使用的构建选项,无需每次构建时指定构建选项
\(C\)配置及测试
文件名、行号/行内偏移、错误信息都可以抓取到
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "selector": "source.c", "variants": [ { "name": "Run", "shell_cmd": "gcc -Wall -std=c99 $file -o $file_base_name && $file_path/$file_base_name" }, { "name": "RunInCmd", "shell_cmd": "gcc -Wall -std=c99 $file -o $file_base_name && start cmd /c \"$file_path/$file_base_name & pause\"" } ] }
-
\(HelloWorld\)测试代码
#include <stdio.h> int main() { puts("Hello World"); return 0; }
-
\(A\ +\ B\ Problem\)测试代码
#include <stdio.h> int main() { int a, b; scanf("%d%d", &a, &b); printf("%d\n", a + b); return 0; }
-
出错测试代码
int main() { 1 + 2 return 0; }
\(C++\)配置及测试
文件名、行号/行内偏移、错误信息都可以抓取到
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "selector": "source.c++", "variants": [ { "name": "Run", "shell_cmd": "g++ -Wall -std=c++0x $file -o $file_base_name && $file_path/$file_base_name" }, { "name": "RunInCmd", "shell_cmd": "g++ -Wall -std=c++0x $file -o $file_base_name && start cmd /c \"$file_path/$file_base_name & pause\"" } ] }
-
\(HelloWorld\)测试代码
#include <iostream> using namespace std; int main() { cout << "Hello World" << endl; return 0; }
-
\(A\ +\ B\ Problem\)测试代码
#include <iostream> using namespace std; int main() { int a, b; cin >> a >> b; cout << a + b << endl; return 0; }
-
出错测试代码
int main() { 1 + 2 return 0; }
\(Go\)配置及测试
文件名、行号/行内偏移、错误信息都可以抓取到
\(Go\)支持解释执行和构建执行,此处选择构建执行,以获取报错信息
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "file_regex": "^([^#][^#][^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "selector": "source.go", "variants": [ { "name": "Run", "shell_cmd": "go build $file && $file_path/$file_base_name" }, { "name": "RunInCmd", "shell_cmd": "go build $file && start cmd /c \"$file_path/$file_base_name & pause\"" } ] }
-
\(HelloWorld\)测试代码
package main import "fmt" func main() { fmt.Println("Hello World") }
-
\(A\ +\ B\ Problem\)测试代码
package main import "fmt" func main() { var a, b int fmt.Scanf("%d%d", &a, &b) fmt.Println(a+b) }
-
出错测试代码
package main func main() { 1 + }
\(Java\)配置及测试
文件名、行号、错误信息都可以抓取到,但由于行内偏移是通过^
指示的形式给出,因此无法抓取到
此外一个坑点是需要使用cp936
编码解决乱码问题
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "cp936", "working_dir": "$file_path", "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "selector": "source.java", "variants": [ { "name": "Run", "shell_cmd": "javac $file -encoding utf-8 && java $file_base_name" }, { "name": "RunInCmd", "shell_cmd": "javac $file -encoding utf-8 && start cmd /c \"java $file_base_name & pause\"" } ] }
-
\(HelloWorld\)测试代码
public class Java_HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } }
-
\(A\ +\ B\ Problem\)测试代码
import java.util.Scanner; public class Java_A_PLUS_B { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println(scanner.nextInt() + scanner.nextInt()); } }
-
出错测试代码
public class Java_Error { public static void main(String[] args) { 1 + 2 } }
\(JavaScript\)配置及测试
\(JavaScript\)是解释型语言,错误信息将在执行时产生,因此没有必要配置file_regex
字段
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "selector": "source.js", "variants": [ { "name": "Run", "shell_cmd": "node $file" }, { "name": "RunInCmd", "shell_cmd": "start cmd /c \"node $file & pause\"" } ] }
-
\(HelloWorld\)测试代码
console.log('Hello World')
-
\(A\ +\ B\ Problem\)测试代码
const readline = require('readline') function read() { return new Promise((resolve) => { const reader = readline.createInterface({ input: process.stdin, output: process.stdout }) reader.question('', (answer) => { reader.close() resolve(answer.trim()) }) }) } read().then((line) => console.log(line.split(' ').map(x => parseInt(x)).reduce((a, b) => a + b, 0)))
-
出错测试代码
alert(1 + 2)
\(Python\)配置及测试
\(Python\)是解释型语言,错误信息将在执行时产生,因此没有必要配置file_regex
字段
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "selector": "source.python", "variants": [ { "name": "Run", "shell_cmd": "python -u $file" }, { "name": "RunInCmd", "shell_cmd": "start cmd /c \"python -u $file & pause\"" } ] }
-
\(HelloWorld\)测试代码
print('Hello World')
-
\(A\ +\ B\ Problem\)测试代码
a, b = input().split() print(int(a) + int(b))
-
出错测试代码
print('' + 1)
\(Scala\)配置及测试
文件名、行号/行内偏移、错误类型都可以抓取到,但更详细的错误信息和其它信息并不在同一行,因此无法抓取,此时\(Sublime\ Text\)将匹配file_regex
的整行作为错误信息
\(Scala\)支持直接解释执行和构建后解释执行,此处选择构建后解释执行,以获取报错信息
此外一个坑点是需要使用-color
避免抓取到用于控制颜色的乱码
-
\(sublime-build\)配置(以\(Windows\)为例)
{ "encoding": "utf-8", "working_dir": "$file_path", "file_regex": "^.*? (..[^:]*):([0-9]+):?([0-9]+)? .*$", "selector": "source.scala", "variants": [ { "name": "Run", "shell_cmd": "scalac -explain -explain-types -color never $file && scala $file_base_name" }, { "name": "RunInCmd", "shell_cmd": "scalac -explain -explain-types -color never $file && start cmd /c \"scala $file_base_name & pause\"" } ] }
-
\(HelloWorld\)测试代码
object Scala_HelloWorld extends App { println("Hello World") }
-
\(A\ +\ B\ Problem\)测试代码
object Scala_A_PLUS_B extends App { println(scala.io.StdIn.readLine().split(" ").map(_.toInt).sum) }
-
出错测试代码
object Scala_Error extends App { 1 + solve() }
在\(Linux\)下完成配置
只需要调整shell_cmd
字段,使用相应的终端,并指定终端启动后需要自动执行的命令即可
以\(Python\)为例,在使用gnome-terminal
(为\(Gnome\)桌面系统默认)时,命令行可以是:
gnome-terminal -- bash -c \"if [ -f '${file_path}/${file_base_name}' ]; then rm '${file_path}/${file_base_name}'; fi; python3 -u '${file}'; read -p 'Process Exit, Press any key to quit...'\"
以\(Python\)为例,在使用konsole
(为\(KDE\)桌面系统默认)时,命令行可以是:
konsole -e bash -c \"if [ -f '${file_path}/${file_base_name}' ]; then rm '${file_path}/${file_base_name}'; fi; python3 -u '${file}'; read -p 'Process Exit, Press any key to quit...'\"
标签:shell,name,示例,简介,cmd,SublimeText,构建,file,测试代码 来源: https://www.cnblogs.com/Chenrt/p/16091455.html