@@ -445,6 +445,76 @@ function! codefmt#GetYAPFFormatter() abort
445445endfunction
446446
447447
448+ " "
449+ " @private
450+ " Formatter: gn
451+ function ! codefmt#GetGnFormatter () abort
452+ let l: url = ' https://www.chromium.org/developers/how-tos/install-depot-tools'
453+ let l: formatter = {
454+ \ ' name' : ' gn' ,
455+ \ ' setup_instructions' : ' install Chromium depot_tools (' . l: url . ' )' }
456+ 457+ function l: formatter .IsAvailable () abort
458+ return executable (s: plugin .Flag (' gn_executable' ))
459+ endfunction
460+ 461+ function l: formatter .AppliesToBuffer () abort
462+ return &filetype is # ' gn'
463+ endfunction
464+ 465+ " "
466+ " Run `gn format` to format the whole file.
467+ "
468+ " We implement Format(), and not FormatRange{,s}(), because gn doesn't
469+ " provide a hook for formatting a range, and all gn files are supposed
470+ " to be fully formatted anyway.
471+ function l: formatter .Format () abort
472+ let l: executable = s: plugin .Flag (' gn_executable' )
473+ let l: cmd = [ l: executable , ' format' , ' --stdin' ]
474+ let l: input = join (getline (1 , line (' $' )), " \n " )
475+ 476+ " gn itself prints errors to stdout, but if the error comes from the
477+ " gn.py wrapper script, it is printed to stderr. Use stdout as the
478+ " error message if stderr is empty.
479+ let l: result = maktaba#syscall#Create (l: cmd ).WithStdin (l: input ).Call (0 )
480+ if ! empty (l: result .stdout)
481+ let l: output = l: result .stdout
482+ else
483+ let l: output = l: result .stderr
484+ endif
485+ 486+ " Other formatters generally catch failure as an exception, but
487+ " v:exception contains stderr in that case, and gn prints errors to
488+ " stdout, so we need to check for a shell error ourselves.
489+ if ! v: shell_error
490+ let l: formatted = split (l: output , " \n " )
491+ call maktaba#buffer#Overwrite (1 , line (' $' ), l: formatted )
492+ else
493+ let l: errors = []
494+ for line in split (l: output , " \n " )
495+ let l: tokens = matchlist (line , ' \C\v^ERROR at :(\d+):(\d+):\s*(.*)' )
496+ if ! empty (l: tokens )
497+ call add (l: errors , {
498+ \ " filename" : @% ,
499+ \ " lnum" : l: tokens [1 ],
500+ \ " col" : l: tokens [2 ],
501+ \ " text" : l: tokens [3 ]})
502+ endif
503+ endfor
504+ 505+ if empty (l: errors )
506+ " Couldn't parse errors; display the whole error message.
507+ call maktaba#error#Shout (' Error formatting file: %s' , l: output )
508+ else
509+ call setqflist (l: errors , ' r' )
510+ cc 1
511+ endif
512+ endif
513+ endfunction
514+ 515+ return l: formatter
516+ endfunction
517+ 448518" "
449519" Checks whether {formatter} is available.
450520" NOTE: If IsAvailable checks are disabled via
0 commit comments