summaryrefslogtreecommitdiff
path: root/internal/repl
AgeCommit message (Collapse)Author
2026-05-25style(repl): use map[string]struct{} for sets instead of map[string]boolPaul Buetow
Idiomatic Go uses struct{} for zero-allocation sets. Two locations: - GetCompletionTopics: seen deduplication map - init(): seenCat category deduplication map
2026-05-25refactor(repl): register 'categories' as HelpTopic with custom RenderPaul Buetow
Add a Render func() string field to HelpTopic that overrides the default formatTopic rendering. Use it to register 'categories' as a normal HelpTopic entry instead of a hardcoded if-branch in GetHelp. - Remove hardcoded if topic == "categories" from GetHelp - Remove hardcoded 'categories' from GetCompletionTopics - Remove dead getCategoriesHelp function from help.go - 'categories' now discovered through normal helpByTopic lookup
2026-05-25refactor(repl): split help.go into data (help_topics.go) and logic (help.go)Paul Buetow
The original help.go was 657 lines mixing data, indexing, and lookup logic. Split into: - help_topics.go (489 lines): HelpTopic struct, helpTopics data slice, index variables, and init() that builds the lookup maps. - help.go (171 lines): GetHelp, GetAllTopics, GetCompletionTopics, getGeneralHelp, getCategoriesHelp, and formatTopic. All tests pass. No behavioral changes.
2026-05-25fix: return readline suffixes instead of full matchesPaul Buetow
Per the readline AutoCompleter docs, Do() should return suffixes (the characters AFTER the common prefix), not full matches. The length parameter indicates how many characters are shared. This fixes the bug where readline appended the full match to the typed input (e.g. 'he' + 'help' = 'hehelp') because commonLen was 0 and readline had no idea what to replace. Now 'he<TAB>' returns suffix 'lp' with commonLen=2, so readline correctly replaces 'he' with 'help'.
2026-05-25fix: don't offer exact-match completions to prevent readline duplicationPaul Buetow
When the typed word already exactly matches a command (e.g. 'help'), return no completions. Readline would append the match, producing 'helphelp'. Partial matches still work normally (e.g. 'he' → 'help').
2026-05-25fix: help <TAB> offers operator topics, not 'help help'Paul Buetow
When user types 'help ' (with trailing space), the completer now offers help topic completions (+, dup, swap, etc.). Just 'help' without a space still completes the command normally. Also skip 'help' itself from GetCompletionTopics to avoid suggesting 'help help'.
2026-05-25fix: exclude 'help' from help topic completionsPaul Buetow
'help <TAB>' was suggesting 'help help'. Skip 'help' itself in GetCompletionTopics so tab completion offers actual topics.
2026-05-25feat: inline help system with per-operator topics and auto-completionPaul Buetow
Replace the old static help text with a data-driven help system that provides one help entry per operator, function, or REPL command, each with category, description, usage, and examples. - help.go: 35+ help topics covering all operators (arithmetic, comparison, stack, hyper, variables, constants, REPL commands) - GetHelp(topic) returns formatted help; GetHelp("") returns overview - help categories lists all topics grouped by category - Aliases supported (e.g. help gt shows help for > operator) - Auto-completion for help topics when typing 'help <TAB>' - REPL entries take priority in helpByTopic (e.g. 'help clear' shows screen clear, not RPN variable clear) - Comprehensive tests for all public functions
2026-05-24fix(rpn): change variadic NewRPN/NewOperations to single optional ↵Paul Buetow
MetricReader (task ok)
2026-05-24fix(repl): add looksLikeRPN guard to prevent swallowing non-RPN input (task 4k)Paul Buetow
2026-05-24repl: remove redundant ToLower on single-token operator lookup (gj)Paul Buetow
All operator registry keys are lowercase, so strings.ToLower(token) was a no-op. Removing the unnecessary lowercasing and the unused op variable, passing the original token directly to IsStandardOperator/IsHyperOperator/EvalOperator.
2026-05-24Add compile-time interface satisfaction checks (xj)Paul Buetow
Add var _ Interface assertions to verify implementations at compile time: - internal/rpn/variables.go: assert *Variables against VariableReader, VariableWriter, VariablePersistence, and VariableStore - internal/repl/handlers.go: assert *BuiltInCommandHandler, *RPNHandler, *PercentageHandler, and *ErrorHandler against CommandHandler (BaseHandler intentionally excluded as it lacks a Handle method and is only meant for embedding) - internal/repl/completer.go: assert *AutoCompleteAdapter against readline.AutoCompleter (adds readline import) Note: internal/rpn/constants.go already had assertions in place.
2026-05-24refactor(repl): extract RPN prefixes to data-driven slice (task uj)Paul Buetow
Replace the hardcoded strings.HasPrefix check for "rpn " and "calc " with a loop over a package-level rpnPrefixes slice. Adding a new prefix now only requires appending to the slice, satisfying the Open/Closed Principle.
2026-05-24refactor(repl): introduce RPNCalculator interface to fix DIP violation (task rj)Paul Buetow
Handlers accessed repl.rpnState.rpnCalc — three levels of concrete types violating DIP and Law of Demeter. Define an RPNCalculator interface capturing only the methods handlers actually need, and expose it via REPL.RpnCalculator() so handlers depend on the interface, not the concrete chain of *rpn.RPN.
2026-05-24refactor(repl): extract evalWithStackRestore helper (task bj)Paul Buetow
Factor out the repeated save-restore-evaluate pattern from RPNHandler.Handle() into a single helper method so the stack is always restored on parse errors, across all call sites.
2026-05-24repl: consolidate single-token handling in RPNHandlerPaul Buetow
Merge three identical single-token blocks (operator, number, symbol) into one block with conditional checks. Eliminates redundant strings.Fields calls and len(fields)==1 checks. The 'rat' command early-return is not redundant — it correctly short-circuits before ExecuteCommand is reached.
2026-05-24fix: restore RPN stack on ParseAndEvaluate error in RPNHandlerPaul Buetow
RPNHandler.Handle silently swallowed ParseAndEvaluate errors on multi-word input, leaving the persistent REPL stack in a corrupted state. evaluate() modifies r.currentStack directly during token processing, so partial evaluation on failure left orphan values. Fix: save the stack before ParseAndEvaluate, restore it on error. Applied to both the bare RPN path and the rpn/calc prefix path. Added tests: - TestRPNHandlerStackNotCorruptedOnError (bare multi-word input) - TestRPNHandlerErrorReturnedNotSwallowed (error propagation) - TestRPNHandlerStackNotCorruptedOnPrefixedError (rpn/calc prefix)
2026-05-24fix(repl): correct misleading comments in completer.goPaul Buetow
- completer() is not used by readline; AutoCompleteAdapter is used instead - AutoCompleteAdapter does not wrap or use the completer() function; it maintains its own commands slice - NewAutoCompleter does not use the completer function
2026-05-24docs: fix inaccurate Start comment in internal/repl/signal.goPaul Buetow
The comment claimed Start blocks until Stop is called, but Start launches a goroutine and returns immediately. Updated the doc comment to accurately describe the non-blocking behavior.
2026-05-24docs(repl): fix inaccurate comments in repl.goPaul Buetow
- NewRPNState: correct 'config directory' to 'state directory' (XDG state, not config) - REPL struct: change 'percentage calculator' to 'calculator' (it's primarily RPN) - NewREPL: clarify that completer parameter is unused and logWriter is only stored - defaultExecutor: remove claim that 'handled commands are added to history' (code does the opposite) - defaultCompleter: remove claim about case-insensitivity and descriptions (not implemented) - RunREPLWithLog: remove claim about logging input/output (logWriter is stored but not used)
2026-05-24docs(internal/repl): fix inaccurate comments in handlers.goPaul Buetow
- Fix Next() doc to show correct 3-value return signature ("", false, nil) instead of (false, nil) - Add missing symbol syntax (:x) to RPNHandler.Handle doc comment
2026-05-24fix(repl): correct misleading comments in commands.goPaul Buetow
- Fix cmdStack doc comment: it redirects to 'rpn show' rather than displaying stack state directly (has no access to RPN state) - Add missing 'rat' and 'stack' to cmdHelp's fallback available commands list
2026-05-23chore: bump go.mod from go 1.25.0 to go 1.26.0Paul Buetow
Update the Go version directive to match the local runtime (go1.26.3). Also includes go mod tidy cleanup and unrelated test improvements.
2026-05-23refactor: reduce GetMetricRegistry() global singleton usage (DIP)Paul Buetow
Dependency Inversion: scope MetricRegistry as a dependency rather than relying on a global singleton. This enables testing with custom registries and decouples code from global mutable state. Changes: - NewRPN(vars, reg...): accepts optional *MetricRegistry parameter. Defaults to GetMetricRegistry() when not provided (backward compatible). - NewOperations(vars, reg...): accepts optional *MetricRegistry parameter. Defaults to GetMetricRegistry() when not provided (backward compatible). - parseNumberWithMetric(token, reg): requires *MetricRegistry parameter instead of calling GetMetricRegistry() internally. - RPN struct stores metricRegistry field, used by rpn_parse.go for metric lookups (@ prefix and parseNumberWithMetric). - Added Operations.MetricRegistry() getter for external access. All existing callers remain backward compatible via variadic defaults. Tests updated to pass GetMetricRegistry() to parseNumberWithMetric.
2026-05-23test: add unit tests for REPL subsystemsPaul Buetow
Add dedicated unit tests for four REPL components that lacked test coverage: - SignalHandler (signal_test.go): 5 tests covering constructor, Stop() without Start, callback execution, goroutine semantics, and single-shot signal handling behavior - TTYChecker (tty_test.go): 5 tests covering EnsureTTY error in non-TTY context, error message content, IsTTY return value, IsTTY/EnsureTTY consistency, and idempotent behavior - HistoryManager (history_test.go): 11 tests covering constructor, Path() with default and custom baseDir, Save/Load roundtrip, maxEntries truncation, non-existent file, empty file/slice, special characters, and file overwrite behavior. Added WithBaseDir() method to enable testing with temp directories. - AutoCompleteAdapter (completer_adapter_test.go): 5 tests covering Do() with empty/whitespace input, exact/partial/no matches, case-insensitive matching, multi-word completion, cursor position, common prefix calculation, and command order preservation
2026-05-23style: run gofmt on all Go source filesPaul Buetow
Fix formatting in 12 files to match gofmt standards. No logical changes.
2026-05-23refactor: replace hardcoded operator whitelist with registry lookups (OCP)Paul Buetow
Add IsStandardOperator/IsHyperOperator forwarding methods on *RPN that delegate to OperatorRegistry. Replace the hardcoded string literal whitelist in RPNHandler.Handle() with dynamic registry lookups. New operators are now automatically recognized without updating handlers.go. Also fixes missing operators in the old whitelist (e.g., comparison operators, assignment operators).
2026-05-23refactor: remove Calculator/RPNCalculator passthrough adapter (KISS)Paul Buetow
Delete internal/repl/calculator.go which defined the Calculator interface and RPNCalculator adapter. Every method delegated directly to *rpn.RPN with zero transformation — unnecessary indirection. RPNState now holds *rpn.RPN directly instead of the Calculator interface. Updated NewRPNState, NewREPL, handleRatCommand, and RPNHandler.Handle() to access *rpn.RPN directly. Removes 71 net lines, zero behavioral changes.
2026-05-22fix(repl): remove unreachable return in ReadlinePrompt.RunPaul Buetow
Task fe: The infinite for loop in Run() can only exit via return (fmt.Errorf on readline error). The trailing 'return nil' was dead code flagged by go vet. Removed.
2026-04-11Multiple code-quality and feature improvementsPaul Buetow
- 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
2026-04-11more on thisPaul Buetow
2026-03-26fix modulePaul Buetow
2026-03-26fix: remove unused variable assignments in test filesPaul Buetow
- internal/repl/repl_test.go: Remove unused state variable assignments - internal/rpn/rpn_test.go: Remove unused result/err variable assignments These changes address golangci-lint 'ineffectual assignment' warnings.
2026-03-26fix: address code quality issues from golangci-lintPaul Buetow
- Fix error handling in test files by explicitly ignoring error returns - Remove trailing punctuation from error message in rpn_parse.go Test file changes: - cli_test.go: Use _ = os.Remove() in Cleanup function - concurrent_test.go: Use _, _ = runRPN() in concurrent goroutines Code change: - rpn_parse.go: Changed error message to end with 'colon' instead of ':'
2026-03-26feat: Add integration tests for variable assignments and fix RPN parser bugsPaul Buetow
2026-03-25rpn: Add unit test for exact user scenario with x =: incremental assignmentPaul Buetow
2026-03-25rpn: Fix incremental assignment with x =: (take value from stack)Paul Buetow
2026-03-25rpn: Add test for incremental assignment with =: operatorPaul Buetow
2026-03-25rpn: Fix := and =: operators semanticsPaul Buetow
2026-03-25rpn: Fix =: operator pop order for REPL modePaul Buetow
2026-03-25code-quality: Various improvements to code quality and thread safetyPaul Buetow
2026-03-25Rename calculator package to percPaul Buetow
Renamed internal/calculator directory to internal/perc, updated package name from 'calculator' to 'perc', and updated all import references.
2026-03-25docs: Add SPDX license headers to all .go source filesPaul Buetow
- Added 'SPDX-License-Identifier: MIT' and 'Copyright (c) 2026 Paul Buetow' headers - Files updated: 24 .go files across cmd/gt/, internal/calculator/, internal/repl/, internal/rpn/ The MIT license from LICENSE file is reflected in all source files.
2026-03-25refactor: Consolidate REPL command descriptions to single sourcePaul Buetow
- Removed duplicate getCommandDescription function from completer.go - Added package-level getCommandDescription in repl.go as single source of truth - Updated defaultGetCommandDescription to delegate to getCommandDescription - Created minimal completer.go that uses getCommandDescription for test compatibility Command descriptions are now defined only once, eliminating duplication between the original completer.go and defaultGetCommandDescription in repl.go. The refactoring maintains: - Backward compatibility (tests still work) - Consistent descriptions across the codebase - Single source of truth for command descriptions
2026-03-25docs: Add comprehensive Go documentation for REPL functionsPaul Buetow
- Enhanced NewREPL documentation with detailed parameter descriptions - Enhanced RunREPL documentation clarifying it's a convenience wrapper - Improved executor documentation explaining backward compatibility and testing usage - Enhanced defaultExecutor documentation with input processing details and panic recovery - Enhanced defaultCompleter documentation with tab-completion behavior details - Enhanced defaultGetCommandDescription documentation with command description details - Improved TTYChecker methods (IsTTY, EnsureTTY) documentation - Improved SignalHandler.Start method documentation All exported and non-exported functions in the REPL package now have comprehensive documentation comments that describe their purpose, parameters, and return values.
2026-03-24test: Improve defaultExecutor and defaultCompleter test coveragePaul Buetow
- Add TestDefaultExecutorCodePaths to test all code paths in defaultExecutor - Improve TestDefaultCompleter to test with multiple input prefixes - Add comprehensive test for unknown commands, built-in commands, and edge cases
2026-03-24refactor: Move RPNState and related declarations to top of repl.goPaul Buetow
- Move RPNState type definition before any functions - Move rpnState and rpnStateOnce variable declarations before any functions - Keep REPL struct and NewREPL constructor at the top (as per Go best practices) - Update getRPNState comment to be more descriptive This change follows Go best practices where constants, global variables, and type definitions should be at the top of the file before functions.
2026-03-24feat: Add RPN mode, rational number support, and improve REPLPaul Buetow
- Add RPN (Reverse Polish Notation) calculator with stack-based operations - Support precise rational number calculations using *big.Rat - Implement chain of responsibility pattern for command handling - Add auto-completion for built-in commands - Add history persistence with configurable max entries - Support standard operators: +, -, *, /, ^, %, lg, log, ln - Support hyper operators: [+], [-], [*], [/], [^], [%], [lg], [log], [ln] - Support stack manipulation: dup, swap, pop, show - Support variable assignments and management - Add rat mode for switching between float64 and rational calculations - Refactor calculator to return Calculation struct with formatting - Add proper version support (v0.3.0) All changes follow Go best practices with comprehensive test coverage.
2026-03-23Add panic recovery to REPL executor for better resiliencePaul Buetow
Added defer-recover mechanism to the executor function to catch unexpected panics. When a panic occurs, a user-friendly error message is displayed and the REPL can continue to function. This improves the robustness of the REPL when handling unexpected errors.
2026-03-23Code quality audit fixes from comprehensive auditPaul Buetow
- Error wrapping improvements across multiple files - Thread-safe singleton initialization using sync.Once - Proper error handling for file close operations - Removed speculative complexity in history management - Fixed operator interface design Audit report: COMPLETE_AUDIT_REPORT.md