Syntax highlighting in emacs

I’m an anachronism: I still use emacs, and I don’t even use syntax highlighting!

Still, I’m presenting at the Haskell Contributors Workshop in a week or so, and having syntax highlighting might help people to read the code I show.

So, can anyone recommend a simple emacs mode for syntax-highlighting in Haskell. Important to me:

  • Does not do any code re-layout. Does not rebind to “mess up all my layout”. Syntax highlighting only.
  • Easy to install (instructions for a stupid person would be very welcome)

Thanks! Maybe the answers will be useful to others too.

Simon

8 Likes

Using haskell-mode should do that for you:

  • If you don’t have an emacs package repository already configured, the instruction in the README should work: setup the package-archive and run M-x package-refresh-contents.
  • Then install the mode with M-x package-install RET haskell-mode.
  • No need to configure anything, after installation the mode should kick-in when opening a Haskell file. Make sure to enable M-x font-lock-mode if the syntax isn’t highlighted.

If something goes wrong, you can remove the package by running M-x package-remove RET haskell-mode TAB.

5 Likes

Note that the mode makes new lines begin with indentation where it makes sense, e.g. after a where clause. You can disable this to get the regular text-mode behavior by setting the following:

(setq haskell-indentation-layout-offset 0)
(setq haskell-indentation-left-offset 0)
(setq haskell-indentation-starter-offset 0)
(setq haskell-indentation-where-post-offset 0)
(setq haskell-indentation-where-pre-offset 0)

The mode should not do code re-layout by default, this just happens when inserting a new line.

5 Likes

I made a 20 line mode for Haskell that I use called h98-mode (it’s not really Haskell 98, but that makes for a short name), that just provides syntax highlighting:

You should just be able to open it and run eval-buffer and then open a .hs file. Alternatively putting it in your load path and putting (require 'h98-mode) in your .emacs also works.

font-lock-mode provides the highlighting, so make sure that’s enabled, as Tristan said above.

8 Likes

Thanks @tristanC.

Installing haskell-mode went fine. But alas there is now a thirty-second lock-up whenever I open a new Haskell file. Since I have many dozens open, that’s not ok. Sadly, I’ll have to uninstall it, unless you know how to fix that.

1 Like

I’ve tried Haskell-mode on a second generation core-i5 from 11 years ago, and the performance was great, but it was using native-comp. If you haven’t already, I suggest you upgrade emacs to a new version that supports native compilation, which would increase the overall performance by a noticeable amount.

1 Like

That’s odd, I wonder if the slowdown is caused by the interactive-haskell-mode. It appears to be enabled by default. So you can try to disable it by running M-x customize-variable RET haskell-mode-hook, and unticking the minor mode and clicking the State button to save your change. Alternatively, you can also disable it by setting this configuration:

(setq haskell-mode-hook '())

Well, I never noticed such slowdown before, so it might be something else. If that doesn’t help, then you should try the h98-mode proposed by @chrisdone.

Hope that helps!

1 Like

Alternatively, you can also disable it by setting this configuration:

(setq haskell-mode-hook '())

I tried putting that in my .emacs file. No change. Still a thirty-second wait.

My guess is that it is not CPU-bound, but rather is searching for a file or something (or lots of such things) that takes a Really Long Time to time out.

If you haven’t already, I suggest you upgrade emacs to a new version that supports native compilation,

I’m on Ubuntu (inside WSL). So I would say “sudo apt update emacs” or something like that?

I’ll be at Zurihac this week, so maybe some savvy person can help me out there. If this affects me, mayt it affects other people.

2 Likes

What does running Emacs via strace (into a log file) show?

# strace -o what_the_heck.txt emacs ... 

https://manpages.ubuntu.com/manpages/impish/man1/strace.1.html

Thanks. Here’s the output of strace.

There seem to be quite quite a few timeouts.

Oddly, though, with strace on, it took a long time to get started, but then opened further .hs files quite quickly. So

  • with strace, it runs quite fast
  • wihout strace it locks up for 30s-1m at a time

While emacs is locked up, it consumes no CPU (as reported by ps). Nor does it respond to kill -9 . The process is then discplayed by ps as but the window is still open.

Bizarre!

Back when I had still used Windows (well, a bit more than a year ago) and WSL 2 I had strange slowdows/hangs with I/O too - sometimes disk I/O sometimes net I/O - and strace often did have the same effect you encountered. And never ever access a mounted Windows partition from inside WSL, this really slows things down.
What worked best for me out of using Emacs or VS Code in WSL or on the Windows host had been using VS Code on Windows and using Code’s remote server via SSH.
Actually using Ubuntu in a Virtualbox VM did work way better than WSL, it had been slower on average, but the performance had been consistent, without strange hangs or pauses.

I’m sorry I couldn’t help, but at least you can rest assured you aren’t alone: Issues · microsoft/WSL · GitHub

Stupid idea, but I am pretty sure there is a native version of emacs for windows, if there it no specific reason to run the WSL one. e.g. See Using Emacs on Windows 10: An Installation Guide, and GNU Emacs download - GNU Project

The odd thing is that this weird slowdown occus only when using haskell-mode. I’ve been using emacs in WSL for years with no problem until I installed haskell-mode. Very strange.

@simonpj, I looked at your strace output and noticed hundreds of faccessat syscalls into “/mnt/c/…”. It seems emacs haskell-mode package is scanning PATH for executables.

I think you’re experiencing this problem [WSL2] Slow completion due to Windows PATH being appended to Linux PATH · Issue #4234 · microsoft/WSL (github.com).

to confirm, run this command: env | grep ‘/mnt/c’

to fix, add below in /etc/wsl.conf

[interop]
appendWindowsPath = false

Restart WSL host (wsl --shutdown from Windows shell)

3 Likes

Wow, thank you @fong. That did indeed fix it. Everyone should know about this WSL setting!

3 Likes