shithub: hell

Download patch

ref: 4a7a258c3973ea05fdbc340150b780c4155c02a9
parent: 5bb44c5f5c1bff3a930f8919f3a72c5d13c1f960
author: penny <penny@limitedideas.org>
date: Sat Aug 9 15:36:33 EDT 2025

Add a pause command and refactor a little to support it

--- a/commands.go
+++ b/commands.go
@@ -4,7 +4,7 @@
 	"strings"
 )
 
-var commands = []string{"examine", "reply", "like", "thread", "open", "preview", "download", "dm", "rt", "parent", "children", "rm", "mark", "unmark", "account", "vim", "import"}
+var commands = []string{"examine", "reply", "like", "thread", "open", "preview", "download", "dm", "rt", "parent", "children", "rm", "mark", "unmark", "account", "vim", "import", "pause", "resume"}
 
 func processInput(input string) (command string, arguments string) {
 
--- /dev/null
+++ b/hellclient.go
@@ -1,0 +1,30 @@
+package main
+
+import (
+	"github.com/chzyer/readline"
+	"strings"
+)
+
+type Hellclient struct {
+	isPaused bool
+	rl       *readline.Instance
+}
+
+func NewHellclient() (*Hellclient, error) {
+	rl, err := readline.New("> ")
+	if err != nil {
+		return nil, err
+	}
+	return &Hellclient{rl: rl}, nil
+}
+
+func (hc *Hellclient) updatePrompt() {
+	var sb strings.Builder
+	if hc.isPaused {
+		sb.WriteString("STREAMING PAUSED ")
+	}
+	sb.WriteString("> ")
+	hc.rl.SetPrompt(sb.String())
+}
+
+
--- a/main.go
+++ b/main.go
@@ -8,7 +8,6 @@
 	"os/exec"
 	"strings"
 
-	"github.com/chzyer/readline"
 	"github.com/mattn/go-mastodon"
 )
 
@@ -21,7 +20,12 @@
 
 	client := initClient(account)
 
-	rl, _ := readline.New("> ")
+	hc, err := NewHellclient()
+	rl := hc.rl
+	if err != nil {
+		fmt.Printf("Error creating client: %v\n", err)
+		return
+	}
 
 	//Horrible io pipe hack
 	//Replaces system stdout with the readline one
@@ -44,7 +48,8 @@
 		return
 	}
 
