This repository was archived by the owner on Apr 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 299
/
Copy pathEditorManager.ts
219 lines (176 loc) · 6.54 KB
/
EditorManager.ts
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/**
* EditorManager.ts
*
* Responsible for managing state of the editor collection, and
* switching between active editors.
*
* It also provides convenience methods for hooking events
* to the active editor, and managing transitions between editors.
*/
import * as Oni from "oni-api"
import { Event, IDisposable, IEvent } from "oni-types"
import { remote } from "electron"
export class EditorManager implements Oni.EditorManager {
private _allEditors: Oni.Editor[] = []
private _activeEditor: Oni.Editor = null
private _anyEditorProxy: AnyEditorProxy = new AnyEditorProxy()
private _onActiveEditorChanged: Event<Oni.Editor> = new Event<Oni.Editor>(
"EditorManager::onActiveEditorChanged",
)
private _closeWhenNoEditors: boolean = true
public get allEditors(): Oni.Editor[] {
return this._allEditors
}
/**
* API Methods
*/
public get anyEditor(): Oni.Editor {
return this._anyEditorProxy
}
public get activeEditor(): Oni.Editor {
return this._activeEditor
}
public get onActiveEditorChanged(): IEvent<Oni.Editor> {
return this._onActiveEditorChanged
}
public openFile(
filePath: string,
openOptions: Oni.FileOpenOptions = Oni.DefaultFileOpenOptions,
): Promise<Oni.Buffer> {
return this._activeEditor.openFile(filePath, openOptions)
}
public setCloseWhenNoEditors(closeWhenNoEditors: boolean) {
this._closeWhenNoEditors = closeWhenNoEditors
}
public registerEditor(editor: Oni.Editor) {
if (this._allEditors.indexOf(editor) === -1) {
this._allEditors.push(editor)
}
}
public unregisterEditor(editor: Oni.Editor): void {
this._allEditors = this._allEditors.filter(ed => ed !== editor)
if (this._activeEditor === editor) {
this.setActiveEditor(null)
}
if (this._allEditors.length === 0 && this._closeWhenNoEditors) {
// Quit?
remote.getCurrentWindow().close()
}
}
/**
* Internal Methods
*/
public setActiveEditor(editor: Oni.Editor) {
this._activeEditor = editor
const oldEditor = this._anyEditorProxy.getUnderlyingEditor()
if (editor !== oldEditor) {
this._onActiveEditorChanged.dispatch(editor)
this._anyEditorProxy.setActiveEditor(editor)
}
}
}
/**
* AllEditors is a proxy for the Neovim interface,
* exposing methods of 'all' editors, as an aggregate.
*
* This enables consumers to use `Oni.editor.allEditors.onModeChanged((newMode) => { ... }),
* for convenience, as it handles manages tracking subscriptions as the active editor changes.
*/
class AnyEditorProxy implements Oni.Editor {
private _activeEditor: Oni.Editor
private _subscriptions: IDisposable[] = []
private _onModeChanged = new Event<Oni.Vim.Mode>("EditorManager::onModeChanged")
private _onBufferEnter = new Event<Oni.EditorBufferEventArgs>("EditorManager::onBufferEnter")
private _onBufferLeave = new Event<Oni.EditorBufferEventArgs>("EditorManager::onBufferLeave")
private _onBufferChanged = new Event<Oni.EditorBufferChangedEventArgs>(
"EditorManager::onBufferChanged",
)
private _onBufferSaved = new Event<Oni.EditorBufferEventArgs>("EditorManager::onBufferSaved")
private _onBufferScrolled = new Event<Oni.EditorBufferScrolledEventArgs>(
"EditorManager::onBufferScrolled",
)
private _onCursorMoved = new Event<Oni.Cursor>("EditorManager::onCursorMoved")
/**
* API Methods
*/
public get mode(): string {
if (!this._activeEditor) {
return null
}
return this._activeEditor.mode
}
public get activeBuffer(): Oni.Buffer {
// TODO: Replace with null-object pattern
if (!this._activeEditor) {
return null
}
return this._activeEditor.activeBuffer
}
public get neovim(): Oni.NeovimEditorCapability {
if (!this._activeEditor) {
return null
}
return this._activeEditor.neovim
}
public get onModeChanged(): IEvent<Oni.Vim.Mode> {
return this._onModeChanged
}
public get onBufferChanged(): IEvent<Oni.EditorBufferChangedEventArgs> {
return this._onBufferChanged
}
public get onBufferEnter(): IEvent<Oni.EditorBufferEventArgs> {
return this._onBufferEnter
}
public get onBufferLeave(): IEvent<Oni.EditorBufferEventArgs> {
return this._onBufferLeave
}
public get onBufferSaved(): IEvent<Oni.EditorBufferEventArgs> {
return this._onBufferSaved
}
public get onBufferScrolled(): IEvent<Oni.EditorBufferScrolledEventArgs> {
return this._onBufferScrolled
}
public get onCursorMoved(): IEvent<Oni.Cursor> {
return this._onCursorMoved
}
public dispose(): void {
// tslint:disable-line
}
public async blockInput(
inputFunction: (input: Oni.InputCallbackFunction) => Promise<void>,
): Promise<void> {
return this._activeEditor.blockInput(inputFunction)
}
public async openFile(filePath: string, openOptions: Oni.FileOpenOptions): Promise<Oni.Buffer> {
return this._activeEditor.openFile(filePath, openOptions)
}
public getBuffers(): Array<Oni.Buffer | Oni.InactiveBuffer> {
return this._activeEditor.getBuffers()
}
public setTextOptions(options: Oni.EditorTextOptions): Promise<void> {
return this._activeEditor.setTextOptions(options)
}
/**
* Internal methods
*/
public setActiveEditor(newEditor: Oni.Editor) {
this._activeEditor = newEditor
this._subscriptions.forEach(d => d.dispose())
if (!newEditor) {
return
}
this._subscriptions = [
newEditor.onModeChanged.subscribe(val => this._onModeChanged.dispatch(val)),
newEditor.onBufferEnter.subscribe(val => this._onBufferEnter.dispatch(val)),
newEditor.onBufferLeave.subscribe(val => this._onBufferLeave.dispatch(val)),
newEditor.onBufferChanged.subscribe(val => this._onBufferChanged.dispatch(val)),
newEditor.onBufferSaved.subscribe(val => this._onBufferSaved.dispatch(val)),
newEditor.onBufferScrolled.subscribe(val => this._onBufferScrolled.dispatch(val)),
newEditor.onCursorMoved.subscribe(val => this._onCursorMoved.dispatch(val)),
]
}
public getUnderlyingEditor(): Oni.Editor {
return this._activeEditor
}
}
export const editorManager: EditorManager = new EditorManager()