# 調教 Sublime Text 3
#### Author: PixelCat
---
寫寫我是怎麼調教我的 Sublime Text 3 的,主要是針對競程向開發。現在 Sublime 好像出到 4 了,不過因為後來我跑去用 VS Code 了所以沒跟上,應該大同小異。另外因為我的環境已經被設定過一波了,我看到的東西可能會跟乾淨的環境不太一樣,發現的話再跟我說 QQ
這篇作業系統以 Windows 為主,Linux 大同小異,MacOS 我根本ㄊㄇ沒用過。
## 摘要(?)
首先最重要的一點,**Sublime Text 只是一款文字編輯器**,跟 dev-C++ 或 Visual Studio 是不一樣的,性質上跟 VS Code 比較接近。把他拿來當 IDE 的原因是**你可以自定義一些重複的任務讓他執行**,我們的目的就是把重複性的工作交給編譯器,專心做題。
打競程的時候,我們希望編輯器做的事情有
1. 編譯原始碼
這個部分交給 g++ 來完成,我們要做的是告訴 Sublime 如何召喚 g++ ,吃一個原始碼檔進去吐一個可執行檔出來。
2. 執行執行檔
告訴 Sublime 如何找到你的執行檔並執行。
3. 自動輸入/輸出
執行過程中,你可能會想把輸入資料放在一個檔案裡,讓輸出流到另外一個資料裡,省去手動輸入的困擾。
以上的工作,都可以用 Sublime 提供的 **Build System** 來完成。
## 前置工作
至少要學過/學會基本命令列用法,還有如何用命令列 (g++) 手動編譯檔案,能會用編譯選項當然更好。假如都不會可能也沒關係,只是出問題了很難自己解決 QQ
一定一定要做的是確認自己有沒有 g++,你可以在 Windows 命令列直接打 g++ 看看 (Jimmy 是我的 Windows 用戶名)
![](https://i.imgur.com/nXH0UGC.png)
假如跳出這種訊息代表恭喜你你已經有 g++ 了,沒有的話請去安裝 [MinGW](https://sourceforge.net/projects/mingw/)。
## Build System
本質上,Build System 就只是讓你把一坨命令列指令包裝成 Sublime 裡面的指令,讓你在編輯器裡打開 Command Palette (Ctrl+Shift+P) 就可以做事。
所以我們先不要管 Sublime,在命令列看看我們想做什麼事。
假設你的資料夾長這樣
```
code/
|- main.cpp # 你的原始碼
|- main.exe # 編譯出來的可執行檔
|- stdin.txt # 要餵到標準輸入的資料
|- stdout.txt # 放程式標準輸出的地方
|- stderr.txt # 放程式標準錯誤輸出的地方
```
你需要的指令有
1. 編譯
```bash
g++ main.cpp -o main.exe
```
這行會幫你編譯原始碼檔並吐出執行檔,假如執行檔已經存在則會覆蓋。
2. 執行
```bash
main.exe < stdin.txt > stdout.txt 2> stderr.txt
```
執行執行檔,並且 _重新導向 (Redirect)_ 你的輸入輸出和錯誤輸出。
所以任務其實是單純的,很大一部分是因為競程通常都只需要一個檔案。現在可以建立 Build System 了,在 Sublime 找到
> 選單 > Tools > Build System > New Build System...
狠狠用力戳下去。你會看到一個幾乎空白的 `.sublime-build`檔。
![](https://i.imgur.com/9DAEHp5.png)
貼上下面這一坨,存檔成 `test.sublime-build` 或其他你想要的名字,檔案路徑用預設的
`C:\Users\[UserName]\AppData\Roaming\Sublime Text 3\Packages\User`
就好。檔名之後會變成你的 Build System 的名字,之後要修改 Build System 也是改這個檔案就好。
```json=
{
"working_dir": "${file_path}",
"variants":
[
{
"name": "Compile",
"shell_cmd": "g++ main.cpp -o main.exe"
},
{
"name": "Run",
"shell_cmd": "main.exe < stdin.txt > stdout.txt 2> stderr.txt"
},
{
"name": "Both",
"shell_cmd": "g++ main.cpp -o main.exe & main.exe < stdin.txt > stdout.txt 2> stderr.txt"
}
]
}
```
![](https://i.imgur.com/8RTgki9.png)
其實他就是一個 json 檔,指定一些指令。其中
- 指定了一個選項 `working_dir`,代表執行命令列指令的時候要在哪裡執行 (也就是命令列裡指令前面那個路徑)。
- 指定了三個 `variant`,代表我們要執行的 (Sublime 裡面的) 指令有三種。
對於每個 `variant` 我們指定兩個選項:
- `name` 代表這條指令的名字。
- `shell_cmd` 代表呼叫這條指令的時候,Sublime 應該幫我們呼叫什麼命令列指令。
接下來隨便在 `main.cpp` 寫一點東西。
![](https://i.imgur.com/Tq0ngVl.png)
找到並選擇你的 Build System。
> 選單 > Tools > Build System > test
現在 Ctrl+Shift+P 叫出指令面板,輸入 `build`,應該會看到剛剛的三個指令。
![](https://i.imgur.com/ryAjBBg.png)
其中,
- `Build With: test` 什麼事都不會做
- `Build With: test - Compile` 會幫你編譯
- `Build With: test - Run` 會幫你執行並重導輸入輸出
- `Build With: test - Both` 就只是前兩個指令合起來而已
選 `Build With: test - Compile`,等個幾秒應該會看到下面出現訊息,表示編譯完成且成功。
![](https://i.imgur.com/Fm66SUO.png)
假如有編譯錯誤也會出現在這裡
![](https://i.imgur.com/1ayUkhQ.png)
接下來在 `stdin.txt` 隨便打字作為輸入,選 `Build With: test - Run`,應該可以在 `stdout.txt` 看到輸出了。以這段程式來說 `stderr.txt` 是空的,因為沒有用到 `cerr` 之類的東西。
到此為止 Build System 已經完成任務了,我們還可以做其他設定讓自己更舒服一些。
## 畫面布局
現在我們一次只能看到一個檔案,要看輸入或輸出還要動滑鼠換分頁,太累了。
依序選擇
> 選單 > View > Layout > Columns: 4
> 選單 > View > Groups > Max Columns: 2
![](https://i.imgur.com/vAgmAP6.png)
畫面被切割成四份了。接著把三個輸入輸出檔丟到右邊那三格,調整一下大小。
![](https://i.imgur.com/O5KW4qR.png)
這樣就可以一次看到所有東西了。
## 快捷鍵
現在要編譯都要召喚指令面板再打指令,不優。我們可以找到
> 選單 > Preferences > Key Bindings
跳出一個新視窗,在右邊加上
```json=
[
{
"keys": ["f9"],
"command": "build",
"args": {"variant": "Compile"}
},
{
"keys": ["f10"],
"command": "build",
"args": {"variant": "Run"}
},
{
"keys": ["f11"],
"command": "build",
"args": {"variant": "Both"}
}
]
```
這樣就可以做到跟 dev-C++ 一樣的快捷鍵了
- `f9` = 編譯
- `f10` = 執行
- `f11` = 編譯+執行
當然也可以改成自己喜歡的鍵。
到這裡就差不多大部分的任務都可以完成了。
## 我不是小孩子
開玩笑,這是 Sublime 耶,怎麼可能這麼{單純|簡陋}。
雖然這樣已經可以解決大部分問題,但是 Sublime 提供了更多更強的功能。比如說,你想用同樣的系統編譯其他檔案呢? Sublime 提供了一串內建變數,可以讓你在命令列指令裡面看到目前想編譯的檔案之類的。
![](https://i.imgur.com/aqCLsme.png)
(圖片來源: [Sublime Text Documentation](https://www.sublimetext.com/docs/build_systems.html))
除此之外,還有各種奇怪的選項可以用,甚至可以寫個 python 腳本幫你做事,需要的話左轉[官方文件](https://www.sublimetext.com/docs/build_systems.html)。
另外,編譯選項當然也是可以設定的,只要加在 Build System 的 `shell_cmd` 裡面就好。我自己的 Build System 長這樣
```json=
{
"working_dir": "${file_path}",
"variants":
[
{
"name": "Compile",
"shell_cmd": "g++ -D LOCAL -std=c++14 -O2 -Wall -Wextra -Wshadow ${file_name} -o ${file_base_name}"
},
{
"name": "Run",
"shell_cmd": "${file_base_name}.exe < out/input.txt > out/output.txt 2> out/error.txt"
},
{
"name": "Both",
"shell_cmd": "g++ -D LOCAL -std=c++14 -O2 -Wall -Wextra -Wshadow ${file_name} -o ${file_base_name} & ${file_base_name}.exe < out/input.txt > out/output.txt 2> out/error.txt"
}
]
}
```
## 廣告時間
但是後來我就捨棄 Sublime 跑去 VS Code 了,為什麼呢? 因為 VS Code 更直覺更好用,包括但不限於
- 內建的擴充插件列表,更好找到需要的插件
- `task` 系統,類似於 Sublime 的 Build System 但是更靈活
- `workspace` 機制,區分不同的工作需求
- 內嵌命令列,可以做到互動式執行 (Sublime 就我所知是不能互動式執行的)
另外,超推薦一款字型 [**`Victor Mono`**](https://rubjo.github.io/victor-mono/),用上他讓你的程式碼賞心悅目!
![](https://i.imgur.com/Xw1FHkD.png)
(圖為 VS Code 截圖)
## 後記
我最喜歡 Sublime 的地方是,他是自由的,有各種套件和各種自定義功能可以讓每個人調教出自己最舒服的環境。調教開發環境有點累也有點麻煩,但是舒服的環境可以讓寫程式變成享受,這也是我為甚麼喜歡 Sublime Text 和 VS Code。
假如抓到我亂寫,請直接來指控我 QQ