Unminify a Pythlike String Pyth is perhaps the most successful general-purpose golfing language. Though it is somewhat in decline as a result of newer languages, from 2014 to 2016 Pyth's concise syntax, constant updates, overloading, and (for its era) many builtins made it a favorite for the majority of questions.
Pyth code is often difficult to read. Even the output of the debug mode (transpiled Python) often consists of a long line, sometimes with parentheses nested ten deep. However, correctly formatted Pyth is very readable.
Here's a piece of Pyth code, written by @isaacg in Play the Word Chain.
.MlZfqhMtTeMPT+Lzs.pMyQ

It's much more readable like this.
.M                     Filter by gives-maximal-value of
   l Z                   lambda Z:length(Z) over
   f                     filter by (lambda T:
     q                     equal
       hM t T                head-map tail T
       eM P T                end-map Pop T)
     +L                    Append z to each element in
        z                        
        s .pM y Q            flattened permutations of each subset of Q

For this challenge, we eliminate the kolmogorov-complexity aspect of categorizing Pyth characters and focus on formatting. Instead of being Pyth code, the input will consist of characters in 0123456789M. The digit n represents a function of arity n, and M represents an operator. For example, the above code is represented as 210221M101M102M011M10. Here are the steps to unminify:
Separate the string into tokens.
A token matches [0-9]M*. 0M will not occur in input.
Add trailing 0s.
When there are not enough arguments, Pyth appends as many implicit variables (lambda variables or Qs) to the code as are necessary to fill the arguments of the program; these should be represented by 0s.
Group tokens into lines.
The arity of a token is the value of its digit.

An arity-0 token (i.e. a 0) ends a line.

For an arity-1 token the next token should go on the same line, separated by a space.

For an arity &gt;=2 token, its arguments go on separate lines, in the order they appear in the code, each followed by their own subarguments and so on. Arguments to a token are indented to the end of that token plus one space.


Input
A nonempty string (or char array, array of length-1 strings, etc. as allowed by Standard I/O Methods) consisting of 0123456789M, which will not contain the substring 0M.
Output
The string formatted according to the above rules.
Test cases
210221M101M102M011M10

2
  1 0
  2
    2
      1M 1 0
      1M 1 0
    2M
       0
       1 1M 1 0


123M4M

1 2
    3M
       4M
          0
          0
          0
          0
       0
       0
    0


2MM

2MM
    0
    0


11011100

1 1 0
1 1 1 0
0


9000000

9
  0
  0
  0
  0
  0
  0
  0
  0
  0
Haskell, 192 190 187 bytes



unlines.snd.f
f(n:r)|(m,t)&lt;-span(&gt;'9')r,(s,l)&lt;-n#t=(s,n?((n:m):map((' '&lt;$(n:n:m))++)l))
f e=(e,["0"])
'1'?(a:b:r)=(a++drop(length a)b):r
_?s=s
'0'#s=(s,[])
n#s|(r,l)&lt;-f s=(l++)&lt;$&gt;pred n#r


Try it online!

There has to be a better way to handle the arity-1 case, it currently takes up 45 bytes.

Edits:  


-2 bytes by switching to a different method of handling 1, though the previous method has probably more optimization potential.  
-3 bytes by not converting the character digits to numbers and using pred instead of n-1.




unlines.snd.f
f(n:r)|(m,t)&lt;-span(&gt;'9')r,(s,l)&lt;-read[n]#t,w&lt;-map((' '&lt;$(n:n:m))++)=(s,last$((n:m):w l):[(n:m++' ':h):w t|n&lt;'2',h:t&lt;-[l]])
f e=(e,["0"])
0#s=(s,[])
n#s|(r,l)&lt;-f s=(l++)&lt;$&gt;(n-1)#r


Try it online!