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.
21
gofmt -rgofmt -w -r 'a[i:len(x)] -> a[i:]' *.go
gofmt -sgo fixgofmt 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: