From 56af69f6588fddb4a6334e367c3b5bb865389bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Wed, 6 Nov 2024 17:48:13 +0100 Subject: [PATCH] Add --bat, -b, --list, -t for listing files with syntax highlighting --- v2/help.go | 4 +++- v2/main.go | 32 +++++++++++++++++++------------- v2/quit.go | 27 ++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/v2/help.go b/v2/help.go index 7cd885a7..f3c959b2 100644 --- a/v2/help.go +++ b/v2/help.go @@ -86,7 +86,9 @@ Flags: The default filename is input.txt. Handy for AoC. -o, --ollama Use Ollama and the ` + codeCompletionModel + ` model for tab completion (experimental feature). - -b, --bat Cat the file with bat (useful in connection with -c and -p). + -b, --bat List the given file using bat, if it exists in the PATH. + This can be useful in connection with -c or -p. + -t, --list List the given file using the red/black theme. -v, --version Display the current version. See the man page for more information. diff --git a/v2/main.go b/v2/main.go index f2cbd243..c2aa11ff 100644 --- a/v2/main.go +++ b/v2/main.go @@ -71,6 +71,7 @@ func main() { nanoMode bool ollamaTabCompletion bool batFlag bool + catFlag bool ) pflag.BoolVarP(©Flag, "copy", "c", false, "copy a file into the clipboard and quit") @@ -87,7 +88,8 @@ func main() { pflag.StringVarP(&inputFileWhenRunning, "input-file", "i", "input.txt", "input file when building and running programs") pflag.BoolVarP(&nanoMode, "nano", "a", false, "Nano/Pico mode") pflag.BoolVarP(&ollamaTabCompletion, "ollama", "o", false, "use Ollama for tab completion") - pflag.BoolVarP(&batFlag, "bat", "b", false, "Cat the file with colors instead of editing it") + pflag.BoolVarP(&batFlag, "bat", "b", false, "Cat the file with colors instead of editing it, using bat") + pflag.BoolVarP(&catFlag, "list", "t", false, "List the file with colors instead of editing it") pflag.Parse() @@ -183,10 +185,11 @@ func main() { fmt.Printf("Wrote %d bytes to %s from the clipboard.\n", n, filename) } if batFlag { - // Run bat and quit - if err := quitBat(filename); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - } + // List the file in a colorful way, using bat, and quit + quitBat(filename) + } else if catFlag { + // List the file in a colorful way and quit + quitCat(&FilenameOrData{filename, []byte{}, 0, false}) } return @@ -220,11 +223,13 @@ func main() { fmt.Printf("Copied %d byte%s from %s to the clipboard.\n", n, plural, filename) } if batFlag { - // Run bat and quit - if err := quitBat(filename); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - } + // List the file in a colorful way, using bat, and quit + quitBat(filename) + } else if catFlag { + // List the file in a colorful way and quit + quitCat(&FilenameOrData{filename, []byte{}, 0, false}) } + return } @@ -421,10 +426,11 @@ func main() { } if batFlag { // This should NOT happen if only ORBITON_BAT is set! - // Run bat and quit - if err := quitBat(fnord.filename); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - } + // List the file in a colorful way, using bat, and quit + quitBat(fnord.filename) + } else if catFlag { + // List the file in a colorful way and quit + quitCat(&fnord) } // Initialize the VT100 terminal diff --git a/v2/quit.go b/v2/quit.go index f2373c27..e92990b0 100644 --- a/v2/quit.go +++ b/v2/quit.go @@ -11,6 +11,7 @@ import ( "github.com/xyproto/env/v2" "github.com/xyproto/files" + "github.com/xyproto/syntax" "github.com/xyproto/textoutput" "github.com/xyproto/vt100" ) @@ -84,12 +85,31 @@ func quitExecShellCommand(tty *vt100.TTY, workDir string, shellCommand string) { syscall.Exec(shellExecutable, []string{shellExecutable, "-c", shellCommand}, env.Environ()) } -func quitBat(filename string) error { +// quitCat tries to list the given source code file using syntax.CatBytes, and then exits +func quitCat(fnord *FilenameOrData) { quitMut.Lock() defer quitMut.Unlock() + if fnord.Empty() { + if sourceCodeBytes, err := os.ReadFile(fnord.filename); err == nil { // success + if err := syntax.CatBytes(sourceCodeBytes, tout); err == nil { // success + vt100.ShowCursor(true) + os.Exit(0) + } + } + } else { + if err := syntax.CatBytes(fnord.data, tout); err == nil { // success + vt100.ShowCursor(true) + os.Exit(0) + } + } vt100.ShowCursor(true) - workDir := filepath.Dir(filename) - _ = os.Chdir(workDir) + os.Exit(1) // could not cat the file in a syntax highlighted way +} + +// quitBat tries to list the given source code file using "bat", if "bat" exists in the path, and then exits +func quitBat(filename string) error { + quitMut.Lock() + defer quitMut.Unlock() batCommandLine := env.Str("ORBITON_BAT", "bat") batExecutable := batCommandLine args := []string{batExecutable} @@ -110,6 +130,7 @@ func quitBat(filename string) error { return fmt.Errorf("%q is not available in the PATH", batExecutable) } args = append(args, filename) + vt100.ShowCursor(true) syscall.Exec(batExecutable, args, env.Environ()) return nil // this is never reached }