@@ -311,6 +311,9 @@ func FormatFuncSignatureNext(signature, indent string, colLimit,
311311 formatted = collapseMultilineParenReturnListIfFits (
312312 formatted , colLimit , tabStop ,
313313 )
314+ formatted = breakLongTypeArgListsIfNeeded (
315+ formatted , colLimit , tabStop ,
316+ )
314317 needsBlank := hasNewlineOutsideBraces (formatted )
315318
316319 return formatted , needsBlank
@@ -405,6 +408,136 @@ func collapseMultilineParenReturnListIfFits(signature string, colLimit,
405408 return signature
406409}
407410
411+ func breakLongTypeArgListsIfNeeded (signature string , colLimit ,
412+ tabStop int ) string {
413+
414+ for {
415+ lines := strings .Split (signature , "\n " )
416+ changed := false
417+
418+ for i , line := range lines {
419+ if width .VisualLenWithTab (line , tabStop ) <= colLimit {
420+ continue
421+ }
422+
423+ indent := leadingWhitespace (line )
424+ rewritten , ok := breakFirstTypeArgListInLine (
425+ line , indent ,
426+ )
427+ if ! ok {
428+ continue
429+ }
430+
431+ newLines := append ([]string {}, lines [:i ]... )
432+ newLines = append (
433+ newLines , strings .Split (rewritten , "\n " )... ,
434+ )
435+ newLines = append (newLines , lines [i + 1 :]... )
436+
437+ signature = strings .Join (newLines , "\n " )
438+ changed = true
439+ break
440+ }
441+
442+ if ! changed {
443+ return signature
444+ }
445+ }
446+ }
447+
448+ func breakFirstTypeArgListInLine (line , indent string ) (string , bool ) {
449+ b := []byte (line )
450+
451+ for i := 0 ; i < len (b ); {
452+ switch {
453+ case scanner .IsStringStart (b , i ):
454+ i = scanner .ScanString (b , i )
455+
456+ case scanner .IsLineCommentStart (b , i ):
457+ return line , false
458+
459+ case scanner .IsBlockCommentStart (b , i ):
460+ i = scanner .ScanBlockComment (b , i )
461+
462+ case b [i ] == '[' :
463+ if ! isTypeArgListStart (line , i ) {
464+ i ++
465+ continue
466+ }
467+ end := scanner .ScanBalanced (b , i , '[' , ']' )
468+ if end == - 1 {
469+ return line , false
470+ }
471+
472+ content := strings .TrimSpace (line [i + 1 : end ])
473+ parts := filterNonEmptyTrimmed (
474+ scanner .SplitTopLevelAny (content ),
475+ )
476+ if len (parts ) <= 1 {
477+ i ++
478+ continue
479+ }
480+
481+ var out strings.Builder
482+ out .Grow (len (line ) + len (parts )* 4 )
483+ out .WriteString (line [:i + 1 ])
484+ out .WriteByte ('\n' )
485+ contIndent := indent + "\t "
486+ for _ , part := range parts {
487+ out .WriteString (contIndent )
488+ out .WriteString (strings .TrimSpace (part ))
489+ out .WriteString (",\n " )
490+ }
491+ out .WriteString (indent )
492+ out .WriteByte (']' )
493+ out .WriteString (line [end + 1 :])
494+
495+ return out .String (), true
496+
497+ default :
498+ i ++
499+ }
500+ }
501+
502+ return line , false
503+ }
504+
505+ func isTypeArgListStart (line string , idx int ) bool {
506+ if idx <= 0 || idx >= len (line ) || line [idx ] != '[' {
507+ return false
508+ }
509+
510+ j := idx - 1
511+ for j >= 0 && (line [j ] == ' ' || line [j ] == '\t' ) {
512+ j --
513+ }
514+ if j < 0 {
515+ return false
516+ }
517+ if line [j ] == ']' {
518+ return true
519+ }
520+ if line [j ] == '.' {
521+ k := j - 1
522+ for k >= 0 && isIdentChar (line [k ]) {
523+ k --
524+ }
525+
526+ return k != j - 1
527+ }
528+ if ! isIdentChar (line [j ]) {
529+ return false
530+ }
531+
532+ k := j
533+ for k >= 0 && isIdentChar (line [k ]) {
534+ k --
535+ }
536+ ident := line [k + 1 : j + 1 ]
537+
538+ return ident != "map"
539+ }
540+
408541func isFuncLitSignature (signature string ) bool {
409542 trimmed := strings .TrimSpace (signature )
410543 // Signatures passed to the formatter may include non-whitespace
@@ -1558,7 +1691,7 @@ func (f *FuncSigFormatter) findMatchingParen(s string, start int) int {
15581691// splitParams splits parameter list by commas, respecting nested
15591692// parens/brackets.
15601693func (f * FuncSigFormatter ) splitParams (params string ) []string {
1561- return scanner .SplitTopLevel (params )
1694+ return scanner .SplitTopLevelAny (params )
15621695}
15631696
15641697func (f * FuncSigFormatter ) splitFuncParamList (params string ) []string {
0 commit comments