SC-IDE code panel "word" semantics

This is not quite ready for a feature request on github, or for an RFC… so, maybe start here to collect opinions.

I am routinely irritated by the behavior of ctrl-left and ctrl-right keys in the IDE.

Here’s an example:

cbufGen: #[[1], [1, 0, 0, 0, 1]]

If you ctrl-right arrow through this, you’ll find that the “words” are:

  • cbufGen: – ok this makes sense
  • #
  • [
  • [
  • 1
  • ]
  • , (with space after)
  • [
  • 1
  • , (with space after)
  • 0
  • , (with space after)
  • 0
  • , (with space after)
  • 0
  • , (with space after)
  • 1
  • ]
  • ]

Out of 32 characters, 13 ctrl-right keystrokes move by a single character only. This seems… unhelpfully fussy.

For this example, one way to improve the behavior would be to scan for alphanumeric tokens: jump from cbufGen to 1, then to 0 and so on.

I think this heuristic is probably a good way to go for many, even most, cases. For example, in a standard method call x.something(argument), if the cursor is between the . and something, and you hit ctrl-right, the current behavior is to position the cursor to the left of the left-paren. Scanning for alphanumerics would put it to the right of the left-paren. That is, to reach the argument, currently you need to ctrl-right twice, but from the user’s perspective, “something” is one word and “argument” is another word… why are we not just moving directly to the other word? What does the user gain from current behavior?

In that example, I’m suggesting that moving over the 10 characters something( would be optimal user-friendly behavior, meaning that the current behavior – to move 9 characters – represents a 10% error. This doesn’t seem like much – but in my array example, there are 13 cases where the error is up to 50%. And we have many such cases in SC code… I wouldn’t bother to write this up if it weren’t a daily “why does ctrl-left/right not work” kind of occurrence. Multiple times every day.

For implementation (just recording this for future, so I don’t have to search it again), sc_editor.cpp has:

void ScCodeEditor::keyPressEvent(QKeyEvent* e) {
    hideMouseCursor(e);
    bool actionInSuper = false;

    QTextCursor cursor(textCursor());
    bool cursorMoved = true;

    if (e == QKeySequence::MoveToNextWord)
        moveToNextToken(cursor, QTextCursor::MoveAnchor);
    else if (e == QKeySequence::MoveToPreviousWord)
        moveToPreviousToken(cursor, QTextCursor::MoveAnchor);
    else if (e == QKeySequence::SelectNextWord)
        moveToNextToken(cursor, QTextCursor::KeepAnchor);
    else if (e == QKeySequence::SelectPreviousWord)
        moveToPreviousToken(cursor, QTextCursor::KeepAnchor);

So we see why… the IDE’s tokenizer considers [ ] etc. to be separate tokens, and the UI logic forces the tokenizer’s view of things onto the user.

It should be possible to modify the moveTo... functions to select the next or previous token in a more intelligent way.

The catch is defining what is user-friendly behavior – hence this thread.

  • Can you think of any cases where “next/previous alphanumeric token” would be bad?
  • Any different opinions about ctrl-lef/right semantics?

Thanks,
hjh

1 Like