Route every input to my package and modify TextBuffer manually


#1

Hello everyone!

I write a package that must parse every input. Based on the input, an internal data structure is modified and the parsed to a text which then replaces the editors text. This is done on every input!
For example: pressing backspace must not lead to a deletion of text. In some cases this is not allowed.

Is there any possibility to suppress the input, so my package can parse the it and update the text without getting the visible text updated twice?

I found TextEditor#onWillInsertText with a cancel property, but it does not work for e.g. backspace. Furthermore I have no access to the selected range(s).
TextBuffer#onWillChange seems the right interface, but I cannot cancel the input.

Or do you have any other ideas on how to handle that problem?


#2

There isn’t a way to do this built in to the Atom API. You would probably have to create your own TextEditor class or subclass to manage such a complete rewrite. You might be able to get away with somehow intercepting all DOM events that go to your editor view and handling them all. Sounds like a lot of work though :grinning:


#3

Well, I think you are right. I wrote this dirty code which worked for now:

buffer.onDidChange (event) =>
    if @ignoreNextOnDidChange
        @ignoreNextOnDidChange = false
    else
        @ignoreNextOnDidChange = true
        # Do some modification or parsing and do the replacement
        newText = event.newText.replace('a', 'b')
        buffer.setTextInRange(event.newRange, newText) # Perhaps undo: 'skip'?

But I’m not really happy with that “solution”.

As far as I can see, text modifications all based on TextBuffer#setTextInRange. What about modifying this method? Any ideas how to overwrite this method? Or replacing TextBuffer/TextEditor class?


#4

Unfortunately, I haven’t ever attempted to dig in that deep to those internals. So I don’t have any suggestions other than to experiment :grinning:


#5

Okay :wink: However, thank you for your answer!