Skip to content

feat: add smart autocomplete for command execution and path navigation#6

Merged
kooler merged 15 commits intokooler:mainfrom
rguziy:feature/cmdexec-autocomplete
Apr 12, 2026
Merged

feat: add smart autocomplete for command execution and path navigation#6
kooler merged 15 commits intokooler:mainfrom
rguziy:feature/cmdexec-autocomplete

Conversation

@rguziy
Copy link
Copy Markdown

@rguziy rguziy commented Apr 4, 2026

Smart Autocomplete for Command Execution and Path Navigation

Overview

This PR adds intelligent autocomplete functionality to Midday Commander, enhancing the user experience when executing commands and navigating directories through two new dialog modes.

Features

🎯 Command Execution Dialog (Ctrl+R)

  • Smart Autocomplete: Provides suggestions for both executable commands and file paths
  • Multi-line Display: Shows multiple suggestions per line for efficient space usage
  • Tab Completion: Intelligent completion with common prefix expansion
  • Tilde Expansion: Supports ~ expansion to home directory
  • Exec-Only Mode: Toggle with Ctrl+G to show only executable commands

📁 Go to Path Dialog (Ctrl+G)

  • Directory-Only Suggestions: Shows only folders for navigation
  • Compact Display: Multiple directory names per line
  • Tab Completion: Smart path completion with prefix matching
  • Tilde Support: Full home directory expansion
  • Basename Display: Shows folder names instead of full paths for clarity

🎨 User Experience Improvements

  • Consistent Interface: Both dialogs use the same visual style and behavior
  • Real-time Suggestions: Updates as you type
  • Smart Clearing: Suggestions persist during typing, clear only after completion
  • Keyboard Navigation: Full keyboard support with Tab, Enter, and Esc

Technical Implementation

Core Components Modified

  • internal/ui/cmdexec/cmdexec.go: Command execution overlay with autocomplete
  • internal/ui/dialog/dialog.go: Go to path dialog with directory suggestions
  • README.md: Updated documentation and keybindings
  • config.example.toml: Added configuration examples

Key Functions Added

  • completeCandidates(): Unified completion logic for paths and executables
  • formatSuggestions(): Multi-line suggestion formatting
  • expandTilde(): Home directory expansion
  • completeDialogPathCandidates(): Directory-only path completion
  • formatDialogSuggestions(): Compact dialog suggestion display

Code Quality

  • ✅ Formatted with gofmt
  • ✅ Passes go vet checks
  • ✅ No breaking changes
  • ✅ Comprehensive error handling
  • ✅ Consistent naming conventions

Usage Examples

Command Execution (Ctrl+R)

Type: ls /ho<Tab>
Suggestions: home/  Documents/  Downloads/
Result: ls /home/

Path Navigation (Ctrl+G)

Type: Doc<Tab>
Suggestions: Documents/  Downloads/  Desktop/
Result: Documents/

Tilde Expansion

Type: ~/Doc<Tab>
Suggestions: Documents/  Downloads/
Result: ~/Documents/

Configuration

The new keybindings can be customized in config.toml:

[keys]
goto     = "ctrl+g"  # Go to path dialog
cmd_exec = "ctrl+r"  # Execute command dialog

Testing

  • ✅ All existing functionality preserved
  • ✅ New dialogs work independently
  • ✅ Tab completion handles edge cases
  • ✅ Tilde expansion works correctly
  • ✅ Multi-line suggestions display properly
  • ✅ Keyboard navigation functions as expected

Screenshots

Command Execution Dialog

┌─ Execute Command ──────────────────────────────┐
│ cd /home/user/                                 │
├─────────────────────────────────────────────────┤
│ Documents/  Downloads/  Desktop/  Projects/    │
│ Images/      Media/                            │
└─────────────────────────────────────────────────┘

Go to Path Dialog

┌─ Go To ────────────────────────────────────────┐
│ /home/user/                                    │
├─────────────────────────────────────────────────┤
│ Documents/  Downloads/  Desktop/  Projects/    │
│ Images/      Media/                            │
└─────────────────────────────────────────────────┘

Breaking Changes

None. This is a purely additive feature that doesn't change existing behavior.

Ruslan Huzii added 9 commits April 4, 2026 17:21
- Add Ctrl+R command execution dialog with path/command autocomplete
- Add Ctrl+G Go to path dialog with directory-only suggestions
- Implement multi-line compact suggestion display (multiple items per line)
- Add Tab completion with smart prefix matching and common prefix expansion
- Support tilde (~) expansion for home directory paths
- Display suggestion basenames for better readability
- Add exec-only mode toggle in command overlay (Ctrl+G)
- Update documentation and configuration examples
- Format code with gofmt for consistency
Copy link
Copy Markdown
Owner

