The Cultural Evolution of gofmt
gofmt 的文化演变
Robert Griesemer
Google, Inc.
Robert Griesemer
Google, Inc.
gofmt
in golang.org
repos.go/format
library.GRINDEF (Bill Gosper, 1967) first to measure line length
SOAP (R. Scowen et al, 1969) Simplifies Obscure Algol Programs NEATER2 (Ken Conrow, R. Smith, 1970) PL/1 reformatter, use as (early) error detection tool cb (Unix Version 7, 1979) C program beautifier indent (4.2 BSD, 1983) indent and format C source code etc.
ClangFormat C/C++/Objective-C formatter Uncrustify beautifier for C, C++, C#, ObjectiveC, D, Java, Pawn and VALA etc.
One formatting style to rule them all!
8go/scanner
, go/parser
, and friends.go/ast
) for each .go
file.// Syntax of an if statement. IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] . // An IfStmt node represents an if statement. IfStmt struct { If token.Pos // position of "if" keyword Init Stmt // initialization statement; or nil Cond Expr // condition Body *BlockStmt Else Stmt // else branch; or nil }
case *ast.IfStmt: p.print(token.IF) p.controlClause(false, s.Init, s.Cond, nil) p.block(s.Body, 1) if s.Else != nil { p.print(blank, token.ELSE, blank) switch s.Else.(type) { case *ast.BlockStmt, *ast.IfStmt: p.stmt(s.Else, nextIsRBrace) default: p.print(token.LBRACE, indent, formfeed) p.stmt(s.Else, true) p.print(unindent, formfeed, token.RBRACE) } }
p.print
) accepts a sequence of tokens, including position and white space information.x = a + b x = a + b*c if a+b <= d { if a+b*c <= d {
// A CommentGroup represents a sequence of comments // with no other tokens and no empty lines between. // type CommentGroup struct { List []*Comment // len(List) > 0 }
func f() { func() { /* /* * foo * foo * bar ==> * bar * bal * bal */ */ if ... if ... } }
var ( var ( x, y int = 2, 3 // foo x, y int = 2, 3 // foo z float32 // bar ==> z float32 // bar s string // bal s string // bal ) )
Regular tabs (\t
) advance writing position to fixed tab stops.
Basic idea: Make tab stops elastic.
Proposed by Nick Gravgaard, 2006
nickgravgaard.com/elastic-tabstops/
Implemented by text/tabwriter
package.
\t
) to indicate elastic tab spots.Works well for fixed-width fonts.
Proportional fonts could be handled by an editor supporting elastic tab stops.
21gofmt -r
gofmt -w -r 'a[i:len(x)] -> a[i:]' *.go
gofmt -s
go fix
gofmt
doesn't do my style!
gofmt
is everybody's favorite.
gofmt
is one of the many reasons why people like Go.Formatting has become a non-issue.
26www.dartlang.org/tools/dartfmt/
Automatic source code formatting is becoming a requirement
for any kind of language.
gofmt
is significant selling point for GoWant:
=> Current design makes it extremely hard to manipulate AST
and maintain comments in right places.
Want: