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

Indentation on pasting of a multiline text #3845

Open
lost-valley opened this issue Apr 19, 2024 · 5 comments
Open

Indentation on pasting of a multiline text #3845

lost-valley opened this issue Apr 19, 2024 · 5 comments

Comments

@lost-valley
Copy link

lost-valley commented Apr 19, 2024

Hi, let me start with an expression of gratitude for this great text editor!

This is a feature request:

Scenario steps:

  1. Have a file with some text already in it.
  2. Have the text be hierarchically organized by indentation levels
  3. Be on a level 2
  4. Paste a multiline text from the clipboard. (but the clipboard text doesn't have any leading tabs or spaces)

Current behavior:
The first line of the text is pasted at the cursor location. (indented on level 2)
All the other lines of the clipboard contents are pasted at column 0 (indentation level 1).

Desired behavior:
Have all the lines of the pasted clipboard text be "padded" with the indentation level of the cursor.

e.g.

Intro:
    This text is indented on level 2
    ....
    ....

Other section:
    This text is also indented on level 2
    
    _my cursor is here_

    |
    v

    #################
    # now I wish to paste a multiline text from the clipboard and have _all_ of the text indented to the "Level 1" (whatever that is, e.g. 1 tab)
    # ... and all
    # the lines
    # of the pasted text
    # should end up being indented
    #################

    ...but instead I end up with this:

     #################
# now I wish to paste a multiline text from the clipboard and have _all_ of the text indented to the "Level 1" (whatever that is, e.g. 1 tab)
# ... and all
# the lines
# of the pasted text
# should end up being indented
#################

Thanks in advance!
Even if this doesn't get implemented, I'd love to hear why this is not a desired behavior :)

@b4n
Copy link
Member

b4n commented Apr 19, 2024

Even if this doesn't get implemented, I'd love to hear why this is not a desired behavior :)

I think it's an interesting (and probably useful) behavior, but it probably also cannot be the default. Here are a couple of reasons why from the top of my head:

  • What currently happens is that the pasted text is inserted as-is in the file -- not "pasted at column 0" if you will. This means that you get exactly what the content of the clipboard was inserted where you asked, which is great for predictability, as well as handling all case a "smart" algorithm might get wrong.
  • What if the clipboard already has indentation for the subsequent lines?
    • Strip the common indentation from all lines in the clipboard, and add back the one at the current position?
      • What about empty lines in the clipboard, do they count as "0-length indentation" or "let's ignore this line"
    • Or maybe strip the indentation from the first clipboard line, and then add (current - delta_from_first_line)? (e.g. aiming for the first line's indent to be the current position's indent, and then adding and removing indentation to match the differences in the pasted content)
      • And then, how to make up what an "indentation level" is in the clipboard? Is it the same size as the current document's? Or is it inferred from the clipboard?
      • But then, what if you copied only a partial first line rather than the whole thing? then applying delta is basically yielding the same as not changing anything.
    • Strip all indentation from the clipboard and past it all at the same level?
    • Simply prepend the current position's indentation to all lines without stripping anything from the clipboard?

All that might or might not make sense I guess, depending on the situation. I guess the "best" algorithm is one that takes clipboard indentation deltas into account and applies them, but it's also the most complex and could get things wrong.


As a currently available workaround (which you might already know about), you can easily adjust indentation of a whole series of lines by selecting it and using Tab or Shift+Tab.

@elextr
Copy link
Member

elextr commented Apr 20, 2024

And what about pasting Python (or other offside languages)?

Are we pasting:

  1. at the levels indicated by the clipboard indentation, or
  2. at the level at the cursor, or
  3. into the level at the cursor?

So just taking deltas into account is still not enough because of 2. vs 3.

Too many choices, but the current behaviour of re-indenting the first line only is likely to be wrong most of the time and probably should be changed for multi-line pastes.

@b4n
Copy link
Member

b4n commented Apr 20, 2024

the current behaviour of re-indenting the first line only is likely to be wrong most of the time and probably should be changed for multi-line pastes.

The current behavior does not indent anything, it just insert whatever there is in the clipboard wherever the caret is at. If the caret was at an indentation, so be it.
Again, IMO that s must still be available and likely default, because it's the simplest thing to do, and is 100% predictable.

@elextr
Copy link
Member

elextr commented Apr 20, 2024

The current behavior does not indent anything

What I mean is that the usual use case is to type return to get a new line to paste on, but that indents with the usual settings for Python, so extra indent is added to the first line unless the user does return then backspaces to remove the indent to start of line and then inserts. Perhaps "re-indent" is the wrong term but the default result is to add indent to the first line of the paste.

Again, IMO that s must still be available and likely default, because it's the simplest thing to do, and is 100% predictable.

Sure I am not suggesting remove it, its is likely the right thing for pastes anywhere besides first on line, just that it isn't the right thing for whole lines with usual settings for offside languages, so that makes more choice and its not really a setting, it will vary from one paste to the next so we need multiple paste options:

  1. paste (do as I tell you and don't argue no matter how wrong I have it!!! :-)
  2. language specific "Paste at current indent"
  3. language specific "Paste indented from current"

Options 2 and 3 should be added to the menu by the language specific plugin that controls behaviour ... what? ... Nooooo!!!

There is a reason nearly all other IDEs are built from plugins, not built-in 😁

@lost-valley
Copy link
Author

lost-valley commented Apr 21, 2024

it probably also cannot be the default

Agree

What if the clipboard already has indentation for the subsequent lines?
...

Good point, nice dissection of the problem.


I would go with a rather simplistic algo, that IMO covers a lot of cases without trying to be too smart:

During pasting, 
if text before cursor is only whitespace then:

- If every clipboard line has non-zero indentation,  
  then strip it until any line becomes "unindented"; ignore empty lines
    - unless "preserve_source_indentation" is set to "yes" - then don't strip anything
- Prefix every clipboard line with the current_line's indenation level

In pseudo code:


IF current_line.text_before_cursor IS whitespace THEN
	IF EVERY clipboard.lines STARTS_WITH whitespace THEN
		IF preferences.preserve_source_indentation == false THEN
			strip_indentation(clipboard)
		END IF
	END IF

        FOREACH line IN clipboard.lines
		line = current_line.text_before_cursor + line
	END FOREACH
END IF

Edit: fixed pseudo code algo

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

3 participants