Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ctrl+Alt+click does not create additional text carets #15242

Open
1 task done
mkupper opened this issue Jun 5, 2024 · 16 comments
Open
1 task done

Ctrl+Alt+click does not create additional text carets #15242

mkupper opened this issue Jun 5, 2024 · 16 comments

Comments

@mkupper
Copy link

mkupper commented Jun 5, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Description of the Issue

Notepad++ v8.6 on through v8.6.8 support multi-caret by using click to position the first text cursor or caret and then Ctrl+click to create and position additional text cursors or carets. If you click in the area past the end of a line then the resulting caret is positioned at the end of the line. Notepad++, including prior to v8.6, also supports Alt+click which works like a regular click and it also allows for positioning the text cursor or caret in the empty area past the end of a line. However, Notepad++ seems to ignore the Ctrl key when Ctrl+Alt+click is used. It acts like a normal Alt+click meaning that it will position the text cursor or caret in the empty area past the end of a line but you can't then create additional text cursors or carets the way you can with Ctrl+click

Describe the solution you'd like.

That Ctrl+Alt+click will work just like Ctrl+click with the additional ability that the text cursors or carets created can be positioned past the ends of the lines.

Debug Information

Notepad++ v8.6.8   (64-bit)
Build time : Jun  4 2024 - 00:30:00
Path : c:\npp\868\notepad++.exe
Command Line : -settingsDir="c:\npp\Settings" -multiInst
Admin mode : OFF
Local Conf mode : ON
Cloud Config : OFF
Periodic Backup : ON
OS Name : Windows 11 Home (64-bit)
OS Version : 23H2
OS Build : 22631.3593
Current ANSI codepage : 1252
Plugins : 
    mimeTools (3.1)
    NppConverter (4.6)
    NppExport (0.4)

Anything else?

No response

@alankilborn
Copy link
Contributor

I think the existing behavior (only one column/block selection allowed) is by-design...and by that I mean by-design of Scintilla. I don't know the reasoning, but it could be one of complexity--it might just be too difficult to manage (in a user's mind) what could go on with multiples. Sure, you can come up with some "simple" cases where it makes perfect sense, though.

I suppose that Notepad++ could "take over" from Scintilla in this regard, and allow it...but I'd think Notepad++ would be wise to let Scintilla do what it does best -- we've all seen what has happened in 8.6 and later where Notepad++ "took over" multiselection behavior, and the dust hasn't settled yet on all of the problems and corner cases with that.


If you click in the area past the end of a line then the resulting caret is positioned at the end of the line.

Note that this is only true if you have virtual space turned on.
...OR you use Alt+click (which, confusingly, you seem to already know).


@mkupper
Copy link
Author

mkupper commented Jun 5, 2024

Thank you @alankilborn - It's unfortunate the issue is more on the Scintilla side. Do you know if there is a word or phrase that best describes a text cursor or caret that is positioned beyond the end of a line? You mentioned "virtual space" but than added the bit about Alt+click.

For example, I wanted to created a second github issue but also want to use the right word if it's not "virtual space".

This issue came about from when I was playing around with Notepad++ to better understand https://community.notepad-plus-plus.org/topic/25848/pasting-alt-drag-blocks-doesn-t-work-anymore that someone started on the forums. In that case someone created a thin or zero width column selection in the "virtual space." Had they started typing characters or pasted a stream selection then the editor (I'm not sure if it's Notepad++ or Scintilla) will pad the lines with spaces so that the resulting text appears exactly where the text cursors or or carets had been out in virtual space. Instead of typing text or pasting a stream selection the person pasted a column selection (which I think is a multi selection). When the person did that, space padding was not inserted and the resulting text is appended directly onto the ends of the lines.

I was also able to replicate that behavior using what I call a multi selection. I double click on a word which selects it. I Ctrl+double click on another word which selects it while leaving the previous selection selected. I Ctrl+double click on a third word which selects that and I have three words selected. Now I do Ctrl+C which loads all selected three words into the copy/paste buffer as a multi-selection. If I paste into a normal single text cursor or caret I get three lines with the three words I had selected. If I paste into a zero-width column selection that is all within text lines (not virtual space) then it's a neat column paste and I have three carets, one at the end of the three words. If I instead paste into a zero-width column selection where one or more of the carets lines are in virtual space then the words for those lines are appended to the lines without space-padding them to position the word at the location of the caret.

While the behavior is the same I don't know if both column selections and Ctrl+double-click of words both are loading exactly the same "multi-selection" format of the data into the copy/paste buffer. Both of them are loading $MSDEVColumnSelect$ and $Borland IDE Block Type$ format blocks into the copy/paste buffer. However, in this stackoverflow thread someone believes that Notepad++ is not using the copy/paste buffer contents but rather has a back door of some sort. I'm skeptical of that but am including the comment here as it may well be I can't trust an inspection of the clipboard to figure out what Notepad++ or Scintilla are doing when copy/pasting.

@alankilborn
Copy link
Contributor

It's unfortunate the issue is more on the Scintilla side.

I don't know why you say that's "unfortunate"... Scintilla's whole reason-for-being is to handle text editing (which includes selection handling). It's best for N++ when Scintilla DOES handle this stuff; N++ developers can concentrate on other things and just let Scintilla "do its stuff".

Do you know if there is a word or phrase that best describes a text cursor or caret that is positioned beyond the end of a line?
You mentioned "virtual space" but than added the bit about Alt+click.

"In virtual space" is the best I can do for describing that situation. The Alt+LClick part is important; it's actually creating a rectangular/column block selection (of zero height by zero width) -- because these types of blocks are allowed to span some virtual space even when the N++ setting to enable virtual space is not enabled.

@Coises
Copy link
Contributor

Coises commented Jun 7, 2024

@mkupper:

While the behavior is the same I don't know if both column selections and Ctrl+double-click of words both are loading exactly the same "multi-selection" format of the data into the copy/paste buffer. Both of them are loading $MSDEVColumnSelect$ and $Borland IDE Block Type$ format blocks into the copy/paste buffer. However, in this stackoverflow thread someone believes that Notepad++ is not using the copy/paste buffer contents but rather has a back door of some sort. I'm skeptical of that but am including the comment here as it may well be I can't trust an inspection of the clipboard to figure out what Notepad++ or Scintilla are doing when copy/pasting.

The Stack Overflow thread you linked is twelve years old.

