Procházet zdrojové kódy

Add support for fuzzy matching filenames

Yegappan Lakshmanan před 4 roky
rodič
revize
c2c4228f2f
4 změnil soubory, kde provedl 83 přidání a 23 odebrání
  1. 1 0
      .gitignore
  2. 1 1
      README.md
  3. 46 11
      doc/mru.txt
  4. 35 11
      plugin/mru.vim

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 doc/tags
+test/results.txt

+ 1 - 1
README.md

@@ -23,4 +23,4 @@ Vim 8.0 and above):
 or you can use any one of the Vim plugin managers (dein.vim, pathogen, vam, vim-plug, volt, Vundle, etc.) to install and manage this plugin.
 
 The user manual is available at:
-http://github.com/yegappan/mru/wiki/User-Manual
+https://github.com/yegappan/mru/wiki/User-Manual

+ 46 - 11
doc/mru.txt

@@ -2,7 +2,7 @@
 
 Author: Yegappan Lakshmanan  (yegappan AT yahoo DOT com)
 For Vim version 7.0 and above
-Last change: Feb 1, 2021
+Last change: Feb 2, 2021
 
 ==============================================================================
 						*mru-license*
@@ -44,15 +44,14 @@ file names as you open/edit them in Vim.
 
 This plugin will work on all the platforms where Vim is supported. This
 plugin will work in both console and GUI Vim. This version of the MRU
-plugin needs Vim 7.0 and above. If you are using an earlier version of
-Vim, then you should use an older version of the MRU plugin.
+plugin needs Vim 7.0 and above.
 
 The recently used filenames are stored in a file specified by the Vim
 MRU_File variable.
 
 The Github repository for the MRU plugin is available at:
 
-      http://github.com/yegappan/mru
+      https://github.com/yegappan/mru
 
 ==============================================================================
 2. Installation					*mru-installation*
@@ -84,6 +83,13 @@ To uninstall the MRU plugin, either use the uninstall command provided by the
 plugin manager or manually remove the plugin/mru.vim, and doc/mru.txt
 files from either the $HOME/.vim or $HOME/vimfiles directory.
 
+You can also install the latest version of the plugin directly from github
+using the following steps (in Vim 8.0 and above): >
+
+    $ mkdir -p $HOME/.vim/pack/downloads/start/mru
+    $ cd $HOME/.vim/pack/downloads/start/mru
+    $ git clone https://github.com/yegappan/mru
+<
 ==============================================================================
 3. Usage					*mru-usage* *:MRU*
 
@@ -212,11 +218,11 @@ to exclude file names matching a pattern, then you can set the
 MRU_Exclude_Files variable to a Vim regular expression. If any part of a
 file name matches the regular expression, then it is not added to the MRU
 list. By default, this variable is set to an empty string. For example, to
-not include files in the temporary (/tmp, /var/tmp and d:\temp) directories,
+not include files in the temporary (/tmp, /var/tmp and D:\temp) directories,
 you can set the MRU_Exclude_Files variable to
 >
       let MRU_Exclude_Files = '^/tmp/.*\|^/var/tmp/.*'  " For Unix
-      let MRU_Exclude_Files = '^c:\\temp\\.*'           " For MS-Windows
+      let MRU_Exclude_Files = '^D:\\temp\\.*'           " For MS-Windows
 <
 The specified pattern should be a Vim regular expression pattern. Note that
 you can specify multiple patterns using '\|'.
@@ -255,6 +261,13 @@ window open.
 >
       let MRU_Auto_Close = 0
 <
+When opening a file from the MRU list, the file is opened in the current
+tab. If the selected file has to be opened in a tab always, then set the
+following variable to 1. If the file is already opened in a tab, then the
+cursor will be moved to that tab.
+>
+      let MRU_Open_File_Use_Tabs = 1
+<
 If you don't use the "File->Recent Files" menu and want to disable it,
 then you can set the 'MRU_Add_Menu' variable to zero. By default, the
 menu is enabled.
@@ -276,16 +289,38 @@ number of file names displayed in a single sub-menu:
 >
       let MRU_Max_Submenu_Entries = 15
 <
+The :MRU command accepts a string that is used to filter the file names
+displayed in the MRU window. The MRU command also supports command-line
+completion using the supplied string. If Vim supports fuzzy matching
+(supported from Vim 8.2.1665), then the :MRU command will fuzzy match the
+supplied string against the file names.  Otherwise it will use regular
+expression matching. To always use regular expression matching, you can set
+the MRU_FuzzyMatch variable to 0:
+>
+      let MRU_FuzzyMatch = 0
+<
 In the MRU window, the filenames are displayed in two parts. The first part
 contains the file name without the path and the second part contains the
 full path to the file in parenthesis. This format is controlled by the
 MRU_Filename_Format variable. If you prefer to change this to some other
-format, then you can modify the MRU_Filename_Format variable. For example,
-to display the full path without splitting it, you can set this variable
-as shown below:
+format, then you can modify the MRU_Filename_Format variable.
+
+The MRU_Filename_Format variable contains a |Dict| with the following keys:
+  formatter: a string value containing an expression that specifies how to
+	     split/format the filename. In the expression v:val refers to the
+	     complete path to a file in the MRU list.
+  parser   : a string value containing an regular expression that specifies
+	     how to read the filename back from a line in the MRU window.
+  syntax   : a string value with a regular expression that matches the part to
+	     be highlighted in the MRU window.
+
+For example, to display the full path of the files without splitting it, you
+can set this variable as shown below:
 >
-      let MRU_Filename_Format =
-      \   {'formatter':'v:val', 'parser':'.*', 'syntax': '[^/\\]\+$'}
+      let MRU_Filename_Format = {
+		\ 'formatter':'v:val',
+		\ 'parser':'.*',
+		\ 'syntax': '[^/\\]\+$'}
 <
 ==============================================================================
 5. FZF Integration				*mru-fzf*

+ 35 - 11
plugin/mru.vim

@@ -1,7 +1,7 @@
 " File: mru.vim
 " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
 " Version: 3.10
-" Last Modified: Feb 1, 2021
+" Last Modified: Feb 2, 2021
 " Copyright: Copyright (C) 2003-2021 Yegappan Lakshmanan
 " License:   Permission is hereby granted to use and distribute this code,
 "            with or without modifications, provided that this copyright
@@ -106,6 +106,15 @@ if !exists('MRU_Open_File_Use_Tabs')
     let MRU_Open_File_Use_Tabs = 0
 endif
 
+" Controls whether fuzzy matching is used for matching a user supplied pattern
+" against the file names in the MRU list.
+if !exists('MRU_FuzzyMatch')
+    if exists('*matchfuzzy')
+      " Fuzzy matching is supported only when matchfuzzy() function is present
+      let MRU_FuzzyMatch = 1
+    endif
+endif
+
 " Format of the file names displayed in the MRU window.
 " The default is to display the filename followed by the complete path to the
 " file in parenthesis. This variable controls the expressions used to format
@@ -647,9 +656,13 @@ func! s:MRU_Open_Window(pat, splitdir, winsz) abort
         " No search pattern specified. Display the complete list
         let m = copy(s:MRU_files)
     else
-        " Display only the entries matching the specified pattern
-	" First try using it as a literal pattern
-	let m = filter(copy(s:MRU_files), 'stridx(v:val, a:pat) != -1')
+	" Display only the entries matching the specified pattern. First try
+	" fuzzy matching or as a literal pattern.
+	if g:MRU_FuzzyMatch
+	  let m = matchfuzzy(s:MRU_files, a:pat)
+	else
+	  let m = filter(copy(s:MRU_files), 'stridx(v:val, a:pat) != -1')
+	endif
 	if len(m) == 0
 	    " No match. Try using it as a regular expression
 	    let m = filter(copy(s:MRU_files), 'v:val =~# a:pat')
@@ -683,8 +696,13 @@ func! s:MRU_Complete(ArgLead, CmdLine, CursorPos) abort
         " Return the complete list of MRU files
         return s:MRU_files
     else
-        " Return only the files matching the specified pattern
-        return filter(copy(s:MRU_files), 'v:val =~? a:ArgLead')
+	if g:MRU_FuzzyMatch
+	  " Return only the files fuzzy matching the specified pattern
+	  return matchfuzzy(s:MRU_files, a:ArgLead)
+	else
+	  " Return only the files matching the specified pattern
+	  return filter(copy(s:MRU_files), 'v:val =~? a:ArgLead')
+	endif
     endif
 endfunc
 
@@ -707,17 +725,23 @@ func! s:MRU_Cmd(pat, splitdir, winsz) abort
         return
     endif
 
-    " First use the specified string as a literal string and search for
-    " filenames containing the string. If only one filename is found,
-    " then edit it (unless the user wants to open the MRU window always)
-    let m = filter(copy(s:MRU_files), 'stridx(v:val, a:pat) != -1')
+    " If Vim supports fuzzy matching, then try fuzzy matching the pattern
+    " against the file names. Otherwise, use the specified string as a literal
+    " string and search for filenames containing the string. If only one
+    " filename is found, then edit it (unless the user wants to open the MRU
+    " window always)
+    if g:MRU_FuzzyMatch
+      let m = matchfuzzy(s:MRU_files, a:pat)
+    else
+      let m = filter(copy(s:MRU_files), 'stridx(v:val, a:pat) != -1')
+    endif
     if len(m) > 0
 	if len(m) == 1 && !g:MRU_Window_Open_Always
 	    call s:MRU_Edit_File(m[0], 0)
 	    return
 	endif
 
-	" More than one file matches. Try find an accurate match
+	" More than one file matches. Try to find an accurate match
 	let new_m = filter(m, 'v:val ==# a:pat')
 	if len(new_m) == 1 && !g:MRU_Window_Open_Always
 	    call s:MRU_Edit_File(new_m[0], 0)