7

I want to sort the following based on their keys

case IndexError:
    PyErr_SetString(PyExc_IndexError, exc.str.c_str());
    break;
case ValueError:
    PyErr_SetString(PyExc_ValueError, exc.str.c_str());
    break;
case RuntimeError:
    PyErr_SetString(PyExc_RuntimeError, exc.str.c_str());
    break;
case IOError:
    PyErr_SetString(PyExc_IOError, exc.str.c_str());
    break;

so it becomes

case IOError:
    PyErr_SetString(PyExc_IOError, exc.str.c_str());
    break;
case IndexError:
    PyErr_SetString(PyExc_IndexError, exc.str.c_str());
    break;
case RuntimeError:
    PyErr_SetString(PyExc_RuntimeError, exc.str.c_str());
    break;
case ValueError:
    PyErr_SetString(PyExc_ValueError, exc.str.c_str());
    break;

Essentially, I am only sorting the lines

case IOError:
case IndexError:
case RuntimeError:
case ValueError:

The contents of the other lines (the ones that do not begin with a case) do not matter but I want them to be sorted with the cases.

  • 1
    A side solution could be that, since the contents of the cases are similar, you could regenerate the whole thing. Get the sorted *Errors (from an enum? Maybe run through sort(1)?), then make a macro that converts XError to case XError: PyErr_SetString(PyExc_XError, exc.str.c_str()); break; and run it for all the enum values. – Shahbaz Jul 1 '16 at 23:43
  • I haven't used this myself but vis.vim claims to do it. (Read section 4 at the link.) You can download vis.vim here. – Dan J. Jul 2 '16 at 1:47
7

The easy way: join the lines in the logical blocks before sorting.

In detail:

  • mark the lines
  • join the indented lines to the lines above: :'<,'>s/\n /^A/
  • mark the lines again: gv
  • sort them: :'<,'>sort
  • mark the lines one more time: gv
  • split the lines back and restore indentation: :'<,'>s/^A/\r /g

^A above is the character Ctrl-A (ASCII SOH). It could be any character that doesn't appear in the lines to be sorted, but Ctrl-A fits the bill. You can enter it as Ctrl-vCtrl-a.

2

Idea: Let's join the n number of lines under case to a single line. Follow the process for all cases. Then, use sort to sort the cases. Then, cut those lines back and indent them.

Steps:

1) Join n lines following case by typing this. (in your case, n is 3)

:g/case / normal! 3gJ

2) Select all such cases using visual mode. Press v ot V to select all cases. Press :. It will appear like :'<,'>. Type sort.

:'<,'>sort

3) Put the lines of case under it. Select them again by pressing gv.

:'<,'>s/\(;\|:\)    /&\r    /g

This splits the case lines. If lines arent indented properly, you can align them by selecting gv and then ==.

This works for any number of lines, provided that you use the steps customised for your purpose.

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.