Package Exports
- @codemirror/merge
Readme
@codemirror/merge 
[ WEBSITE | ISSUES | FORUM | CHANGELOG ]
This package implements a merge interface for the CodeMirror code editor.
The project page has more information, a number of examples and the documentation.
This code is released under an MIT license.
We aim to be an inclusive, welcoming community. To make that explicit, we have a code of conduct that applies to communication around the project.
Usage
A split merge view can be created like this:
import {MergeView} from "@codemirror/merge"
import {EditorView, basicSetup} from "codemirror"
import {EditorState} from "@codemirror/state"
let doc = `one
two
three
four
five`
const view = new MergeView({
a: {
doc,
extensions: basicSetup
},
b: {
doc: doc.replace(/t/g, "T") + "\nSix",
extensions: [
basicSetup,
EditorView.editable.of(false),
EditorState.readOnly.of(true)
]
},
parent: document.body
})Or a unified view like this:
import {EditorView, basicSetup} from "codemirror"
import {unifiedMergeView} from "@codemirror/merge"
const view = new EditorView({
parent: document.body,
doc: "one\ntwo\nthree\nfour",
extensions: [
basicSetup,
unifiedMergeView({
original: "one\n...\nfour"
})
]
})API Reference
Side-by-side Merge View
-
interfaceMergeConfig Configuration options to
MergeViewthat can be provided both initially and toreconfigure.-
orientation?: "a-b" | "b-a" Controls whether editor A or editor B is shown first. Defaults to
"a-b".-
revertControls?: "a-to-b" | "b-to-a" Controls whether revert controls are shown between changed chunks.
-
renderRevertControl?: fn() → HTMLElement When given, this function is called to render the button to revert a chunk.
-
highlightChanges?: boolean By default, the merge view will mark inserted and deleted text in changed chunks. Set this to false to turn that off.
-
gutter?: boolean Controls whether a gutter marker is shown next to changed lines.
-
collapseUnchanged?: {margin?: number, minSize?: number} When given, long stretches of unchanged text are collapsed.
margingives the number of lines to leave visible after/before a change (default is 3), andminSizegives the minimum amount of collapsible lines that need to be present (defaults to 4).-
diffConfig?: DiffConfig Pass options to the diff algorithm. By default, the merge view sets
scanLimitto 500.
-
-
interfaceDirectMergeConfigextends MergeConfig Configuration options given to the
MergeViewconstructor.-
a: EditorStateConfig Configuration for the first editor (the left one in a left-to-right context).
-
b: EditorStateConfig Configuration for the second editor.
-
parent?: Element | DocumentFragment Parent element to append the view to.
-
root?: Document | ShadowRoot An optional root. Only necessary if the view is mounted in a shadow root or a document other than the global
documentobject.
-
-
classMergeView A merge view manages two editors side-by-side, highlighting the difference between them and vertically aligning unchanged lines. If you want one of the editors to be read-only, you have to configure that in its extensions.
By default, views are not scrollable. Style them (
.cm-mergeView) with a height andoverflow: autoto make them scrollable.-
new MergeView(config: DirectMergeConfig) Create a new merge view.
-
a: EditorView The first editor.
-
b: EditorView The second editor.
-
dom: HTMLElement The outer DOM element holding the view.
-
chunks: readonly Chunk[] The current set of changed chunks.
-
reconfigure(config: MergeConfig) Reconfigure an existing merge view.
-
destroy() Destroy this merge view.
-
-
uncollapseUnchanged: StateEffectType<number> A state effect that expands the section of collapsed unchanged code starting at the given position.
Unified Merge View
-
unifiedMergeView(config: Object) → Extension[] Create an extension that causes the editor to display changes between its content and the given original document. Changed chunks will be highlighted, with uneditable widgets displaying the original text displayed above the new text.
-
config -
original: Text | string The other document to compare the editor content with.
-
highlightChanges?: boolean By default, the merge view will mark inserted and deleted text in changed chunks. Set this to false to turn that off.
-
gutter?: boolean Controls whether a gutter marker is shown next to changed lines.
-
syntaxHighlightDeletions?: boolean By default, deleted chunks are highlighted using the main editor's language. Since these are just fragments, not full documents, this doesn't always work well. Set this option to false to disable syntax highlighting for deleted lines.
-
syntaxHighlightDeletionsMaxLength?: number Deleted blocks larger than this size do not get syntax-highlighted. Defaults to 3000.
-
mergeControls?: boolean Controls whether accept/reject buttons are displayed for each changed chunk. Defaults to true.
-
diffConfig?: DiffConfig Pass options to the diff algorithm. By default, the merge view sets
scanLimitto 500.-
collapseUnchanged?: {margin?: number, minSize?: number} When given, long stretches of unchanged text are collapsed.
margingives the number of lines to leave visible after/before a change (default is 3), andminSizegives the minimum amount of collapsible lines that need to be present (defaults to 4).
-
-
-
acceptChunk(view: EditorView, pos?: number) → boolean In a unified merge view, accept the chunk under the given position or the cursor. This chunk will no longer be highlighted unless it is edited again.
-
rejectChunk(view: EditorView, pos?: number) → boolean In a unified merge view, reject the chunk under the given position or the cursor. Reverts that range to the content it has in the original document.
-
getOriginalDoc(state: EditorState) → Text Get the original document from a unified merge editor's state.
-
originalDocChangeEffect(state: EditorState, changes: ChangeSet) → StateEffect<{doc: Text, changes: ChangeSet}> Create an effect that, when added to a transaction on a unified merge view, will update the original document that's being compared against.
-
updateOriginalDoc: StateEffectType<{doc: Text, changes: ChangeSet}> The state effect used to signal changes in the original doc in a unified merge view.
Chunks
-
classChunk A chunk describes a range of lines which have changed content in them. Either side (a/b) may either be empty (when its
tois equal to itsfrom), or points at a range starting at the start of the first changed line, to 1 past the end of the last changed line. Note thattopositions may point past the end of the document. UseendA/endBif you need an end position that is certain to be a valid document position.-
new Chunk(changes: readonly Change[], fromA: number, toA: number, fromB: number, toB: number, precise?: boolean = true) -
changes: readonly Change[] The individual changes inside this chunk. These are stored relative to the start of the chunk, so you have to add
chunk.fromA/fromBto get document positions.-
fromA: number The start of the chunk in document A.
-
toA: number The end of the chunk in document A. This is equal to
fromAwhen the chunk covers no lines in document A, or is one unit past the end of the last line in the chunk if it does.-
fromB: number The start of the chunk in document B.
-
toB: number The end of the chunk in document A.
-
precise: boolean This is set to false when the diff used to compute this chunk fell back to fast, imprecise diffing.
-
endA: number Returns
fromAif the chunk is empty in A, or the end of the last line in the chunk otherwise.-
endB: number Returns
fromBif the chunk is empty in B, or the end of the last line in the chunk otherwise.-
static build(a: Text, b: Text, conf?: DiffConfig) → readonly Chunk[] Build a set of changed chunks for the given documents.
-
static updateA(chunks: readonly Chunk[], a: Text, b: Text, changes: ChangeDesc, conf?: DiffConfig) → readonly Chunk[] Update a set of chunks for changes in document A.
ashould hold the updated document A.-
static updateB(chunks: readonly Chunk[], a: Text, b: Text, changes: ChangeDesc, conf?: DiffConfig) → readonly Chunk[] Update a set of chunks for changes in document B.
-
-
getChunks(state: EditorState) → {chunks: readonly Chunk[], side: "a" | "b" | null} | null Get the changed chunks for the merge view that this editor is part of, plus the side it is on if it is part of a
MergeView. Returns null if the editor doesn't have a merge extension active or the merge view hasn't finished initializing yet.-
goToNextChunk: StateCommand Move the selection to the next changed chunk.
-
goToPreviousChunk: StateCommand Move the selection to the previous changed chunk.
Diffing Utilities
-
classChange A changed range.
-
new Change(fromA: number, toA: number, fromB: number, toB: number) -
fromA: number The start of the change in document A.
-
toA: number The end of the change in document A. This is equal to
fromAin case of insertions.-
fromB: number The start of the change in document B.
-
toB: number The end of the change in document B. This is equal to
fromBfor deletions.
-
-
diff(a: string, b: string, config?: DiffConfig) → readonly Change[] Compute the difference between two strings.
-
presentableDiff(a: string, b: string, config?: DiffConfig) → readonly Change[] Compute the difference between the given strings, and clean up the resulting diff for presentation to users by dropping short unchanged ranges, and aligning changes to word boundaries when appropriate.
-
interfaceDiffConfig Options passed to diffing functions.
-
scanLimit?: number When given, this limits the depth of full (expensive) diff computations, causing them to give up and fall back to a faster but less precise approach when there is more than this many changed characters in a scanned range. This should help avoid quadratic running time on large, very different inputs.
-
timeout?: number When set, this makes the algorithm periodically check how long it has been running, and if it has taken more than the given number of milliseconds, it aborts detailed diffing in falls back to the imprecise algorithm.
-