antonmedv/walk

Add syntax highlighting

yonas opened this issue · 9 comments

yonas commented

I created this patch to use bat for sytnax highlighting, but the output isn't quite right:

diff --git a/main.go b/main.go
index 0f6ba98..522ed48 100644
--- a/main.go
+++ b/main.go
@@ -4,6 +4,7 @@ import (
        "fmt"
        "io"
        "io/fs"
+       "bytes"
        "math"
        "os"
        "os/exec"
@@ -689,22 +690,32 @@ func (m *model) preview() {
                return
        }
 
-       file, err := os.Open(filePath)
-       defer file.Close()
-       if err != nil {
-               m.previewContent = err.Error()
-               return
-       }
-       content, _ := io.ReadAll(file)
+       cmd := exec.Command("bat", "-pP", filePath)
+       Spawn(cmd)
+
+       var buf bytes.Buffer
+       io.MultiWriter(cmd.Stdout, &buf)
 
        switch {
-       case utf8.Valid(content):
-               m.previewContent = Replace(string(content), "\t", "    ", -1)
+       case utf8.Valid(buf.Bytes()):
+               m.previewContent = Replace(buf.String(), "\t", "    ", -1)
        default:
                m.previewContent = warning.Render("No preview available")
        }
 }
 
+func Spawn(cmd *exec.Cmd) {
+    cmd.Stdout = os.Stdout
+    cmd.Stderr = os.Stderr
+
+    err := cmd.Start()
+    if err != nil {
+        err.Error()
+    }
+
+    defer cmd.Wait()
+}
+
 func (m *model) performPendingDeletions() {
        for _, toDelete := range m.toBeDeleted {
                _ = os.RemoveAll(toDelete.path)

I was planning to add simple highlighting into llama. Integrating preview with bat will be challenging to combine styles.

yonas commented

@antonmedv Thanks. Can you help me figure out why bat's output takes over the entire screen instead of being restrained to the right side of the screen.

I guess this is how our libgloss is working

Played around a bit and found a way to integrate bat as preview. I will also add LLAMA_PREVIEW_COMMAND="cat" so bat won't turn on by default for users who may lack the tool.

yonas commented

@guy-av Awesome! Where can I checkout your code?

Here is the diff (Based on your original patch) so you can patch it specifically with bat.

diff --git a/main.go b/main.go
index 5cc4d2e..721f2e9 100644
--- a/main.go
+++ b/main.go
@@ -1,8 +1,8 @@
 package main
 
 import (
+   "bytes"
    "fmt"
-   "io"
    "io/fs"
    "math"
    "os"
@@ -713,22 +713,35 @@ func (m *model) preview() {
        return
    }
 
-   file, err := os.Open(filePath)
-   defer file.Close()
+   buf, err := runPreviewCmd(filePath)
    if err != nil {
        m.previewContent = err.Error()
        return
    }
-   content, _ := io.ReadAll(file)
 
    switch {
-   case utf8.Valid(content):
-       m.previewContent = Replace(string(content), "\t", "    ", -1)
+   case utf8.Valid(buf.Bytes()):
+       m.previewContent = Replace(string(buf.String()), "\t", "    ", -1)
    default:
        m.previewContent = warning.Render("No preview available")
    }
 }
 
+func runPreviewCmd(filePath string) (*bytes.Buffer, error) {
+   var buf bytes.Buffer
+   cmd := exec.Command("bat", "-pP", "--color=always", filePath)
+   cmd.Stdout = &buf
+
+   err := cmd.Start()
+   if err != nil {
+       return nil, err
+   }
+
+   defer cmd.Wait()
+
+   return &buf, nil
+}
+
 func (m *model) performPendingDeletions() {
    for _, toDelete := range m.toBeDeleted {
        _ = os.RemoveAll(toDelete.path)

Regarding highlighting as a broader subject, @antonmedv what do you think about integrating a highlighting library to manually preview files? Instead of bat it is possible to use zyedidia/highlight. It will offer specific styling (Maybe matching the current purple theme) and will work for everyone regardless of external installed software.

I want to create a simple syntax HL. Only for comments and strings.

@antonmedv Closed as completed - where is the commit that adds this feature?