fortrangoingonforty/fortsh / a1fe1b5

Browse files

add set -o fuzzy-complete for opt-in fuzzy tab completion

Tab completion now uses prefix-only matching by default (like bash/zsh).
Fuzzy subsequence matching (where 'fort' matches 'install_intel_fortran')
is available via: set -o fuzzy-complete

Short patterns (≤3 chars) always require prefix match regardless of
the setting, to prevent noise like 'ls' matching 'false'.
Authored by espadonne
SHA
a1fe1b5405f6085ac6e3480cf0c846b2652db3f7
Parents
d5ec6ce
Tree
6080622

3 changed files

StatusFile+-
M src/common/types.f90 1 0
M src/io/readline.f90 14 4
M src/scripting/shell_options.f90 4 1
src/common/types.f90modified
@@ -376,6 +376,7 @@ module shell_types
376376
     logical :: option_physical = .false.       ! set -o physical (resolve symlinks in cd)
377377
     logical :: option_posix = .false.          ! set -o posix (POSIX mode)
378378
     logical :: option_privileged = .false.     ! set -o privileged (restricted mode)
379
+    logical :: option_fuzzy_complete = .false. ! set -o fuzzy-complete (fuzzy tab completion)
379380
     integer :: original_stderr_fd = 2          ! Saved copy of original stderr for shell messages
380381
     ! Bash-style shell options (shopt)
381382
     logical :: shopt_nullglob = .false.        ! nullglob (empty glob matches)
src/io/readline.f90modified
@@ -234,6 +234,10 @@ module readline
234234
   ! Module-level editing mode (set by shell via option_vi)
235235
   integer, save :: global_editing_mode = EDITING_MODE_EMACS
236236
 
237
+  ! Fuzzy completion: off by default (prefix-only like bash/zsh)
238
+  ! Enable with: set -o fuzzy-complete
239
+  logical, save :: global_fuzzy_complete = .false.
240
+
237241
   ! Detect macOS for potential platform-specific workarounds
238242
   logical, save :: is_macos_system = .false.
239243
   logical, save :: macos_detected = .false.
@@ -907,6 +911,11 @@ contains
907911
     end if
908912
   end subroutine
909913
 
914
+  subroutine set_global_fuzzy_complete(enabled)
915
+    logical, intent(in) :: enabled
916
+    global_fuzzy_complete = enabled
917
+  end subroutine
918
+
910919
   ! Check if we're on macOS (called once at startup)
911920
   subroutine detect_macos()
912921
     character(len=256) :: sysname
@@ -6290,10 +6299,11 @@ contains
62906299
       return
62916300
     end if
62926301
 
6293
-    ! For short patterns (1-3 chars), require prefix match for better UX
6294
-    ! This prevents "RE" from matching "parser_enhanced.mod"
6295
-    ! and "tes" from matching "ast_types.mod"
6296
-    if (pattern_len <= 3) then
6302
+    ! Require prefix match unless fuzzy-complete is enabled.
6303
+    ! With fuzzy off (default): behaves like bash/zsh — only prefix matches.
6304
+    ! With fuzzy on (set -o fuzzy-complete): short patterns still require
6305
+    ! prefix, longer patterns allow fuzzy subsequence matching.
6306
+    if (.not. global_fuzzy_complete .or. pattern_len <= 3) then
62976307
       is_prefix_match = .true.
62986308
       do i = 1, pattern_len
62996309
         if (to_lowercase(pattern(i:i)) /= to_lowercase(candidate(i:i))) then
src/scripting/shell_options.f90modified
@@ -6,7 +6,7 @@ module shell_options
66
   use shell_types
77
   use variables, only: set_shell_variable
88
   use system_interface, only: get_pid, get_ppid
9
-  use readline, only: set_global_editing_mode
9
+  use readline, only: set_global_editing_mode, set_global_fuzzy_complete
1010
   use iso_fortran_env, only: output_unit, error_unit
1111
   use io_helpers, only: write_stdout
1212
   implicit none
@@ -174,6 +174,9 @@ contains
174174
                   shell%option_errtrace = enable_option
175175
                 case ('functrace')
176176
                   shell%option_functrace = enable_option
177
+                case ('fuzzy-complete')
178
+                  shell%option_fuzzy_complete = enable_option
179
+                  call set_global_fuzzy_complete(enable_option)
177180
                 case ('hashall')
178181
                   shell%option_hashall = enable_option
179182
                 case ('histexpand')