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

Small but infuriating undesired auto-indentation in C++ source files #36148

Closed
tlemo opened this issue Oct 12, 2017 · 30 comments
Closed

Small but infuriating undesired auto-indentation in C++ source files #36148

tlemo opened this issue Oct 12, 2017 · 30 comments
Assignees
Labels
bug Issue identified by VS Code Team member as probable bug c++ C++ support issues editor-autoindent Editor auto indentation issues
Milestone

Comments

@tlemo
Copy link

tlemo commented Oct 12, 2017

  • VSCode Version: Code 1.15.1 (41abd21, 2017-08-16T18:05:38.342Z)
  • OS Version: Windows_NT ia32 10.0.14393
  • Extensions:
Extension Author (truncated) Version
Bookmarks ale 0.16.0
githistory don 0.2.3
xml Dot 1.9.2
cpptools ms- 0.13.1

Steps to Reproduce:

Here's a small snippet, where ^ is the cursor position (not an actual character in the file!)

{
    if(x)
        foo();
}^

If I press ENTER, the closing bracket and the cursor are auto-indented:

{
    if(x)
        foo();
    }
    ^

This is a small but extremely distracting issue in code bases which don't use brackets for single sub-statements.

Btw, "editor.autoIndent" is set to false

Reproduces without extensions: Yes/No - Yes

@vscodebot vscodebot bot added the editor label Oct 12, 2017
@tlemo
Copy link
Author

tlemo commented Oct 12, 2017

Uploading a screenshot too since the bug report comment strips the indentation:

image

@mxschmitt
Copy link
Member

Tried to reproduce the issue like you described above. There is no ability to format the file without the cpptools extension. So there it must be an issue of the extension in my opinion. (When the extension does the formatting + indenting for you)

@tlemo
Copy link
Author

tlemo commented Oct 12, 2017

I was able to reproduce it with --disable-extensions. I also uninstalled the C++ extension and it still reproduces : you do need to save the file with .cpp extension though. So it seems something related to the built-in C++ support.

