#1648 Rectangular Selection

Feature_Request
closed-fixed
5
2016-09-05
2014-08-26
No

Set selection mode to rectangular (SCI_SETSELECTIONMODE, SC_SEL_RECTANGLE), then go right several position <Cursor Key="" Right=""> and the go left <Cursor Key="" Left=""> the caret doen´t go left one position, it jumps. If you use SHIFT + ALT + Cursor Keys for rectangular selection, this doesn´t happen, the caret moves as expected.

I changed "editor.cxx"

...
case SCI_LINEDOWN:
// JK
if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
CursorUpOrDown(1, Selection::selRectangle);
} else {
CursorUpOrDown(1);
}
break;
...
case SCI_LINEUP:
// JK
if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
CursorUpOrDown(-1, Selection::selRectangle);
} else {
CursorUpOrDown(-1);
}
break;
...
case SCI_CHARLEFT:
// JK
if (virtualSpaceOptions == 7) {
if ((pdoc->IsLineStartPosition(sel.MainCaret())) && (sel.RangeMain().caret.VirtualSpace() == 0)) {
break;
}
}

    if (SelectionEmpty() || sel.MoveExtends()) {
        if ((sel.Count() == 1) && pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
            SelectionPosition spCaret = sel.RangeMain().caret;
            spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
            MovePositionTo(spCaret);
        } else if (sel.MoveExtends() && sel.selType == Selection::selStream) {
            MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1));

// JK
} else if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
SelectionPosition spCaret = sel.RangeMain().caret;
spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
MovePositionTo(spCaret, Selection::selRectangle);
} else {
MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle);
}

        } else {
            MovePositionTo(MovePositionSoVisible(
                SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1));
        }
    } else {      
        MovePositionTo(sel.LimitsForRectangularElseMain().start);
    }
    SetLastXChosen();
    break;

this seems to solve the problem

I made an addition:
if (virtualSpaceOptions == 7) {
if ((pdoc->IsLineStartPosition(sel.MainCaret())) && (sel.RangeMain().caret.VirtualSpace() == 0)) {
break;
}
}

this prevents the caret from going up one line, if it reaches line start in virtual space mode (set to 7), It needs "IsLineStartPosition" which was added in Document.h and Document.cxx

bool Document::IsLineStartPosition(int position) const {
return LineStart(LineFromPosition(position)) == position;
}

It just makes SCI_CHARLEFT(RECT/EXTEND) do nothing on a <Cursor Key="" Left=""> keystroke, if line start (taking virtualspace into accaount) is reached. Is that a correct way to do it or is bound to get me into trouble somehow (no trouble so far...)?

JK

