0

How do I turn a long one-line list, such as

test_list = ['a0000000', 'b1111111', 'c2222222', 'd3333333', 'e4444444', 'f5555555', 'g6666666']

into a one element per line list:

test_list = ['a0000000',
             'b1111111',
             'c2222222',
             'd3333333',
             'e4444444',
             'f5555555',
             'g6666666']

Or:

test_list = [
    'a0000000',
    'b1111111',
    'c2222222',
    'd3333333',
    'e4444444',
    'f5555555',
    'g6666666',
]

With fill-paragraph long one-line lists are at least broken up into multiline lists:

test_list = ['a0000000', 'b1111111', 'c2222222', 'd3333333',
             'e4444444', 'f5555555', 'g6666666' ]

But I would find a one element per line list in many cases more useful. Is anyone aware of such a elisp function (e.g. in elpy or anywhere else)?

1
  • Black formats it accordig to PEP guidlines. And I found most of the time, it does so with 1 value per line. The other possibility I see, is for you to try out macros. Do it one time with the first element, select the rest and set the cursor correctly for the second one. Then run apply-macro-to-region-lines. You will probably fail the first time, but it's a good way to learn. – Swedgin Nov 25 '20 at 15:01
1

You can always write a function to do what you want and bind it to a key sequence. The following will deal with the vast majority of cases, but it will fail if a list element contains the string ", ". It assumes that your cursor is at the beginning of the line in question (and leaves point unchanged), searches for the string ", " in the line and calls newline after each one (which deals intelligently with the space-to-newline conversion). It then calls indent-region between the original point and the final end-of-line, to reindent everything properly. It will also work on multi-line lists (e.g. the two-line list after M-q) although you will have to call it once on each line:

(defun python-list-break-and-indent ()
  "Convert a single-line list into a block list, indented properly.
   ASSUMPTION: the only occurrences of the string \", \" are between
   list elements."
  (interactive)
  (save-excursion
    (let ((beg (point)))
      (while (search-forward ", " (save-excursion (end-of-line) (point)) t)
        (newline))
      (end-of-line)
      (indent-region beg (point)))))

(define-key python-mode-map (kbd "C-c b") #'python-list-break-and-indent)

I bound the function to C-c b because it was undefined in python-mode-map in my case, but you should check with C-h c C-c b in a python mode buffer and choose something else if it is taken (C-c <letter> keys are supposed to be reserved for users).

4
  • Thanks @NickD nice solution! – Wuff Nov 26 '20 at 14:55
  • I realized that, for example, the ESS mode for R files overrides fill-paragraph with ess-r--fill-paragraph. This works even with commas in the string and at any point in the list. Unfortunately my knowledge of elisp is not good enough to understand what is done there. But anyways, NickD your solution is a good start, which already helps a lot ;) – Wuff Nov 26 '20 at 14:56
  • ess-r--fill-paragraph is a function that's used to advise fill-paragraph: it basically deals with a few R-specific constructs (code comments, call arguments, continuations, roxy blocks - whatever they are) but in all other cases calls the original fill-paragraph function. It's a powerful method to customize a function that does almost what you want, amd make it do exactly what you want. – NickD Nov 26 '20 at 15:07
  • Thanks for pointing out the advice feature! Having a look at the ESS functions didn't bring me very far. Too little knowledge in elisp :/ But thanks for your answer :) – Wuff Nov 26 '20 at 15:47

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.