In CSV files (especially ones with a lot of columns and/or a lot of rows) I find that it's hard to tell which column I'm on. Normally I'd like to know either the column heading, or sometimes the column index (usually I want the index only if there are no headings). I know about csv-align-fields, which helps, but:

  1. The heading names are not visible when you scroll down
  2. Even with two windows displaying the CSV buffer (one scrolled to the top always), it takes mental effort to figure out which column you are on, and it is inconvenient to set up that window configuration for each CSV file you visit.

I can already just create two windows, but that is a bit tedious and does not solve problem 2.

I guess ideally I'd want something like which-function-mode but showing the current CSV heading name and index, AND also have headers always visible at the top of the frame or window by some means?

Short of that, I think this could be solved by some way to apply a saved window configuration to a buffer? Then I could have one very short window at the top of the frame, scrolled to the top so that the headings are visible, and another window at the bottom displaying the same buffer for viewing/editing the bulk of the CSV. Note that all the window configuration tools I've come across save the buffers together with the window configuration, but here I want a particular set of windows & their sizes to be restored and then have both windows display the same buffer.

  • Thanks for asking a really obvious question. I've hacked some lisp below which puts the field number and name into the modeline. It is also possible to put text into the the header line. That might solve the question about keeping the headers visible.
    – Realraptor
    Dec 5, 2017 at 23:52

2 Answers 2


csv-mode is a fairly primitive major mode. So I don't think there's anything like what you want. But it shouldn't be too hard to add a command to use a given line as "header" (in the header-line-format sense).

Hmm... OK a bit harder than I thought because of horizontal scrolling, but not that bad if you plagiarize what SES-mode does. It's now in csv-mode-1.7 under the name csv-header-line.


I think I can solve a part of your problem relating to the modeline:

csv-mode.el (in some versions of emacs-goodies-el) provides a csv-mode.el.

https://github.com/deestan/emacs/blob/8e5825f0937c61fe3e01f10974e7c2d30c178796/emacs-goodies-el/csv-mode.el#L754 is a link to a minor mode called csv-field-index-mode

That mode provides the string "F%d" in the modeline.

The following code over-writes the key function in order to change that format to "F%d:%s" with the name of the column included.

(require 'csv-mode)

(defvar csv-field-index-header-fields-list nil
  "List to hold the text of fields in csv file.")
(make-variable-buffer-local 'csv-field-index-header-fields-list)

(defcustom csv-field-display-names t
  "When true, display both name and field number instead of 
just field number under `csv-field-index-mode'.")

(defun csv-populate-header-fields ()
    (goto-char (point-min))
    (let* ((text (buffer-substring (point) (line-end-position)))
           (fields (split-string text ",")))
      (setq csv-field-index-header-fields-list fields))))
(add-hook 'csv-mode-hook #'csv-populate-header-fields)

;; Stolen from csv-mode.el (GPL) 
(defun csv-field-index ()
  "Construct `csv-field-index-string' to display in mode line. 
Called by `csv-field-index-idle-timer'."
  (if (eq major-mode 'csv-mode)
        (let ((lbp (line-beginning-position)) (field 1))
          (while (re-search-backward csv-separator-regexp lbp 1)
            ;; Move as far as possible, i.e. to beginning of line.

            (setq field (1+ field)))
          (if (csv-not-looking-at-record) (setq field nil))
          (when (not (eq field csv-field-index-old))
            (setq csv-field-index-old field
                  (and field
                         (and csv-field-display-names
                               (nth (1- field)
                         (format "F%d" field))
                         'help-echo csv-mode-line-help-echo)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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