Discussion

  • Juergen Kuehlwein

    Sorry - looks uggly, should have read "Formatting Help" before ...

    A second try (still cannot get preview working):

    Set selection mode to rectangular (SCI_SETSELECTIONMODE, SC_SEL_RECTANGLE), then go right several position <Cursor Key="" Right=""> and the go left <Cursor Key="" Left=""> the caret doen´t go left one position, it jumps. If you use SHIFT + ALT + Cursor Keys for rectangular selection, this doesn´t happen, the caret moves as expected.

    I changed "editor.cxx"

    ...
    case SCI_LINEDOWN:
    // JK
    if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
    CursorUpOrDown(1, Selection::selRectangle);
    } else {
    CursorUpOrDown(1);
    }
    break;
    ...
    case SCI_LINEUP:
    // JK
    if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
    CursorUpOrDown(-1, Selection::selRectangle);
    } else {
    CursorUpOrDown(-1);
    }
    break;
    ...
    case SCI_CHARLEFT:
    // JK
    if (virtualSpaceOptions == 7) {
    if ((pdoc->IsLineStartPosition(sel.MainCaret())) && (sel.RangeMain().caret.VirtualSpace() == 0)) {
    break;
    }
    }
    
        if (SelectionEmpty() || sel.MoveExtends()) {
            if ((sel.Count() == 1) && pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
                SelectionPosition spCaret = sel.RangeMain().caret;
                spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
                MovePositionTo(spCaret);
            } else if (sel.MoveExtends() && sel.selType == Selection::selStream) {
                MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1));
    
    // JK
    } else if (sel.MoveExtends() && sel.selType == Selection::selRectangle) {
    if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
    SelectionPosition spCaret = sel.RangeMain().caret;
    spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
    MovePositionTo(spCaret, Selection::selRectangle);
    } else {
    MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle);
    }
    
            } else {
                MovePositionTo(MovePositionSoVisible(
                    SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1));
            }
        } else {      
            MovePositionTo(sel.LimitsForRectangularElseMain().start);
        }
        SetLastXChosen();
        break;
    

    this seems to solve the problem

    I made an addition:

    if (virtualSpaceOptions == 7) {
    if ((pdoc->IsLineStartPosition(sel.MainCaret())) && (sel.RangeMain().caret.VirtualSpace() == 0)) {
    break;
    }
    }
    

    this prevents the caret from going up one line, if it reaches line start in virtual space mode (set to 7), It needs "IsLineStartPosition" which was added in Document.h and Document.cxx

    bool Document::IsLineStartPosition(int position) const {
    return LineStart(LineFromPosition(position)) == position;
    }

    It just makes SCI_CHARLEFT(RECT/EXTEND) do nothing on a <Cursor Key="" Left=""> keystroke, if line start (taking virtualspace into accaount) is reached. Is that a correct way to do it or is bound to get me into trouble somehow (no trouble so far...)?

    JK

     
  • Neil Hodgson

    Neil Hodgson - 2014-08-26

    The same effect still occurs if you go left then right as you haven't changed SCI_CHARRIGHT.

    I didn't implement the "move extends" mode and am uncertain how it should behave. It may be an idea to post something on the mailing list to see if the people that currently use the feature like these changes.

    Stopping rectangular selections from wrapping at line start occurs even when virtual space is turned off so this shouldn't go into virtualSpaceOptions. It may be OK to just stop rectangular selections from moving past line start but its also easy to just CHARRIGHT when this occurs.

    The LINEDOWN/LINEUP cases can be more easily changed by modifying the 3rd line of CursorUpOrDown to
    if (!sel.MoveExtends() && (selt == Selection::noSel)) {

     
  • Juergen Kuehlwein

    Neil,

    first of all thanks for developping and sharing this wonderful software!

    I was a bit short and unclear in my post, it is about two different things:
    Rectangular selection and virtual space options

    Rectangular selection:

    I know of three different methods of creating a rectangular selection

    method 1: mouse selection - works as expected

    method 2: Alt+Shift+Cursor Keys - works as expected

    method 3: SCI_Setselection -> SC_SEL_RECTANGLE + Cursor Keys - works different

    method 3 shows a different caret behaviour compared to method 2
    I don´t know, if this done intentionally (a feature), but in my opinion
    the caret behaviour should be the same in method 2 and 3.

    The code i posted (you are right CHARRIGHT is missing in my post) might solve
    this "issue"

    There are two questions, i would like to be answered:

    • wouldn´t it be better, if the caret behaviour were the same in method 2 nd three ?

    • is the code i suggested appropriate and sufficient to accomplish this ? (i studied only small parts of your code, from your superior knowledge of this code, is this a correct solution)

    Virtual space options:

    There are two widespread modes an edit control is working

    mode 1: the caret is bound to the text, the caret wraps at line start/end

    mode 2: the caret can be placed outside of text, horizontal caret movement never wraps
    and vertical movement never changes column

    Scintilla by default works in mode 1. By setting virtual space options scintilla works
    in mode 2 except for wrapping the caret at line start.

    In my opinion another virtual space option making scintilla work totally like mode 2 (even with all kinds of selection) should be added.

    The code i supplied seems to do that.

    Again there are two questions, i would like to be answered:

    • wouldn´t it be better, to add such an option

    • is the code i suggested appropriate and sufficient to accomplish this ?

    Please don´t get me wrong, i appreciate your work and don´t want to tell you hwo to do it. I appreciate even more that there are sources available and i can apply changes and make it work "my way". Among these changes the two addressed above might be be of public interest, i thought. And i hopped you could confirm the changes i suggested don´t arise problems of any kind.

    Thanks

    JK

     
  • Stephan R.A. Deibel

    I think Wingware just uses the SCI_SETSELECTIONMODE feature and didn't write it, although I may be misremembering.

    I don't see the bug in Wing IDE when I turn on rectangular selection and move around, but virtual spacing is disabled in our case.

    Jumping around doesn't seem to be desirable. The selection should grow and shrink in a logical way with caret movement. When there is no virtual space there can be jumping when moving to short lines, but I think it's reasonable in that case.

    When there is virtual space I would have expected mode 2 described above (no wrapping and column never changes on its own).

     
  • Juergen Kuehlwein

    "When there is virtual space I would have expected mode 2 described above (no wrapping and column never changes on its own)."

    That´s exactly how i feel i should be, and i was a bit surprised to see it isn´t like this - the caret wraps at line start always. I´m using Scintila for a project and i prefer mode 2, so i tried to get Scintilla work this way. That´s when i came across "issue".

     
  • Neil Hodgson

    Neil Hodgson - 2014-09-03

    virtualSpaceOptions is a bit mask so this new no-wrap mode should be 4 and tested with & like other tests of virtualSpaceOptions. It is likely that the mode is wanted when either SCVS_USERACCESSIBLE or SCVS_RECTANGULARSELECTION is set.

     
  • Juergen Kuehlwein

    Neil,

    "virtualSpaceOptions is a bit mask so this new no-wrap mode should be 4 and tested "

    yes, of course and for me it makes sense only in combination with the others. That´s why i tested for 7 (1+2+4) - i want them all or none of them.

    Adding a no-wrap mode (maybe SCVC_NOWRAP = 4) would be a nice feature. If you want to be able to set this no-wrap mode separately from the other, you would have to test for 4 - agreed.

    JK

     
    • Neil Hodgson

      Neil Hodgson - 2014-09-03

      Why does it make sense only with both of the other flags turned on? If you have SCVS_USERACCESSIBLE but not SCVS_RECTANGULARSELECTION, then isn't no wrap at beginning also something that may be wanted?

       
  • Juergen Kuehlwein

    Neil,

    i want to have wrap or no-wrap in each and every situation - even with rectangular selection. SCVS_RECTANGULARSELECTION allone makes sense in wrap and no-wrap mode, but SCVS_USERACCESSIBLE allone is ugly. You can go up and down and the column always remains the same, but whitin a rectangular selection going up and down doesn´t keep always the column. I would expect the caret bevaviour always to be the same regardless if i am selecting or not. This is the case only, if both flags are turned on.

    This is how i feel it should be - YMMV. Introducing a new option SCVC_NOWRAP = 4, and testing for 4 instead of 7 would be perfect, and everyone could have it just as he/she likes it best.

    JK

     
    • Neil Hodgson

      Neil Hodgson - 2014-09-05

      Its because people have different opinions on correct behaviour that the different flags are available independently.

      SCVS_NOWRAPLINESTART may be clearer in explaining the intention than SCVS_NOWRAP.

      If you want either of these features included, you'll have to complete the code since they are not features I will be using. It would be better to separate the wrapping change from the other changes as it appears to make sense as an independent feature. This makes it easier to review and to isolate bugs if there are any.

       
  • Neil Hodgson

    Neil Hodgson - 2016-08-20
    • labels: --> scintilla, virtualspace
    • status: open --> open-fixed
    • assigned_to: Neil Hodgson
    • Group: Cosmetic --> Feature_Request
     
  • Neil Hodgson

    Neil Hodgson - 2016-08-20

    Committed SCVS_NOWRAPLINESTART as [92f5a7].

    This report is quite complex to understand and the change appears to have satisfied the main need. If there are still more changes wanted, these should be extracted into a new bug report.

     

    Related

    Commit: [92f5a7]

  • Neil Hodgson

    Neil Hodgson - 2016-09-05
    • status: open-fixed --> closed-fixed
     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks