jiangmiao / auto-pairs

Vim plugin, insert or delete brackets, parens, quotes in pair
http://www.vim.org/scripts/script.php?script_id=3599
4.09k stars 373 forks source link

Pressing enter inside brackets destroys indentation #372

Open ei14 opened 9 months ago

ei14 commented 9 months ago

Pressing enter inside brackets often messes up indentation.

Example

I created an example and reproduced the problem, even upon opening Vim with no other plugins and no vimrc.

Open an HTML file and type the following. The █ character represents the position of the cursor in insert mode.

<html>
    <head>
        <style>
            div {█}
        </style>
    </head>
</html>

Next, in insert mode, type enter (<CR>).

Expected result

I'd expect indentation to be preserved.

<html>
    <head>
        <style>
            div {
                █
            }
        </style>
    </head>
</html>

Actual result

The indentation is completely reset to 0.

<html>
    <head>
        <style>
div {
    █
}
        </style>
    </head>
</html>

If this is intended behavior, then there must be a way to turn this off. Perhaps the plugin is trying to "intelligently" recognize that I am not inside any curly braces, so it tries to establish the braces as being at root-level indentation. This is far too crude to be useful in most situations. In this situation, I think most people would much prefer the plugin to just blindly type <CR><BS><c-o>O instead of this sort of "smart" indentation.

LunarWatcher commented 9 months ago

If this is intended behavior, then there must be a way to turn this off. Perhaps the plugin is trying to "intelligently" recognize that I am not inside any curly braces, so it tries to establish the braces as being at root-level indentation

Nope, blame Vim (or whatever formatter it is you're using). Auto-pairs uses = under the hood for formatting. It drops indent because Vim's formatter says it should. Your alternative solution is a perfect demonstration of why. Unmapping CR for science, <CR><BS><C-o>O (for me) yields

<html>
    <head>
        <style>
            div {
                |
        }
        </style>
    </head>
</html>

This is why auto-pairs relies on a formatter. I use a non-standard (but by no means uncommon) formatter. You can basically shove in any formatter you want in Vim (with at least a little vimscript anyway), which means any static system relying on the default formatter is going to fail.

If you don't like the format output, you need to configure your formatter, vim, or find a new formatter. In my case, or if you're using Vim's built-in formatter, use

let g:html_indent_style1 = "inc"

and you get

<html>
    <head>
        <style>
            div {
                |
            }
        </style>
    </head>
</html>

Other valid options (see https://github.com/vim/vim/issues/3205#issuecomment-474000831) appear to be auto (which aligns it with the start of the <style>, and zero, which is default and provides the output you demonstrated.

Auto-pairs does auto-format, but it isn't a formatter. The bug (or in this case, misconfiguration) is therefore usually elsewhere. Would be great if the formatting options were in a standardised format so it isn't necessary to have individual options for things in different languages, but it is what it is right now.

ei14 commented 6 days ago

Auto-pairs uses = under the hood for formatting.

That feels needlessly complicated. Without the plugin, the motion that one does is: <Enter><c-o>O or <Enter><c-o>O<Tab>. As a result of this plugin, now pressing the enter key invokes some crazy stuff involving formatters.

Can I (user) disable that? Pressing enter after an open bracket should do something as simple as <Enter><c-o>O in many use cases.

ei14 commented 6 days ago

I've found the issue. On line 416 of auto-pairs.vim, the line

        return "\<ESC>".cmd."=ko"

has to be be replaced with

        return "\<ESC>".cmd."ko\t"

for anyone else experiencing this issue. Perhaps someone out there prefers the current behavior, so I suggest a configurable option, e.g. g:AutoPairsFormatCR or something.