Whatever else might have changed since then, Scintilla made a big change between the version used in Notepad++ 8.5.8 and the one used in 8.6. I still haven’t found time and energy to track down all the details, but a few things I’ve figured out:

  1. Previously, Scintilla copied multiple selections to the clipboard back-to-back, with no intervening line endings, making them indistinguishable in the clipboard from a copied stream selection.

  2. Now, Scintilla copies multiple selections with line endings between each selection and the $MSDEVColumnSelect$ signal is added; this makes them indistinguishable from a copied rectangular selection.

  3. Scintilla documentation (e.g., “When discontiguous selections are copied to the clipboard, each selection is added to the clipboard text in order with no delimiting characters.” from https://www.scintilla.org/ScintillaDoc.html#MultipleSelectionAndVirtualSpace) has not been updated. I couldn’t find anything in release notes, either, but I’m not familiar with the Scintilla repository system and I haven’t figured out how to figure out what happened yet.

  4. While I don’t know it for a fact, I strongly suspect many of the Notepad++ changes beginning in 8.6 were either motivated or necessitated by the Scintilla changes.

  5. The Notepad++ paste behavior is managed here:

    if (nbSelections > 1 && !isRO)
    which does indeed ignore whether the paste is into a multiple stream selection or a rectangular selection. See Issue [BUG] Copying a rectangular selection and pasting into another rectangular selection that contains half as many lines, or fewer, produces unexpected results. #15139 and Issue [BUG] Copied lines are inserted in the wrong order #15151 for some of the fallout from this decision.

Despite that fallout, I suspect it was an intentional decision to make rectangular selections and multiple selections behave the same wherever possible.

I’m not sure this has much to do with the subject of your issue, though. Have you checked (I haven’t) whether it is Scintilla or Notepad++ that makes Alt+click work to put the cursor in virtual space even when virtual space is not enabled? It looks like Scintilla makes Alt+click place the cursor in virtual space even when virtual space is not enabled here. I am not successfully parsing the rest of that routine, but from what happens, I have to assume that when the control key and the alt key are both down, it resets the selection. So this would seem to be a Scintilla request rather than a Notepad++ request.

@mpheath
Copy link
Contributor

mpheath commented Jun 7, 2024

@Coises

  1. Previously, Scintilla copied multiple selections to the clipboard back-to-back, with no intervening line endings, making them indistinguishable in the clipboard from a copied stream selection.
  2. Now, Scintilla copies multiple selections with line endings between each selection and the $MSDEVColumnSelect$ signal is added; this makes them indistinguishable from a copied rectangular selection, not multiple selection.

Check with SciTE as still does copy multiple selections to the clipboard back-to-back, Notepad++ inserts CRLF between multiple selections and adds MSDEVColumnSelect. SciTE only uses MSDEVColumnSelect with a rectangular selection. Both use Scintilla so I guess it must be the application causing the differences.

  1. Scintilla documentation (e.g., “When discontiguous selections are copied to the clipboard, each selection is added to the clipboard text in order with no delimiting characters.” from https://www.scintilla.org/ScintillaDoc.html#MultipleSelectionAndVirtualSpace) has not been updated. I couldn’t find anything in release notes, either, but I’m not familiar with the Scintilla repository system and I haven’t figured out how to figure out what happened yet.

SciTE does not select into virtual space by default SCVS_NONE unless virtual space is enabled. Notepad++ by default has set SCVS_RECTANGULARSELECTION which allows the rectangular selection to go past EOLs into virtual space. Enable virtual space checkbox in Notepad++ and it sets SCVS_RECTANGULARSELECTION | SCVS_USERACCESSIBLE | SCVS_NOWRAPLINESTART

You can check the integer returned with editor.getVirtualSpaceOptions() in PythonScript.

  1. While I don’t know it for a fact, I strongly suspect many of the Notepad++ changes beginning in 8.6 were either motivated or necessitated by the Scintilla changes.

The Ctrl click is Scintilla that upset the Ctrl drag though the rest pretty much is Notepad++ v8.6+ changes.

Despite that fallout, I suspect it was an intentional decision to make rectangular selections and multiple selections behave the same wherever possible.

If there is a strategy, I have not figured it out yet. I am just observing what will unfold.

So this would seem to be a Scintilla request rather than a Notepad++ request.

SCVS_RECTANGULARSELECTION as the Notepad++ set default allows "cursor in virtual space" so I do not see a reason for a request unless want SCVS_NONE as new Notepad++ default which might upset some existing users due to the new behavior.

@Coises
Copy link
Contributor

Coises commented Jun 7, 2024

@mpheath

Check with SciTE as still does copy multiple selections to the clipboard back-to-back, Notepad++ inserts CRLF between multiple selections and adds MSDEVColumnSelect. SciTE only uses MSDEVColumnSelect with a rectangular selection. Both use Scintilla so I guess it must be the application causing the differences.

Admittedly, I have not tested with SciTE yet. That, and trying to trace the history of the Scintilla code referenced below, remain “to do” for me.

I just downloaded SciTE 5.5.0 64-bit from this page and I can verify your observation. Making a multiple selection in SciTE, copying to the clipboard, and pasting into Windows Notepad produces a single line of text with all the pieces run together. Making a multiple selection in Notepad++, copying to the clipboard, and pasting into Windows Notepad yields one line for each component of the multiple selection.

And this commit provides the answer. It never occurred to me before that Notepad++ might use a modified version of Scintilla. So... I suppose all bets are off as for expecting Scintilla within Notepad++ to conform to Scintilla vanilla (or its documentation).

Given the observations that follow, I am entirely stumped as to what is going on. Is it possible that SciTE and Notepad++ are not using the same Scintilla code?

I do note these two things:

A search of the Notepad++ repository shows only one appearance of MSDEVColumnSelect in the PowerEditor code, with the rest being in Scintilla code:
https://github.com/search?q=repo%3Anotepad-plus-plus%2Fnotepad-plus-plus%20MSDEVColumnSelect&type=code
Examining that one PowerEditor use shows that it is only used to test what is in the clipboard; it never sets that format into the clipboard. Also, the code that processes the copy command does nothing but pass it along to Scintilla.

This code in Scintilla:

void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {

looks to me like it inserts line endings and passes the flag to set MSDEVColumnSelect to the copy-to-clipboard routine whenever there are multiple selections. The only difference for rectangular selections is that it sorts them first.

@Coises
Copy link
Contributor

Coises commented Jun 7, 2024

@mpheath

SCVS_RECTANGULARSELECTION as the Notepad++ set default allows "cursor in virtual space" so I do not see a reason for a request unless want SCVS_NONE as new Notepad++ default which might upset some existing users due to the new behavior.

Well, the “complaint” amounts to: If Alt lets you click to place the cursor in virtual space (even when virtual space is not enabled for unmodified clicks) and Ctrl lets you make multiple selections, why doesn’t Ctrl+Alt let you make multiple selections in virtual space?

Since both the Ctrl and the Alt behavior are implemented in Scintilla code, it seems to me that attempting to implement Ctrl+Alt in Notepad++ as a combination of the two would risk fragility. Whether Scintilla has a reason for not implementing it (perhaps it leads to some inconsistency we haven’t yet recognized), or whether it was just an oversight (or something no one ever requested), I don’t know.

I can guess that part of it might be that Alt+drag creates a rectangular selection (even when it’s all on one line), and multiple rectangular selections are not supported. Perhaps the semantics of Ctrl+Alt+click/drag were deemed too confusing.

@xomx
Copy link
Contributor

xomx commented Jun 7, 2024

@Coises

And this commit provides the answer. It never occurred to me before that Notepad++ might use a modified version of Scintilla.

Nice find. I am curious if that direct modification of the Scintilla library code was intentional and mainly - what will happen after the next possible Scintilla update... (FYI @donho)

@mpheath
Copy link
Contributor

mpheath commented Jun 8, 2024

@Coises

Ctrl lets you make multiple selections, why doesn’t Ctrl+Alt let you make multiple selections in virtual space?

Quick answer, not implemented it seems. Longer answer read on.

Alt is for rectangular selections and Ctrl is for multiple selections. SCVS_RECTANGULARSELECTION allows virtual space click as Alt is used to create a rectangular selection. The Shift key can also play a part though not mentioned yet so I consider the question could be why Ctrl click to start then Ctrl+Shift click to end does not extend into virtual space for multiple selections (like a SCVS_MULTIPLESELECTION option could exist). It does extend if the virtual space checkbox is checked so perhaps is already implemented by option. Now this makes me curious if virtual space checkbox is not checked, then what is it in empty virtual space is worth a multiple selection extending past EOL as nothing is expected to be out there.

Alt+Ctrl seems a strange combination the more I consider it as though rectangular and multiple selections are somehow the same, which does not seem to be the case. I am curious as why Ctrl+Alt should have this ability with the question asked. I consider that Scintilla might be able to make something happen rather than here though Neil may agree there and ask for a patch. But that could be pure speculation :)

const SelectionPosition clickPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt));

