众所周知,VSCode 是宇宙第一代码编辑器——
但是 Ren'Py 默认只支持 Atom,并没有 VSCode 支持。
但是有宇宙第一代码编辑器在这里,为什么不用呢?这篇文章就来讲一讲如何给 Ren'Py 添加 VSCode 支持。
VSCode 方面的工作
其实在 VSCode 方面倒不需要多少工作,因为已经有人把我们所需要的做成扩展了:
Ren'Py Language - Visual Studio Marketplacemarketplace.visualstudio.com在 VSCode 的拓展商店中搜索 Ren'Py Language 安装即可。
Ren'Py 方面的工作
仅有 VSCode 对 rpy 文件的语法支持还不够,我们要做到在 Ren'Py 启动器界面上直接建立与 VSCode 的关联。
这个时候就需要用到 Ren'Py 的「集成文本编辑器」功能了。
在 Ren'Py 的文档中,我们发现有这样的描述:
Ren'Py允许用户从启动器(launcher)加载一个文本编辑器编辑游戏脚本,同时也使用这个文本编辑器向用户汇报错误。
通过在.edit.py文件中创建一个Editor类,就可以定制编辑器了。这个类包含了管理文本编辑的方法。
按照文档接下来的描述,我们需要建立一个 VSCode.edit.py
文件,来指导 Ren'Py 如何启动 VSCode。
在这之前,我们需要先了解一下 VSCode 的启动参数。
在命令行中打开 VSCode 的安装文件夹(Windows 系统),输入code --help
就可以查看 VSCode 支持的启动参数:
我们主要使用的是以下几个:
- -n 和 -r,分别表示打开新窗口和重用已有的窗口。
- -g,表示跳转到文件的某一行。
此外,使用code <文件名>
的形式可以打开一个文件,如果改为文件夹名(以/
结尾) ,就可以打开一个文件夹。当然也可以同时打开多个文件或文件夹。
编写 VSCode.edit.py
要编写这个文件,我们需要了解Editor
类是如何工作的。
按照面向对象的设计模式,Editor
类是一个抽象基类。在我们编写的VSCode.edit.py
中,需要继承renpy.editor.Editor
,并重写其抽象方法。从官方文档中,我们可以看到Editor
基类有三个方法:
begin(self, new_window=False, **kwargs)
end(self, **kwargs)
open(self, filename, line=None, **kwargs)
通过对内置的Atom.edit.py
的研究,我发现还有两个必要的属性或方法:
has_project
open_project(self, directory)
Ren'Py 在启动编辑器时,采用的是「会话」机制。
这是什么意思呢?一个「会话」就是一次启动编辑器的操作,每个会话中,Ren'Py 会先调用begin
方法作为会话的开始,接着调用若干个open
或者open_project
(实际上目前的应用场景只会调用一次) ,最后调用end
作为会话结束。按照这个原理,我们可以在begin
中做一些初始化的工作,然后在open
和open_project
中生成命令行参数,最后在end
中执行启动 VSCode。
这几个方法的参数都很浅显易懂。begin
的new_window
就是指定编辑器是否要在新窗口打开;open
的filename
就是要打开的文件名 ,如果指定line
参数,就跳转到对应的行号;open_project
的directory
参数就是工程的文件目录。
此外,还有一个类变量:has_project
,设置为True
表示我们的自定义编辑器支持打开工程(文件夹)。
到这里,我们就可以写出VSCode.edit.py
的代码了:
# -*- encoding: utf-8 -*-
# Ren'py 的 VSCode 编辑器支持
import os
import subprocess
import renpy
# VSCode 的文件位置,请根据你的配置自行修改
CODE_PATH = r'C:Program FilesMicrosoft VS CodeCode.exe'
def code(argv):
subprocess.Popen([CODE_PATH] + argv)
class Editor(renpy.editor.Editor):
has_projects = True
def begin(self, new_window=False, **kwargs):
self.args = ['-n' if new_window else '-r']
def end(self, **kwargs):
self.args.reverse()
code(self.args)
def open(self, filename, line=None, **kwargs):
filename = os.path.realpath(renpy.exports.fsencode(filename))
if line: # 若指定行号,则跳转
self.args.append('%s:%d' % (filename, line))
self.args.append('-g') # 由于最后使用了 reverse 所以要放后面
# 不过好像不加 -g 也可以?
else:
self.args.append(filename) # 打开文件
self.args.append(os.path.split(filename)[0] + '/') # 打开文件所在的文件夹
def open_project(self, directory):
directory = os.path.realpath(renpy.exports.fsencode(directory))
self.args.append('%s/' % directory)
def main():
e = Editor()
e.begin()
for i in sys.argv[1:]:
e.open(i)
e.end()
if __name__ == "__main__":
main()
上述代码仅限 Windows 系统,其他操作系统需要进行修改,这里不再赘述。
其中使用了renpy.exports.fsencode
和 os.path.realpath
,保证路径的规范性。
最后,将VSCode.edit.py
保存于 Ren'Py 的 SDK 的根目录,或者任意子文件夹下。重新启动 Ren'Py,就能在「设置/文本编辑器」中找到 VSCode 项了。