Atomでlatex用パッケージを作成する


動機

Atomでlatexを書いてるけど、多用する\itemizeとか\itemを出すのがスニペットを使っても面倒。Atomならどうにか出来るだろうしやってみるか。


目標

texファイルを編集している最中、alt-enterで改行して\itemalt-shift-enterで改行して

\begin{itemize}

\item %ここにカーソル
\end{itemize}

みたいな感じにしたい。


環境

$ sw_vers

ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G65
$ atom -v
Atom : 1.29.0
Electron: 2.0.5
Chrome : 61.0.3163.100
Node : 8.9.3


プログラムの作成

AtomのAPIや既存のパッケージを参考に作る。


init.coffee

atom.commands.add 'atom-text-editor[data-grammar~="latex"]', 'custom:newline-item', ->

editor = atom.workspace.getActiveTextEditor()
view = atom.views.getView editor
editor.transact =>
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\item ')

atom.commands.add 'atom-text-editor[data-grammar~="latex"]', 'custom:newline-itemize', ->
editor = atom.workspace.getActiveTextEditor()
cursor = editor.getLastCursor()
view = atom.views.getView editor
editor.transact =>
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\begin{itemize}')
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\item ')
pos = cursor.getBufferPosition()
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\end{itemize}')
cursor.setBufferPosition(pos)



keymap.cson

'atom-text-editor[data-grammar~="latex"]':

'alt-enter': 'custom:newline-item'
'alt-shift-enter': 'custom:newline-itemize'

demo.gif

custom:newline-itemize'\\item ''\\end{itemize}'のインデントが自動で行われるので、調べたらlanguage-latexパッケージによるものだと判明。


パッケージの作成


雛形の作成

Atom内でcmd-shift-PPackage Generator: Generate Package/Users/aaaa/github/latex-itemizer

$ tree

.
|-- keymaps # ショートカットキー
| `-- latex-itemizer.json
|-- lib # 実装
| |-- latex-itemizer-view.js
| `-- latex-itemizer.js
|-- menus # メニューバーとコンテキストメニュー
| `-- latex-itemizer.json
|-- package.json # パッケージの基本情報
|-- spec # テスト
| |-- latex-itemizer-spec.js
| `-- latex-itemizer-view-spec.js
`-- styles # スタイル
`-- latex-itemizer.less


移植

既存のパッケージを参考にして作り、今回のプログラムはこんな感じに。

$ tree

.
|-- keymaps
| `-- latex-itemizer.cson
|-- lib
| `-- latex-itemizer.coffee
`-- package.json


lib/latex-itemizer.coffee

{CompositeDisposable} = require 'atom'

module.exports =
subscriptions: null

activate: ->
@subscriptions = new CompositeDisposable
@subscriptions.add atom.commands.add 'atom-workspace', {
'latex-itemizer:newline-item' : => @newline_item()
'latex-itemizer:newline-itemize' : => @newline_itemize()
}

deactivate: ->
@subscriptions.dispose()

newline_item: ->
editor = atom.workspace.getActiveTextEditor()
view = atom.views.getView editor
editor.transact =>
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\item ')

newline_itemize: ->
editor = atom.workspace.getActiveTextEditor()
cursor = editor.getLastCursor()
view = atom.views.getView editor
editor.transact =>
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\begin{itemize}')
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\item ')
pos = cursor.getBufferPosition()
atom.commands.dispatch view, 'editor:newline'
editor.insertText('\\end{itemize}')
cursor.setBufferPosition(pos)



keymaps/latex-itemizer.cson

'atom-text-editor[data-grammar~="latex"]':

'alt-enter': 'latex-itemizer:newline-item'
'alt-shift-enter': 'latex-itemizer:newline-itemize'


package.json

{

"name": "latex-itemizer",
"main": "./lib/latex-itemizer",
"version": "0.0.0",
"description": "For latex-itemizer",
"activationCommands": {
"atom-text-editor[data-grammar~=\"latex\"]": [
"latex-itemizer:newline-item",
"latex-itemizer:newline-itemize"
]
},
"repository": "https://github.com/atom/latex-itemizer",
"license": "MIT",
"engines": {
"atom": ">=1.0.0 <2.0.0"
},
"dependencies": {
"atom-package-dependencies": "latest"
},
"package-dependencies": {
"language-latex": "1.1.1"
}
}



  • newline_itemizeを綺麗に書きたいけど、動くので…。


  • package.jsonに依存パッケージの部分"package-dependencies"を忘れずに。


テスト

ctrl-alt-cmd-LでAtomを再読み込みしてtexファイルで試すが、'alt-enter': 'latex-itemizer:newline-item'が作動しない。

キーマップがAtom本来のものと重複していることが判明。

スクリーンショット.png

Overriding core keybindings? - support - Atom Discussionを参考にkeymaps/latex-itemizer.csonを修正。


keymaps/latex-itemizer.cson

'.editor[data-grammar~="latex"]:not([mini])':

'alt-enter': 'latex-itemizer:newline-item'
'alt-shift-enter': 'latex-itemizer:newline-itemize'

これで上手くいったので終わり。

公開編へ