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

Stop indentation after two newlines (or don't indent after module ... where) #52

Open
Tehnix opened this issue Jan 12, 2018 · 14 comments
Open
Labels

Comments

@Tehnix
Copy link

Tehnix commented Jan 12, 2018

Not entirely sure indentation rules are specified in the syntax packages, so just ignore this if that's not the case.

I find that I often wrestle with the automatic indentation, especially after where blocks. For example, pasting in Haskell code, will automatically indent everything after the module ... where in the top, which is not really intended. Take e.g.

module Main where

import Primes

main = putStrLn $ "The 101st prime is " ++ show (primes !! 100)

which becomes (when pasted),

module Main where

  import Primes

  main = putStrLn $ "The 101st prime is " ++ show (primes !! 100)

It would be great if one could either disable the indentation for module ... where specifically, or better yet have the behaviour of resetting indentation after two blank lines in a row.

Is this even possible in VS Code?

@JustusAdam
Copy link
Owner

I am not sure. I am very aware that this happens (it annoys me too) but I am really not sure whether it is possible to change this.
The way that autoindent is done at the moment is that there is a regex for when to trigger the indent which is being set in extension.ts. You can have a look at it and try if you can get the behaviour you want but I suspect it may not be possible or at least pretty difficult.

@Tehnix
Copy link
Author

Tehnix commented Mar 12, 2018

I'm trying to find time for this, but in the meantime, I was trying out PureScript, and it doesn't have the indentation behaviour on where https://github.com/nwolverson/vscode-language-purescript/blob/master/src/extension.ts.

Might be a starting point.

@simonyangme
Copy link

simonyangme commented Mar 20, 2018

It looks like PureScript's implementation doesn't try to detect indentation at all due to the lack of indentationRules?

I've tried addressing with this with a PR (#53) Don't have a good implementation :(

I've personally just removed while from the indentation rules.

@JustusAdam
Copy link
Owner

JustusAdam commented Mar 21, 2018

Yes. @simonyangme is right. Purescript has no automatic indentation at all. I mean theoretically we could add a configuration option that turns the auto-indent on or off ...

Or add one that only turns it off for where it that really is a big issue.

@akhra
Copy link

akhra commented May 25, 2018

I suggest taking a look at the built-in SQL indenter. It auto-indents after parens/brackets, otherwise matches indentation on the previous (only!) line, and pasting after an indented line does not indent the pasted text.

@akhra
Copy link

akhra commented Oct 3, 2018

I had been under the impression that block indentation was required after where, but (at least in GHC 8.x?) that appears not to be the case. This is legal:

foo = bar
  where
  bar = ()

I believe this means that we don't need post-where indentation at all.

@Weizilla
Copy link

I think this might be related since it is happening after two new lines.

I noticed that if I'm on a line below the end of a where block or guard and unindent, hitting enter again will cause it auto indent. I feel like this is bad behavior because if the cursor is at the beginning of a blank line and I start a new line below that, it shouldn't automatically indent.

For example, after I finish the last line and hit enter, the cursor is auto indented as expected:

replicate' :: (Ord n, Num n) => n -> a -> [a]
replicate' n x
    | n <= 0 = [x]
    | otherwise = x : replicate' (n - 1) x
    | <--- cursor

I then backspace to unindent:

    | otherwise = x : replicate' (n - 1) x
| <--- cursor

Then I hit enter to start a new line with the intention of writing a new function. Instead of the cursor remaining at the beginning of the new line, it's now auto indented again:

    | otherwise = x : replicate' (n - 1) x

    | <--- cursor

I feel like it should be at the beginning since that's where the cursor was before you hit enter.

    | otherwise = x : replicate' (n - 1) x

| <--- cursor

@Tehnix
Copy link
Author

Tehnix commented Nov 12, 2018

I'm quite a newb when it comes to regex, but I think we could use decreaseIndentPattern, to say that if the previous line is a newline, then decrease the indent. This would help vastly, because right now, I almost prefer having indentation off.

The relevant line would be at https://github.com/JustusAdam/language-haskell/blob/master/src/extension.ts#L12.

@hajinko
Copy link
Contributor

hajinko commented Jul 8, 2019

I haven't noticed this issue in the Python extension, so I looked at their code to see what they did differently. Rather than using indentationRules, they used onEnterRules here. I fiddled around a little bit with the extension files and it does appear to get rid of the most annoying indentation kinks, such as the issues mentioned in this thread. I don't know if changing it would cause any other issues but I believe it would be a massive quality of life increase - this is the biggest thing causing me pain with Haskell in vscode at the moment.

import * as vscode from 'vscode';

const MATCH_NOTHING_RE = /(?!x)x/;

export function activate(context: vscode.ExtensionContext) {

    vscode.languages.setLanguageConfiguration('haskell', {
        onEnterRules: [
            {
                beforeText: vscode.workspace.getConfiguration('haskell').indentationRules.enabled
                ? /(\bif\b(?!')(.(?!then))*|\b(then|else|m?do|of|let|in|where)\b(?!')|=|->|>>=|>=>|=<<|(^(data)( |\t)+(\w|')+( |\t)*))( |\t)*$/
                : MATCH_NOTHING_RE,
                action: { indentAction: vscode.IndentAction.Indent }
            }
        ],
        wordPattern: /([\w'_][\w'_\d]*)|([0-9]+\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)/
    })  	
}

@JustusAdam
Copy link
Owner

JustusAdam commented Jul 8, 2019

@hajinko thanks for looking into that. Clever idea to spy on Python in this case.

If I understand you correctly, you have already added it to the Haskell extension and it seems to work well?

@JustusAdam JustusAdam reopened this Jul 8, 2019
@hajinko
Copy link
Contributor

hajinko commented Jul 8, 2019

@JustusAdam Yeah, I repackaged the extension with only those few lines changed and it seemed to fix the indentation issues.

@JustusAdam
Copy link
Owner

Would you like to submit a PR?

hajinko added a commit to hajinko/language-haskell that referenced this issue Jul 9, 2019
Replaced "indentationRules" with "onEnterRules" to only trigger indention in the very next line.
@hajinko
Copy link
Contributor

hajinko commented Jul 9, 2019

Yeah, I'll try. I'm not very familiar with github at the moment so if I make a mistake somewhere I apologize in advance.

JustusAdam added a commit that referenced this issue Dec 2, 2019
Fixes indentation after two lines #52
@sheaf sheaf added the actions label May 1, 2020
@elldritch
Copy link

This issue is still occurring for me. I've verified that I'm on 3.0.3, and that disabling language-haskell causes this behaviour to go away (so I'm pretty sure it's coming from this extension). Are there other possible sources of indentation?

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

No branches or pull requests

8 participants