-	go StreamHomeTimeline(client, rl, homeMap)
+	pauseChan := make(chan bool)
+	go StreamHomeTimeline(client, homeMap, pauseChan)
 
 	for {
 		line, err := rl.Readline()
@@ -70,6 +75,16 @@
 
 		//Contextual commands that need to handle their own requirements
 		switch command {
+		case "pause":
+			hc.isPaused = true
+			hc.updatePrompt()
+			pauseChan <- true
+			continue
+		case "resume":
+			hc.isPaused = false
+			hc.updatePrompt()
+			pauseChan <- false
+			continue
 		case "rm":
 			if !postOK && recentpost != nil {
 				err = client.DeleteStatus(context.Background(), recentpost.ID)
--- a/mastodon.go
+++ b/mastodon.go
@@ -8,7 +8,6 @@
 	"net/url"
 	"strings"
 
-	"github.com/chzyer/readline"
 	"github.com/k3a/html2text"
 	"github.com/mattn/go-mastodon"
 	"golang.org/x/net/html"
@@ -229,7 +228,7 @@
 	return
 }
 
-func StreamHomeTimeline(client *mastodon.Client, rl *readline.Instance, postMap map[string]*mastodon.Status) {
+func StreamHomeTimeline(client *mastodon.Client, postMap map[string]*mastodon.Status, pauseChan <-chan bool) {
 
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
@@ -244,11 +243,27 @@
 	postref := "a"
 	plaintext := ""
 	idmap := make(map[mastodon.ID]*mastodon.Status)
+	isPaused := false
+	var actionBuffer []func()
 
 	// Enter a loop to continuously listen for events from the event channel.
 	for {
 		select {
+		case newPauseState := <-pauseChan:
+			if newPauseState == isPaused {
+				continue
+			}
+			isPaused = newPauseState
+
+			if !isPaused {
+				fmt.Println("Output resumed")
+				for _, action := range actionBuffer {
+					action()
+				}
+			actionBuffer = nil
+			}
 		case event, ok := <-eventCh: // Read from the event channel, checking 'ok' for closure
+
 			if !ok {
 				// The channel was closed, which indicates the stream has ended.
 				fmt.Println("Stream closed.\n")
@@ -257,14 +272,30 @@
 
 			switch post := event.(type) {
 			case *mastodon.UpdateEvent:
-				post.Status = printPost(postref, post.Status)
+				if isPaused {
+					currentPostRef := postref
+					capturedPost := post
+					actionBuffer = append(actionBuffer, func() {
+						capturedPost.Status = printPost(currentPostRef, capturedPost.Status)
+					})
+				} else {
+					post.Status = printPost(postref, post.Status)
+				}
 				saveRef(postMap, post.Status, postref)
 				idmap[post.Status.ID] = post.Status
 				postref = IncrementString(postref)
 
 			case *mastodon.UpdateEditEvent:
+				if isPaused {
+					currentPostRef := postref
+					capturedPost := post
+					actionBuffer = append(actionBuffer, func() {
+						fmt.Println(formatEdit(capturedPost.Status, currentPostRef))
+					})
+				} else {
+					fmt.Println(formatEdit(post.Status, postref))
+				}
 				saveRef(postMap, post.Status, postref)
-				fmt.Println(formatEdit(post.Status, postref))
 				postref = IncrementString(postref)
 				idmap[post.Status.ID] = post.Status
 
@@ -272,27 +303,60 @@
 				deleted, ok := idmap[post.ID]
 				//didn't have this in the cache
 				if !ok {
-					fmt.Printf("Deleted: ID %v\n", post.ID)
+					capturedID := post.ID
+					if isPaused {
+						actionBuffer = append(actionBuffer, func() {
+							fmt.Printf("Deleted: ID %v\n", capturedID)
+						})
+					} else {
+						fmt.Printf("Deleted: ID %v\n", capturedID)
+					}
 					continue
 				}
-				printPostDetailed("", deleted, "Deleted:")
+				if isPaused {
+					actionBuffer = append(actionBuffer, func() {
+						printPostDetailed("", deleted, "Deleted:")
+					})
+				} else {
+					printPostDetailed("", deleted, "Deleted:")
+				}
 				continue
 
 			case *mastodon.NotificationEvent:
 				if post.Notification.Status == nil {
 					notification := fmt.Sprintf("Notification [%v] from <%v>\n", post.Notification.Type, post.Notification.Account.Acct)
-					fmt.Printf(hyphenate(notification))
+					if isPaused {
+						actionBuffer = append(actionBuffer, func() {
+							fmt.Printf(hyphenate(notification))
+						})
+					} else {
+						fmt.Printf(hyphenate(notification))
+					}
 					continue
 				}
 				_, plaintext = RenderPostPlaintext(post.Notification.Status, postref, "")
 				notification := fmt.Sprintf("Notification [%v] from <%v>: %v\n", post.Notification.Type, post.Notification.Account.Acct, plaintext)
-				fmt.Printf(hyphenate(notification))
+				if isPaused {
+					actionBuffer = append(actionBuffer, func() {
+						fmt.Printf(hyphenate(notification))
+					})
+				} else {
+					fmt.Printf(hyphenate(notification))
+				}
 				saveRef(postMap, post.Notification.Status, postref)
 				postref = IncrementString(postref)
 			default:
 				// Catch any other unexpected event types.
-				fmt.Printf("Unhandled event: %T\n", post)
+				unhandledEvent := event
+				if isPaused {
+					actionBuffer = append(actionBuffer, func() {
+						fmt.Printf("Unhandled event: %T\n", unhandledEvent)
+					})
+				} else {
+					fmt.Printf("Unhandled event: %T\n", unhandledEvent)
+				}
 			}
 		}
 	}
 }
+
--