dag / vim2hs

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

Strange behavior with 'e' (end) and 'w' (word) #72

Open pjrt opened 10 years ago

pjrt commented 10 years ago

It seems that vim2hs makes e behave like E and w as W (only in *.hs files, of course).

I uninstalled it and it went back to normal, so it is something vim2hs is doing. Is this intended? If so, how can it be disabled?

dag commented 10 years ago

I've noticed it includes dots in word motions but thought it was something I did myself, intentionally, for sake of qualified names. However looking at the source I only ever add ' to iskeyword. It seems the dot gets added by Vim's native syntax file for shell scripts, which vim2hs loads to highlight quasi-quoted shell scripts. That's a bug in Vim because syntax files shouldn't set filetype options, at least IMO.

You can work around it by disabling the support for these quotes:

:let g:haskell_shqq = 0

You probably never used that anyway. :-)

pjrt commented 10 years ago

Well that worked. I also tried to see if it was happening in plain *.sh files and yep, it does.

Hit e and w in a bash file containing Some.Import and it behaves like E and W. Definitely a bug in vim, but why is vim2hs also affected? Does it not differentiate between the quasi-quoted text and the rest of the "haskell" text?

dag commented 10 years ago

So the definition of a "word" in Vim depends on the buffer-local iskeyword option, and the dot is probably included in sh.vim because dots are perfectly valid in shellscript keywords and even common since commands can be scripts with filename extensions. This in itself is not a bug per-se, rather, the bug is that it is set in syntax/sh.vim rather than the more appropriate ftplugin/sh.vim which means that the line of code setting the option is executed when vim2hs does :syntax include to be able to use its syntax definitions embedded in quasi-quotes. Understand that Vim as a scripting language is sort of an anti-Haskell: basically everything is global mutable state. Sure there are buffer-local options, which includes iskeyword, but they are "global" to a buffer and that buffer is shared between Haskell and shellscripts when we use :syn include. That's one reason it's bad practice (to the point I'm calling it a bug) to do anything other than adding syntax definitions in a syntax file. Presumably in this case it's done because iskeyword also affects what \k matches in patterns which is neat as it can make for cleaner patterns (matching on keywords being a common need) but breaks if iskeyword isn't set correctly.

Which in turn implies that it's probably bad to use \k in syntax files, and I think it's used extensively in vim2hs like that, meaning it'd be similarly troublesome to try and embed Haskell syntax in another filetype.

Gah.

pjrt commented 10 years ago

Is there something we can do about it? If not, oh well, I've never used quasi-stuff in Haskell yet anyways.

I'll leave this issue open in case we can do something. If not, feel free to close it.

dag commented 10 years ago

We could work around it on a per-option basis, which assumes we catch all problems and new ones aren't added. Basically

let l:iskeyword = &l:iskeyword
syntax include ...
let &l:iskeyword = l:iskeyword

Makes the Haskeller in me cringe but I think it's fairly standard for Vimscripting.

pjrt commented 10 years ago

It seems this issue is back. Not sure when it happened but now it is doing regardless of which haskel_* variable I set to 0.

Ofenhed commented 8 years ago

It was added by ab6197b5c50c434c5144775e290b54056dff47e8, and can be avoided by adding let g:haskell_rlangqq = 0 to your configuration.