Align function arguments on their own lines Given an input of a string representing a function definition, output the
string with newlines and spaces inserted so that the function's arguments are
newline-separated and aligned.

The input string will follow the following pattern:


First, it will start with a prefix, which is always at least one character
long and does not contain any of the characters ,().
An open parenthesis (() will then mark the beginning of the argument list.
A list of zero or more arguments will then follow. These are separated by the
string ", " (a comma and then a space). None of the arguments will contain
any of the characters ,().
A close parenthesis ()) will mark the end of the argument list.
Lastly, a postfix may be found, which is zero or more characters long and
may contain the characters ,().


The input string will consist solely of printable ASCII (which means it will never contain a newline).

The output must be:


The prefix, copied down verbatim, and the open parenthesis.
The argument list, this time separated not by ", " but by a comma, newline, and as
many spaces as is needed to vertically align the first character of each
argument.
The close paren and postfix (if it exists) verbatim.


Since this is code-golf, the shortest code in bytes will win.

Test cases (format: single-line input followed by output followed by double
newline):

def foo(bar, baz, quux):
def foo(bar,
        baz,
        quux):

int main() {
int main() {

fn f(a: i32, b: f64, c: String) -&gt; (String, Vec&lt;i32&gt;) {
fn f(a: i32,
     b: f64,
     c: String) -&gt; (String, Vec&lt;i32&gt;) {

function g(h) {
function g(h) {

def abc(def, ghi, jkl, mno)
def abc(def,
        ghi,
        jkl,
        mno)

x y z(x, y, z) x, y, z)
x y z(x,
      y,
      z) x, y, z)
Haskell, 115 bytes

import Data.Lists
f x|(a,b:c)&lt;-span(/='(')x,(d,e)&lt;-span(/=')')c=a++b:intercalate(",\n "++(a&gt;&gt;" "))(splitOn", "d)++e


Usage example:

*Main&gt; putStrLn $ f "fn f(a: i32, b: f64, c: String) -&gt; (String, Vec&lt;i32&gt;) {"
fn f(a: i32,
     b: f64,
     c: String) -&gt; (String, Vec&lt;i32&gt;) {


How it works:

bind
  a: everything before the first (
  b: the first (
  c: everything after the first (
  d: everything of c before the first )
  e: everything of c from the first ) to the end

construct the output string by concatenating
  a
  b
  splitting d at the argument separator ", " and rejoining it with ",\n " followed by (length a) spaces    
  e