dag / vim2hs

vim2hs :: Vim -> Haskell
340 stars 47 forks source link

indentation doesn't really work as advertised #44

Open tko opened 11 years ago

tko commented 11 years ago

Opening the bindings.hs test file and reindenting the whole thing I get the following:

main =
                putStrLn $ yell str
                where
                        str = "hello"

yell :: String
-> String
yell s = map toUpper s

data Something
                = Something
                | Other

isLarge :: (Ord a, Num a) => a -> String
isLarge x
| x > 10    = "yep"
| otherwise = "nope"

instance Functor [] where
                fmap :: (a -> b)
                -> f a -> f b
                fmap = map

($) :: (a -> b) -> a -> b
f $ x =  f x

buildLib
:: Verbosity -> PackageDescription -> LocalBuildInfo
-> Library -> ComponentLocalBuildInfo -> IO ()

which is very different from the screenshot, not to mention syntactically broken.

Tested with Vim 7.3 using vim -u vimrc where vimrc is as follows:

set rtp+=~/.vim/bundle/vim2hs
set nocompatible expandtab
filetype plugin indent on

What settings am I and/or documentation missing?

dag commented 11 years ago

You need to set shiftwidth=2 to get indentation similar to the screenshots, but even then it won't be able to handle everything if you try to indent whole blocks. It's optimized for human input, line by line, with manual intervention in certain cases. For example bindings.hs has multi-line type signatures to demonstrate that it highlights those correctly, but the expectation when writing a type signature and hitting Enter is that the following line is not indented more than the type signature.

Haskell is very hard to manipulate without a full parser, the syntax is very liberal with lots of odd edge cases. If you want whole-file reindentation, it might be better to propose it as a feature to the stylish-haskell project and set formatprg=stylish-haskell.

It's probably possible to improve the indentexpr in vim2hs, though. For example we could look at having where automatically dedented using indentkeys and some extra rules in indentexpr.

tko commented 11 years ago

Right, shiftwidth explains the differences between absolute number of spaces in the examples, but not the lack of relative indentation like with where and and |

I was just reindenting the whole file as that largely gives the same results as when typing. I can understand the problems with edge cases but when it comes to normal stuff like where and | one shouldn't have to fight with your editor for valid indentation IMO

Re multiline type signature, couldn't indentexpr notice it's a continuation if starts with -> (or similar logic) and indent accordingly?

dag commented 11 years ago

Re multiline type signature, couldn't indentexpr notice it's a continuation if starts with -> (or similar logic) and indent accordingly?

Sure, we could do that, and it might improve things in this example. However it will never work completely in all cases, for example you can wrap a type signature at any whitespace, not just at arrows.

tko commented 11 years ago

Sure, it's impossible to handle ambiguous cases completely, but in unambiguous (and common?) cases like with -> or | or others which can not be anything but continuations it just seems weird for a computer to not handle such obvious (well, for a human eyes at least) cases as such.

dag commented 11 years ago

I'm not disagreeing. Note that I haven't closed this issue. ;-)

victoredwardocallaghan commented 11 years ago

Hi, could we add perhaps this? https://github.com/vim-scripts/indenthaskell.vim and then improve it? Not sure however I too would like to see this `fixed'. :)

victoredwardocallaghan commented 11 years ago

Ah I just read the above, sorry, maybe formatprg=stylish-haskell is the way to go. I noticed sublime text 2 does this.