Also, the problem is not triggered by an explicit format (I didn't use "format document", just typed ENTER with the cursor right after the closing bracket.

@tlemo
Copy link
Author

tlemo commented Oct 12, 2017

One more example which shows how this is completely broken:

image

While it would be nice to revisit the auto-indentation logic (maybe have an option similar to VS indentation rules), I think the most critical part of the fix is to honor editor.autoIndent - if it's set to false just don't auto-indent!

@egamma
Copy link
Member

egamma commented Oct 13, 2017

The langugage configuration rules for c++ are defined in an extension that is bundled with VS Code, so it should repro without any other extensions installed.

Need to investigate while the setting editor.autoIndent is not honered.

//CC @sean-mcmanus

@tlemo
Copy link
Author

tlemo commented Oct 13, 2017

Thanks Erich, you're right: this repros on a bare bone installation.

I think this is a regression, I don't remember having so much trouble with automatic indentation in earlier versions.

@BillyONeal
Copy link
Member

Possible duplicate of #32746

@tlemo
Copy link
Author

tlemo commented Oct 17, 2017

It may be worth splitting this into two separate bugs for tracking purposes:

  1. editor.autoindent = false not being honored
  2. the bizarre auto-indent behavior for C++ illustrated by the examples I included. likely a regression too.

I opened this issue primarily to report the latter.

@alexdima
Copy link
Member

alexdima commented Oct 21, 2017

1. editor.autoIndent = false

I can no longer reproduce after 004d0da (pushed for #36090). The commit will be part of our upcoming Monday Insiders build.

kapture 2017-10-21 at 11 51 03

kapture 2017-10-21 at 11 53 34


2. editor.autoIndent = true

I can reproduce when the cursor is placed before the } bracket:
kapture 2017-10-21 at 11 49 12
kapture 2017-10-21 at 11 55 51


I therefore suggest we keep this issue to track the case of editor.autoIndent = true.

The C++ indentation rules are at https://github.com/Microsoft/vscode/blob/47c8925894fedd4bae7962448f7af7ab5ca2e00b/extensions/cpp/language-configuration.json#L25 . I am not sure if this issue can be tackled simply by tweaking those rules or it needs a code change in our indentation rules logic.

The rules are not simple at all:

	"indentationRules": {
		"increaseIndentPattern": "^.*\\{[^}\"\\']*$|^.*\\([^\\)\"\\']*$|^\\s*(public|private|protected):\\s*$|^\\s*@(public|private|protected)\\s*$|^\\s*\\{\\}$",
		"decreaseIndentPattern": "^\\s*(\\s*/[*].*[*]/\\s*)*\\}|^\\s*(\\s*/[*].*[*]/\\s*)*\\)|^\\s*(public|private|protected):\\s*$|^\\s*@(public|private|protected)\\s*$"
	},

and they could be expanded with two additional properties:

	/**
	 * Describes indentation rules for a language.
	 */
	export interface IndentationRule {
		/**
		 * If a line matches this pattern, then all the lines after it should be unindendented once (until another rule matches).
		 */
		decreaseIndentPattern: RegExp;
		/**
		 * If a line matches this pattern, then all the lines after it should be indented once (until another rule matches).
		 */
		increaseIndentPattern: RegExp;
		/**
		 * If a line matches this pattern, then **only the next line** after it should be indented once.
		 */
		indentNextLinePattern?: RegExp;
		/**
		 * If a line matches this pattern, then its indentation should not be changed and it should not be evaluated against the other rules.
		 */
		unIndentedLinePattern?: RegExp;
	}

@alexdima alexdima added bug Issue identified by VS Code Team member as probable bug editor-autoindent Editor auto indentation issues labels Oct 21, 2017
@alexdima alexdima removed their assignment Oct 21, 2017
@tlemo
Copy link
Author

tlemo commented Oct 23, 2017

Thanks @alexandrudima !

PS. the animated screen shoots are really nice, how did you capture them?

@alexdima
Copy link
Member

@tlemo I captured those on a mac, but for Windows I use LICEcap

@sean-mcmanus
Copy link
Contributor

sean-mcmanus commented Nov 21, 2017

@alexandrudima FYI, the cpptools extension sets the configurationDefaults.[cpp]|[c].editor.autoIndent setting to false in our package.json in order to provide a good default experience for C/C++ users.

@rebornix
Copy link
Member

@sean-mcmanus I've removed c/cpp indentation rules from core then ppl can get a good c/cpp experience with vanilla vscode.

@csholmq
Copy link

csholmq commented Jan 21, 2018

@rebornix This seems almost impossible to fix using regex rules. Would using IntelliSense with direct knowledge of scope be more feasible?

@DaanDeMeyer
Copy link

DaanDeMeyer commented Nov 13, 2018

Not sure if this is the right place to post this, but I'm also having an issue with indentation in C++ source files. I'm not using the VSCode C++ extension so I'm assuming this behaviour is coming from stock VSCode.

When writing a function definition, after writing the opening brace (vscode automatically inserts the closing brace) and pressing Enter, vscode indents the next line and closing brace way too far. I've not found a setting to disable this. Setting autoIndent to false does not change the behaviour.

Example:

Before:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {<cursor-is-here>}

After pressing Enter:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {
                                       <cursor-is-here>
                                     }

Desired:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {
  <cursor-is-here>
}

@sean-mcmanus
Copy link
Contributor

@DaanDeMeyer The issue you are describing repros for other languages like TypeScript as well. It looks like a duplicate of #30872 . But maybe you can upvote it and add your repro details.

@zhangboyang
Copy link

I also have this problem for other languages such as C or JavaScript. I want to control indent increase or decrease by myself. Is there any possible way to override IndentationRule?

@CallumJamieson
Copy link

Hi, I have just started using vscode on ubuntu 16.04. I am having problems disabling Auto Indent. I have tried on V1.31 and also the insider version (V1.32-insider). I use the WhiteSmiths style for coding... I know this is a less common style but it is very frustrating not being able to turn the Auto Indent off. I usually use visual studio (currently 2015); I always switch the editor to the block mode and this is perfect. Is there any possible work around - or am I doing something wrong? Just disabling Auto Indenting and having me control all indenting seems like the best option for now. Is it possible I somehow have an old version?

@naveenk2k
Copy link

Not sure if this is the right place to post this, but I'm also having an issue with indentation in C++ source files. I'm not using the VSCode C++ extension so I'm assuming this behaviour is coming from stock VSCode.

When writing a function definition, after writing the opening brace (vscode automatically inserts the closing brace) and pressing Enter, vscode indents the next line and closing brace way too far. I've not found a setting to disable this. Setting autoIndent to false does not change the behaviour.

Example:

Before:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {<cursor-is-here>}

After pressing Enter:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {
                                       <cursor-is-here>
                                     }

Desired:

void IQuicHttpStream::OnReadComplete(CompletionOnceCallback callback,
                                     int result) {
  <cursor-is-here>
}

@DaanDeMeyer
I know this is years after your post but I was wondering if you ever did manage to fix that issue. If so, how did you go about it?

@sean-mcmanus
Copy link
Contributor

@naveenk2k It looks like it's still an open issue on VS Code: #30872

@naveenk2k
Copy link

@sean-mcmanus I see. Thank you for the quick response.

@ghost
Copy link

ghost commented Jul 31, 2020

same thing when creating a class

@rebornix rebornix added this to the Backlog milestone Nov 11, 2020
@davidben
Copy link

davidben commented Jun 5, 2021

#30872 is closed, but I'm not sure it's the best solution to #36148 (comment). The issue isn't that auto-indent is enabled, but that it goes to the wrong place. With auto-indent off entirely, the cursor ends up in the wrong location most of the time. It's just that, in the cases where auto-indent would be catastrophically wrong, it's now only a few indent levels wrong.

@stoyannk
Copy link
Contributor

The current indent rules make it basically impossible to fix the issue reported by @DaanDeMeyer.
This is particularly problematic for codebases that follow rules that often lead to breaking statements on multiple lines (e.g. Google's style guide).
The main issue is that all the indent rules in src\vs\editor\common\controller\cursorTypeOperations.ts:_enter (and overall in the codebase) only take into account the line where the curly brace starts. Changing this would require a significant refactoring of the indent logic + potentially changing the API. The regex-based rules can't (I think) cover these situations.

The only workaround I can think of is implementing a formatter that fixes this "on typing". I implemented a simple proof of concept here (https://github.com/stoyannk/indent-formatter). The downside is that the formatter might cause unintended "flickering" of the code, as it runs in a different thread after the VSCode internal formatter has already put the cursor and brace in the wrong place.

This item has been in the backlog since late 2020. Are there plans to address it or the formatters are the only way?

@davidben
Copy link

Is the API enough to detect when there's insufficient information? Like if the line where the curly brace starts is known to be incomplete? As a hacky workaround, maybe it could report an indent of zero in those cases? It'd still be wrong, but 0 is usually closer to the correct answer than what vscode currently does, and that'd preserve autoindent for the cases it can detect.

@a-stewart
Copy link
Contributor

Looking at a more extreme / contrived example we need to be able to consider times where we both honour and ignore the existing indentation.

1  if (myArray
2      .filter(x
3          .paramWithLongName)
4      .map(x -> {
5        return x.id == 7;
6      })
7      .findAny()
8      .orElse(false)) {
9    // Do something
10 }

On line 5, we indent 6 (continuation indent + regular indent) whereas on line 9 we only indent 2 (cancelling the continuation indent).

I think it would be tricky to distinguish between lines 4 and 8 using regex alone.

As far as I can see, we would need to not only consider the indent size, but also the reason for the indents so when we close a section, we can undo that part of the indent. We may also need to have some kind of bracket matching in place too.

Here is some very hacky TS I put together to test the idea (no safety checks for incorrect order of closing and not very neat as I just wanted to check all the ways indentation might change.

TS Lang Playground link

I am not sure how much this would effect performance either. The current solution only looks at a single line and uses regex whereas this would require the file to be parsed. Perhaps we could do something with a window of ~1000 lines and then make assumptions if we need to close an indentation which was started longer ago than that?

@kkurkiewicz
Copy link

Please see also #164177.

@aiday-mar aiday-mar assigned aiday-mar and unassigned rebornix Mar 8, 2024
@aiday-mar aiday-mar added the c++ C++ support issues label Mar 15, 2024
@aiday-mar
Copy link
Contributor

I was not able to reproduce the original issue in this thread. The following gif shows the behavior with editor.autoIndent=full:

Screen.Recording.2024-03-28.at.12.09.41.mov

The following gif shows the behavior with editor.autoIndent='none'

Screen.Recording.2024-03-28.at.12.11.32.mov

I have no extensions installed relative to C++. I will therefore close this issue. If you continue seeing issues, please feel free to comment on this issue so I can reopen it.

@davidben
Copy link

@aiday-mar The example in #36148 (comment) still occurs. Or should that be moved now to a separate issue?

@aiday-mar
Copy link
Contributor

Hi @davidben yes thank you for pointing that out. There is similar issue posted here (#178334). You may track that issue in that thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue identified by VS Code Team member as probable bug c++ C++ support issues editor-autoindent Editor auto indentation issues
Projects
None yet
Development

No branches or pull requests