0

I am writing Go code but the error messages do not agree with Emacs' column count.

Go code with a syntax error on line 4. gofmt is showing the error on column 2. In the emacs buffer the cursor is on the error; the column count is 4. There is a label highlighting that these numbers should match.

Is there an off-the-shelf solution for this? I'm wondering about a minor mode or even a few lines for my .emacs file. I've tried searching but haven't found anything. I can't be the only one who has come across this and I'm sure it's not just Go that has this issue.

Background

  • My tab-width is set to 4.
  • My Emacs counts \t (tab) as four columns; go and gofmt counts \t as one column.
  • Emacs starts counting columns from 0; gofmt starts counting from 1. (I can solve this)
  • gofmt, which runs whenever I save a Go file, puts tabs instead of spaces at the start of each line. (I like this standardisation.)
  • I'm running Emacs 24.5. (This is the latest version available on the Long Term Support Linux distribution I'm using.)

The main problem comes from the discrepancy between the tab counts. The secondary issue is the column count in Emacs starting from 0 instead of 1.

0
2

This sounds like an X–Y problem, where someone has a detailed question that we could find an answer for but that seems to be leading them in the wrong direction. Since you haven’t said what you’re really trying to accomplish here, we can only guess.

My guess is that next-error (or other ways of navigating to error locations, such as clicking on them) is taking you to the wrong column, because of the odd way that gofmt reports error locations.

The bad news is that there’s no good way to transform the error locations before you call next-error. The good news is that you can fix this after you invoke next-error.

Emacs identifies errors by using compilation-error-regexp-alist, which is an index into all the available regexes for matching error messages and extracting their line and column numbers. You should use C-h v to pull up the documentation and familiarize yourself with the details, though they’re not directly useful. The regexes don’t provide you with any way to do math on the column number, but it’s useful background information.

If you check the help for next-error, however, you will find that it calls hook functions after it does the main job. The variable next-error-hook holds a list of functions to call right after moving to the error location. If you add a function to this list, you can move to the correct point. Perhaps something like this:

(defun db48x/go-next-error-hook ()
  (let ((col (current-column)))
    (move-beginning-of-line nil)
    (right-char col)))

(add-hook 'next-error-hook #'db48x/go-next-error-hook)

This is pretty simple; it just moves back to the beginning of the line, then moves over the right number of characters, counting tabs as one character.

You can find elsewhere how to add this hook only in buffers that are visiting a go file.

Also, I should point out that this problem is apparently already handled correctly in Emacs 27.1. I don’t know what version it was fixed in, but given the number of new features and bug fixes that have gone in since Emacs 24, I recommend upgrading. Even in the long–term support version of an OS you deserve to have the best possible editor.

Naturally, if this answer doesn’t solve your problem, feel free to amend your question to supply additional information.

2
  • I'm coming back to Emacs after 10 years. I had forgotten about next-error/clicking on errors. The reason for my question was that I was matching up column numbers manually. I am running tests/compiling in a terminal, which also give mismatched column numbers when it reports errors. This has prompted me to learn how to run them from within Emacs. Both next-error and upgrading Emacs are the 'off the shelf' solution I was looking for. Thank you for the additional background too. I've tried to simplify my question to reduce the XY problem aspect.
    – Mehmet
    Mar 15 at 8:52
  • p.s. I tried to up vote your answer but I don't have enough reputation for it show.
    – Mehmet
    Mar 15 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.