See alt used as the flag argument to access the virtual space. This function is where the main key handling is for selections originate from.

@alankilborn
Copy link
Contributor

I consider that Scintilla might be able to make something happen rather than here though Neil may agree there and ask for a patch.

Is it time to ask the man himself ( @nyamatongwe ) if he's interesting in commenting on this discussion?

@mpheath
Copy link
Contributor

mpheath commented Jun 8, 2024

If use Shift key with Ctrl key then it does go into virtual space. So the Ctrl+Alt might be unneeded to achieve the solution asked for in the OP. If not use Shift, then this code might capture the event and so selection does not happen.

if (!shift) {
const ptrdiff_t selectionPart = SelectionFromPoint(pt);
if (selectionPart >= 0) {
if (multipleSelection && ctrl) {

Agh, forget it. I had virtual space checkbox checked. :(

@donho
Copy link
Member

donho commented Jun 8, 2024

@xomx

I am curious if that direct modification of the Scintilla library code was intentional and mainly

All the modifications of Scintilla are intentional, though it's not encouraged (for the sake of upgrading Scintilla).
It's allowed, for only interesting features which need the modification of small amount of source code of Scintilla.

  • what will happen after the next possible Scintilla update...

Please see the file:
https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/scintilla.original.forUpdating/scintillaUpdatingWorkFlow.txt

@Coises
Copy link
Contributor

Coises commented Jun 8, 2024

@mkupper

Notepad++, including prior to v8.6, also supports Alt+click which works like a regular click and it also allows for positioning the text cursor or caret in the empty area past the end of a line.

Both Alan and Michael have made note of this, but I just wanted to condense it in one place so the point isn’t missed:

This is a kind of side-effect. Mouse down with the Alt key pressed begins a rectangular selection. In Notepad++ (as a result of the settings it makes in Scintilla), rectangular selections are allowed to have the anchor and/or caret in virtual space even when virtual space is not enabled in the settings, so mouse down with the Alt key in virtual space doesn’t snap back to the end of a line, like an unmodified mouse down would. (Observe that the text caret is positioned on mouse down.)

If you then drag (even if you let the Alt key up — but not the mouse button!), you’ll get a rectangular selection.

If you mouse up without moving, then (I’m fairly sure, though I’d have to test it in code to be 100% certain) the selection reverts to an ordinary empty stream selection. However, the caret doesn’t snap back to the end of the line after the fact; it stays in virtual space.

So you can use this to put the caret for an empty selection in virtual space, but that’s not its purpose; it just happens to work as a result of the way rectangular selections work.

@alankilborn
Copy link
Contributor

alankilborn commented Jun 8, 2024

If you mouse up without moving, then (I’m fairly sure, though I’d have to test it in code to be 100% certain) the selection reverts to an ordinary empty stream selection.

Nope. You can prove it by running editor.getSelectionMode() in the PythonScript console. It stays in rectangular mode if you are in virtual/non-virtual space. You just have a 0-by-0 rectangle.

However, the caret doesn’t snap back to the end of the line after the fact; it stays in virtual space.

And this is because you're in rectangular selection mode.

@nyamatongwe
Copy link

With alt meaning "rectangular" and ctrl meaning "multiple", alt+ctrl could mean "multiple rectangular" and be used for adding a rectangular selection piece to the selection in the future. That is, it would enable the selection to be a collection of stream and rectangular selection pieces. This is a complex feature so hasn't been implemented.

The current behaviour of ctrl+alt+click produces a single empty rectangular selection. When SCVS_RECTANGULARSELECTION is on, this can be in virtual space. This is caused by the implementation checking that the alt state is on and not checking that ctrl is off. It could reject the click completely but that seems unfriendly.

The reason that there is a separate SCVS_RECTANGULARSELECTION is that text is often ragged on the right so it can be difficult to select a full column if the caret snaps to the end of the last selected line.

The original poster seems to want virtual space so should enable that in the editing preferences. Temporarily allowing virtual space with ctrl+alt+click is taking over a potentially valuable gesture for (to me) little benefit.

@alankilborn
Copy link
Contributor

I have long-exploited the "feature" in Notepad++ where I can Alt+Lclick past the end of line to place a caret "far out to the right" so that I can then paste some rectangular text there (giving me a nice "space gap" between there and existing text). I'm not sure what else might be proposed in this discussion, but I hope it doesn't become the elimination of this capability. Note that I don't normally want "virtual space" enabled, so that isn't an answer for me on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants