summaryrefslogtreecommitdiff
path: root/internal/repl/repl.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-20 22:53:55 +0200
committerPaul Buetow <paul@buetow.org>2026-03-20 22:53:55 +0200
commita90f7eb6a1c538972eaf52898dd65fa76f26b1d3 (patch)
tree19ea5311a7f31e65bebfae198c297c2858e58b04 /internal/repl/repl.go
parent53777ee18c94b0267a327e48f65e2977e08aaf70 (diff)
internal/repl: Reorder functions per Go best practices
- Moved public RunREPL function before private functions - Constructor-like getRPNState immediately follows type definition - This aligns with project Go best practices for file organization
Diffstat (limited to 'internal/repl/repl.go')
-rw-r--r--internal/repl/repl.go80
1 files changed, 40 insertions, 40 deletions
diff --git a/internal/repl/repl.go b/internal/repl/repl.go
index 3e2d4c9..0234e49 100644
--- a/internal/repl/repl.go
+++ b/internal/repl/repl.go
@@ -24,9 +24,9 @@ type RPNState struct {
rpnCalc *rpn.RPN
}
+// getRPNState returns or creates the RPN state
var rpnState *RPNState
-// getRPNState returns or creates the RPN state
func getRPNState() *RPNState {
if rpnState == nil {
vars := rpn.NewVariables()
@@ -38,6 +38,45 @@ func getRPNState() *RPNState {
return rpnState
}
+// RunREPL starts the interactive REPL
+func RunREPL() error {
+ // Check if stdin is a TTY
+ if !isatty.IsTerminal(os.Stdin.Fd()) {
+ fmt.Fprintln(os.Stderr, "REPL mode requires a TTY. Use 'perc <calculation>' for non-interactive mode.")
+ return fmt.Errorf("stdin is not a TTY")
+ }
+
+ history := loadHistory()
+
+ p := prompt.New(
+ executor,
+ completer,
+ prompt.OptionTitle("perc - Percentage Calculator"),
+ prompt.OptionPrefix("perc> "),
+ prompt.OptionLivePrefix(func() (string, bool) {
+ return "perc> ", true
+ }),
+ prompt.OptionHistory(history),
+ )
+
+ // Handle SIGINT gracefully
+ sigChan := make(chan os.Signal, 1)
+ signal.Notify(sigChan, syscall.SIGINT)
+
+ go func() {
+ <-sigChan
+ fmt.Println("\nUse 'quit' or 'exit' to exit, or Ctrl+D")
+ }()
+
+ // Run the prompt
+ p.Run()
+
+ // Note: History is not saved automatically in this version
+ // The prompt library stores it in memory but doesn't expose a getter
+
+ return nil
+}
+
// executor runs a calculation command and returns the result
func executor(input string) {
input = strings.TrimSpace(input)
@@ -186,45 +225,6 @@ func saveHistory(history []string) error {
return writer.Flush()
}
-// RunREPL starts the interactive REPL
-func RunREPL() error {
- // Check if stdin is a TTY
- if !isatty.IsTerminal(os.Stdin.Fd()) {
- fmt.Fprintln(os.Stderr, "REPL mode requires a TTY. Use 'perc <calculation>' for non-interactive mode.")
- return fmt.Errorf("stdin is not a TTY")
- }
-
- history := loadHistory()
-
- p := prompt.New(
- executor,
- completer,
- prompt.OptionTitle("perc - Percentage Calculator"),
- prompt.OptionPrefix("perc> "),
- prompt.OptionLivePrefix(func() (string, bool) {
- return "perc> ", true
- }),
- prompt.OptionHistory(history),
- )
-
- // Handle SIGINT gracefully
- sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, syscall.SIGINT)
-
- go func() {
- <-sigChan
- fmt.Println("\nUse 'quit' or 'exit' to exit, or Ctrl+D")
- }()
-
- // Run the prompt
- p.Run()
-
- // Note: History is not saved automatically in this version
- // The prompt library stores it in memory but doesn't expose a getter
-
- return nil
-}
-
// completer provides auto-completion for built-in commands
func completer(d prompt.Document) []prompt.Suggest {
text := d.GetWordBeforeCursor()