feat(config): add some more config options (#64)
## Add Make these things configurable - Expand aliases - Suggest hidden files (#59) - Toggle menu and mode ``` [ui] hidden-files = true # or false [core] expand-alias = true # or false [keybindings] toggle-mode = "ctrl+r" toggle-menu = "ctrl+space" ``` - Auto reload config on changes: now just changes config and save the file, IRIS will auto detect and reload in silent - Added all these in config on init and docs ## Fix I tested on holding backspace and the ghost text keep glitching so I fixed it, this is just a small fix
This commit is contained in:
@@ -107,14 +107,20 @@ version = 1
|
||||
shell = "" # "zsh", "bash", "fish", or empty for auto-detection
|
||||
mode = "last" # "last", "spec", or "history"
|
||||
debug = false
|
||||
expand-alias = true
|
||||
|
||||
[ui]
|
||||
style = "modern" # "modern" or "classic"
|
||||
ghost-text = true
|
||||
hidden-files = false
|
||||
max-suggestions = 100
|
||||
max-height = 15
|
||||
nerd-fonts = true
|
||||
|
||||
[keybindings]
|
||||
toggle-mode = "ctrl+r"
|
||||
toggle-menu = "ctrl+space"
|
||||
|
||||
[git]
|
||||
filter-active-branch = true
|
||||
deduplicate-branches = true
|
||||
|
||||
+19
-1
@@ -434,6 +434,24 @@ func (o *Overlay) GetGhostText(buffer string, cursorAtEnd bool) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (o *Overlay) ClearGhostTextState() {
|
||||
o.mu.Lock()
|
||||
defer o.mu.Unlock()
|
||||
o.LastGhostLen = 0
|
||||
}
|
||||
|
||||
func (o *Overlay) HideGhostTextSync() string {
|
||||
o.mu.Lock()
|
||||
defer o.mu.Unlock()
|
||||
if o.LastGhostLen > 0 {
|
||||
padLen := o.LastGhostLen + 4
|
||||
res := "\0337" + strings.Repeat(" ", padLen) + "\0338"
|
||||
o.LastGhostLen = 0
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (o *Overlay) RenderGhostText(buffer string, userNavigated bool, cursorAtEnd bool) string {
|
||||
o.mu.Lock()
|
||||
defer o.mu.Unlock()
|
||||
@@ -757,7 +775,7 @@ func (o *Overlay) draw() string {
|
||||
if !isClassic {
|
||||
keyStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#a277ff")).Bold(true)
|
||||
tabKey := keyStyle.Render("<Tab>")
|
||||
ctrlRKey := keyStyle.Render("<Ctrl+R>")
|
||||
ctrlRKey := keyStyle.Render(config.FormatKeyName(config.Get().Keybindings.ToggleMode))
|
||||
acceptText := lipgloss.NewStyle().Foreground(t.ScrollInfo).Render(" Accept")
|
||||
modeText := lipgloss.NewStyle().Foreground(t.ScrollInfo).Render(" Mode")
|
||||
footerInfo = fmt.Sprintf(" %s%s • %s%s ", tabKey, acceptText, ctrlRKey, modeText)
|
||||
|
||||
+59
-19
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
@@ -32,18 +33,20 @@ func (d Duration) MarshalText() ([]byte, error) {
|
||||
}
|
||||
|
||||
type CoreConfig struct {
|
||||
Version int `toml:"version"`
|
||||
Shell string `toml:"shell"`
|
||||
Mode string `toml:"mode"`
|
||||
Debug bool `toml:"debug"`
|
||||
Version int `toml:"version"`
|
||||
Shell string `toml:"shell"`
|
||||
Mode string `toml:"mode"`
|
||||
Debug bool `toml:"debug"`
|
||||
ExpandAlias bool `toml:"expand-alias"`
|
||||
}
|
||||
|
||||
type UIConfig struct {
|
||||
Style string `toml:"style"`
|
||||
GhostText bool `toml:"ghost-text"`
|
||||
MaxSuggestions int `toml:"max-suggestions"`
|
||||
MaxHeight int `toml:"max-height"`
|
||||
NerdFonts bool `toml:"nerd-fonts"`
|
||||
Style string `toml:"style"`
|
||||
GhostText bool `toml:"ghost-text"`
|
||||
ShowHiddenFiles bool `toml:"hidden-files"`
|
||||
MaxSuggestions int `toml:"max-suggestions"`
|
||||
MaxHeight int `toml:"max-height"`
|
||||
NerdFonts bool `toml:"nerd-fonts"`
|
||||
}
|
||||
|
||||
type GitConfig struct {
|
||||
@@ -57,6 +60,11 @@ type UpdaterConfig struct {
|
||||
CheckInterval Duration `toml:"check-interval"`
|
||||
}
|
||||
|
||||
type KeybindingsConfig struct {
|
||||
ToggleMode string `toml:"toggle-mode"`
|
||||
ToggleMenu string `toml:"toggle-menu"`
|
||||
}
|
||||
|
||||
type SuggestOnEmptyConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
DebounceMS int `toml:"debounce_ms"`
|
||||
@@ -101,32 +109,64 @@ func (p *ProviderConfig) GetAPIKey() string {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Core CoreConfig `toml:"core"`
|
||||
UI UIConfig `toml:"ui"`
|
||||
Git GitConfig `toml:"git"`
|
||||
Updater UpdaterConfig `toml:"updater"`
|
||||
AI AIConfig `toml:"ai"`
|
||||
Core CoreConfig `toml:"core"`
|
||||
UI UIConfig `toml:"ui"`
|
||||
Git GitConfig `toml:"git"`
|
||||
Updater UpdaterConfig `toml:"updater"`
|
||||
AI AIConfig `toml:"ai"`
|
||||
Keybindings KeybindingsConfig `toml:"keybindings"`
|
||||
}
|
||||
|
||||
var (
|
||||
activeConfig *Config
|
||||
activeConfig atomic.Pointer[Config]
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
func Get() *Config {
|
||||
once.Do(func() {
|
||||
if activeConfig == nil {
|
||||
activeConfig = DefaultConfig()
|
||||
if activeConfig.Load() == nil {
|
||||
activeConfig.Store(DefaultConfig())
|
||||
}
|
||||
})
|
||||
return activeConfig
|
||||
return activeConfig.Load()
|
||||
}
|
||||
|
||||
func Init(cfg *Config) {
|
||||
activeConfig = cfg
|
||||
activeConfig.Store(cfg)
|
||||
once.Do(func() {})
|
||||
}
|
||||
|
||||
func AutoDetectConfigChange(onReload func(cfg *Config)) {
|
||||
path, err := ConfigPath()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
var lastMod time.Time
|
||||
if info, err := os.Stat(path); err == nil {
|
||||
lastMod = info.ModTime()
|
||||
}
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
info, err := os.Stat(path)
|
||||
if err == nil {
|
||||
if !lastMod.IsZero() && info.ModTime().After(lastMod) {
|
||||
lastMod = info.ModTime()
|
||||
if newCfg, err := Load(); err == nil {
|
||||
Init(newCfg)
|
||||
if onReload != nil {
|
||||
onReload(newCfg)
|
||||
}
|
||||
}
|
||||
} else if lastMod.IsZero() {
|
||||
lastMod = info.ModTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func Load() (*Config, error) {
|
||||
cfg := DefaultConfig()
|
||||
|
||||
|
||||
@@ -5,17 +5,19 @@ import "time"
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Core: CoreConfig{
|
||||
Version: 1,
|
||||
Shell: "",
|
||||
Mode: "last",
|
||||
Debug: false,
|
||||
Version: 1,
|
||||
Shell: "",
|
||||
Mode: "last",
|
||||
Debug: false,
|
||||
ExpandAlias: true,
|
||||
},
|
||||
UI: UIConfig{
|
||||
Style: "modern",
|
||||
GhostText: true,
|
||||
MaxSuggestions: 100,
|
||||
MaxHeight: 15,
|
||||
NerdFonts: true,
|
||||
Style: "modern",
|
||||
GhostText: true,
|
||||
ShowHiddenFiles: false,
|
||||
MaxSuggestions: 100,
|
||||
MaxHeight: 15,
|
||||
NerdFonts: true,
|
||||
},
|
||||
Git: GitConfig{
|
||||
FilterActiveBranch: true,
|
||||
@@ -38,6 +40,10 @@ func DefaultConfig() *Config {
|
||||
MinIntervalMS: 5000,
|
||||
},
|
||||
},
|
||||
Keybindings: KeybindingsConfig{
|
||||
ToggleMode: "ctrl+r",
|
||||
ToggleMenu: "shift+tab",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MatchKey matches a sequence of terminal bytes against a configured key string.
|
||||
// Key strings can be e.g. "ctrl+r", "tab", "shift+tab", "right".
|
||||
// Returns matched=true if the byte sequence matches the configured key, and consumed=number of bytes to consume.
|
||||
func MatchKey(input []byte, expected string) (matched bool, consumed int) {
|
||||
if len(input) == 0 {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
expected = strings.ToLower(strings.TrimSpace(expected))
|
||||
|
||||
if strings.HasPrefix(expected, "ctrl+") && len(expected) == 6 {
|
||||
char := expected[5]
|
||||
if char >= 'a' && char <= 'z' {
|
||||
targetByte := char - 'a' + 1
|
||||
if input[0] == targetByte {
|
||||
return true, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch expected {
|
||||
case "ctrl+space":
|
||||
if input[0] == 0x00 {
|
||||
return true, 1
|
||||
}
|
||||
case "tab":
|
||||
if input[0] == 0x09 {
|
||||
return true, 1
|
||||
}
|
||||
case "shift+tab":
|
||||
// typically \033[Z
|
||||
if len(input) >= 3 && input[0] == 0x1b && input[1] == '[' && input[2] == 'Z' {
|
||||
return true, 3
|
||||
}
|
||||
case "right":
|
||||
// typically \033[C or \033OC
|
||||
if len(input) >= 3 && input[0] == 0x1b && (input[1] == '[' || input[1] == 'O') && input[2] == 'C' {
|
||||
return true, 3
|
||||
}
|
||||
case "enter":
|
||||
if input[0] == 0x0d || input[0] == 0x0a {
|
||||
return true, 1
|
||||
}
|
||||
}
|
||||
|
||||
return false, 0
|
||||
}
|
||||
|
||||
// FormatKeyName takes a config key string like "ctrl+r" and formats it for UI display, e.g. "<Ctrl+R>".
|
||||
func FormatKeyName(key string) string {
|
||||
parts := strings.Split(key, "+")
|
||||
for i, p := range parts {
|
||||
if len(p) > 0 {
|
||||
parts[i] = strings.ToUpper(p[:1]) + strings.ToLower(p[1:])
|
||||
}
|
||||
}
|
||||
return "<" + strings.Join(parts, "+") + ">"
|
||||
}
|
||||
@@ -50,6 +50,9 @@ mode = "last"
|
||||
# enable debug logging
|
||||
debug = false
|
||||
|
||||
# auto expand alias when typing space
|
||||
expand-alias = true
|
||||
|
||||
[ui]
|
||||
# visual style: "modern" (icons, category pills, shortcut footer) or "classic" (minimalist, centered number, no icons)
|
||||
style = "modern"
|
||||
@@ -60,12 +63,22 @@ nerd-fonts = true
|
||||
# enable inline ghost text
|
||||
ghost-text = true
|
||||
|
||||
# show hidden files (starting with dot) in file generator
|
||||
hidden-files = false
|
||||
|
||||
# maximum suggestions to display
|
||||
max-suggestions = 100
|
||||
|
||||
# maximum height of the overlay
|
||||
max-height = 15
|
||||
|
||||
[keybindings]
|
||||
# toggle between spec and history mode
|
||||
toggle-mode = "ctrl+r"
|
||||
|
||||
# toggle menu visibility
|
||||
toggle-menu = "ctrl+space"
|
||||
|
||||
[git]
|
||||
# hide current branch in checkout/switch list
|
||||
filter-active-branch = true
|
||||
|
||||
@@ -186,6 +186,9 @@ mode = "last"
|
||||
# enable debug logging
|
||||
debug = false
|
||||
|
||||
# automatically expand aliases on space
|
||||
expand-alias = true
|
||||
|
||||
[ui]
|
||||
# visual style: "modern" (icons, category pills, shortcut footer) or "classic" (minimalist, centered number, no icons)
|
||||
style = "modern"
|
||||
@@ -193,6 +196,9 @@ style = "modern"
|
||||
# enable Nerd Fonts icons in overlay menu
|
||||
nerd-fonts = true
|
||||
|
||||
# show hidden files with dot prefix
|
||||
hidden-files = false
|
||||
|
||||
# enable inline ghost text
|
||||
ghost-text = true
|
||||
|
||||
@@ -218,6 +224,12 @@ channel = "stable"
|
||||
|
||||
# interval between update checks, e.g. "24h", "6h", "30m"
|
||||
check-interval = "24h"
|
||||
|
||||
[keybindings]
|
||||
toggle_mode = "ctrl+r"
|
||||
toggle_menu = "shift+tab"
|
||||
select_suggestion = "tab"
|
||||
accept_suggestion = "right"
|
||||
`
|
||||
if errWrite := os.WriteFile(path, []byte(defaultContent), 0644); errWrite == nil {
|
||||
fmt.Printf("✓ Initialized default config file at %s\n", path)
|
||||
|
||||
+78
-49
@@ -247,6 +247,8 @@ func runWrapper() {
|
||||
|
||||
overlay := integration.NewOverlay()
|
||||
|
||||
|
||||
|
||||
// start background update check (async)
|
||||
pendingUpdate = startBackgroundUpdateCheck()
|
||||
updatePrinted := false
|
||||
@@ -256,6 +258,12 @@ func runWrapper() {
|
||||
shellPGID = spec.ShellPID
|
||||
}
|
||||
var isCommandActive atomic.Bool
|
||||
var disableGhostText atomic.Bool
|
||||
disableGhostText.Store(!config.Get().UI.GhostText)
|
||||
config.AutoDetectConfigChange(func(cfg *config.Config) {
|
||||
disableGhostText.Store(!cfg.UI.GhostText)
|
||||
})
|
||||
var renderOverlay func()
|
||||
isExecuting := func() bool {
|
||||
if isCommandActive.Load() {
|
||||
return true
|
||||
@@ -311,10 +319,6 @@ func runWrapper() {
|
||||
}
|
||||
}()
|
||||
|
||||
var disableGhostText atomic.Bool
|
||||
disableGhostText.Store(!config.Get().UI.GhostText)
|
||||
var renderOverlay func()
|
||||
|
||||
// listen for suggestion requests from shell scripts via the ipc pipe
|
||||
go func() {
|
||||
defer func() {
|
||||
@@ -576,9 +580,9 @@ func runWrapper() {
|
||||
}
|
||||
|
||||
if renderTimer != nil {
|
||||
renderTimer.Stop()
|
||||
return
|
||||
}
|
||||
renderTimer = time.AfterFunc(25*time.Millisecond, func() {
|
||||
renderTimer = time.AfterFunc(20*time.Millisecond, func() {
|
||||
renderMu.Lock()
|
||||
renderTimer = nil
|
||||
renderMu.Unlock()
|
||||
@@ -614,6 +618,21 @@ func runWrapper() {
|
||||
b := inputSlice[i]
|
||||
intercepted := false
|
||||
|
||||
if matched, consumed := config.MatchKey(inputSlice[i:], config.Get().Keybindings.ToggleMenu); matched {
|
||||
intercepted = true
|
||||
suggestionsEnabled = !suggestionsEnabled
|
||||
logger.Debugf("Intercepted ToggleMenu, suggestionsEnabled=%v", suggestionsEnabled)
|
||||
if !suggestionsEnabled {
|
||||
writeStdout([]byte(overlay.ClearAndDisable()))
|
||||
} else {
|
||||
shouldOverlayDraw = true
|
||||
}
|
||||
i += consumed - 1
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
|
||||
if b == '\033' {
|
||||
// check for bracketed paste start/end
|
||||
if i+5 < n && inputSlice[i+1] == '[' && inputSlice[i+2] == '2' && inputSlice[i+3] == '0' {
|
||||
@@ -628,20 +647,6 @@ func runWrapper() {
|
||||
}
|
||||
// handle escape sequences like arrow keys and functional shortcuts
|
||||
if i+2 < n && (inputSlice[i+1] == '[' || inputSlice[i+1] == 'O') {
|
||||
// shift tab: hide/unhide menu dropdown
|
||||
if inputSlice[i+1] == '[' && inputSlice[i+2] == 'Z' {
|
||||
intercepted = true
|
||||
suggestionsEnabled = !suggestionsEnabled
|
||||
logger.Debugf("Intercepted Shift+Tab, suggestionsEnabled=%v", suggestionsEnabled)
|
||||
if !suggestionsEnabled {
|
||||
writeStdout([]byte(overlay.ClearAndDisable()))
|
||||
} else {
|
||||
shouldOverlayDraw = true
|
||||
}
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
|
||||
if overlay.IsVisible() && (inputSlice[i+2] == 'A' || inputSlice[i+2] == 'B') {
|
||||
intercepted = true
|
||||
userNavigated.Store(true)
|
||||
@@ -722,24 +727,6 @@ func runWrapper() {
|
||||
}
|
||||
i += 2
|
||||
continue
|
||||
} else if !disableGhostText.Load() && inputSlice[i+2] == 'C' { // right arrow
|
||||
bufferMu.Lock()
|
||||
atEnd := (cursorOffset == 0)
|
||||
ghostText := overlay.GetGhostText(naiveBuffer, atEnd)
|
||||
bufferMu.Unlock()
|
||||
|
||||
if len(ghostText) > 0 {
|
||||
intercepted = true
|
||||
logger.Debugf("Intercepted Right Arrow (accepted ghost text: %q)", ghostText)
|
||||
bufferMu.Lock()
|
||||
naiveBuffer += ghostText
|
||||
cursorOffset = 0
|
||||
bufferMu.Unlock()
|
||||
_, _ = ptmx.Write([]byte(ghostText))
|
||||
shouldOverlayDraw = true
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,6 +762,29 @@ func runWrapper() {
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
|
||||
bufferMu.Lock()
|
||||
atEnd := (cursorOffset == 0)
|
||||
ghostText := ""
|
||||
if !disableGhostText.Load() {
|
||||
ghostText = overlay.GetGhostText(naiveBuffer, atEnd)
|
||||
}
|
||||
bufferMu.Unlock()
|
||||
|
||||
if len(ghostText) > 0 {
|
||||
intercepted = true
|
||||
logger.Debugf("Intercepted Right Arrow (accepted ghost text: %q)", ghostText)
|
||||
bufferMu.Lock()
|
||||
naiveBuffer += ghostText
|
||||
cursorOffset = 0
|
||||
bufferMu.Unlock()
|
||||
overlay.ClearGhostTextState()
|
||||
_, _ = ptmx.Write([]byte(ghostText))
|
||||
shouldOverlayDraw = true
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
|
||||
bufferMu.Lock()
|
||||
if naiveBuffer != "" || overlay.IsVisible() {
|
||||
cursorOffset--
|
||||
@@ -813,7 +823,8 @@ func runWrapper() {
|
||||
continue
|
||||
}
|
||||
|
||||
if b == 0x12 { // ctrl+r: toggle between command specs and command history
|
||||
if matched, consumed := config.MatchKey(inputSlice[i:], config.Get().Keybindings.ToggleMode); matched { // ctrl+r: toggle between command specs and command history
|
||||
i += consumed - 1
|
||||
intercepted = true
|
||||
activeModeMu.Lock()
|
||||
if activeMode == "spec" {
|
||||
@@ -869,12 +880,33 @@ func runWrapper() {
|
||||
}
|
||||
renderMu.Unlock()
|
||||
|
||||
if cmdToSubmit == "" {
|
||||
bufferMu.Lock()
|
||||
cmdToSubmit = naiveBuffer
|
||||
bufferMu.Unlock()
|
||||
}
|
||||
|
||||
if strings.TrimSpace(cmdToSubmit) == "iris reload" {
|
||||
if newCfg, err := config.Load(); err == nil {
|
||||
config.Init(newCfg)
|
||||
disableGhostText.Store(!newCfg.UI.GhostText)
|
||||
}
|
||||
// Clear the shell line with Ctrl+U, then echo message, then Enter
|
||||
msg := "echo -e '\\033[32m✓ Iris configuration reloaded successfully.\\033[0m'\r"
|
||||
_, _ = ptmx.Write(append([]byte{0x15}, []byte(msg)...))
|
||||
bufferMu.Lock()
|
||||
naiveBuffer = ""
|
||||
cursorOffset = 0
|
||||
bufferMu.Unlock()
|
||||
disableGhostText.Store(false)
|
||||
shouldOverlayDraw = false
|
||||
userNavigated.Store(false)
|
||||
continue
|
||||
}
|
||||
|
||||
isCommandActive.Store(true)
|
||||
_, _ = ptmx.Write([]byte{b})
|
||||
bufferMu.Lock()
|
||||
if cmdToSubmit == "" {
|
||||
cmdToSubmit = naiveBuffer
|
||||
}
|
||||
lastSubmittedCommand = strings.TrimSpace(cmdToSubmit)
|
||||
naiveBuffer = ""
|
||||
cursorOffset = 0
|
||||
@@ -930,12 +962,8 @@ func runWrapper() {
|
||||
bufferMu.Unlock()
|
||||
|
||||
_, _ = ptmx.Write(append([]byte{0x15}, selected...))
|
||||
|
||||
overlay.ResetCursor() // this prevents when you tab, it switches between suggestions non-stop
|
||||
|
||||
shouldOverlayDraw = true // <- rerender after tab to choose, if you set to false,
|
||||
// when you press tab continually, it will print all folder from menu suggestions
|
||||
// and make the cursor jump to next line
|
||||
overlay.ResetCursor()
|
||||
shouldOverlayDraw = true
|
||||
userNavigated.Store(false)
|
||||
}
|
||||
continue
|
||||
@@ -1034,8 +1062,9 @@ func runWrapper() {
|
||||
// track normal printable characters in the buffer for matching
|
||||
if b >= 32 && b <= 126 {
|
||||
// expand alias on space, but only when typing manually (not pasting)
|
||||
// and only if expand-alias configuration is enabled
|
||||
bufferMu.Lock()
|
||||
isSpaceAlias := !inBracketedPaste && b == ' ' && naiveBuffer != "" && !strings.Contains(naiveBuffer, " ")
|
||||
isSpaceAlias := config.Get().Core.ExpandAlias && !inBracketedPaste && b == ' ' && naiveBuffer != "" && !strings.Contains(naiveBuffer, " ")
|
||||
var target string
|
||||
var ok bool
|
||||
if isSpaceAlias {
|
||||
|
||||
+5
-3
@@ -6,6 +6,8 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/versenilvis/iris/internal/config"
|
||||
)
|
||||
|
||||
// for tracking current working dir
|
||||
@@ -34,7 +36,7 @@ func GetCWD() string {
|
||||
// dir = "src/", filePrefix = "mai"
|
||||
// search for which matches "mai" case, and show it (whici is both main.go and main.py)
|
||||
// but if you type "go run src/mai" -> it will only shows suggestion about src/main.go
|
||||
// NOTE: it will skip hidden file start with dot prefix
|
||||
// NOTE: it will skip hidden file start with dot prefix unless configured otherwise
|
||||
func FileGenerator(filters ...string) GeneratorFunc {
|
||||
dirOnly := false
|
||||
filterSet := make(map[string]bool)
|
||||
@@ -82,8 +84,8 @@ func FileGenerator(filters ...string) GeneratorFunc {
|
||||
for _, entry := range entries {
|
||||
name := entry.Name()
|
||||
|
||||
// skip hidden files
|
||||
if strings.HasPrefix(name, ".") {
|
||||
// skip hidden files if not configured to show them
|
||||
if !config.Get().UI.ShowHiddenFiles && strings.HasPrefix(entry.Name(), ".") {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user