Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Mirror Get Current Line Number every time content changes

I am trying to use Code Mirror to create a text editor. I want to show the current line number to the user at the bottom of the display, as text editors do.

So far I have tried this:

function updateInfo(){
var lines = editor.lineCount();
document.getElementById('line-no.').innerText = lines;
editor.refresh();
}
editor.on("change", updateInfo());

The line-no. is a span where I want to display the Line Number. This works for the first Line Number but then when I go to some other line, it doesn't do anything. The console shows this error:

codemirror.js:2154 Uncaught TypeError: Cannot read property 'apply' of undefined
at codemirror.js:2154
at fireCallbacksForOps (codemirror.js:2111)
at finishOperation (codemirror.js:2125)
at endOperation (codemirror.js:3747)
at HTMLTextAreaElement.<anonymous> (codemirror.js:3884)
like image 903
Uncertainly Certain Avatar asked Mar 06 '23 01:03

Uncertainly Certain


1 Answers

Update

To follow updates in the editor, register a handler on the cursorActivity event. This event is fired when there is a change in the cursor or selection.
The handler is called with the instance of CodeMirror; on this you can call the getCursor method to be the an object that contains the current line number that the cursor is active on.
Note that the line number is zero-based, so you may or may not increment it by 1.

const STATUS_CURRENT_LINE = document.getElementById('line-no.');

const onCursorActivity = (instance) => {
  const cursor = cm.getCursor();
  STATUS_CURRENT_LINE.textContent = cursor.line + 1;
}

editor.on("cursorActivity", onCursorActivity);

Setting the current line number when there is a doc change in the editor

The error happens because the updateInfo callback is called even before you register it. So that the value registered as the callback is undefined.

editor.on('change', updateInfo()) // -> editor.on('change', undefined)

This can be resolved by registering the function.

editor.on('change', updateInfo)

However, the signature for the callback should follow what is documented.

The change callback is passed the instance of CodeMirror and a changeObject from which you can retrieve the current line.

"change" (instance: CodeMirror, changeObj: object)
Fires every time the content of the editor is changed. The changeObj is a {from, too, text, removed, origin} object containing information about the changes that occurred as the second argument. from and to are the positions (in the pre-change coordinate system) where the change started and ended (for example, it might be {ch:0, line:18} if the position is at the beginning of line #19). text is an array of strings representing the text that replaced the changed range (split by line). removed is the text that used to be between from and to, which is overwritten by this change. This event is fired before the end of an operation before the DOM updates happen.

const STATUS_CURRENT_LINE = document.getElementById('line-no.');

function updateInfo(instance, changeObj){
   STATUS_CURRENT_LINE.innerText = changeObj.to.line;
}

editor.on("change", updateInfo);
like image 55
Oluwafemi Sule Avatar answered Apr 30 '23 06:04

Oluwafemi Sule