@kooler kooler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good addition, a couple of improvements points:

  1. The PR adds NewInputWithBase(title, message, defaultValue, tag, basePath string) and refactors NewInput to delegate to it with basePath: "". However, app.go:644 still calls dialog.NewInput(...), so basePath is always "". When completeDialogPathCandidates resolves relative paths, filepath.Join("", ".") gives the process working directory — not the active panel's directory. Autocomplete will show completions relative to wherever mdc was launched from.
  2. code duplication between cmdexec and dialog
  • expandTilde() — identical in both files
  • commonPrefix() — identical in both files
  • formatSuggestions() / formatDialogSuggestions() — same logic, different names
  • completePathCandidates() / completeDialogPathCandidates() — nearly identical (dialog version filters dirs-only)
  • padOrTrim() / truncOrPad() — same logic, different names
    Let's move them to a shared lib.
  1. updateSuggestions() (which calls os.ReadDir) fires on cursor movement keys (left/right/home/end) even though the input text didn't change
  2. PATH scanning (completeExecCandidates) runs on every keystroke with no caching
  3. No bounds checking in completeCurrentWord cursor positioning in internal/ui/cmdexec/cmdexec.go:349-362
m.inputPos = clamp(start+len(common)-(end-m.inputPos), len(m.input))

The expression start+len(common)-(end-m.inputPos) can produce unexpected values when end > m.inputPos (which happens when the cursor is in the middle of a word). The clamp function saves it from going out of bounds, but the cursor may jump to an incorrect position after completion when the cursor isn't at the end of the word.
6. execOnly mode has no visual indicator and no way to toggle off
7. Ctrl+G keybinding conflict: inside the command execution overlay, Ctrl+G is repurposed to toggle "exec-only mode" (m.execOnly = true). But Ctrl+G is already the global keybinding for "Go To path.". Let's perhaps pick another keybinding to avoid a confusion.

@rguziy
Copy link
Copy Markdown
Author

rguziy commented Apr 11, 2026

Review Comment Response

Summary

Implemented the smart autocomplete refactor, fixed command execution overlay behavior, and resolved the config.example.toml merge conflict.

Fixes Applied

  • internal/app/app.go

    • Updated Go To dialog creation to use NewInputWithBase(..., m.activePanel().Path())
    • Ensures Go To path completion resolves relative to the active panel directory
  • Shared logic moved to internal/ui/completion/completion.go

    • ExpandTilde
    • CommonPrefix
    • PadOrTrim
    • FormatSuggestions
    • CurrentWord
    • CompletePathCandidates
    • CompleteExecCandidates
  • Removed duplicate completion helpers from:

    • internal/ui/cmdexec/cmdexec.go
    • internal/ui/dialog/dialog.go

Review Comment Responses

  • updateSuggestions() no longer updates suggestions on cursor-only keys such as left, right, home, and end.
  • CompleteExecCandidates() now caches PATH scanning and rebuilds the cache only when PATH changes.
  • completeCurrentWord() cursor repositioning was corrected to avoid unexpected cursor jumps when the cursor is in the middle of a word.
  • Exec-only mode was moved off Ctrl+G to Ctrl+E to avoid the global Go To path conflict.
  • Exec-only mode now has a visible footer indicator showing ExecOnly or All.
  • config.example.toml merge conflict was resolved cleanly, preserving both dialog-related keys and terminal bindings.

Validation

  • go test ./internal/ui/cmdexec ./internal/ui/completion ./internal/ui/dialog passes.
  • Merge conflict in config.example.toml was resolved and committed.

@rguziy rguziy requested a review from kooler April 11, 2026 15:37
Copy link
Copy Markdown
Owner

@kooler kooler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update, just one small issue left: code duplication persists in dialog.go despite shared completion package. The shared package now provides CompletePathCandidates(prefix, dir, dirsOnly), CommonPrefix, FormatSuggestions, and PadOrTrim. However, dialog.go still contains its own local copies that don't delegate to the shared package.

@rguziy rguziy requested a review from kooler April 12, 2026 06:52
@rguziy
Copy link
Copy Markdown
Author

rguziy commented Apr 12, 2026

Addressed

Copy link
Copy Markdown
Owner

@kooler kooler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks!

@kooler kooler merged commit ff0fbc0 into kooler:main Apr 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants