Skip to content

Commit a79db03

Browse files
committed
enable/disable the table editor without restarting the app
1 parent 7cf9dda commit a79db03

File tree

1 file changed

+131
-117
lines changed

1 file changed

+131
-117
lines changed

browser/components/CodeEditor.js

Lines changed: 131 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export default class CodeEditor extends React.Component {
6060
this.searchState = null
6161

6262
this.formatTable = () => this.handleFormatTable()
63+
this.editorActivityHandler = () => this.handleEditorActivity()
6364
}
6465

6566
handleSearch (msg) {
@@ -100,6 +101,28 @@ export default class CodeEditor extends React.Component {
100101
this.tableEditor.formatAll(options({textWidthOptions: {}}))
101102
}
102103

104+
handleEditorActivity () {
105+
if (!this.textEditorInterface.transaction) {
106+
this.updateTableEditorState()
107+
}
108+
}
109+
110+
updateTableEditorState () {
111+
const active = this.tableEditor.cursorIsInTable(this.tableEditorOptions)
112+
if (active) {
113+
if (this.extraKeysMode !== 'editor') {
114+
this.extraKeysMode = 'editor'
115+
this.editor.setOption('extraKeys', this.editorKeyMap)
116+
}
117+
} else {
118+
if (this.extraKeysMode !== 'default') {
119+
this.extraKeysMode = 'default'
120+
this.editor.setOption('extraKeys', this.defaultKeyMap)
121+
this.tableEditor.resetSmartCursor()
122+
}
123+
}
124+
}
125+
103126
componentDidMount () {
104127
const { rulers, enableRulers } = this.props
105128
const expandSnippet = this.expandSnippet.bind(this)
@@ -120,56 +143,7 @@ export default class CodeEditor extends React.Component {
120143
)
121144
}
122145

123-
this.value = this.props.value
124-
this.editor = CodeMirror(this.refs.root, {
125-
rulers: buildCMRulers(rulers, enableRulers),
126-
value: this.props.value,
127-
lineNumbers: this.props.displayLineNumbers,
128-
lineWrapping: true,
129-
theme: this.props.theme,
130-
indentUnit: this.props.indentSize,
131-
tabSize: this.props.indentSize,
132-
indentWithTabs: this.props.indentType !== 'space',
133-
keyMap: this.props.keyMap,
134-
scrollPastEnd: this.props.scrollPastEnd,
135-
inputStyle: 'textarea',
136-
dragDrop: false,
137-
foldGutter: true,
138-
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
139-
autoCloseBrackets: {
140-
pairs: '()[]{}\'\'""$$**``',
141-
triples: '```"""\'\'\'',
142-
explode: '[]{}``$$',
143-
override: true
144-
}
145-
})
146-
147-
this.setMode(this.props.mode)
148-
149-
this.editor.on('focus', this.focusHandler)
150-
this.editor.on('blur', this.blurHandler)
151-
this.editor.on('change', this.changeHandler)
152-
this.editor.on('paste', this.pasteHandler)
153-
eventEmitter.on('top:search', this.searchHandler)
154-
155-
eventEmitter.emit('code:init')
156-
this.editor.on('scroll', this.scrollHandler)
157-
158-
const editorTheme = document.getElementById('editorTheme')
159-
editorTheme.addEventListener('load', this.loadStyleHandler)
160-
161-
CodeMirror.Vim.defineEx('quit', 'q', this.quitEditor)
162-
CodeMirror.Vim.defineEx('q!', 'q!', this.quitEditor)
163-
CodeMirror.Vim.defineEx('wq', 'wq', this.quitEditor)
164-
CodeMirror.Vim.defineEx('qw', 'qw', this.quitEditor)
165-
CodeMirror.Vim.map('ZZ', ':q', 'normal')
166-
this.setState({ isReady: true })
167-
168-
const editorIntf = new TextEditorInterface(this.editor)
169-
this.tableEditor = new TableEditor(editorIntf)
170-
eventEmitter.on('code:format-table', this.formatTable)
171-
172-
const defaultKeyMap = CodeMirror.normalizeKeyMap({
146+
this.defaultKeyMap = CodeMirror.normalizeKeyMap({
173147
Tab: function (cm) {
174148
const cursor = cm.getCursor()
175149
const line = cm.getLine(cursor.line)
@@ -222,76 +196,103 @@ export default class CodeEditor extends React.Component {
222196
}
223197
})
224198

225-
if (this.props.enableTableEditor) {
226-
const opts = options({
227-
smartCursor: true
228-
})
199+
this.value = this.props.value
200+
this.editor = CodeMirror(this.refs.root, {
201+
rulers: buildCMRulers(rulers, enableRulers),
202+
value: this.props.value,
203+
lineNumbers: this.props.displayLineNumbers,
204+
lineWrapping: true,
205+
theme: this.props.theme,
206+
indentUnit: this.props.indentSize,
207+
tabSize: this.props.indentSize,
208+
indentWithTabs: this.props.indentType !== 'space',
209+
keyMap: this.props.keyMap,
210+
scrollPastEnd: this.props.scrollPastEnd,
211+
inputStyle: 'textarea',
212+
dragDrop: false,
213+
foldGutter: true,
214+
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
215+
autoCloseBrackets: {
216+
pairs: '()[]{}\'\'""$$**``',
217+
triples: '```"""\'\'\'',
218+
explode: '[]{}``$$',
219+
override: true
220+
},
221+
extraKeys: this.defaultKeyMap
222+
})
229223

230-
const editorKeyMap = CodeMirror.normalizeKeyMap({
231-
'Tab': () => { this.tableEditor.nextCell(opts) },
232-
'Shift-Tab': () => { this.tableEditor.previousCell(opts) },
233-
'Enter': () => { this.tableEditor.nextRow(opts) },
234-
'Ctrl-Enter': () => { this.tableEditor.escape(opts) },
235-
'Cmd-Enter': () => { this.tableEditor.escape(opts) },
236-
'Shift-Ctrl-Left': () => { this.tableEditor.alignColumn(Alignment.LEFT, opts) },
237-
'Shift-Cmd-Left': () => { this.tableEditor.alignColumn(Alignment.LEFT, opts) },
238-
'Shift-Ctrl-Right': () => { this.tableEditor.alignColumn(Alignment.RIGHT, opts) },
239-
'Shift-Cmd-Right': () => { this.tableEditor.alignColumn(Alignment.RIGHT, opts) },
240-
'Shift-Ctrl-Up': () => { this.tableEditor.alignColumn(Alignment.CENTER, opts) },
241-
'Shift-Cmd-Up': () => { this.tableEditor.alignColumn(Alignment.CENTER, opts) },
242-
'Shift-Ctrl-Down': () => { this.tableEditor.alignColumn(Alignment.NONE, opts) },
243-
'Shift-Cmd-Down': () => { this.tableEditor.alignColumn(Alignment.NONE, opts) },
244-
'Ctrl-Left': () => { this.tableEditor.moveFocus(0, -1, opts) },
245-
'Cmd-Left': () => { this.tableEditor.moveFocus(0, -1, opts) },
246-
'Ctrl-Right': () => { this.tableEditor.moveFocus(0, 1, opts) },
247-
'Cmd-Right': () => { this.tableEditor.moveFocus(0, 1, opts) },
248-
'Ctrl-Up': () => { this.tableEditor.moveFocus(-1, 0, opts) },
249-
'Cmd-Up': () => { this.tableEditor.moveFocus(-1, 0, opts) },
250-
'Ctrl-Down': () => { this.tableEditor.moveFocus(1, 0, opts) },
251-
'Cmd-Down': () => { this.tableEditor.moveFocus(1, 0, opts) },
252-
'Ctrl-K Ctrl-I': () => { this.tableEditor.insertRow(opts) },
253-
'Cmd-K Cmd-I': () => { this.tableEditor.insertRow(opts) },
254-
'Ctrl-L Ctrl-I': () => { this.tableEditor.deleteRow(opts) },
255-
'Cmd-L Cmd-I': () => { this.tableEditor.deleteRow(opts) },
256-
'Ctrl-K Ctrl-J': () => { this.tableEditor.insertColumn(opts) },
257-
'Cmd-K Cmd-J': () => { this.tableEditor.insertColumn(opts) },
258-
'Ctrl-L Ctrl-J': () => { this.tableEditor.deleteColumn(opts) },
259-
'Cmd-L Cmd-J': () => { this.tableEditor.deleteColumn(opts) },
260-
'Alt-Shift-Ctrl-Left': () => { this.tableEditor.moveColumn(-1, opts) },
261-
'Alt-Shift-Cmd-Left': () => { this.tableEditor.moveColumn(-1, opts) },
262-
'Alt-Shift-Ctrl-Right': () => { this.tableEditor.moveColumn(1, opts) },
263-
'Alt-Shift-Cmd-Right': () => { this.tableEditor.moveColumn(1, opts) },
264-
'Alt-Shift-Ctrl-Up': () => { this.tableEditor.moveRow(-1, opts) },
265-
'Alt-Shift-Cmd-Up': () => { this.tableEditor.moveRow(-1, opts) },
266-
'Alt-Shift-Ctrl-Down': () => { this.tableEditor.moveRow(1, opts) },
267-
'Alt-Shift-Cmd-Down': () => { this.tableEditor.moveRow(1, opts) }
268-
})
224+
this.setMode(this.props.mode)
269225

270-
const updateActiveState = () => {
271-
const active = this.tableEditor.cursorIsInTable(opts)
272-
if (active) {
273-
this.editor.setOption('extraKeys', editorKeyMap)
274-
} else {
275-
this.editor.setOption('extraKeys', defaultKeyMap)
276-
this.tableEditor.resetSmartCursor()
277-
}
278-
}
226+
this.editor.on('focus', this.focusHandler)
227+
this.editor.on('blur', this.blurHandler)
228+
this.editor.on('change', this.changeHandler)
229+
this.editor.on('paste', this.pasteHandler)
230+
eventEmitter.on('top:search', this.searchHandler)
279231

280-
this.editor.on('cursorActivity', () => {
281-
if (!editorIntf.transaction) {
282-
updateActiveState()
283-
}
284-
})
285-
this.editor.on('changes', () => {
286-
if (!editorIntf.transaction) {
287-
updateActiveState()
288-
}
289-
})
290-
editorIntf.onDidFinishTransaction = () => {
291-
updateActiveState()
292-
}
293-
} else {
294-
this.editor.setOption('extraKeys', defaultKeyMap)
232+
eventEmitter.emit('code:init')
233+
this.editor.on('scroll', this.scrollHandler)
234+
235+
const editorTheme = document.getElementById('editorTheme')
236+
editorTheme.addEventListener('load', this.loadStyleHandler)
237+
238+
CodeMirror.Vim.defineEx('quit', 'q', this.quitEditor)
239+
CodeMirror.Vim.defineEx('q!', 'q!', this.quitEditor)
240+
CodeMirror.Vim.defineEx('wq', 'wq', this.quitEditor)
241+
CodeMirror.Vim.defineEx('qw', 'qw', this.quitEditor)
242+
CodeMirror.Vim.map('ZZ', ':q', 'normal')
243+
this.setState({ isReady: true })
244+
245+
this.textEditorInterface = new TextEditorInterface(this.editor)
246+
this.tableEditor = new TableEditor(this.textEditorInterface)
247+
eventEmitter.on('code:format-table', this.formatTable)
248+
249+
this.tableEditorOptions = options({
250+
smartCursor: true
251+
})
252+
253+
this.editorKeyMap = CodeMirror.normalizeKeyMap({
254+
'Tab': () => { this.tableEditor.nextCell(this.tableEditorOptions) },
255+
'Shift-Tab': () => { this.tableEditor.previousCell(this.tableEditorOptions) },
256+
'Enter': () => { this.tableEditor.nextRow(this.tableEditorOptions) },
257+
'Ctrl-Enter': () => { this.tableEditor.escape(this.tableEditorOptions) },
258+
'Cmd-Enter': () => { this.tableEditor.escape(this.tableEditorOptions) },
259+
'Shift-Ctrl-Left': () => { this.tableEditor.alignColumn(Alignment.LEFT, this.tableEditorOptions) },
260+
'Shift-Cmd-Left': () => { this.tableEditor.alignColumn(Alignment.LEFT, this.tableEditorOptions) },
261+
'Shift-Ctrl-Right': () => { this.tableEditor.alignColumn(Alignment.RIGHT, this.tableEditorOptions) },
262+
'Shift-Cmd-Right': () => { this.tableEditor.alignColumn(Alignment.RIGHT, this.tableEditorOptions) },
263+
'Shift-Ctrl-Up': () => { this.tableEditor.alignColumn(Alignment.CENTER, this.tableEditorOptions) },
264+
'Shift-Cmd-Up': () => { this.tableEditor.alignColumn(Alignment.CENTER, this.tableEditorOptions) },
265+
'Shift-Ctrl-Down': () => { this.tableEditor.alignColumn(Alignment.NONE, this.tableEditorOptions) },
266+
'Shift-Cmd-Down': () => { this.tableEditor.alignColumn(Alignment.NONE, this.tableEditorOptions) },
267+
'Ctrl-Left': () => { this.tableEditor.moveFocus(0, -1, this.tableEditorOptions) },
268+
'Cmd-Left': () => { this.tableEditor.moveFocus(0, -1, this.tableEditorOptions) },
269+
'Ctrl-Right': () => { this.tableEditor.moveFocus(0, 1, this.tableEditorOptions) },
270+
'Cmd-Right': () => { this.tableEditor.moveFocus(0, 1, this.tableEditorOptions) },
271+
'Ctrl-Up': () => { this.tableEditor.moveFocus(-1, 0, this.tableEditorOptions) },
272+
'Cmd-Up': () => { this.tableEditor.moveFocus(-1, 0, this.tableEditorOptions) },
273+
'Ctrl-Down': () => { this.tableEditor.moveFocus(1, 0, this.tableEditorOptions) },
274+
'Cmd-Down': () => { this.tableEditor.moveFocus(1, 0, this.tableEditorOptions) },
275+
'Ctrl-K Ctrl-I': () => { this.tableEditor.insertRow(this.tableEditorOptions) },
276+
'Cmd-K Cmd-I': () => { this.tableEditor.insertRow(this.tableEditorOptions) },
277+
'Ctrl-L Ctrl-I': () => { this.tableEditor.deleteRow(this.tableEditorOptions) },
278+
'Cmd-L Cmd-I': () => { this.tableEditor.deleteRow(this.tableEditorOptions) },
279+
'Ctrl-K Ctrl-J': () => { this.tableEditor.insertColumn(this.tableEditorOptions) },
280+
'Cmd-K Cmd-J': () => { this.tableEditor.insertColumn(this.tableEditorOptions) },
281+
'Ctrl-L Ctrl-J': () => { this.tableEditor.deleteColumn(this.tableEditorOptions) },
282+
'Cmd-L Cmd-J': () => { this.tableEditor.deleteColumn(this.tableEditorOptions) },
283+
'Alt-Shift-Ctrl-Left': () => { this.tableEditor.moveColumn(-1, this.tableEditorOptions) },
284+
'Alt-Shift-Cmd-Left': () => { this.tableEditor.moveColumn(-1, this.tableEditorOptions) },
285+
'Alt-Shift-Ctrl-Right': () => { this.tableEditor.moveColumn(1, this.tableEditorOptions) },
286+
'Alt-Shift-Cmd-Right': () => { this.tableEditor.moveColumn(1, this.tableEditorOptions) },
287+
'Alt-Shift-Ctrl-Up': () => { this.tableEditor.moveRow(-1, this.tableEditorOptions) },
288+
'Alt-Shift-Cmd-Up': () => { this.tableEditor.moveRow(-1, this.tableEditorOptions) },
289+
'Alt-Shift-Ctrl-Down': () => { this.tableEditor.moveRow(1, this.tableEditorOptions) },
290+
'Alt-Shift-Cmd-Down': () => { this.tableEditor.moveRow(1, this.tableEditorOptions) }
291+
})
292+
293+
if (this.props.enableTableEditor) {
294+
this.editor.on('cursorActivity', this.editorActivityHandler)
295+
this.editor.on('changes', this.editorActivityHandler)
295296
}
296297
}
297298

@@ -429,6 +430,19 @@ export default class CodeEditor extends React.Component {
429430
this.editor.setOption('scrollPastEnd', this.props.scrollPastEnd)
430431
}
431432

433+
if (prevProps.enableTableEditor !== this.props.enableTableEditor) {
434+
if (this.props.enableTableEditor) {
435+
this.editor.on('cursorActivity', this.editorActivityHandler)
436+
this.editor.on('changes', this.editorActivityHandler)
437+
} else {
438+
this.editor.off('cursorActivity', this.editorActivityHandler)
439+
this.editor.off('changes', this.editorActivityHandler)
440+
}
441+
442+
this.extraKeysMode = 'default'
443+
this.editor.setOption('extraKeys', this.defaultKeyMap)
444+
}
445+
432446
if (needRefresh) {
433447
this.editor.refresh()
434448
}

0 commit comments

Comments
 (0)