Moving cursor past a collection in the editor
Hi there,
I am having trouble doing something relatively simple, and I think I could use some help.
My language has indented blocks of statements that are not surrounded by braces, much like Python. I want to make it easy for a user to finish a block of code and continue writing un-indented statements.
In the base language, this is easy to do by typing within the braces and simply moving the cursor past the brace when ready to insert another high-level child. If I am not using braces, one simple thing I can do is have an empty cell as the end tag. However, this end tag is always on another line because the indented block adds a newline after every child, and a user would expect to be able to type on this line, but is unable to.
What is a solution for this? Some things that would work would be:
Somehow always have an extra EmptyLine child at the highest lever so the cursor can be moved to it (but how?)
If a user deletes an empty line, end the block and create a sibling for it. I guess I would make a DELETE action map here, but how would I check that the EmptyLine was the last child in the block? I've been having a lot of trouble doing anything with action maps.
If the user is about to type a third EmptyLine in a row at the end of a block, end that block and insert an empty line on the next line instead. Once again, I can't figure out how to check this in an action map.
Any help is really appreciated.
Please sign in to leave a comment.
Simon, have you seen Indentation-oriented languages with MPS ?
Thanks for the link. It was somewhat helpful but I still can't get the keymaps to do what I want.
I create a keymap for <none> + <VK_BACK_SPACE> that does "node.parent.add next-sibling(new node<EmptyLine>());", add it to the EmptyLine editor, but the keymap does not take effect. If I set the key binding to something else, however, such as "VK_0", then it works. Are we unable to override keys that have existing effects?
Trying to create a "DELETE" or "BACKSPACE" action map doesn't seem to help either. Incidentally, I don't understand the difference between a "BACKSPACE" action map and keymap.
I've been trying all kinds of other solutions without much success.
Is there a way to create an end tag on the same line as the last child? In other words, is there a way to have a newline after every child except the last one? That would solve my problem somewhat. Alternatively, is there a way to have every statement block always have a newline as its last child so that there is a child to jump to? Creating an INSERT action map to do this hasn't been successful.
The desired behavior is that within a statement block, pressing enter creates another child (another statement with the same indentation). However, there needs to be a way to go up in the statement block hierarchy if needed, either by pressing down or backspace. In other words, the user shouldn't be stuck in only being able to add statements to that block.
So far every solution has either made it so that a user was able to only insert one statement before jumping out of the block (unless there were already higher level statements following), or made it impossible to jump out of a block (unless there were already higher level statements following).
You are using the latest MPS, aren't you?
I'm not sure how to sort out backspace vs delete issues. I had issues with "preventing default backspace and delete": https://mps-support.jetbrains.com/hc/en-us/community/posts/207248325-Prevent-removal-of-certain-elements-from-children-collection As far as I can remember, it was not possible.
Have you considered TAB and Shift+TAB for changing the "indent" level? It might play well.
Regarding keymaps: some behavior regarding deletion and insertion is currently hardcoded (for example, deleting text inside an editable label cell) - in this case MPS doesn't call user-defined actions from the keymap.
Thank you for the responses. Sounds like there isn't a very simple solution so I abandoned that effort. I'm now using a normal child cell list with an empty constant cell at the end and making the entire indented collection (the square brackets) not selectable. That seems to make things fairly user-friendly.