SublimeREPL: 定制与改造
Sublime
是一款提供了可自定义的强大编辑器。我们可以根据个人的使用习惯,通过修改相应的参数配置,就可以搭建一个得心应手的编程环境。
对于现代(c以后)的解释型编程语言,基本上都是支持 REPL
的,即 read-evalue-print-loop
^[wiki:read-evalue-print-loop,这些语言包括:APL、BASIC、Clojure、F#、Haskell、J、Julia、Perl、PHP、Prolog、Python、R、Ruby、Scala、Smalltalk、Standard ML、Swift、Tcl、Javascript、Java这样的编程语言所拥有的类似的编程环境。],简单来说,就是可以在源文件与解释器之间进行实时的交互。这一点尤其是对于数据分析工作意义重大。一般而言,我们使用 R
或则 python
対数据进行探索性分析时,往往需要在程序与结果之间进行多次的交互分析,通过程序来查看结果,同时又通过结果来修改程序。很难想象如果没有 REPL
的支持,仅凭借编译语言,每次修改程序后都需要重新编译、执行,工作量是多么的巨大。
而做为一款现代的、优秀的编辑器,Sublime Text
当然夜提供了支持 REPL
的功能了。通过安装相关的插件,并设置一定的参数,我们便可以把 sublime
改造成为一个称心如意的数据分析套件了。
安装插件
可以通过调用 shift+ctrl+p
来安装需要的插件:
SublimeREPl
:支持REPL
交互SendCode
:发送代码到SublimeREPL
安装完成后,我们可以在 sublime
的菜单中,打开 Preferences -> Browse Packages
查看已安装的插件,这也是后面改造插件的配置文件所在。
改造
下面,我们一步步地完成対 SublimeREPL
进行改造。
执行终端显示代码
可以在执行的终端显示已发送的代码。打开 Preference -> Package Setting
,然后找到 SublimeREPL
,打开 Settigns-User
:
|
|
这样,我们便可以在终端看到已经执行了哪些代码。
修改快捷键
可以配置快捷键,用于打开特定的编程环境,如 R
、python
。同时,我们还可以通过 ssh
直接连接到远程服务器,实现在本地编辑器修改源文件、在远程服务器执行代码。
打开 Preference -> Key Bindings
R 编程
-
local machine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
// 使用 F5 打开 本地R { "keys": ["f5"], "caption": "SublimeREPL: R", "command":"repl_open","args": { "type": "subprocess", "external_id": "r", "additional_scopes": ["tex.latex.knitr"], "encoding": { "windows": "$win_cmd_encoding", "linux": "utf8", "osx": "utf8" }, "soft_quit": "\nquit(save=\"no\")\n", "cmd": { "linux": ["R", "--interactive", "--no-readline"], "osx": ["R", "--interactive", "--no-readline"], "windows": ["Rterm.exe", "--ess", "--encoding=$win_cmd_encoding"] }, "cwd": "$file_path", "extend_env": {"osx": {"PATH": "{PATH}:/usr/local/bin"}, "linux": {"PATH": "{PATH}:/usr/local/bin"}, "windows": {}}, "cmd_postfix": "\n", "suppress_echo": {"osx": true, "linux": true, "windows": false}, "syntax": "Packages/R/R Console.tmLanguage" } },
-
remote server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// 使用 F6 打开 远程R { "keys": ["f6"], "caption": "SublimeREPL: Rssh135", "command":"repl_open","args": { "type": "subprocess", "external_id": "r", "additional_scopes": ["tex.latex.knitr"], "encoding": { "windows": "$win_cmd_encoding", "linux": "utf8", "osx": "utf8" }, "soft_quit": "\nquit(save=\"no\")\n", "cmd": { "linux": ["ssh","fl@192.168.1.135","-p22","R","--interactive", "--no-readline"], "osx": ["ssh","fl@gczhang.imwork.net", "-p58873","R","--interactive", "--no-readline"] }, "cwd": "$file_path", "extend_env": {"osx": {"PATH": "{PATH}:/usr/local/bin"}, "linux": {"PATH": "{PATH}:/usr/local/bin"}, "windows": {}}, "cmd_postfix": "\n", "suppress_echo": {"osx": true, "linux": true, "windows": false}, "syntax": "Packages/R/R Console.tmLanguage" } },
python 编程
-
python2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 使用 F2 打开 本地python2 { "keys": ["f2"], "caption": "SublimeREPL: Python2", "command":"repl_open","args": { "type": "subprocess", "encoding": "utf8", //"cmd": ["python", "-i", "-u"], "cmd": ["/home/william/anaconda2/bin/python", "-i", "-u"], "cwd": "$file_path", "syntax": "Packages/Python/Python.tmLanguage", "external_id": "python", "extend_env": {"PYTHONIOENCODING": "utf-8"} } },
-
python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 使用 F3 打开 本地python3 { "keys": ["f3"], "caption": "SublimeREPL: Python3", "command":"repl_open","args": { "type": "subprocess", "encoding": "utf8", //"cmd": ["python", "-i", "-u"], "cmd": ["/home/william/anaconda3/bin/python", "-i", "-u"], "cwd": "$file_path", "syntax": "Packages/Python/Python.tmLanguage", "external_id": "python", "extend_env": {"PYTHONIOENCODING": "utf-8"} } },
-
远程
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// 使用 F4 打开 远程python2 { "keys": ["f4"], "caption": "SublimeREPL: PySSH166", "command":"repl_open","args": { "type": "subprocess", "encoding": "utf8", "cmd": {"linux": ["ssh","fl@192.168.1.166","-p22","python2", "-i", "-u"]}, "cwd": "$file_path", "syntax": "Packages/Python/Python.tmLanguage", "suppress_echo": false, "external_id": "python", "extend_env": {"PYTHONIOENCODING": "utf-8"}, "cmd_postfix": "\n", "suppress_echo": {"osx": true, "linux": true, "windows": false} } },
repl-restart
对于一个完整的分析项目,我们有时候想重启终端,以便查看修改后的程序是否依然能完整的运行。这个可以通过调用 shift-ctrl-p
来实现
当然,这个略显笨拙,尤其是对于一个需要多次重启的过程,十分的耗费时间与精力。做为一个「懒惰」的程序员,当然需要一键搞定全过程了。
-
我们可以找到
~/.config/sublime-text-3/Packages/SublimeREPL
,查看repl:restart
是由Context.sublime-menu
控制1 2 3 4 5 6 7 8
vim ~/.config/sublime-text-3/Packages/SublimeREPL/Context.sublime-menu [ {"caption": "-"}, {"command": "repl_kill", "caption": "Kill"}, {"command": "repl_restart", "caption": "Restart"}, {"command": "subprocess_repl_send_signal", "caption": "Send other SIGNAL"} ]
-
既然这样,我们就可以设置一个快捷键来映射这个命令
1 2 3 4 5
// 使用 F12 实现 repl:restart 功能 { "keys": ["f12"], "caption": "SublimeREPL: Restart", "command": "repl_restart", "caption": "Restart" },
-
同时,我们还观察到每次重启终端后,都会有窗口询问是否确定需要关闭。这个其实也是冗余的操作,同样可以去掉。找到
~/.config/sublime-text-3/Packages/SublimeREPL/sublimerepl.py
,这是控制整个插件的核心功能模块。找到1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def restart(self, view, edit): repl_restart_args = view.settings().get("repl_restart_args") if not repl_restart_args: sublime.message_dialog("No restart parameters found") return False ## --------------------------------------------------------------------- rv = self.repl_view(view) if rv: if rv.repl and rv.repl.is_alive() and not sublime.ok_cancel_dialog("Still running. Really restart?"): return False rv.on_close() # yes on_close, delete rv from ## --------------------------------------------------------------------- view.insert(edit, view.size(), RESTART_MSG) repl_restart_args["view_id"] = view.id() self.open(view.window(), **repl_restart_args) return True
可以看到,其实询问的窗口是一个
rv = self.repl_view(view)
的对象。我们直接把这个注释掉,以后每次重启终端就不会再有提示了。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def restart(self, view, edit): repl_restart_args = view.settings().get("repl_restart_args") if not repl_restart_args: sublime.message_dialog("No restart parameters found") return False ## --------------------------------------------------------------------- # rv = self.repl_view(view) # if rv: # if rv.repl and rv.repl.is_alive() and not sublime.ok_cancel_dialog("Still running. Really restart?"): # return False # rv.on_close() # yes on_close, delete rv from ## --------------------------------------------------------------------- view.insert(edit, view.size(), RESTART_MSG) repl_restart_args["view_id"] = view.id() self.open(view.window(), **repl_restart_args) return True
再次运行
F12
,确实是没有提示了,直接重启终端。