Detect blank lines with simple mode

Hello.
I’m trying to create a mode for my little markup language (simple mode). In my language, a comment starts with a # and ends when a line break is encountered. This is my actual code :

CodeMirror.defineSimpleMode('tale', {
start: [
	{
		sol: true,
		regex: /#\s?/,
		token: 'tale-cmt',
		next: 'comment'
	}
],
comment: [
	{
		// detect blank line here ?
		next: 'start'
	},
	{
		regex: /.+/,
		token: 'tale-cmt',
		next: 'comment'
	},
	
]
})

I hope it’s possible with the simple mode.

Unfortunately, no, that’s not something the simple-mode system supports. Shouldn’t be too hard to write your mode as a regular mode, though.

Thank you. I can do what I want with the regular mode, but it remains a problem (a little hard to explain especially that I speak bad English):

A comment in my language looks like this:

# this is a comment
on multiple lines if I want

If I put my cursor at the end of the comment and press Enter, the previous line loses its style and the news I enter does not have it.

However, if I edit text above the comment, the comment finds its style on all these lines.

Where should I look to solve this?

Regular modes have a blankLine method called every time an empty line is passed over.

This is my code :

...
startState: function() {
    return {isComment: false}
},
blankLine: function(state) {
    console.log('blank line')
    state.isComment = false
},
token: function(stream, state) {
    if (stream.sol()) {
        const cmt = stream.match(/#(\s(.+))?$/, false)
        if (cmt) {
            stream.next()
            stream.next()
            state.isComment = true
            return 'ml-type'
        }
    }
    if (state.isComment) {
        stream.skipToEnd()
        return 'ml-comment'
    }
}
...

When I look in the console, the message “blank line” appears 14 times when I refresh the page, while there are exactly 13 empty lines in my code. If I type text at the top of my code, the message appears 13 times. And if I type code at the bottom, the message appears 0 times. This may have a relationship?

That code doesn’t consume any token when there’s no comment, so it’d lead to a bunch of ‘mode failed to advance stream’ errors when you use it. If I fix that (always calling skipToEnd after the first if), it seems to work.

Sorry, I forgot to put stream.next () in my previous example, at the end of token function. But the problem is still there. It seems to work, but for me, it doesn’t work well (like on previous screenshot).

Well, I can’t reproduce that problem.

I’m confused. By doing a demo on JSFiddle, I realize that everything is working fine. The problem seems to come from elsewhere in my code. I’ll look. Thank you for your help.

I found !
It’s a bit strange. In the code of my application, I put the states in an object. Leaving the state of the object, everything works well. I did this to organize my code and find myself there, because I have many states and some are groupable. I modified the JSFiddle to show that it worked badly as it was. I wonder why.

State is copied by the editor, when creating resume points in the document to partially re-highlight it. By default, that does a shallow object copy, so your block object would be accidentally shared between all instances of the state. (You can define a custom copyState to work around this.)

1 Like

This has nothing to do directly with blank lines, but if you’re asking because they’re causing trouble with your comments, this may be a better solution for your comments. Based on your requirements (a comment starts with a # and ends when a line break is encountered) it should be as simple as this:

CodeMirror.defineSimpleMode('tale', { 
    start: [
        {regex: /#.*/, token: 'tale-cmt'}
    ]
)

/#.*/ works because ‘.’ does not include newline characters in javascript, so it will start with your ‘#’ and run through the end of the line. No need for a second state.

If you want to require that the comment is at the start of the line then you’ll need to add the ‘sol: true’ back in.

OK, thank you for this clarification. This can always be useful.