I was just going to ask how to accomplish this, but through a few DuckDuckGo searches, I was able to answer a lot of my question. I have a buffer of part numbers and part number descriptions each in a single line like this...

123456789 Description1  
234567890 Descripton2

and I want to separate the different part numbers and descriptions by a new line, and also keep the part numbers with their corresponding descriptions together (separate each new part number with a blank line). I created this function which does the job this time anyway.

(defun auto-new-line()
  (move-to-column 0)
  (insert ?\n)        ;; This, along with the previous line moves to column 0 in the first line and inserts a beginning new line to separate the part numbers with their descriptions from the other part number/description combinations.
  (move-to-column 18) ;; In this case the part numbers are 18 characters wide.
  (insert ?\n)

The output of this goes something like.

(there's a tab here not sure how to input that)Description1  


And it keeps going to the end of the file.

Being an Elisp newb, there are a couple of custom things that I would like to add, but I am unsure how.

  1. I would like to add an interactive variable so that the (move-to-column 18) can be customized for different lengths of part numbers.

  2. Also, this is just stopping abruptly when Emacs runs out of file (because it is calling itself recursively) is there another way to have the recursive nature, but end it by itself? Will letting Emacs just run out of file cause any sort of problems?

  3. If anyone else has any suggestions I am open to hearing them.

  • You miss a final () in your function's definition. And it would be good if you posted correct input sample data - part numbers are not 18 chars wide now. Commented Dec 16, 2017 at 23:54

4 Answers 4


This is also a pretty good spot to use a macro. Something like (with point at beginning of a line):

<f3>  ;; kmacro-start-macro-or-insert-counter

M-f   ;; forward-word
C-d   ;; delete-char
RET   ;; newline
C-q   ;; quoted-insert
C-e   ;; end-of-line
RET   ;; newline
C-n   ;; next-line
C-a   ;; beginning-of-line

<f4>  ;; kmacro-end-or-call-macro

You can then do things like C-x C-k n to give the macro a name (to be able to call it like a function), or C-x C-k r to run the macro for all lines in the selected region.


Something like this will do the job:

(defun auto-new-line-mine()

  (setq moreLines t ) ;; whether there are more lines to parse

  (while moreLines
    (move-end-of-line nil)

    (setq moreLines (= 0 (forward-line 1))))

It works with arbitrary column widths and does not use recursion. I took an idea from here: http://ergoemacs.org/emacs/elisp_process_lines.html.

(defun auto-new-line(&optional width)
  (interactive (list (read-number "Description width: ")))
  (goto-char (point-min))
  (while (not (eobp))
    (forward-char width)
    (insert-char ?\n)
    (insert-char ?\t)
    (insert-char ?\n)))

I assume this is some sort of CSV (or Tab separated value)? If so, the column isn't the important thing, the delimiter is. Just do a query replace. You can quote things with C-q.

C-< C-M-% C-q TAB RET C-q C-j RET !

Unpacking that key sequence: C-< is move to the beginning of the buffer, C-M-% is query-replace-regexp, C-q TAB inserts a literal tab character, RET commits the search pattern, C-q C-j inserts a literal newline character, RET commits the replacement string, and ! executes the replacement on all matches.

In an elisp command, you would probably use something like

  (goto-char (point-min))
  (while (search-forward "\t" nil t)
    (replace-match "\n" nil t))))
  • I think he is asking for tabs in his output; they don't exist in the input so this search would fail.
    – 0x5453
    Commented Feb 15, 2018 at 14:08
  • @0x5453 I read it as there are tabs in their output, but they don't know how to put the tabs in stackexchange. I'm totally guessing, but it really looks like a TSV.
    – jpkotta
    Commented Feb 15, 2018 at 17:40

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.