Skip to content

Commit d242eee

Browse files
authored
feat: logger print command fit in term width (#11)
The default logger will check the terminal width and if the command to be printed is wider than the terminal width, it will be broken up into multiple lines, similar to a shell command represented on multiple lines.
1 parent af01dbf commit d242eee

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Additionally many of the tests can provide some example usage.
2828

2929
### Logging
3030

31-
Cmder logs all commands being run using the specified, using the `Logger` method, logger which implements the [`Logger`](https://github.com/scottames/cmder/blob/master/pkg/log/logger.go#L10-L27) interface.
31+
Cmder logs all commands being run, using the `Logger` method, which implements the [`Logger`](https://github.com/scottames/cmder/blob/master/pkg/log/logger.go#L10-L27) interface:
3232

3333
```golang
3434
type Logger interface {
@@ -43,12 +43,14 @@ type Logger interface {
4343
}
4444
```
4545

46-
By default (if none specified with the `Logger` method) the built-in logger will be used. See Additional `log.Logger*` variables for configuration
46+
By default (if none specified with the `Cmder.Logger()` method) the built-in [logger](pkg/log/logger.go) will be used. See Additional `log.Logger*` variables for configuration
4747
options.
4848

4949
Color is disabled by default, but can be enabled by setting either `MAGEFILE_ENABLE_COLOR` or
5050
`CMDER_ENABLE_COLOR` environment variables to true.
5151

52+
The default logger will check the terminal width and if the command to be printed is wider than the terminal width, it will be broken up into multiple lines, similar to a shell command represented on multiple lines.
53+
5254
## Contributing
5355

5456
See [CONTRIBUTING.md](CONTRIBUTING.md). Contributors should follow the [Go Community Code of Conduct

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ require (
66
github.com/go-test/deep v1.1.0
77
github.com/magefile/mage v1.14.0
88
github.com/stretchr/testify v1.8.2
9+
golang.org/x/term v0.7.0
910
)
1011

1112
require (
1213
github.com/davecgh/go-spew v1.1.1 // indirect
1314
github.com/pmezard/go-difflib v1.0.0 // indirect
15+
golang.org/x/sys v0.7.0 // indirect
1416
gopkg.in/yaml.v3 v3.0.1 // indirect
1517
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
1414
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
1515
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
1616
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
17+
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
18+
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
19+
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
20+
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
1721
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
1822
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1923
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

pkg/log/logger.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import (
44
"fmt"
55
"os"
66
"strconv"
7+
"strings"
78
"time"
9+
10+
"golang.org/x/term"
811
)
912

1013
// Logger is a generic logging interface
@@ -176,12 +179,65 @@ func (l logger) Logf(format string, v ...interface{}) {
176179
fmt.Printf(s+format+timestamp+"\n", v...)
177180
}
178181

182+
// splitArgsToNewLine returns a new string formatted as a shell command as if being executed
183+
// on multiple lines - padding between the [] of the command (slice) to be printed
184+
func splitArgsToNewLine(s string) string {
185+
var result string
186+
187+
const (
188+
bBracket = "["
189+
eBracket = "]"
190+
)
191+
192+
newArgs := []string{}
193+
args := strings.Split(s, " ")
194+
195+
for _, w := range args {
196+
if strings.HasPrefix(w, bBracket) {
197+
w = strings.Replace(w, bBracket, bBracket+"\n\n ", 1)
198+
}
199+
200+
if strings.HasSuffix(w, eBracket) {
201+
i := strings.LastIndex(w, eBracket)
202+
w = w[:i] + strings.Replace(w[i:], eBracket, "\n\n"+eBracket, 1)
203+
}
204+
205+
if strings.Contains(w, eBracket+string(LoggerColor)) {
206+
w = strings.Replace(w, eBracket+string(LoggerColor), "\n\n"+eBracket+string(LoggerColor), 1)
207+
}
208+
209+
if strings.HasPrefix(w, "-") {
210+
newArgs = append(newArgs, "\\\n "+w)
211+
} else {
212+
newArgs = append(newArgs, w)
213+
}
214+
}
215+
216+
result = strings.Join(newArgs, " ")
217+
218+
return result
219+
}
220+
221+
// stringLen returns the length of a given string
222+
func stringLen(s string) int {
223+
return len([]rune(s))
224+
}
225+
179226
// Log implements the Logger interface
180227
func (l logger) Log(v ...interface{}) {
181228
s := l.prependStr()
182229
timestamp := l.timestamp(string(LoggerDarkGrey))
230+
msg := fmt.Sprintf("%v", v...)
231+
232+
termWidth, _, err := term.GetSize(int(os.Stdin.Fd()))
233+
if err == nil {
234+
absLen := stringLen(msg) + stringLen(s) + stringLen(timestamp)
235+
if absLen > termWidth {
236+
msg = splitArgsToNewLine(msg)
237+
}
238+
}
183239

184-
fmt.Printf(s+"%v"+timestamp+"\n", v...)
240+
fmt.Printf(s+"%s"+timestamp+"\n", msg)
185241
}
186242

187243
func (l logger) prependStr() string {

0 commit comments

Comments
 (0)