summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-11 22:33:41 +0300
committerPaul Buetow <paul@buetow.org>2026-04-11 22:33:41 +0300
commitf05d957389412125b5b955794b3c5f69fbe965f5 (patch)
tree7fd1adaefaad41819c33d993ac442692e4b6931e /cmd
parentb315ebbcd92e58249c6ed8f04217ef7adcdde5d5 (diff)
Multiple code-quality and feature improvements
- Task 31: Refactor repl tests to remove dependency on package-level singletons - Task 41: Introduce Calculator interface to decouple REPL from RPN engine - Task 61: Implement persistent variable store with Save/Load methods - Task 71: Add stack inspection (peek) command to REPL - Task 81: Expand constants library with additional mathematical constants - Task a1: Add session logging flag (--log) to gt CLI - Task 91: Integrate reverse history search (Ctrl+R) using readline This commit includes: - New: internal/repl/calculator.go - Calculator interface for RPN decoupling - New: internal/repl/completer.go - AutoCompleteAdapter for readline - Modified: internal/repl/repl.go - Uses readline instead of go-prompt - Modified: internal/rpn/variables.go - Added Save/Load for persistent state - Modified: internal/rpn/rpn_state.go - Added Stack() method - Modified: internal/rpn/constants.go - Added more mathematical constants - Modified: internal/repl/commands.go - Added 'stack' command - Modified: internal/repl/completer_test.go - Updated for readline API - Modified: internal/repl/repl_test.go - Updated for Calculator interface - Modified: internal/repl/concurrent_test.go - Updated for Calculator interface - Modified: internal/repl/handlers.go - Updated for Calculator interface - Modified: internal/rpn/variables_test.go - Added Save/Load tests - Modified: internal/rpn/constants_test.go - Added new constant tests - Modified: cmd/gt/main.go - Added --log flag support - Modified: Magefile.go - Symmetrized Install/Uninstall logic - Deleted: internal/repl/prompt.go - Replaced by readline integration - Added: STORY.md - Project history documentation
Diffstat (limited to 'cmd')
-rw-r--r--cmd/gt/main.go48
1 files changed, 45 insertions, 3 deletions
diff --git a/cmd/gt/main.go b/cmd/gt/main.go
index 1ef54ca..e01bcef 100644
--- a/cmd/gt/main.go
+++ b/cmd/gt/main.go
@@ -48,6 +48,7 @@ package main
import (
"fmt"
+ "io"
"os"
"strings"
@@ -65,21 +66,62 @@ func main() {
fmt.Println("Error:", err)
os.Exit(1)
}
- fmt.Println(output)
+ if output != "" {
+ fmt.Println(output)
+ }
+}
+
+// LogWriter wraps io.Writer for use with io.MultiWriter in REPL mode.
+// It provides a log writer that can be passed to the REPL.
+type LogWriter struct {
+ writer io.WriteCloser
+}
+
+// Write writes data to the log file.
+func (lw *LogWriter) Write(p []byte) (n int, err error) {
+ return lw.writer.Write(p)
+}
+
+// Close closes the log file.
+func (lw *LogWriter) Close() error {
+ return lw.writer.Close()
}
// runCommand processes command-line arguments and executes the appropriate action.
//
// It handles:
+// - --log <file>: Append REPL input/output to the specified log file
// - No arguments: Start REPL mode if stdin is a TTY, otherwise read from stdin
// - "version" argument: Return the version string
// - Other arguments: Try RPN parsing first, then fall back to percentage calculation
func runCommand(args []string) (string, error) {
+ // Check for --log flag
+ var logFile string
+ var remainingArgs []string
+
+ for i := 0; i < len(args); i++ {
+ if args[i] == "--log" && i+1 < len(args) {
+ logFile = args[i+1]
+ i++ // Skip the filename argument
+ } else {
+ remainingArgs = append(remainingArgs, args[i])
+ }
+ }
+
+ // Update args to exclude --log flag
+ args = remainingArgs
+
if len(args) < 2 {
// No args provided - check if stdin is a TTY for REPL mode
if isatty.IsTerminal(os.Stdin.Fd()) {
- if err := runREPL(); err != nil {
- return "", err
+ if logFile != "" {
+ if err := repl.RunREPLWithLog(logFile); err != nil {
+ return "", err
+ }
+ } else {
+ if err := runREPL(); err != nil {
+ return "", err
+ }
}
return "", nil
}