Skip to content

Instantly share code, notes, and snippets.

@andy0130tw
Last active October 10, 2025 17:57
Show Gist options
  • Save andy0130tw/62d692ab52159f533584c78429d1bc5a to your computer and use it in GitHub Desktop.
Save andy0130tw/62d692ab52159f533584c78429d1bc5a to your computer and use it in GitHub Desktop.
Sample single line setup CodeMirror; note that you need to tweak the default keymap
import { minimalSetup } from 'codemirror'
import { EditorState } from '@codemirror/state'
import { EditorView, keymap } from '@codemirror/view'
import { insertNewlineAndIndent, insertBlankLine } from '@codemirror/commands'
function removeNewlineCommands(exts) {
const newlineCommands = [insertNewlineAndIndent, insertBlankLine]
return exts.map(ext => {
if (ext?.facet == keymap) {
const newMap = ext.value.map(cmd => {
const overrides = ['run', 'shift'].filter(k => newlineCommands.includes(cmd[k]))
if (overrides.length) {
cmd = {
...cmd,
...Object.fromEntries(overrides.map(k => [k, () => true])),
}
}
return cmd
})
return keymap.of(newMap)
}
return ext
})
}
function dispatchTransactions(trs, view) {
const docChanged = trs.some(tr => tr.docChanged)
if (!docChanged) {
view.update(trs)
return
}
const lastTr = trs[trs.length - 1]
const removeNLs = []
for (let len = 0, iter = lastTr.newDoc.iterLines().next();
!iter.done;
len += iter.value.length + 1, iter.next()) {
// skip the first line
if (len == 0) continue
removeNLs.push({from: len - 1, to: len})
}
// console.log(removeNLs)
view.update(removeNLs.length ?
[...trs, lastTr.state.update({ changes: removeNLs })] :
trs)
}
new EditorView({
doc: 'this editor only allows a single line',
extensions: [
removeNewlineCommands(minimalSetup),
EditorView.lineWrapping,
EditorState.allowMultipleSelections.of(true),
],
dispatchTransactions,
parent: document.body,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment