最近在学习Python,自然也安装了Atom编辑器的一些Python插件。有一个插件名字叫做atom-python-run,作用很简单,就是按F5运行当前Python文件。不过这个插件有一个问题,就是只能在Windows平台上以cmd方式运行。我希望这个插件能支持Powershell方式运行,所以我就给作者提了Issue。结果发现Issue还不少。而作者正好比较忙,目前没工夫。所以我就想,为什么不自己做一个Atom插件呢?
以上就是我开发这个插件的目的了。这个插件的主要功能就是按F5启动一个终端运行Python文件,终端可以是cmd也可以是powershell。
编写插件
这个插件我就叫它run-python-simply
,听名字应该就能猜出它的作用。首先打开Atom编辑器,然后点击菜单栏Packages->Package Generator->Generate Package
,输入要创建的插件名字,然后按回车。
时间统计
在编写插件之前,我们首先分析一下插件的需求。由于atom-python-run这个插件有CodeBlocks式的程序返回值和运行时间的显示,我希望我的插件也具有这个功能。看了一下atom-python-run的源代码,作者的实现方式是写一个C++程序,用这个C++程序调用Python文件,时间统计在C++程序中。我这里就不使用C++了,既然是Python的插件,那么我这里就使用Python来统计时间。
下面的脚本很简单,要执行的文件通过命令行参数传入。程序返回的结果附带时间统计和返回值的,这个和atom-python-run插件的输出结果相同。
# Python 3 file
import subprocess
import time
import sys
script = sys.argv[1]
start = time.time()
process = subprocess.run(['python', script], stderr=subprocess.STDOUT)
exitcode = process.returncode
end = time.time()
seconds = end - start
print()
print(
f'Process return {exitcode} ({hex(exitcode)}) execution time: {seconds:.03f} s')
subprocess.call("pause", shell=True)
主要代码
插件的主要代码我使用了CoffeeScript编写。默认自动生成的代码有两个,一个视图,另一个是代码。由于我们这个插件不需要显示什么内容,所以那个View文件直接删了就行。剩下一个文件写成下面这样。
这个文件的实现参考了atom-python-run。由于我也是刚刚学习编写插件,对于插件怎么写还是不太懂,所以最简单的办法就是参考另一个插件了。当然即使是参考,过程也是很痛苦的。因为我毕竟对JavaScript和CoffeeScript不太熟悉,有些简单的地方也浪费了不少时间。而且插件的调试也不太方便,需要开两个Atom窗口,一个修改完之后,重载另一个。
写完之后再看看代码,并不怎么难。由于代码时间的统计已经做Python文件中做好了,所以在这里只需要调用那个Python,让Python调用实际的Python文件就行了。
这里用到的知识点有NodeJS的path
、child_process
模块。具体用法看NodeJS文档就好了。还有就是几个Atom接口的使用:notifications
用来创建通知,就是右上角的气泡通知;atom.config
用来获取Atom的配置项;config
节点用来添加插件的配置。具体使用到时不难,看Atom的文档就行了。
{CompositeDisposable} = require 'atom'
child_process = require 'child_process'
path = require 'path'
module.exports = RunPythonSimply =
subscriptions: null
activate: (state) ->
@subscriptions = new CompositeDisposable
@subscriptions.add atom.commands.add 'atom-workspace', 'run-python-simply:toggle': => @toggle()
deactivate: ->
@subscriptions.dispose()
serialize: ->
toggle: ->
editor = atom.workspace.getActiveTextEditor()
if editor
file = editor.buffer.file
if file
fileInfo = path.parse(file.path)
if fileInfo.ext != ".py"
atom.notifications.add("warning", "Current file is not a python source file")
else
editor.save()
@run(file.path)
else
atom.notifications.add("info", "No source file to run")
run: (file)->
command = atom.config.get('run-python-simply.command')
args = command.split(" ").concat(['python', __dirname + path.sep + 'exec.py', file])
process = child_process.spawn("start", args, {
shell: true
detached: true
})
process.unref()
config:
command:
title: "Command Prompt"
type: 'string'
default: 'cmd /c'
enum: [
{value: 'cmd /c', description: 'Command Line Prompt'}
{value: 'powershell -command', description: 'Powershell'}
]
其实Atom的插件系统比我想的要简单。一开始我觉得Atom插件要做的事情其实还挺多,还要自己管理自己的配置对话框。后来我发现根本不需要,Atom的系统比较智能。就像上面代码中的那样,只要我们在代码中声明了一个config
元素,编辑器就会自动生成对应的配置界面。比方说上面我声明了两个enum
,编辑器那么编辑器就自动生成了下拉列表。
本来在写这个插件的时候我有很多想法准备总结一下,后来写完了回头一看感觉也就这样。没什么说的了,大家都是聪明人,看看就得了。所以就这样吧。
发布插件
推送到Github
代码写完之后,就能发布了。首先需要将它推送到Github。我们在Github上创建一个仓库,然后把代码推进去就好了。如果对Git命令不熟悉的话,可以使用Git Extensions,这是Windows下最好用的图形客户端了。
发布插件
第一步是输入apm login
。这样会在浏览器中打开一个网页,在网页上登录Atom账号之后,复制网页上的Token,然后粘贴回命令行中,再按回车。这样就完成了登录工作。
登录之后,命令行切到我们插件的Git目录中,然后输入apm publish minor
,稍等片刻插件就发布成功了。这个命令可以接受minor
、major
、patch
三个参数,当我们需要更新大版本、小版本、修订版本的时候使用。
这个命令在后台其实会做很多事情,比如设置package.json
中的版本号、添加版本标签并提交到版本库中。完成之后,会显示下面这样的祝贺信息。这样,插件就发布完成了。可以看到第一次提交插件的版本号为v0.0.1
。如果我们查看一下Github仓库,也会发现多了一个名为Prepare v0.0.1
的提交。
这时候搜索一下Atom插件仓库,会发现我们的插件已经成功出现在了插件仓库中。这样这个插件就算开发完成了!插件地址是run-python-simply,源代码地址是Github。这个插件作用很简单,就是在cmd或者powershell中运行当前的Python文件,有兴趣的同学可以下载试试。