-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindenting_writer.go
More file actions
91 lines (79 loc) · 2.35 KB
/
indenting_writer.go
File metadata and controls
91 lines (79 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
Package formatting is a library of text formatting utilities
*/
package formatting
import (
"fmt"
"io"
"strings"
)
// IndentingWriter is a Writer implementation that inserts variable amounts
// of whitespace at the begginging of a line. This is generally most useful
// for formatting source code.
type IndentingWriter struct {
doIndent, indentRequired bool
currentIndent int
indentStr string
Writer io.Writer
}
// NewIndentingWriter returns an initialised IndentingWriter
func NewIndentingWriter(writer io.Writer) *IndentingWriter {
wr := &IndentingWriter{
doIndent: true,
indentRequired: true,
currentIndent: 0,
indentStr: "\t",
Writer: writer,
}
return wr
}
// SetIndentString specifies the indent to use at the beginning of a line.
// The default value is '\t'
func (w *IndentingWriter) SetIndentString(s string) {
w.indentStr = s
}
// IncrIndent increases the indent amount by 1
func (w *IndentingWriter) IncrIndent() {
w.currentIndent++
}
// DecrIndent decreases the indent amount by 1
func (w *IndentingWriter) DecrIndent() {
if w.currentIndent > 0 {
w.currentIndent--
}
}
func (wr *IndentingWriter) writeIndent() {
for i := 0; i < wr.currentIndent; i++ {
fmt.Fprint(wr.Writer, wr.indentStr)
}
}
// Printf prints formatted text to the Writer, adding indents as needed
func (wr *IndentingWriter) Printf(format string, a ...interface{}) (n int, err error) {
if wr.doIndent && wr.indentRequired {
wr.writeIndent()
}
wr.indentRequired = wr.doIndent && endsInNewline(format)
return fmt.Fprintf(wr.Writer, format, a...)
}
// Print prints text to the writer, adding indents as needed
func (wr *IndentingWriter) Print(a ...interface{}) (n int, err error) {
if wr.doIndent && wr.indentRequired {
wr.writeIndent()
}
wr.indentRequired = false
return fmt.Fprint(wr.Writer, a...)
}
// Println prints text and a newline to the writer, adding indents as needed
func (wr *IndentingWriter) Println(a ...interface{}) (n int, err error) {
if wr.doIndent && wr.indentRequired {
wr.writeIndent()
}
wr.indentRequired = wr.doIndent && true
return fmt.Fprintln(wr.Writer, a...)
}
// endsInNewline checks to see if a string ends in a newline.
func endsInNewline(s string) bool {
trimmed := strings.TrimRight(s, "\t ")
c := trimmed[len(trimmed)-1]
return byte(c) == '\n' || byte(c) == '\r'
}