Summing Columns in Emacs

I recently noticed that I had to do one task in Emacs a fair amount, so I decided to write some code so that I didn’t have to do it manually.

(defun sum-column()
  "Sums a column of numbers starting at point"
  (interactive)
  (save-excursion
    (if (and (not (= (current-column) 0))
	     (re-search-backward "[ \t]" 0 t ))
	(forward-char))
    (let ((retn 0)
	  (old-column (current-column))
	  (old-next-line-add-newlines))
      (setq next-line-add-newlines nil)
      (while (not
	      (looking-at "^[ \t]*$"))
	(move-to-column old-column t)
	(if (and (looking-at "-?[0123456789]+")
		 (eq (current-column) old-column))
		(setq retn (+ retn (string-to-number (current-word)))))
	(next-line)
	(beginning-of-line))
      (next-line)
      (next-line)
      (move-end-of-line 0)
      (inse rt (make-string (- old-column (current-column)) 32))
      (insert (number-to-string retn))
      (setq next-line-add-newlines old-next-line-add-newlines)
      retn)))

This function will sum a column of numbers in a buffer when the point is at the start of them. It will insert the total after the first whitespace-only line, aligned with the rest of the numbers. For example, the following text

10
20
40

Will be replaced with:

10
20
40

70

This works even for columns that are not at the left column of the screen, so

foo 10
bar 20
baz 40

Becomes

foo	10
bar	20
baz	40

	70

If you have multiple columns, you can sum them up individually:

10	20
30	40
50	60

After two calls to sum-column, this becomes:

10	20
30	40
50	60

90	120

Enjoy!

Tags: ,

3 Responses to “Summing Columns in Emacs”

  1. pearl! says:

    Way cool!

  2. (on behalf of) dfan, Reddit says:

    or just use C-x * : (calc-grab-sum-down): “Parse a rectangle as a matrix of numbers and sum its columns.”

  3. Eisen says:

    Handy little function. And opposed to calc, it writes the result into the buffer. Would be nice if it supported floats too. Also, I’m afraid it doesn’t work when there aren’t enough blank lines before the end of the buffer. Unless next-line-add-newlines is non-nil, I guess (haven’t tried).

Leave a Reply