With the new CodeMirror 6, how can we do relative line numbers that based on the current line where the cursor is?
Like this in this video (shamelessly lifted from Vim’s absolute, relative and hybrid line numbers )
https://jeffkreeftmeijer.com/vim-number/relative.mp4
With CM5, this seemed pretty straight-forward, but with CM6, I’m running into an issue where, while I can make new lines have the proper line numbers, old lines never have their line numbers update.
I made a CodeSandbox to display the issue.
morning-wildflower-g36o0 using @codemirror/commands, @codemirror/gutter, @codemirror/state, @codemirror/text, @codemirror/view
marijn
January 27, 2021, 11:04am
2
Right, formatNumber
only took a number, and the code assumed it only depended on the number, so closing over the view like that wouldn’t work. @codemirror/gutter
0.17.2 passes the editor state to formatNumber
and should handle this correctly.
Whoa. That was ridiculously quick! You’re amazing! Thank you so much!
Do you have a working example for this? @wardellbagby
Not of VIM style line numbers; I only used that as an example for my true ends: a way to more generically provide a value for the line number in the gutter that would update when the doc changed.
My usage ended up looking like this:
import { Extension } from '@codemirror/state';
import { lineNumbers } from '@codemirror/gutter';
import syllable from 'syllable';
export const syllableCounts = (): Extension =>
lineNumbers({
formatNumber: (lineNo, state) => {
if (lineNo > state.doc.lines) {
return '0';
}
return syllable(state.doc.line(lineNo).text).toString();
},
});
2 Likes
Thank you for your answer! That helped me a lot
1 Like
Did you ever come up with a working solution? Very new to Codemirror and could use some pointers
I finally figured it out! Here’s a working solution based on @wardellbagby ’s original CodeSandbox:
1 Like
I ended up publishing this as an extension on npm:
Preview Example
import { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { lineNumbersRelative } from '@uiw/codemirror-extensions-line-numbers-relative';
const state = EditorState.create({
doc: 'my source code',
extensions: [lineNumbersRelative],
});
const view = new EditorView({
parent: document.querySelector('#editor'),
state,
});
return lineNumbers({
formatNumber: (lineNo, state) => {
if (lineNo > state.doc.lines) {
return '0';
}
const cursorLine = state.doc.lineAt(state.selection.asSingle().ranges[0].to).number;
if (lineNo === cursorLine) {
return '0';
} else {
return Math.abs(cursorLine - lineNo).toString();
}
},
});