做一个统计单词数目的Atom插件
2017-04-16 01:34
141 查看
本文是Atom 教程 制作单词计数插件的简化介绍,所有代码都来自这篇文章。如果希望参考详细的文档,请直接查看原文。这篇文章用一个简单的小例子,为我们讲解了如何编写一个Atom编辑器插件。
该例子使用的是CoffeeScript,所以为了更好地实现这个例子,我们需要打开Atom编辑器的官方插件
这里先说明一下,由于Atom官方的统计单词数插件已经发布到了Atom插件插件库中,所以如果我们创建的插件也叫
具体生成了图上所示的文件。
![](http://upload-images.jianshu.io/upload_images/832668-ea3782ca3ba1f6d0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可用的函数如下:
以上几个方法都是可选的。
这个插件使用了CoffeeScript语法,如果你对CoffeeScript不熟悉的话,可以看看我的这篇文章《CoffeeScript 简介》。当然,JavaScript也得非常熟悉,因为这里用的就是JavaScript操作DOM树的方式。
首先,
值得注意的是最后两个方法。
这个类就讲解完毕了,是不是很简单?
首先,照例将代码直接替换。文件的前两句引用了两个模块,第一个就是刚才我们编写的
和前面的
这里用到了一些Atom的API,不过这里不做介绍,因为这篇文章主要是介绍插件的执行流程。如果需要查阅文档的话,直接看Atom API reference documentation,其中定义了大量接口用于操作编辑器。Atom的强大可定制功能就来源于此。
剩下几个方法就很简单了:
如果代码全部编写正确,然后按下默认快捷键
![](http://upload-images.jianshu.io/upload_images/832668-0567f68ad8dd9d9c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在开发过程中,可能需要多次调试插件。修改插件代码并保存之后,并不能马上生效,我们需要按快捷键
另外按
Atom 启动
Atom 开始加载插件
Atom 读取插件的
Atom 加载你的插件的键位、菜单、样式和主模块
Atom 加载插件完成
在某个时候,用户触发了插件的
Atom 执行主模块的
Atom 执行插件的
在某个时候,用户再次出发了
Atom 执行了
最后,Atom关闭,同时会触发你的插件定义的序列化操作。
要运行测试,点击菜单项
![](http://upload-images.jianshu.io/upload_images/832668-23fe52e15ddf0ab4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
到此为止,整个插件就介绍完了。这篇文章说了这么长时间,其实核心代码就一行而已。看到这里,你应该对Atom插件的编写和执行,有了一个基本概念了。那么这篇文章的目的就达到了。
该例子使用的是CoffeeScript,所以为了更好地实现这个例子,我们需要打开Atom编辑器的官方插件
package-generator,并设置默认语言为CoffeeScript。
新建插件
点击菜单栏Package->Package Generator-> Generate Atom Package,然后输入插件位置。这样就生成了一个空的插件。这个插件会自动添加到Atom的插件目录下,所以重启Atom之后,就会出现这个新安装的插件。以后如果向删除该插件,直接删除创建的文件夹即可,插件目录下的链接也会自动删除。
这里先说明一下,由于Atom官方的统计单词数插件已经发布到了Atom插件插件库中,所以如果我们创建的插件也叫
word-count的话,有可能产生混淆。所以教程建议我们将自己的插件名字改为
Your-Name-Word-Count,前面改成你自己的名字。例如我这里的就简单粗暴的叫
fuck-word-count。如果你想直接复制粘贴我的代码运行插件的话,你的插件名字也得叫
fuck-word-count才行。由于自动生成的代码多处引用了插件名字作为变量名,所以在修改代码的时候需要注意。
插件结构
插件的目录结构如下。如果编写过npm模块的话,会发现这个目录结构和npm模块的类似,只不过多了一些插件相关的东西。my-package/ ├─ grammars/ ├─ keymaps/ ├─ lib/ ├─ menus/ ├─ spec/ ├─ snippets/ ├─ styles/ ├─ index.coffee └─ package.json
具体生成了图上所示的文件。
![](http://upload-images.jianshu.io/upload_images/832668-ea3782ca3ba1f6d0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
package.json
package.json是Atom插件的描述文件,基本上和npm的描述文件类似,只不过多了几个Atom插件的特定属性。一个典型的
package.json文件类似下面这样。这些属性我就不介绍了,基本上都是见文知意。
{ "name": "wordcount", "main": "./lib/wordcount", "version": "0.0.0", "description": "A short description of your package", "activationCommands": { "atom-workspace": "wordcount:toggle" }, "repository": "https://github.com/atom/your-name-word-count", "license": "MIT", "engines": { "atom": ">=1.0.0 <2.0.0" }, "dependencies": { } }
源代码
package.json文件中的
main属性所指的文件就是我们的源代码。默认情况下它指向
lib/wordcount.coffee。打开该文件会发现类似下面的东西。在这里我们需要声明一个顶层模块,在顶层模块中需要包含一些函数,在插件的生命周期内执行相应的动作。
WordCountView = require './word-count-view' {CompositeDisposable} = require 'atom' module.exports = WordCount = wordCountView: null modalPanel: null subscriptions: null activate: (state) -> @wordCountView = new WordCountView(state.wordCountViewState) @modalPanel = atom.workspace.addModalPanel(item: @wordCountView.getElement(), visible: false) # Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable @subscriptions = new CompositeDisposable # Register command that toggles this view @subscriptions.add atom.commands.add 'atom-workspace', 'word-count:toggle': => @toggle() deactivate: -> @modalPanel.destroy() @subscriptions.dispose() @wordCountView.destroy() serialize: -> wordCountViewState: @wordCountView.serialize() toggle: -> console.log 'WordCount was toggled!' if @modalPanel.isVisible() @modalPanel.hide() else @modalPanel.show()
可用的函数如下:
activate(state),在插件激活的时候触发,这时候工作区已经准备就绪了。常用于执行初始化,例如绑定事件等等。
initialize(state),在Atom 1.14之后引入,这个函数触发的更早,如果你想执行更多初始化控制,可以使用该方法。
serialize(),在窗口关闭的时候,如果你的插件需要保存某些状态信息,可以使用该函数。当窗口再次打开的时候,状态信息会传递给
activate(state)。
deactivate(),该方法在窗口关闭的时候执行,在这里需要解绑事件绑定、清理插件需要的资源。
以上几个方法都是可选的。
其他文件
styles文件夹下存放着插件使用的样式表,这些文件用于设定插件的样式、编辑器的外观等等。
keymaps目录包括一个
cson文件,用于设定插件的快捷键。
menus目录包括一个
cson文件,用于设置插件的菜单项。默认的文件如下,其中
context-menu设置上下文菜单,也就是右键打开的菜单;
menu设置菜单项中打开的菜单。
# See https://atom.io/docs/latest/hacking-atom-package-word-count#menus for more details 'context-menu': 'atom-text-editor': [ { 'label': 'Toggle word-count' 'command': 'word-count:toggle' } ] 'menu': [ { 'label': 'Packages' 'submenu': [ 'label': 'word-count' 'submenu': [ { 'label': 'Toggle' 'command': 'word-count:toggle' } ] ] } ]
核心代码
下面我们来编码实现统计单词数的功能。视图文件
首先打开lib/XXX.view.coffee文件,这个文件是视图模板,我们的插件的外观需要在这里设置。将代码修改为如下所示。如果你的插件名和这里的不一样需要仔细修改对应的变量名,否则插件跑不起来,最好使用大小写敏感批量替换的方式修改代码。
module.exports = class FuckWordCountView constructor: (serializedState) -> # Create root element @element = document.createElement('div') @element.classList.add('fuck-word-count') # Create message element message = document.createElement('div') message.textContent = "The Your Name Word Count package is Alive! It's ALIVE!" message.classList.add('message') @element.appendChild(message) # Returns an object that can be retrieved when package is activated serialize: -> # Tear down any state and detach destroy: -> @element.remove() getElement: -> @element setCount: (count) -> displayText = "There are #{count} words." @element.children[0].textContent = displayText
这个插件使用了CoffeeScript语法,如果你对CoffeeScript不熟悉的话,可以看看我的这篇文章《CoffeeScript 简介》。当然,JavaScript也得非常熟悉,因为这里用的就是JavaScript操作DOM树的方式。
首先,
module.exports =指定要向外暴露的接口,这里暴露了
FuckWordCountView这个类,以后可以在其他代码中调用。然后看看这个类的构造器,用操作DOM树的方式,创建了几个HTML元素,用于显示初始化信息。由于统计单词数不需要记录状态变量,所以
serialize方法啥也不干。类似地,
destroy方法简单的销毁在构造器中创建的元素。
值得注意的是最后两个方法。
getElement方法会在其他地方调用,就是简单的返回显示元素。
setCount方法用于显示单词数,在接受单词数之后,会将单词数添加到显示元素中。
这个类就讲解完毕了,是不是很简单?
主要代码
然后来看看主要代码文件,就是package.json中
main属性指定的这个文件。它就是我们插件的核心文件,作用很简单——统计单词数。在这个文件中,我们会看到Atom插件的编写方式。
首先,照例将代码直接替换。文件的前两句引用了两个模块,第一个就是刚才我们编写的
WordCountView类。第二个是Atom编辑器的官方接口,我们引用了其中的
CompositeDisposable组件,它主要用于事件订阅,在关闭插件的时候统一取消事件订阅。
和前面的
WordCountView类一样,
WordCount类需要对外暴露。一开始定义了三个实例变量,并将它们置空。在激活插件的时候,会调用
activate: (state)方法,在这里会执行一些初始化操作:创建
WordCountView;创建
modalPanel用于显示View;创建
CompositeDisposable并向其添加事件订阅。
这里用到了一些Atom的API,不过这里不做介绍,因为这篇文章主要是介绍插件的执行流程。如果需要查阅文档的话,直接看Atom API reference documentation,其中定义了大量接口用于操作编辑器。Atom的强大可定制功能就来源于此。
FuckWordCountView = require './fuck-word-count-view' {CompositeDisposable} = require 'atom' module.exports = FuckWordCount = fuckWordCountView: null modalPanel: null subscriptions: null activate: (state) -> @fuckWordCountView = new FuckWordCountView(state.fuckWordCountViewState) @modalPanel = atom.workspace.addModalPanel(item: @fuckWordCountView.getElement(), visible: false) # Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable @subscriptions = new CompositeDisposable # Register command that toggles this view @subscriptions.add atom.commands.add 'atom-workspace', 'fuck-word-count:toggle': => @toggle() deactivate: -> @modalPanel.destroy() @subscriptions.dispose() @wordcountView.destroy() serialize: -> fuckWordCountViewState: @fuckWordCountView.serialize() toggle: -> console.log 'FuckWordCount was toggled!' if @modalPanel.isVisible() @modalPanel.hide() else editor = atom.workspace.getActiveTextEditor() words = editor.getText().split(/\s+/).length @fuckWordCountView.setCount(words) @modalPanel.show()
剩下几个方法就很简单了:
deactivate方法销毁所创建的资源;
serialize方法在关闭窗口的时候保存序列化数据,不过这个插件用不着所以实际上啥也没干;
toggle方法算是最重要的了,它执行了我们这个插件的核心功能统计单词数。不过这个方法其实也很简单,如果提示是可见的,就把它隐藏;如果提示不可见,就统计单词数,整个统计过程其实就是一句话:
editor.getText().split(/\s+/).length,正则表达式分词,然后获取长度。然后把单词数传递给View,让View来显示。
如果代码全部编写正确,然后按下默认快捷键
Ctrl+Alt+O,或者点击菜单项中的
Toggle word-count,就会显示插件定义的界面,再次点击菜单该界面会消失。
![](http://upload-images.jianshu.io/upload_images/832668-0567f68ad8dd9d9c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在开发过程中,可能需要多次调试插件。修改插件代码并保存之后,并不能马上生效,我们需要按快捷键
Ctrl+Shift+F5,或者按
Ctrl+Shift+P呼出调试版并输入
Window Reload重新加载窗口,插件才能生效。一种常见做法是打开两个Atom窗口,一个用于编写代码,另一个随时重载并测试插件。
另外按
Ctrl+Shift+I可以打开开发人员工具,基本上和Chrome的完全一样,从这个调试工具可以看到,Atom编辑器整个其实就是一个浏览器,拥有自己的DOM树,所有界面都是HTML。
工作流
介绍完了插件的代码,我们再来看看Atom编辑器的基本执行顺序。如果你在package.json中指定了
activationCommands,那么这个执行顺序会略微不同。
Atom 启动
Atom 开始加载插件
Atom 读取插件的
package.json
Atom 加载你的插件的键位、菜单、样式和主模块
Atom 加载插件完成
在某个时候,用户触发了插件的
your-name-word-count:toggle命令
Atom 执行主模块的
activate方法, 设置隐藏的用户界面
Atom 执行插件的
your-name-word-count:toggle方法 ,显示隐藏的界面
在某个时候,用户再次出发了
your-name-word-count:toggle命令
Atom 执行了
toggle命令并隐藏插件界面,这个过程可以来回进行多次
最后,Atom关闭,同时会触发你的插件定义的序列化操作。
测试
最后再来说说Atom的测试。测试代码全都放在spec文件夹下,我们可以看到默认生成了两个测试文件。由于我们修改了默认文件,所以测试应该是通不过的。
要运行测试,点击菜单项
View->Developer->Run Package Specs,这样就会打开一个窗口并运行测试。底层的测试框架是 Jasmine v1.3,想编写测试的话,需要先看看它的文档。
![](http://upload-images.jianshu.io/upload_images/832668-23fe52e15ddf0ab4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
到此为止,整个插件就介绍完了。这篇文章说了这么长时间,其实核心代码就一行而已。看到这里,你应该对Atom插件的编写和执行,有了一个基本概念了。那么这篇文章的目的就达到了。
相关文章推荐
- 练习2-3:编一个程序用来打开文件并统计文件中以空格隔开的单词数目
- 实现一个字符串中单词个数的统计,并按照单词字典序输出单词以及单词的出现个数。使用strsep
- 给定一个英文原文,统计文件里面一共有多少个不同的英文单词
- 第 0004 题:任一个英文的纯文本文件,统计其中的单词出现的个数。
- 一没考虑单词重复,二没考虑先输入空格,三没考虑后面连续输空格,方法见空格将空格前面的当成一个字符串,字符串比较是否相同,再统计
- 每天一个python小程序 004:任一个英文的纯文本文件,统计其中的单词出现的个数
- Java 统计一个字符串中每个单词,或者字母出现的次数
- 意外收获-ruby编写的一个简单统计单词出现次数的程序
- 【字符串操作】01.统计一个字符串中单词的个数
- 统计一个文档中出现频率最多的10个单词(英文文档)
- Atom通过插件打造一个Hexo编辑器
- MYSQL里面统计一个表的列数(即字段数目)怎么查
- 编写一个程序,统计给定文件中包含的每个单词出现的频率,并按单词表的顺序显示统计结果
- 统计字符串中的单词数目
- 0004题--任一个英文的纯文本文件,统计其中的单词出现的个数.
- 单词数目统计
- 做一个运行Python文件的Atom插件
- Python统计一个英文文档中各单词出现的行数
- 针对一个文件 统计其中的单词和字符数 找出文件中出现次数最多的单词数 将文件中出现的单词按频率进行排序并输出
- 统计单词数目及单词首字母大写