Repository: pterm/pterm
Pull request #167 (2021-03-01 15:35:22)

feat(prefixprinter): Add option to show line number of caller
### Description
Adds an option to `PrefixPrinter`, which outputs the line number and filename, where the `PrefixPrinter` is used.

### Scope
> What is affected by this pull request?

- [ ] Bug Fix
- [x] New Feature
- [ ] Documentation
- [ ] Other


### To-Do Checklist
- [x] I tested my changes
- [x] I have commented every method that I created/changed
- [x] I updated the examples to fit with my changes
- [x] I have added tests for my newly created methods



Patch:
diff --git a/_examples/prefix/main.go b/_examples/prefix/main.go
index c176023b..404fabaf 100644
--- a/_examples/prefix/main.go
+++ b/_examples/prefix/main.go
@@ -6,11 +6,12 @@ func main() {
 	// Enable debug messages.
 	pterm.EnableDebugMessages()
 
-	pterm.Debug.Println("Hello, World!")   // Print Debug.
-	pterm.Info.Println("Hello, World!")    // Print Info.
-	pterm.Success.Println("Hello, World!") // Print Success.
-	pterm.Warning.Println("Hello, World!") // Print Warning.
-	pterm.Error.Println("Hello, World!")   // Print Error.
+	pterm.Debug.Println("Hello, World!")                                             // Print Debug.
+	pterm.Info.Println("Hello, World!")                                              // Print Info.
+	pterm.Success.Println("Hello, World!")                                           // Print Success.
+	pterm.Warning.Println("Hello, World!")                                           // Print Warning.
+	pterm.Error.Println("Errors show the file and linenumber inside the terminal!")  // Print Error.
+	pterm.Info.WithShowLineNumber().Println("Other PrefixPrinters can do that too!") // Print Error.
 	// Temporarily set Fatal to false, so that the CI won't crash.
 	pterm.Fatal.WithFatal(false).Println("Hello, World!") // Print Fatal.
 }
diff --git a/prefix_printer.go b/prefix_printer.go
index 594dbd38..c8806da2 100644
--- a/prefix_printer.go
+++ b/prefix_printer.go
@@ -2,6 +2,7 @@ package pterm
 
 import (
 	"fmt"
+	"runtime"
 	"strings"
 
 	"github.com/pterm/pterm/internal"
@@ -47,6 +48,7 @@ var (
 			Style: &ThemeDefault.ErrorPrefixStyle,
 			Text:  " ERROR ",
 		},
+		ShowLineNumber: true,
 	}
 
 	// Fatal returns a PrefixPrinter, which can be used to print text with an "fatal" Prefix.
@@ -83,10 +85,11 @@ var (
 
 // PrefixPrinter is the printer used to print a Prefix.
 type PrefixPrinter struct {
-	Prefix       Prefix
-	Scope        Scope
-	MessageStyle *Style
-	Fatal        bool
+	Prefix         Prefix
+	Scope          Scope
+	MessageStyle   *Style
+	Fatal          bool
+	ShowLineNumber bool
 	// If Debugger is true, the printer will only print if PrintDebugMessages is set to true.
 	// You can change PrintDebugMessages with EnableDebugMessages and DisableDebugMessages, or by setting the variable itself.
 	Debugger bool
@@ -119,6 +122,12 @@ func (p PrefixPrinter) WithFatal(b ...bool) *PrefixPrinter {
 	return &p
 }
 
+// WithShowLineNumber sets if the printer should print the line number from where it's called in a go file.
+func (p PrefixPrinter) WithShowLineNumber(b ...bool) *PrefixPrinter {
+	p.ShowLineNumber = internal.WithBoolean(b)
+	return &p
+}
+
 // WithDebugger returns a new Printer with specific Debugger value.
 // If Debugger is true, the printer will only print if PrintDebugMessages is set to true.
 // You can change PrintDebugMessages with EnableDebugMessages and DisableDebugMessages, or by setting the variable itself.
@@ -166,6 +175,13 @@ func (p *PrefixPrinter) Sprint(a ...interface{}) string {
 		}
 	}
 
+	_, fileName, line, _ := runtime.Caller(3)
+
+	if p.ShowLineNumber {
+		ret += FgGray.Sprint("\n└ " + fmt.Sprintf("(%s:%d)\n", fileName, line))
+		newLine = false
+	}
+
 	if newLine {
 		ret += "\n"
 	}


Test patch:
diff --git a/prefix_printer_test.go b/prefix_printer_test.go
index 1cacf56f..ee442ad3 100644
--- a/prefix_printer_test.go
+++ b/prefix_printer_test.go
@@ -99,6 +99,16 @@ func TestPrefixPrinter_WithFatal(t *testing.T) {
 	}
 }
 
+func TestPrefixPrinter_WithShowLineNumber(t *testing.T) {
+	for _, p := range prefixPrinters {
+		t.Run("", func(t *testing.T) {
+			p2 := p.WithShowLineNumber()
+
+			assert.Equal(t, true, p2.ShowLineNumber)
+		})
+	}
+}
+
 func TestPrefixPrinter_WithMessageStyle(t *testing.T) {
 	for _, p := range prefixPrinters {
 		t.Run("", func(t *testing.T) {