From 2538a00dff90f4bf4fc761a1defbdedd071e5605 Mon Sep 17 00:00:00 2001 From: Kurtis Moxley Date: Thu, 19 May 2022 23:12:17 +0800 Subject: [PATCH] Update mru.vim. --- .../mru.vim/.github/workflows/coverage.yml | 39 + .../mru.vim/.github/workflows/unittests.yml | 66 + sources_non_forked/mru.vim/.gitignore | 2 + sources_non_forked/mru.vim/LICENSE | 20 + sources_non_forked/mru.vim/README | 192 -- sources_non_forked/mru.vim/README.md | 61 + sources_non_forked/mru.vim/doc/mru.txt | 450 ++++ sources_non_forked/mru.vim/plugin/mru.vim | 1644 ++++++++------- sources_non_forked/mru.vim/test/.coveragerc | 3 + .../mru.vim/test/run_mru_tests.cmd | 18 + .../mru.vim/test/run_mru_tests.sh | 30 + .../mru.vim/test/unit_tests.vim | 1830 +++++++++++++++++ 12 files changed, 3365 insertions(+), 990 deletions(-) create mode 100644 sources_non_forked/mru.vim/.github/workflows/coverage.yml create mode 100644 sources_non_forked/mru.vim/.github/workflows/unittests.yml create mode 100644 sources_non_forked/mru.vim/.gitignore create mode 100644 sources_non_forked/mru.vim/LICENSE delete mode 100644 sources_non_forked/mru.vim/README create mode 100644 sources_non_forked/mru.vim/README.md create mode 100644 sources_non_forked/mru.vim/doc/mru.txt create mode 100644 sources_non_forked/mru.vim/test/.coveragerc create mode 100644 sources_non_forked/mru.vim/test/run_mru_tests.cmd create mode 100755 sources_non_forked/mru.vim/test/run_mru_tests.sh create mode 100644 sources_non_forked/mru.vim/test/unit_tests.vim diff --git a/sources_non_forked/mru.vim/.github/workflows/coverage.yml b/sources_non_forked/mru.vim/.github/workflows/coverage.yml new file mode 100644 index 00000000..c95fe77e --- /dev/null +++ b/sources_non_forked/mru.vim/.github/workflows/coverage.yml @@ -0,0 +1,39 @@ +name: coverage +on: [push, pull_request] +jobs: + linux: + name: linux + runs-on: ubuntu-18.04 + steps: + - name: Checkout Code + uses: actions/checkout@v2 + - name: Run Tests + run: | + uname -a + export MRU_PROFILE=1 + export VIMPRG=vim + $VIMPRG --version + cd ./test + ./run_mru_tests.sh + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: 3.5 + - name: Install covimerage + run: | + pip install covimerage + covimerage --version + - name: Run covimerage + run: | + cd ./test + covimerage write_coverage mru_profile.txt + - name: Take coverage + run: | + cd ./test + coverage report + coverage xml + - name: Upload coverage to codecov + uses: codecov/codecov-action@v2 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./test/coverage.xml diff --git a/sources_non_forked/mru.vim/.github/workflows/unittests.yml b/sources_non_forked/mru.vim/.github/workflows/unittests.yml new file mode 100644 index 00000000..e93b749a --- /dev/null +++ b/sources_non_forked/mru.vim/.github/workflows/unittests.yml @@ -0,0 +1,66 @@ +name: unit-tests +on: [push, pull_request] +jobs: + linux: + name: linux + runs-on: ubuntu-latest + strategy: + matrix: + vim: + - nightly + - v8.2.0000 + - v8.1.0000 + - v8.0.0000 + - v7.4 + steps: + - name: Checkout Code + uses: actions/checkout@v2 + - name: Setup Vim + uses: rhysd/action-setup-vim@v1 + id: vim + with: + version: ${{ matrix.vim }} + - name: Run Tests + run: | + uname -a + export VIMPRG=${{ steps.vim.outputs.executable }} + $VIMPRG --version + cd test + ./run_mru_tests.sh + windows: + name: windows + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Download Vim + shell: PowerShell + run: Invoke-WebRequest -Uri https://github.com/vim/vim-win32-installer/releases/download/v8.2.2488/gvim_8.2.2488_x64.zip -OutFile vim.zip + - name: Extract vim + shell: PowerShell + run: Expand-Archive -Path vim.zip -DestinationPath $env:USERPROFILE + - name: Run Tests + run: | + $env:PATH = $env:PATH + ';' + $env:USERPROFILE + '\vim\vim82' + Get-ComputerInfo -Property Windows* + vim --version + cd test + .\run_mru_tests.cmd + neovim-linux: + name: neovim-linux + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + - name: Setup Neovim + uses: rhysd/action-setup-vim@v1 + id: vim + with: + version: stable + neovim: true + - name: Run Tests + run: | + uname -a + export VIMPRG=${{ steps.vim.outputs.executable }} + $VIMPRG --version + cd test + ./run_mru_tests.sh diff --git a/sources_non_forked/mru.vim/.gitignore b/sources_non_forked/mru.vim/.gitignore new file mode 100644 index 00000000..e485cc5f --- /dev/null +++ b/sources_non_forked/mru.vim/.gitignore @@ -0,0 +1,2 @@ +doc/tags +test/results.txt diff --git a/sources_non_forked/mru.vim/LICENSE b/sources_non_forked/mru.vim/LICENSE new file mode 100644 index 00000000..b85de0f7 --- /dev/null +++ b/sources_non_forked/mru.vim/LICENSE @@ -0,0 +1,20 @@ +License: MIT License +Copyright (c) 2003-2021 Yegappan Lakshmanan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/sources_non_forked/mru.vim/README b/sources_non_forked/mru.vim/README deleted file mode 100644 index 04c3a748..00000000 --- a/sources_non_forked/mru.vim/README +++ /dev/null @@ -1,192 +0,0 @@ -This is a mirror of http://www.vim.org/scripts/script.php?script_id=521 - -Overview - -The Most Recently Used (MRU) plugin provides an easy access to a list of -recently opened/edited files in Vim. This plugin automatically stores the -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. - -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 - -Usage - -To list and edit files from the MRU list, you can use the ":MRU" command. -The ":MRU" command displays the MRU file list in a temporary Vim window. If -the MRU window is already opened, then the MRU list displayed in the window -is refreshed. - -If you are using GUI Vim, then the names of the recently edited files are -added to the "File->Recent Files" menu. You can select the name of a file -from this sub-menu to edit the file. - -You can use the normal Vim commands to move around in the MRU window. You -cannot make changes in the MRU window. - -You can select a file name to edit by pressing the key or by double -clicking the left mouse button on a file name. The selected file will be -opened. If the file is already opened in a window, the cursor will be moved -to that window. Otherwise, the file is opened in the previous window. If the -previous window has a modified buffer or is the preview window or is used by -some other plugin, then the file is opened in a new window. - -You can press the 'o' key to open the file name under the cursor in the -MRU window in a new window. You can also press instead of 'o' -to open the file in a new window. - -To open a file from the MRU window in read-only mode (view), press the 'v' -key. - -To open a file from the MRU window in a new tab, press the 't' key. If the -file is already opened in a window in the current or in another tab, then -the cursor is moved to that tab. Otherwise, a new tab is opened. - -You can open multiple files from the MRU window by specifying a count before -pressing '' or 'v' or 'o' or 't'. You can also visually (using -linewise visual mode) select multiple filenames and invoke the commands to -open the files. Each selected file will be opened in a separate window or -tab. - -You can press the 'u' key in the MRU window to update the file list. This is -useful if you keep the MRU window open always. - -You can close the MRU window by pressing the 'q' key or the key or -using one of the Vim window commands. - -To display only files matching a pattern from the MRU list in the MRU -window, you can specify a pattern to the ":MRU" command. For example, to -display only file names matching "vim" in them, you can use the following -command ":MRU vim". When you specify a partial file name and only one -matching filename is found, then the ":MRU" command will edit that file. - -The ":MRU" command supports command-line completion of file names from -the MRU list. You can enter a partial file name and then press -or to complete or list all the matching file names. Note that -after typing the ":MRU" command, you have to enter a space before completing -the file names with . - -When a file supplied to the ":MRU" command is not present in the MRU list, -but it is a readable file, then the file will be opened (even though it is -not present in the MRU list). This is useful if you want to open a file -present in the same directory as a file in the MRU list. You can use the -command-line completion of the ":MRU" command to complete the full path of a -file and then modify the path to open another file present in the same path. - -Whenever the MRU list changes, the MRU file is updated with the latest MRU -list. When you have multiple instances of Vim running at the same time, the -latest MRU list will show up in all the instances of Vim. - -The MRUFilename syntax group is used to highlight the file names in the MRU -window. By default, this syntax group is linked to the Identifier highlight -group. You can change the highlight group by adding the following line in -your .vimrc: - - highlight link MRUFileName LineNr - -The MRU buffer uses the 'mru file type. You can use this file type to add -custom auto commands, syntax highlighting, etc. - -Configuration - -By changing the following variables you can configure the behavior of this -plugin. Set the following variables in your .vimrc file using the 'let' -command. - -The list of recently edited file names is stored in the file specified by the -MRU_File variable. The default setting for this variable is -$HOME/.vim_mru_files for Unix-like systems and $USERPROFILE/_vim_mru_files -for MS-Windows systems. You can change this variable to point to a file by -adding the following line to the .vimrc file: - - let MRU_File = 'd:\myhome\_vim_mru_files' - -By default, the plugin will remember the names of the last 100 used files. -As you edit more files, old file names will be removed from the MRU list. -You can set the 'MRU_Max_Entries' variable to remember more file names. For -example, to remember 1000 most recently used file names, you can use - - let MRU_Max_Entries = 1000 - -By default, all the edited file names will be added to the MRU list. If you -want to exclude file names matching a list of patterns, you can set the -MRU_Exclude_Files variable to a list of Vim regular expressions. 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, 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 - -The specified pattern should be a Vim regular expression pattern. - -If you want to add only file names matching a set of patterns to the MRU -list, then you can set the MRU_Include_Files variable. This variable should -be set to a Vim regular expression pattern. For example, to add only .c and -.h files to the MRU list, you can set this variable as below: - - let MRU_Include_Files = '\.c$\|\.h$' - -By default, MRU_Include_Files is set to an empty string and all the edited -filenames are added to the MRU list. - -The default height of the MRU window is 8. You can set the MRU_Window_Height -variable to change the window height. - - let MRU_Window_Height = 15 - -By default, when the :MRU command is invoked, the MRU list will be displayed -in a new window. Instead, if you want the MRU plugin to reuse the current -window, then you can set the 'MRU_Use_Current_Window' variable to one. - - let MRU_Use_Current_Window = 1 - -The MRU plugin will reuse the current window. When a file name is selected, -the file is also opened in the current window. - -When you select a file from the MRU window, the MRU window will be -automatically closed and the selected file will be opened in the previous -window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU -window open. - - let MRU_Auto_Close = 0 - -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. - - let MRU_Add_Menu = 0 - -If too many file names are present in the MRU list, then updating the MRU -menu to list all the file names makes Vim slow. To avoid this, the -MRU_Max_Menu_Entries variable controls the number of file names to show in -the MRU menu. By default, this is set to 10. You can change this to show -more entries in the menu. - - let MRU_Max_Menu_Entries = 20 - -If many file names are present in the MRU list, then the MRU menu is split -into sub-menus. Each sub-menu contains MRU_Max_Submenu_Entries file names. -The default setting for this is 10. You can change this to increase the -number of file names displayed in a single sub-menu: - - let MRU_Max_Submenu_Entries = 15 - -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: - - let MRU_Filename_Format={'formatter':'v:val', 'parser':'.*'} - diff --git a/sources_non_forked/mru.vim/README.md b/sources_non_forked/mru.vim/README.md new file mode 100644 index 00000000..1c766584 --- /dev/null +++ b/sources_non_forked/mru.vim/README.md @@ -0,0 +1,61 @@ +![unit-tests](https://github.com/yegappan/mru/workflows/unit-tests/badge.svg?branch=master) ![Coverage Status](https://codecov.io/gh/yegappan/mru/coverage.svg?branch=master) + +# Most Recently Used (MRU) Vim plugin + +The Most Recently Used (MRU) plugin provides an easy access to a list of +recently opened/edited files in Vim. This plugin automatically stores the +file names as you open/edit them in Vim. + +This plugin works with both Vim and Neovim and will work on all the platforms +where Vim/Neovim are supported. This plugin will work in both console and GUI +Vim. This version of the MRU plugin needs Vim 7.0 and above. + +## Installation + +You can install this plugin by downloading the .zip or the .tar.gz file for the latest MRU release from the following page: + +https://github.com/yegappan/mru/releases/latest + +For Vim 8.0 and above, you can expand the .zip file in the following directory (on Unix/Linux/MacOS systems): + + $ mkdir -p $HOME/.vim/pack/downloads/start/mru + $ cd $HOME/.vim/pack/downloads/start/mru + $ unzip + +For Vim 7.4 and before, you can use the following steps (on Unix/Linux/MacOS systems): + + $ mkdir $HOME/.vim + $ cd $HOME/.vim + $ unzip + +You can also install this plugin directly from github using the following steps (for 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 + +For NeoVim: + + $ mkdir -p $HOME/.config/nvim/pack/downloads/start/mru + $ cd $HOME/.config/nvim/pack/downloads/start/mru + $ git clone https://github.com/yegappan/mru + +or you can use any one of the Vim plugin managers ([vim-plug](https://github.com/junegunn/vim-plug), [dein.vim](https://github.com/Shougo/dein.vim), [pathogen](https://github.com/tpope/vim-pathogen), [minpac](https://github.com/k-takata/minpac), [vam](https://github.com/MarcWeber/vim-addon-manager), [volt](https://github.com/vim-volt/volt), [Vundle](https://github.com/VundleVim/Vundle.vim), etc.) to install and manage this plugin. + +## Usage +After the plugin is installed, it will automatically start to record the names of all the recently used files in the `$HOME/.vim_mru_files` text file. + +To open a file from the recently used file list, enter the following command: + + :MRU + +This will open a temporary window with the list of file names in the MRU list where you can press `` to open a file. + +You can fuzzy search a text in the list of file names, by passing a search text to the `:MRU` command: + + :MRU + +This will open the MRU window with only the file names fuzzy matching the supplied search string. + +The user manual is available at: +https://github.com/yegappan/mru/wiki/User-Manual diff --git a/sources_non_forked/mru.vim/doc/mru.txt b/sources_non_forked/mru.vim/doc/mru.txt new file mode 100644 index 00000000..c913a1d6 --- /dev/null +++ b/sources_non_forked/mru.vim/doc/mru.txt @@ -0,0 +1,450 @@ +*mru.txt* Plugin for accessing most recently used files + +Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) +For Vim version 7.0 and above +Last change: January 13, 2022 + +============================================================================== + *mru-license* +License: MIT License +Copyright (c) 2003-2021 Yegappan Lakshmanan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +============================================================================== +CONTENTS~ + +1. Overview |mru-overview| +2. Installation |mru-installation| +3. Usage |mru-usage| +4. Configuration |mru-configuration| +5. FZF Integration |mru-fzf| + +============================================================================== +1. Overview *mru-overview* + +The Most Recently Used (MRU) plugin provides an easy access to a list of +recently opened/edited files in Vim. This plugin automatically stores the +file names as you open/edit them in Vim. + +This plugin works with both Vim and Neovim and will work on all the platforms +where Vim/Neovim are supported. This plugin will work in both console and GUI +Vim. This version of the MRU 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: + + https://github.com/yegappan/mru + +============================================================================== +2. Installation *mru-installation* + +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. + +Alternatively, you can also manually download and install the plugin +using the following steps. + +1. Download the mru.zip file from https://github.com/yegappan/mru/releases +2. Unzip the mru.zip file into the $HOME/.vim directory for Linux/MacOS/Unix + systems or the $HOMEPATH/vimfiles directory for MS-Windows. After this + step, you should have the following files (the directory structure should + be preserved): + + plugin/mru.vim - MRU plugin + doc/mru.txt - documentation (help) file + +3. Start Vim and run the ":helptags ALL" command to process the help file. + Without this step, you cannot jump to the MRU help topics. +4. Restart Vim. +5. You can use the |:MRU| command to list and edit the recently used files. + In GUI Vim, you can use the 'File->Recent Files' menu to access the + recently used files. + +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.git +< +For Neovim: > + + $ mkdir -p $HOME/.config/nvim/pack/downloads/start/mru + $ cd $HOME/.config/nvim/pack/downloads/start/mru + $ git clone https://github.com/yegappan/mru.git +< +============================================================================== +3. Usage *mru-usage* + + *:MRU* +To list and edit files from the Most Recently Used (MRU) list, you can use the +":MRU" command. The |:MRU| command displays the list of recently used files +in a temporary Vim window. If the MRU window is already opened, then the MRU +list currently displayed in the window is refreshed. + + *:MRUToggle* +Alternatively, you can use the ":MRUToggle" command to toggle (open or close) +the MRU window. If the window is already opened, then running the ":MRUToggle" +command will close the window. + +If you are using GUI Vim, then the names of the recently edited files are +added to the "File->Recent Files" menu. You can select the name of a file +from this sub-menu to edit the file. + +You can use the normal Vim commands to move around in the MRU window. You +cannot make changes in the MRU window. + +In the MRU window, the following keys can be used: + + - open the file under cursor + o - open the file under cursor in a horizontally split window + - idem + O - open the file under cursor in a vertically split window + v - open the file under cursor in read-only mode + t - open the file under cursor in a tab page + p - open the file under cursor in the preview window + u - update (refresh) the MRU list + d - delete the file name under cursor from the MRU list + q - close the MRU window + - idem + +You can select a file name to edit by pressing the key or by double +clicking the left mouse button on a file name. The selected file will be +opened. If the file is already opened in a window, the cursor will be moved +to that window. Otherwise, the file is opened in the previous window. If the +previous window has a modified buffer or is the preview window or is used by +some other plugin, then the file is opened in a new window. + +You can press the 'o' key to open the file name under the cursor in the +MRU window in a new window. You can also press instead of 'o' +to open the file in a new window. + +To open a file from the MRU window in read-only mode (view), press the 'v' +key. + +To open a file from the MRU window in a new tab, press the 't' key. If the +file is already opened in a window in the current or in another tab, then +the cursor is moved to that tab. Otherwise, a new tab is opened. + +You can open multiple files from the MRU window by specifying a count before +pressing '' or 'v' or 'o' or 't'. You can also visually (using +linewise visual mode) select multiple filenames and invoke the commands to +open the files. Each selected file will be opened in a separate window or +tab. + +You can press the 'u' key in the MRU window to update/refresh the file list. +This is useful if you keep the MRU window open always. + +You can press the 'd' key to remove the entry under the cursor in the MRU +window from the MRU list. + +You can close the MRU window by pressing the 'q' key or the key or +using one of the Vim window commands. + +By default, the MRU window is opened as the bottom-most window. If you are +using Vim version 8.0 and above, then you can use command modifiers like +|:topleft| or |:botright| or |:vertical| with the :MRU command to control +where the window is opened. Example: > + + :topleft MRU " horizontally split topmost window + :botright MRU " horizontally split bottommost window + :vertical topleft MRU " vertically split far-left window + :vertical botright MRU " vertically split far-right window +< +By default, the height of the MRU window is 8 or the value specified by the +g:MRU_Window_Height variable. You can pass a count to the :MRU command to use +a different height. Example: > + + :15MRU + :vertical topleft 20MRU +< +To display only files matching a pattern from the MRU list in the MRU window, +you can specify a pattern to the |:MRU| command. Example: > + + :MRU mystr +< +The above command displays only the file names containing the string "mystr" +in them. When you specify a partial file name and only one matching filename +is found, then the |:MRU| command will edit that file. + +The |:MRU| command supports command-line completion of file names from +the MRU list. You can enter a partial file name and then press +or to complete or list all the matching file names. Note that +after typing the |:MRU| command, you have to enter a space before completing +the file names with . + +When the search pattern supplied to the |:MRU| command matches only one file, +then the file will be opened in the current window if it contains an +unmodified buffer. Otherwise it will be opened in a new window. You can use +command-line completion to select a file and directly open the file without +opening the MRU window. If you are using Vim version 8.0 and above, you can +use the command modifiers (|:leftabove|, |:rightbelow|, |:vertical|, |:tab|, +etc.) to open the file in a horizontally or vertically split window or a tab +page. Example: > + + :topleft MRU myfile.py " horizontally split topmost window + :botright MRU myfile.py " horizontally split bottommost window + :vertical MRU myfile.py " vertically split window + :vertical topleft MRU myfile.py " vertically split far-left window + :vertical botright MRU myfile.py " vertically split far-right window + :tab MRU myfile.py " new tab page +< +When a file supplied to the |:MRU| command is not present in the MRU list, +but it is a readable file, then the file will be opened (even though it is +not present in the MRU list). This is useful if you want to open a file +present in the same directory as a file in the MRU list. You can use the +command-line completion of the |:MRU| command to complete the full path of a +file and then modify the path to open another file present in the same path. + +Whenever the MRU list changes, the MRU file is updated with the latest MRU +list. When you have multiple instances of Vim running at the same time, the +latest MRU list will show up in all the instances of Vim. + +The MRUFilename syntax group is used to highlight the file names in the MRU +window. By default, this syntax group is linked to the Identifier highlight +group. You can change the highlight group by adding the following line in +your .vimrc: +> + highlight link MRUFileName LineNr +< +The MRU buffer uses the 'mru file type. You can use this file type to add +custom auto commands, syntax highlighting, etc. + + *:MruRefresh* +After using the MRU plugin for a period of time, the MRU list may contain +files which are no longer present in the system. The |:MruRefresh| command can +be used to remove non-existing files from the MRU list. + + *MruGetFiles()* +The MruGetFiles() function can be used to get the current list of file names +in the MRU list as a |List|. This can be used with Ex commands that accept one +or more file names as argument. Some example uses for this function are below: +> + " search for 'my_text' in all the files in the MRU list + :vimgrep my_text `=MruGetFiles()` + " search for 'my_text' in the files ending in .java in the MRU list + :vimgrep my_text `=MruGetFiles('.java')` + " add all the .py files in the MRU list to the argument list + :n `=MruGetFiles('.py')` + " Add the files in MRU list to a quickfix list + :call setqflist([], ' ', {'efm' : '%f', 'lines' : MruGetFiles()}) +< +============================================================================== +4. Configuration *mru-configuration* + +The MRU plugin supports many configurable features. These can be enabled or +disabled by setting one or more variables in your .vimrc file using the |:let| +command. For Neovim, set these variables in the $HOME/.config/nvim/init.vim +file. A summary of these variables is below: + + |MRU_File| name of the file containing the MRU list + |MRU_Max_Entries| size of the MRU list + |MRU_Exclude_Files| pattern to exclude files from MRU list + |MRU_Include_Files| pattern to include files in the MRU list + |MRU_Window_Height| height of the MRU window + |MRU_Use_Current_Window| use current window to display MRU list + |MRU_Auto_Close| close the MRU window when a file is selected + |MRU_Window_Open_Always| open the MRU window even for a single file + |MRU_Open_File_Use_Tabs| open files in separate tab pages + |MRU_FuzzyMatch| use fuzzy match for filtering file names + |MRU_Add_Menu| add MRU files to the "Recent Files" menu + |MRU_Max_Menu_Entries| maximum number of entries in the MRU menu + |MRU_Max_Submenu_Entries| maximum number of entries in the MRU submenu + |MRU_Set_Alternate_File| set the alternate file on plugin startup + |MRU_Filename_Format| patterns to populate and parse file names in + the MRU window + +These variables are described in more detail below. + + *MRU_File* +The list of recently edited file names is stored in the file specified by the +MRU_File variable. The default setting for this variable is +$HOME/.vim_mru_files for Unix-like systems and $USERPROFILE/_vim_mru_files +for MS-Windows systems. You can change this variable to point to a file by +adding the following line to the .vimrc file: +> + let MRU_File = 'd:\myhome\_vim_mru_files' +< + *MRU_Max_Entries* +By default, the plugin will remember the names of the last 100 used files. +As you edit more files, old file names will be removed from the MRU list. +You can set the 'MRU_Max_Entries' variable to remember more file names. For +example, to remember 1000 most recently used file names, you can use +> + let MRU_Max_Entries = 1000 +< + *MRU_Exclude_Files* +By default, all the edited file names are added to the MRU list. If you want +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, +you can set the MRU_Exclude_Files variable to +> + let MRU_Exclude_Files = '^/tmp/.*\|^/var/tmp/.*' " For Unix + 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 '\|'. + + *MRU_Include_Files* +If you want to add only file names matching a pattern to the MRU list, then +you can set the MRU_Include_Files variable. This variable should be set to a +Vim regular expression pattern. If the regular expression matches any part +of a file name, then it is added to the MRU list. For example, to add only +.c and .h files to the MRU list, you can set this variable as below: +> + let MRU_Include_Files = '\.c$\|\.h$' +< +By default, MRU_Include_Files is set to an empty string and all the edited +filenames are added to the MRU list. Note that you can specify multiple +patterns using '\|'. + + *MRU_Window_Height* +The default height of the MRU window is 8. You can set the MRU_Window_Height +variable to change the window height. You can also set the height of the MRU +window by passing a count to the :MRU command. +> + let MRU_Window_Height = 15 +< + *MRU_Use_Current_Window* +By default, when the |:MRU| command is invoked, the MRU list will be displayed +in a new window. Instead, if you want the MRU plugin to reuse the current +window, then you can set the 'MRU_Use_Current_Window' variable to one. +> + let MRU_Use_Current_Window = 1 +< +The MRU plugin will reuse the current window. When a file name is selected, +the file is also opened in the current window. + + *MRU_Auto_Close* +When you select a file from the MRU window, the MRU window will be +automatically closed and the selected file will be opened in the previous +window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU +window open. +> + let MRU_Auto_Close = 0 +< + *MRU_Window_Open_Always* +When a search pattern is supplied to the :MRU command, the MRU window is +opened if multiple files matching the pattern are found in the MRU list. If +only one matching file is found, instead of opening the MRU window the file is +directly opened. To force open the MRU window always, you can set the +MRU_Window_Open_Always variable to 1. By default this variable is set to 0. +> + let MRU_Window_Open_Always = 1 +< + *MRU_Open_File_Use_Tabs* +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 +< + *MRU_FuzzyMatch* +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 +< + *MRU_Add_Menu* +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. +> + let MRU_Add_Menu = 0 +< + *MRU_Max_Menu_Entries* +If too many file names are present in the MRU list, then updating the MRU +menu to list all the file names makes Vim slow. To avoid this, the +MRU_Max_Menu_Entries variable controls the number of file names to show in +the MRU menu. By default, this is set to 10. You can change this to show +more entries in the menu. +> + let MRU_Max_Menu_Entries = 20 +< + *MRU_Max_Submenu_Entries* +If many file names are present in the MRU list, then the MRU menu is split +into sub-menus. Each sub-menu contains MRU_Max_Submenu_Entries file names. +The default setting for this is 10. You can change this to increase the +number of file names displayed in a single sub-menu: +> + let MRU_Max_Submenu_Entries = 15 +< + *MRU_Set_Alternate_File* +When the MRU plugin starts up, if the MRU_Set_Alternate_File variable is set +to 1, then it sets the alternate file (|alternate-file|) to the first file in +the MRU list. You can edit this file using the ":e #" command. By default this +variable is set to 0. You can enable this behavior, by setting the +MRU_Set_Alternate_File variable to 1: +> + let MRU_Set_Alternate_File = 1 +< + *MRU_Filename_Format* +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. + +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': '[^/\\]\+$'} +< +============================================================================== +5. FZF Integration *mru-fzf* + +You can use the MRU plugin with FZF (command-line fuzzy finder). You can +download and install FZF from https://github.com/junegunn/fzf. + +To select a file from the MRU file list using FZF, run the following command: +> + :FZFMru +< +This will invoke FZF to select a file from the MRU list. + +============================================================================== + +vim:tw=78:ts=8:noet:ft=help: diff --git a/sources_non_forked/mru.vim/plugin/mru.vim b/sources_non_forked/mru.vim/plugin/mru.vim index 5cf7015d..365964ad 100644 --- a/sources_non_forked/mru.vim/plugin/mru.vim +++ b/sources_non_forked/mru.vim/plugin/mru.vim @@ -1,8 +1,8 @@ " File: mru.vim " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) -" Version: 3.9 -" Last Modified: Feb 3, 2015 -" Copyright: Copyright (C) 2003-2015 Yegappan Lakshmanan +" Version: 3.10.2 +" Last Modified: August 14, 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 " notice is copied with it. Like anything else that's free, @@ -11,288 +11,83 @@ " holder be liable for any damages resulting from the use of this " software. " -" Overview -" -------- -" The Most Recently Used (MRU) plugin provides an easy access to a list of -" recently opened/edited files in Vim. This plugin automatically stores the -" 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. -" -" 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 -" -" Installation -" ------------ -" 1. Copy the mru.vim file to one of the following directories: -" $HOME/.vim/plugin - Unix like systems -" $HOME/vimfiles/plugin - MS-Windows -" $VIM:vimfiles:plugin - Macintosh -" $VIM/vimfiles/plugin - All -" 2. Restart Vim. -" 3. You can use the ":MRU" command to list and edit the recently used files. -" In GUI Vim, you can use the 'File->Recent Files' menu to access the -" recently used files. -" -" To uninstall this plugin, remove this file (mru.vim) from the -" $HOME/.vim/plugin or $HOME/vimfiles/plugin or the $VIM/vimfile/plugin -" directory. -" -" Usage -" ----- -" To list and edit files from the MRU list, you can use the ":MRU" command. -" The ":MRU" command displays the MRU file list in a temporary Vim window. If -" the MRU window is already opened, then the MRU list displayed in the window -" is refreshed. -" -" If you are using GUI Vim, then the names of the recently edited files are -" added to the "File->Recent Files" menu. You can select the name of a file -" from this sub-menu to edit the file. -" -" You can use the normal Vim commands to move around in the MRU window. You -" cannot make changes in the MRU window. -" -" You can select a file name to edit by pressing the key or by double -" clicking the left mouse button on a file name. The selected file will be -" opened. If the file is already opened in a window, the cursor will be moved -" to that window. Otherwise, the file is opened in the previous window. If the -" previous window has a modified buffer or is the preview window or is used by -" some other plugin, then the file is opened in a new window. -" -" You can press the 'o' key to open the file name under the cursor in the -" MRU window in a new window. You can also press instead of 'o' -" to open the file in a new window. -" -" To open a file from the MRU window in read-only mode (view), press the 'v' -" key. -" -" To open a file from the MRU window in a new tab, press the 't' key. If the -" file is already opened in a window in the current or in another tab, then -" the cursor is moved to that tab. Otherwise, a new tab is opened. -" -" You can open multiple files from the MRU window by specifying a count before -" pressing '' or 'v' or 'o' or 't'. You can also visually (using -" linewise visual mode) select multiple filenames and invoke the commands to -" open the files. Each selected file will be opened in a separate window or -" tab. -" -" You can press the 'u' key in the MRU window to update the file list. This is -" useful if you keep the MRU window open always. -" -" You can close the MRU window by pressing the 'q' key or the key or -" using one of the Vim window commands. -" -" To display only files matching a pattern from the MRU list in the MRU -" window, you can specify a pattern to the ":MRU" command. For example, to -" display only file names matching "vim" in them, you can use the following -" command ":MRU vim". When you specify a partial file name and only one -" matching filename is found, then the ":MRU" command will edit that file. -" -" The ":MRU" command supports command-line completion of file names from -" the MRU list. You can enter a partial file name and then press -" or to complete or list all the matching file names. Note that -" after typing the ":MRU" command, you have to enter a space before completing -" the file names with . -" -" When a file supplied to the ":MRU" command is not present in the MRU list, -" but it is a readable file, then the file will be opened (even though it is -" not present in the MRU list). This is useful if you want to open a file -" present in the same directory as a file in the MRU list. You can use the -" command-line completion of the ":MRU" command to complete the full path of a -" file and then modify the path to open another file present in the same path. -" -" Whenever the MRU list changes, the MRU file is updated with the latest MRU -" list. When you have multiple instances of Vim running at the same time, the -" latest MRU list will show up in all the instances of Vim. -" -" The MRUFilename syntax group is used to highlight the file names in the MRU -" window. By default, this syntax group is linked to the Identifier highlight -" group. You can change the highlight group by adding the following line in -" your .vimrc: -" -" highlight link MRUFileName LineNr -" -" The MRU buffer uses the 'mru file type. You can use this file type to add -" custom auto commands, syntax highlighting, etc. -" -" Configuration -" ------------- -" By changing the following variables you can configure the behavior of this -" plugin. Set the following variables in your .vimrc file using the 'let' -" command. -" -" The list of recently edited file names is stored in the file specified by the -" MRU_File variable. The default setting for this variable is -" $HOME/.vim_mru_files for Unix-like systems and $USERPROFILE/_vim_mru_files -" for MS-Windows systems. You can change this variable to point to a file by -" adding the following line to the .vimrc file: -" -" let MRU_File = 'd:\myhome\_vim_mru_files' -" -" By default, the plugin will remember the names of the last 100 used files. -" As you edit more files, old file names will be removed from the MRU list. -" You can set the 'MRU_Max_Entries' variable to remember more file names. For -" example, to remember 1000 most recently used file names, you can use -" -" let MRU_Max_Entries = 1000 -" -" By default, all the edited file names will be added to the MRU list. If you -" want to exclude file names matching a list of patterns, you can set the -" MRU_Exclude_Files variable to a list of Vim regular expressions. 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, 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 -" -" The specified pattern should be a Vim regular expression pattern. -" -" If you want to add only file names matching a set of patterns to the MRU -" list, then you can set the MRU_Include_Files variable. This variable should -" be set to a Vim regular expression pattern. For example, to add only .c and -" .h files to the MRU list, you can set this variable as below: -" -" let MRU_Include_Files = '\.c$\|\.h$' -" -" By default, MRU_Include_Files is set to an empty string and all the edited -" filenames are added to the MRU list. -" -" The default height of the MRU window is 8. You can set the MRU_Window_Height -" variable to change the window height. -" -" let MRU_Window_Height = 15 -" -" By default, when the :MRU command is invoked, the MRU list will be displayed -" in a new window. Instead, if you want the MRU plugin to reuse the current -" window, then you can set the 'MRU_Use_Current_Window' variable to one. -" -" let MRU_Use_Current_Window = 1 -" -" The MRU plugin will reuse the current window. When a file name is selected, -" the file is also opened in the current window. -" -" When you select a file from the MRU window, the MRU window will be -" automatically closed and the selected file will be opened in the previous -" window. You can set the 'MRU_Auto_Close' variable to zero to keep the MRU -" window open. -" -" let MRU_Auto_Close = 0 -" -" 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. -" -" let MRU_Add_Menu = 0 -" -" If too many file names are present in the MRU list, then updating the MRU -" menu to list all the file names makes Vim slow. To avoid this, the -" MRU_Max_Menu_Entries variable controls the number of file names to show in -" the MRU menu. By default, this is set to 10. You can change this to show -" more entries in the menu. -" -" let MRU_Max_Menu_Entries = 20 -" -" If many file names are present in the MRU list, then the MRU menu is split -" into sub-menus. Each sub-menu contains MRU_Max_Submenu_Entries file names. -" The default setting for this is 10. You can change this to increase the -" number of file names displayed in a single sub-menu: -" -" let MRU_Max_Submenu_Entries = 15 -" -" 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: -" -" let MRU_Filename_Format = -" \ {'formatter':'v:val', 'parser':'.*', 'syntax': '[^/\\]\+$'} -" " ****************** Do not modify after this line ************************ if exists('loaded_mru') - finish + finish endif let loaded_mru=1 if v:version < 700 - finish + finish endif " Line continuation used here -let s:cpo_save = &cpo -set cpo&vim +let s:cpo_save = &cpoptions +set cpoptions&vim " MRU configuration variables {{{1 " Maximum number of entries allowed in the MRU list if !exists('MRU_Max_Entries') - let MRU_Max_Entries = 100 + let MRU_Max_Entries = 100 endif " Files to exclude from the MRU list if !exists('MRU_Exclude_Files') - let MRU_Exclude_Files = '' + let MRU_Exclude_Files = '' endif " Files to include in the MRU list if !exists('MRU_Include_Files') - let MRU_Include_Files = '' + let MRU_Include_Files = '' endif " Height of the MRU window " Default height is 8 if !exists('MRU_Window_Height') - let MRU_Window_Height = 8 + let MRU_Window_Height = 8 endif if !exists('MRU_Use_Current_Window') - let MRU_Use_Current_Window = 0 + let MRU_Use_Current_Window = 0 endif if !exists('MRU_Auto_Close') - let MRU_Auto_Close = 1 + let MRU_Auto_Close = 1 endif -if !exists('MRU_File') - if has('unix') || has('macunix') - let MRU_File = $HOME . '/.vim_mru_files' - else - let MRU_File = $VIM . '/_vim_mru_files' - if has('win32') - " MS-Windows - if $USERPROFILE != '' - let MRU_File = $USERPROFILE . '\_vim_mru_files' - endif - endif +if !exists('g:MRU_File') + if has('unix') || has('macunix') + let s:MRU_File = $HOME . '/.vim_mru_files' + else + let s:MRU_File = $VIM . '/_vim_mru_files' + if has('win32') + " MS-Windows + if !empty($USERPROFILE) + let s:MRU_File = $USERPROFILE . '\_vim_mru_files' + endif endif + endif +else + let s:MRU_File = expand(g:MRU_File) endif " Option for enabling or disabling the MRU menu if !exists('MRU_Add_Menu') - let MRU_Add_Menu = 1 + let MRU_Add_Menu = 1 endif " Maximum number of file names to show in the MRU menu. If too many files are " listed in the menu, then Vim becomes slow when updating the menu. So set " this to a low value. if !exists('MRU_Max_Menu_Entries') - let MRU_Max_Menu_Entries = 10 + let MRU_Max_Menu_Entries = 10 endif " Maximum number of file names to show in a MRU sub-menu. If the MRU list " contains more file names than this setting, then the MRU menu is split into " one or more sub-menus. if !exists('MRU_Max_Submenu_Entries') - let MRU_Max_Submenu_Entries = 10 + let MRU_Max_Submenu_Entries = 10 endif " When only a single matching filename is found in the MRU list, the following @@ -300,7 +95,7 @@ endif " file is directly opened. When this variable is set to 0 and a single " matching file name is found, then the file is directly opened. if !exists('MRU_Window_Open_Always') - let MRU_Window_Open_Always = 0 + let MRU_Window_Open_Always = 0 endif " When opening a file from the MRU list, the file is opened in the current @@ -308,7 +103,25 @@ endif " following variable to 1. If the file is already opened in a tab, then the " cursor will be moved to that tab. if !exists('MRU_Open_File_Use_Tabs') - let MRU_Open_File_Use_Tabs = 0 + 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 + else + let MRU_FuzzyMatch = 0 + endif +endif + +" Controls whether the alternate file (:help alternate-file) is set when the +" plugin is loaded to the first file in the MRU list. Default is to set the +" alternate file. +if !exists('MRU_Set_Alternate_File') + let MRU_Set_Alternate_File = 0 endif " Format of the file names displayed in the MRU window. @@ -319,217 +132,256 @@ endif " and 'parser' specifies how to read the filename back; 'syntax' matches the " part to be highlighted. if !exists('MRU_Filename_Format') - let MRU_Filename_Format = { - \ 'formatter': 'fnamemodify(v:val, ":t") . " (" . v:val . ")"', - \ 'parser': '(\zs.*\ze)', - \ 'syntax': '^.\{-}\ze(' - \} + let MRU_Filename_Format = { + \ 'formatter': 'fnamemodify(v:val, ":t") . " (" . v:val . ")"', + \ 'parser': '(\zs.*\ze)', + \ 'syntax': '^.\{-}\ze(' + \} endif +let s:MRU_buf_name = '-RecentFiles-' + " Control to temporarily lock the MRU list. Used to prevent files from " getting added to the MRU list when the ':vimgrep' command is executed. let s:mru_list_locked = 0 " MRU_LoadList {{{1 " Loads the latest list of file names from the MRU file -function! s:MRU_LoadList() - " If the MRU file is present, then load the list of filenames. Otherwise - " start with an empty list. - if filereadable(g:MRU_File) - let s:MRU_files = readfile(g:MRU_File) - if s:MRU_files[0] =~# '^\s*" Most recently edited files in Vim' - " Generated by the previous version of the MRU plugin. - " Discard the list. - let s:MRU_files = [] - elseif s:MRU_files[0] =~# '^#' - " Remove the comment line - call remove(s:MRU_files, 0) - else - " Unsupported format - let s:MRU_files = [] - endif +func! s:MRU_LoadList() abort + " If the MRU file is present, then load the list of filenames. Otherwise + " start with an empty list. + if filereadable(s:MRU_File) + let s:MRU_files = readfile(s:MRU_File) + if s:MRU_files[0] =~# '^\s*" Most recently edited files in Vim' + " Generated by the previous version of the MRU plugin. + " Discard the list. + let s:MRU_files = [] + elseif s:MRU_files[0] =~# '^#' + " Remove the comment line + call remove(s:MRU_files, 0) else - let s:MRU_files = [] + " Unsupported format + let s:MRU_files = [] endif + else + let s:MRU_files = [] + endif - " Refresh the MRU menu with the latest list of filenames - call s:MRU_Refresh_Menu() -endfunction + " Refresh the MRU menu with the latest list of filenames + call s:MRU_Refresh_Menu() +endfunc " MRU_SaveList {{{1 " Saves the MRU file names to the MRU file -function! s:MRU_SaveList() - let l = [] - call add(l, '# Most recently edited files in Vim (version 3.0)') - call extend(l, s:MRU_files) - call writefile(l, g:MRU_File) -endfunction +func! s:MRU_SaveList() abort + let l = [] + call add(l, '# Most recently edited files in Vim (version 3.0)') + call extend(l, s:MRU_files) + call writefile(l, s:MRU_File) +endfunc " MRU_AddFile {{{1 " Adds a file to the MRU file list " acmd_bufnr - Buffer number of the file to add -function! s:MRU_AddFile(acmd_bufnr) - if s:mru_list_locked - " MRU list is currently locked - return +func! s:MRU_AddFile(acmd_bufnr) abort + if s:mru_list_locked + " MRU list is currently locked + return + endif + + " Get the full path to the filename + let fname = fnamemodify(bufname(a:acmd_bufnr + 0), ':p') + if empty(fname) + return + endif + + " Skip temporary buffers with buftype set. The buftype is set for buffers + " used by plugins. + if !empty(&buftype) + return + endif + + if !empty(g:MRU_Include_Files) + " If MRU_Include_Files is set, include only files matching the + " specified pattern + if fname !~# g:MRU_Include_Files + return endif + endif - " Get the full path to the filename - let fname = fnamemodify(bufname(a:acmd_bufnr + 0), ':p') - if fname == '' - return + if !empty(g:MRU_Exclude_Files) + " Do not add files matching the pattern specified in the + " MRU_Exclude_Files to the MRU list + if fname =~# g:MRU_Exclude_Files + return endif + endif - " Skip temporary buffers with buftype set. The buftype is set for buffers - " used by plugins. - if &buftype != '' - return + " If the filename is not already present in the MRU list and is not + " readable then ignore it + let idx = index(s:MRU_files, fname) + if idx == -1 + if !filereadable(fname) + " File is not readable and is not in the MRU list + return endif + endif - if g:MRU_Include_Files != '' - " If MRU_Include_Files is set, include only files matching the - " specified pattern - if fname !~# g:MRU_Include_Files - return - endif + " Load the latest MRU file list + call s:MRU_LoadList() + + " Remove the new file name from the existing MRU list (if already present) + call filter(s:MRU_files, 'v:val !=# fname') + + " Add the new file list to the beginning of the updated old file list + call insert(s:MRU_files, fname, 0) + + " Trim the list + if len(s:MRU_files) > g:MRU_Max_Entries + call remove(s:MRU_files, g:MRU_Max_Entries, -1) + endif + + " Save the updated MRU list + call s:MRU_SaveList() + + " Refresh the MRU menu + call s:MRU_Refresh_Menu() + + " If the MRU window is open, update the displayed MRU list + let bname = s:MRU_buf_name + let winnum = bufwinnr(bname) + if winnum != -1 + let cur_winnr = winnr() + call s:MRU_Open_Window('', '', 0) + if winnr() != cur_winnr + exe cur_winnr . 'wincmd w' endif - - if g:MRU_Exclude_Files != '' - " Do not add files matching the pattern specified in the - " MRU_Exclude_Files to the MRU list - if fname =~# g:MRU_Exclude_Files - return - endif - endif - - " If the filename is not already present in the MRU list and is not - " readable then ignore it - let idx = index(s:MRU_files, fname) - if idx == -1 - if !filereadable(fname) - " File is not readable and is not in the MRU list - return - endif - endif - - " Load the latest MRU file list - call s:MRU_LoadList() - - " Remove the new file name from the existing MRU list (if already present) - call filter(s:MRU_files, 'v:val !=# fname') - - " Add the new file list to the beginning of the updated old file list - call insert(s:MRU_files, fname, 0) - - " Trim the list - if len(s:MRU_files) > g:MRU_Max_Entries - call remove(s:MRU_files, g:MRU_Max_Entries, -1) - endif - - " Save the updated MRU list - call s:MRU_SaveList() - - " Refresh the MRU menu - call s:MRU_Refresh_Menu() - - " If the MRU window is open, update the displayed MRU list - let bname = '__MRU_Files__' - let winnum = bufwinnr(bname) - if winnum != -1 - let cur_winnr = winnr() - call s:MRU_Open_Window() - if winnr() != cur_winnr - exe cur_winnr . 'wincmd w' - endif - endif -endfunction + endif +endfunc " MRU_escape_filename {{{1 " Escape special characters in a filename. Special characters in file names " that should be escaped (for security reasons) let s:esc_filename_chars = ' *?[{`$%#"|!<>();&' . "'\t\n" -function! s:MRU_escape_filename(fname) - if exists("*fnameescape") - return fnameescape(a:fname) - else - return escape(a:fname, s:esc_filename_chars) - endif -endfunction +func! s:MRU_escape_filename(fname) abort + if exists('*fnameescape') + return fnameescape(a:fname) + else + return escape(a:fname, s:esc_filename_chars) + endif +endfunc " MRU_Edit_File {{{1 " Edit the specified file " filename - Name of the file to edit " sanitized - Specifies whether the filename is already escaped for special " characters or not. -function! s:MRU_Edit_File(filename, sanitized) - if !a:sanitized - let esc_fname = s:MRU_escape_filename(a:filename) - else - let esc_fname = a:filename - endif +" splitdir - command modifier for a split (topleft, belowright, etc.) +" Used by the :MRU command and the "Recent Files" menu item +func! s:MRU_Edit_File(filename, sanitized, splitdir) abort + if !a:sanitized + let esc_fname = s:MRU_escape_filename(a:filename) + else + let esc_fname = a:filename + endif - " If the user wants to always open the file in a tab, then open the file - " in a tab. If it is already opened in a tab, then the cursor will be - " moved to that tab. - if g:MRU_Open_File_Use_Tabs - call s:MRU_Open_File_In_Tab(a:filename, esc_fname) - return - endif + " If the user wants to always open the file in a tab, then open the file + " in a tab. If it is already opened in a tab, then the cursor will be + " moved to that tab. + if g:MRU_Open_File_Use_Tabs + call s:MRU_Open_File_In_Tab(a:filename, esc_fname) + return + endif - " If the file is already open in one of the windows, jump to it - let winnum = bufwinnr('^' . a:filename . '$') - if winnum != -1 - if winnum != winnr() - exe winnum . 'wincmd w' - endif - else - if !&hidden && (&modified || &buftype != '' || &previewwindow) - " Current buffer has unsaved changes or is a special buffer or is - " the preview window. The 'hidden' option is also not set. - " So open the file in a new window. - exe 'split ' . esc_fname - else - " The current file can be replaced with the selected file. - exe 'edit ' . esc_fname - endif + " If the file is already open in one of the windows, jump to it + let winnum = bufwinnr('^' . a:filename . '$') + if winnum != -1 + if winnum != winnr() + exe winnum . 'wincmd w' endif -endfunction + else + if !empty(a:splitdir) || (!&hidden && (&modified || !empty(&buftype) + \ || &previewwindow)) + " If a split command modifier is specified, always open the file + " in a new window. + " Or if the current buffer has unsaved changes or is a special buffer or + " is the preview window. The 'hidden' option is also not set. So open + " the file in a new window. + if bufexists(esc_fname) + exe a:splitdir . ' sbuffer ' . esc_fname + else + exe a:splitdir . ' split ' . esc_fname + endif + else + " The current file can be replaced with the selected file. + if bufexists(esc_fname) + exe 'buffer ' . esc_fname + else + exe 'edit ' . esc_fname + endif + endif + " Make the buffer a listed buffer (in case it was deleted before) + setlocal buflisted + endif +endfunc " MRU_Open_File_In_Tab " Open a file in a tab. If the file is already opened in a tab, jump to the " tab. Otherwise, create a new tab and open the file. " fname : Name of the file to open " esc_fname : File name with special characters escaped -function! s:MRU_Open_File_In_Tab(fname, esc_fname) - " If the selected file is already open in the current tab or in - " another tab, jump to it. Otherwise open it in a new tab - if bufwinnr('^' . a:fname . '$') == -1 - let tabnum = -1 - let i = 1 - let bnum = bufnr('^' . a:fname . '$') - while i <= tabpagenr('$') - if index(tabpagebuflist(i), bnum) != -1 - let tabnum = i - break - endif - let i += 1 - endwhile +func! s:MRU_Open_File_In_Tab(fname, esc_fname) abort + " If the selected file is already open in the current tab or in + " another tab, jump to it. Otherwise open it in a new tab + if bufwinnr('^' . a:fname . '$') == -1 + let tabnum = -1 + let i = 1 + let bnum = bufnr('^' . a:fname . '$') + while i <= tabpagenr('$') + if index(tabpagebuflist(i), bnum) != -1 + let tabnum = i + break + endif + let i += 1 + endwhile - if tabnum != -1 - " Goto the tab containing the file - exe 'tabnext ' . i + if tabnum != -1 + " Goto the tab containing the file + exe 'tabnext ' . i + else + if (winnr('$') == 1) && empty(@%) && !&modified + " Reuse the current tab if it contains a single new unmodified + " file. + if bufexists(a:esc_fname) + exe 'buffer ' . a:esc_fname else - " Open a new tab as the last tab page - exe '$tabnew ' . a:esc_fname + exe 'edit ' . a:esc_fname endif + else + " Open a new tab as the last tab page + if v:version >= 800 + if bufexists(a:esc_fname) + exe '$tab sbuffer ' . a:esc_fname + else + exe '$tabnew ' . a:esc_fname + endif + else + if bufexists(a:esc_fname) + exe '99999tab sbuffer ' . a:esc_fname + else + exe '99999tabnew ' . a:esc_fname + endif + endif + endif endif + endif - " Jump to the window containing the file - let winnum = bufwinnr('^' . a:fname . '$') - if winnum != winnr() - exe winnum . 'wincmd w' - endif -endfunction + " Jump to the window containing the file + let winnum = bufwinnr('^' . a:fname . '$') + if winnum != winnr() + exe winnum . 'wincmd w' + endif +endfunc " MRU_Window_Edit_File {{{1 " fname : Name of the file to edit. May specify single or multiple @@ -548,84 +400,107 @@ endfunction " newtab - Open the file in a new tab. If the file is already " opened in a tab, then jump to that tab. " preview - Open the file in the preview window -function! s:MRU_Window_Edit_File(fname, multi, edit_type, open_type) - let esc_fname = s:MRU_escape_filename(a:fname) +func! s:MRU_Window_Edit_File(fname, multi, edit_type, open_type) abort + let esc_fname = s:MRU_escape_filename(a:fname) - if a:open_type ==# 'newwin_horiz' - " Edit the file in a new horizontally split window above the previous - " window - wincmd p - exe 'belowright new ' . esc_fname - elseif a:open_type ==# 'newwin_vert' - " Edit the file in a new vertically split window above the previous - " window - wincmd p - exe 'belowright vnew ' . esc_fname - elseif a:open_type ==# 'newtab' || g:MRU_Open_File_Use_Tabs - call s:MRU_Open_File_In_Tab(a:fname, esc_fname) - elseif a:open_type ==# 'preview' - " Edit the file in the preview window - exe 'topleft pedit ' . esc_fname + if a:open_type ==# 'newwin_horiz' + " Edit the file in a new horizontally split window below the previous + " window + wincmd p + if bufexists(esc_fname) + exe 'belowright sbuffer ' . esc_fname else - " If the selected file is already open in one of the windows, - " jump to it - let winnum = bufwinnr('^' . a:fname . '$') - if winnum != -1 - exe winnum . 'wincmd w' - else - if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0 - " Jump to the window from which the MRU window was opened - if exists('s:MRU_last_buffer') - let last_winnr = bufwinnr(s:MRU_last_buffer) - if last_winnr != -1 && last_winnr != winnr() - exe last_winnr . 'wincmd w' - endif - endif - else - if g:MRU_Use_Current_Window == 0 - " Goto the previous window - " If MRU_Use_Current_Window is set to one, then the - " current window is used to open the file - wincmd p - endif - endif - - let split_window = 0 - - if (!&hidden && (&modified || &previewwindow)) || a:multi - " Current buffer has unsaved changes or is the preview window - " or the user is opening multiple files - " So open the file in a new window - let split_window = 1 - endif - - if &buftype != '' - " Current buffer is a special buffer (maybe used by a plugin) - if g:MRU_Use_Current_Window == 0 || - \ bufnr('%') != bufnr('__MRU_Files__') - let split_window = 1 - endif - endif - - " Edit the file - if split_window - " Current buffer has unsaved changes or is a special buffer or - " is the preview window. So open the file in a new window - if a:edit_type ==# 'edit' - exe 'split ' . esc_fname - else - exe 'sview ' . esc_fname - endif - else - if a:edit_type ==# 'edit' - exe 'edit ' . esc_fname - else - exe 'view ' . esc_fname - endif - endif - endif + exe 'belowright new ' . esc_fname endif -endfunction + elseif a:open_type ==# 'newwin_vert' + " Edit the file in a new vertically split window right of the previous + " window + wincmd p + if bufexists(esc_fname) + exe 'vertical belowright sbuffer ' . esc_fname + else + exe 'belowright vnew ' . esc_fname + endif + elseif a:open_type ==# 'newtab' || g:MRU_Open_File_Use_Tabs + call s:MRU_Open_File_In_Tab(a:fname, esc_fname) + elseif a:open_type ==# 'preview' + " Edit the file in the preview window + exe 'topleft pedit ' . esc_fname + else + " If the selected file is already open in one of the windows, + " jump to it + let winnum = bufwinnr('^' . a:fname . '$') + if winnum != -1 && g:MRU_Use_Current_Window == 0 + exe winnum . 'wincmd w' + else + if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0 + " Jump to the window from which the MRU window was opened + if exists('s:MRU_last_buffer') + let last_winnr = bufwinnr(s:MRU_last_buffer) + if last_winnr != -1 && last_winnr != winnr() + exe last_winnr . 'wincmd w' + endif + endif + else + if g:MRU_Use_Current_Window == 0 + " Goto the previous window + " If MRU_Use_Current_Window is set to one, then the + " current window is used to open the file + wincmd p + endif + endif + + let split_window = 0 + + if (!&hidden && (&modified || &previewwindow)) || a:multi + " Current buffer has unsaved changes or is the preview window + " or the user is opening multiple files + " So open the file in a new window + let split_window = 1 + endif + + if !empty(&buftype) + " Current buffer is a special buffer (maybe used by a plugin) + if g:MRU_Use_Current_Window == 0 || + \ bufnr('%') != bufnr(s:MRU_buf_name) + let split_window = 1 + endif + endif + + " Edit the file + if split_window + " Current buffer has unsaved changes or is a special buffer or + " is the preview window. So open the file in a new window + if a:edit_type ==# 'edit' + if bufexists(esc_fname) + exe 'sbuffer ' . esc_fname + else + exe 'split ' . esc_fname + endif + else + exe 'sview ' . esc_fname + endif + else + let mod = '' + if g:MRU_Use_Current_Window + let mod = 'keepalt ' + endif + if a:edit_type ==# 'edit' + if bufexists(esc_fname) + exe mod . 'buffer ' . esc_fname + else + exe mod . 'edit ' . esc_fname + endif + else + exe mod . 'view ' . esc_fname + endif + endif + endif + endif + + " Make the buffer a listed buffer (in case it was deleted before) + setlocal buflisted +endfunc " MRU_Select_File_Cmd {{{1 " Open a file selected from the MRU window @@ -639,401 +514,574 @@ endfunction " 'newtab' to open the file in a new tab. " If multiple file names are selected using visual mode, then open multiple " files (either in split windows or tabs) -function! s:MRU_Select_File_Cmd(opt) range - let [edit_type, open_type] = split(a:opt, ',') +func! s:MRU_Select_File_Cmd(opt) range abort + let [edit_type, open_type] = split(a:opt, ',') - let fnames = getline(a:firstline, a:lastline) + let fnames = getline(a:firstline, a:lastline) - if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0 - " Automatically close the window if the file window is - " not used to display the MRU list. - silent! close + if g:MRU_Auto_Close == 1 && g:MRU_Use_Current_Window == 0 + " Automatically close the window if the file window is + " not used to display the MRU list. + silent! close + endif + + let multi = 0 + + for f in fnames + if empty(f) + continue endif - let multi = 0 + " The text in the MRU window contains the filename in parenthesis + let file = matchstr(f, g:MRU_Filename_Format.parser) - for f in fnames - if f == '' - continue - endif + call s:MRU_Window_Edit_File(file, multi, edit_type, open_type) - " The text in the MRU window contains the filename in parenthesis - let file = matchstr(f, g:MRU_Filename_Format.parser) - - call s:MRU_Window_Edit_File(file, multi, edit_type, open_type) - - if a:firstline != a:lastline - " Opening multiple files - let multi = 1 - endif - endfor -endfunction + if a:firstline != a:lastline + " Opening multiple files + let multi = 1 + endif + endfor +endfunc " MRU_Warn_Msg {{{1 " Display a warning message -function! s:MRU_Warn_Msg(msg) - echohl WarningMsg - echo a:msg - echohl None -endfunction +func! s:MRU_Warn_Msg(msg) abort + echohl WarningMsg + echo a:msg + echohl None +endfunc " MRU_Open_Window {{{1 " Display the Most Recently Used file list in a temporary window. -" If the optional argument is supplied, then it specifies the pattern of files +" If the 'pat' argument is not empty, then it specifies the pattern of files " to selectively display in the MRU window. -function! s:MRU_Open_Window(...) +" The 'splitdir' argument specifies the location (topleft, belowright, etc.) +" of the MRU window. +func! s:MRU_Open_Window(pat, splitdir, winsz) abort - " Load the latest MRU file list - call s:MRU_LoadList() + " Load the latest MRU file list + call s:MRU_LoadList() - " Check for empty MRU list - if empty(s:MRU_files) - call s:MRU_Warn_Msg('MRU file list is empty') - return - endif + " Check for empty MRU list + if empty(s:MRU_files) + call s:MRU_Warn_Msg('MRU file list is empty') + return + endif - " Save the current buffer number. This is used later to open a file when a - " entry is selected from the MRU window. The window number is not saved, - " as the window number will change when new windows are opened. - let s:MRU_last_buffer = bufnr('%') + " Save the current buffer number. This is used later to open a file when a + " entry is selected from the MRU window. The window number is not saved, + " as the window number will change when new windows are opened. + let s:MRU_last_buffer = bufnr('%') - let bname = '__MRU_Files__' + let bname = s:MRU_buf_name - " If the window is already open, jump to it - let winnum = bufwinnr(bname) - if winnum != -1 - if winnr() != winnum - " If not already in the window, jump to it - exe winnum . 'wincmd w' - endif - - setlocal modifiable - - " Delete the contents of the buffer to the black-hole register - silent! %delete _ - else - if g:MRU_Use_Current_Window - " Reuse the current window - " - " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open - " a new buffer - let bufnum = bufnr(bname) - if bufnum == -1 - let cmd = 'edit ' . bname - else - let cmd = 'buffer ' . bufnum - endif - - exe cmd - - if bufnr('%') != bufnr(bname) - " Failed to edit the MRU buffer - return - endif - else - " Open a new window at the bottom - - " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open - " a new buffer - let bufnum = bufnr(bname) - if bufnum == -1 - let wcmd = bname - else - let wcmd = '+buffer' . bufnum - endif - - exe 'silent! botright ' . g:MRU_Window_Height . 'split ' . wcmd - endif + " If the window is already open, jump to it + let winnum = bufwinnr(bname) + if winnum != -1 + if winnr() != winnum + " If not already in the window, jump to it + exe winnum . 'wincmd w' endif setlocal modifiable - " Mark the buffer as scratch - setlocal buftype=nofile - setlocal bufhidden=delete - setlocal noswapfile - setlocal nowrap - setlocal nobuflisted - " Set the 'filetype' to 'mru'. This allows the user to apply custom - " syntax highlighting or other changes to the MRU bufer. - setlocal filetype=mru - " Use fixed height for the MRU window - setlocal winfixheight + " Delete the contents of the buffer to the black-hole register + silent! %delete _ + else + if g:MRU_Use_Current_Window + " Reuse the current window - " Setup the cpoptions properly for the maps to work - let old_cpoptions = &cpoptions - set cpoptions&vim + " If the current buffer has unsaved changes or is a special buffer + " or is the preview window and 'hidden' is not set, then open a + " new window. Otherwise, open in the current window. + if !&hidden && (&modified || !empty(&buftype) || &previewwindow) + let split_window = 1 + else + let split_window = 0 + endif - " Create mappings to select and edit a file from the MRU list - nnoremap - \ :call MRU_Select_File_Cmd('edit,useopen') - vnoremap - \ :call MRU_Select_File_Cmd('edit,useopen') - nnoremap o - \ :call MRU_Select_File_Cmd('edit,newwin_horiz') - vnoremap o - \ :call MRU_Select_File_Cmd('edit,newwin_horiz') - nnoremap - \ :call MRU_Select_File_Cmd('edit,newwin_horiz') - vnoremap - \ :call MRU_Select_File_Cmd('edit,newwin_horiz') - nnoremap O - \ :call MRU_Select_File_Cmd('edit,newwin_vert') - vnoremap O - \ :call MRU_Select_File_Cmd('edit,newwin_vert') - nnoremap t - \ :call MRU_Select_File_Cmd('edit,newtab') - vnoremap t - \ :call MRU_Select_File_Cmd('edit,newtab') - nnoremap v - \ :call MRU_Select_File_Cmd('view,useopen') - nnoremap p - \ :call MRU_Select_File_Cmd('view,preview') - vnoremap p - \ :if line("'<") == line("'>") - \ call MRU_Select_File_Cmd('open,preview') - \ else - \ echoerr "Only a single file can be previewed" - \ endif - nnoremap u :MRU - nnoremap <2-LeftMouse> - \ :call MRU_Select_File_Cmd('edit,useopen') - nnoremap q :close - - " Restore the previous cpoptions settings - let &cpoptions = old_cpoptions - - " Display the MRU list - if a:0 == 0 - " 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:1) != -1') - if len(m) == 0 - " No match. Try using it as a regular expression - let m = filter(copy(s:MRU_files), 'v:val =~# a:1') + " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open + " a new buffer + let bufnum = bufnr(bname) + if bufnum == -1 + if split_window + let cmd = 'botright split ' . bname + else + let cmd = 'edit ' . bname endif + else + if split_window + let cmd = 'botright sbuffer ' . bufnum + else + let cmd = 'buffer ' . bufnum + endif + endif + + exe cmd + + if bufnr('%') != bufnr(bname) + " Failed to edit the MRU buffer + return + endif + else + " Open a new window at the bottom + let cmd = 'silent! ' + if empty(a:splitdir) + let cmd .= 'botright ' + else + let cmd .= a:splitdir . ' ' + endif + let sz = a:winsz + if sz == 0 + let sz = g:MRU_Window_Height + endif + let cmd .= sz . 'split ' + + " If the __MRU_Files__ buffer exists, then reuse it. Otherwise open + " a new buffer + let bufnum = bufnr(bname) + if bufnum == -1 + let cmd .= bname + else + let cmd .= '+buffer' . bufnum + endif + + exe cmd endif + endif - " Get the tail part of the file name (without the directory) and display - " it along with the full path in parenthesis. - let output = map(m, g:MRU_Filename_Format.formatter) - silent! 0put =output + setlocal modifiable - " Delete the empty line at the end of the buffer - silent! $delete _ + " Mark the buffer as scratch + setlocal buftype=nofile + if g:MRU_Use_Current_Window + " avoid using mru buffer as alternate file + setlocal bufhidden=wipe + else + setlocal bufhidden=delete + endif + setlocal noswapfile + setlocal nobuflisted + setlocal nowrap + setlocal nonumber + if exists('&relativenumber') + setlocal norelativenumber + endif + if exists('&signcolumn') + setlocal signcolumn=no + endif + setlocal foldcolumn=0 + " Set the 'filetype' to 'mru'. This allows the user to apply custom + " syntax highlighting or other changes to the MRU bufer. + setlocal filetype=mru + " Use fixed height and width for the MRU window + setlocal winfixheight winfixwidth - " Move the cursor to the beginning of the file - normal! gg + " Setup the cpoptions properly for the maps to work + let old_cpoptions = &cpoptions + set cpoptions&vim - " Add syntax highlighting for the file names - if has_key(g:MRU_Filename_Format, 'syntax') - exe "syntax match MRUFileName '" . g:MRU_Filename_Format.syntax . "'" - highlight default link MRUFileName Identifier + " Create mappings to select and edit a file from the MRU list + nnoremap + \ :call MRU_Select_File_Cmd('edit,useopen') + vnoremap + \ :call MRU_Select_File_Cmd('edit,useopen') + nnoremap o + \ :call MRU_Select_File_Cmd('edit,newwin_horiz') + vnoremap o + \ :call MRU_Select_File_Cmd('edit,newwin_horiz') + nnoremap + \ :call MRU_Select_File_Cmd('edit,newwin_horiz') + vnoremap + \ :call MRU_Select_File_Cmd('edit,newwin_horiz') + nnoremap O + \ :call MRU_Select_File_Cmd('edit,newwin_vert') + vnoremap O + \ :call MRU_Select_File_Cmd('edit,newwin_vert') + nnoremap t + \ :call MRU_Select_File_Cmd('edit,newtab') + vnoremap t + \ :call MRU_Select_File_Cmd('edit,newtab') + nnoremap v + \ :call MRU_Select_File_Cmd('view,useopen') + nnoremap p + \ :call MRU_Select_File_Cmd('view,preview') + vnoremap p + \ :if line("'<") == line("'>") + \ call MRU_Select_File_Cmd('open,preview') + \ else + \ echoerr "Only a single file can be previewed" + \ endif + nnoremap u :MRU + nnoremap <2-LeftMouse> + \ :call MRU_Select_File_Cmd('edit,useopen') + nnoremap d + \ :call MRU_Delete_From_List() + nnoremap q :close + + " Restore the previous cpoptions settings + let &cpoptions = old_cpoptions + + " Display the MRU list + if empty(a:pat) + " 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 + " 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') + endif + endif - setlocal nomodifiable -endfunction + " Get the tail part of the file name (without the directory) and display + " it along with the full path in parenthesis. + let output = map(m, g:MRU_Filename_Format.formatter) + silent! 0put =output + + " Delete the empty line at the end of the buffer + silent! $delete _ + + " Move the cursor to the beginning of the file + normal! gg + + " Add syntax highlighting for the file names + if has_key(g:MRU_Filename_Format, 'syntax') + exe "syntax match MRUFileName '" . g:MRU_Filename_Format.syntax . "'" + highlight default link MRUFileName Identifier + endif + + setlocal nomodifiable +endfunc " MRU_Complete {{{1 " Command-line completion function used by :MRU command -function! s:MRU_Complete(ArgLead, CmdLine, CursorPos) - if a:ArgLead == '' - " Return the complete list of MRU files - return s:MRU_files +func! s:MRU_Complete(ArgLead, CmdLine, CursorPos) abort + if empty(a:ArgLead) + " Return the complete list of MRU files + return s:MRU_files + else + 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') + " Return only the files matching the specified pattern + return filter(copy(s:MRU_files), 'v:val =~? a:ArgLead') endif -endfunction + endif +endfunc " MRU_Cmd {{{1 " Function to handle the MRU command " pat - File name pattern passed to the MRU command -function! s:MRU_Cmd(pat) - if a:pat == '' - " No arguments specified. Open the MRU window - call s:MRU_Open_Window() - return - endif +func! s:MRU_Cmd(pat, splitdir, winsz) abort + if empty(a:pat) + " No arguments specified. Open the MRU window + call s:MRU_Open_Window('', a:splitdir, a:winsz) + return + endif - " Load the latest MRU file - call s:MRU_LoadList() + " Load the latest MRU file + call s:MRU_LoadList() - " Empty MRU list - if empty(s:MRU_files) - call s:MRU_Warn_Msg('MRU file list is empty') - return - endif + " Empty MRU list + if empty(s:MRU_files) + call s:MRU_Warn_Msg('MRU file list is empty') + 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) + " 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') - 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 - 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) - return - endif - - " Couldn't find an exact match, open the MRU window with all the - " files matching the pattern. - call s:MRU_Open_Window(a:pat) - return - endif - - " Use the specified string as a regular expression pattern and search - " for filenames matching the pattern - let m = filter(copy(s:MRU_files), 'v:val =~? a:pat') - - if len(m) == 0 - " If an existing file (not present in the MRU list) is specified, - " then open the file. - if filereadable(a:pat) - call s:MRU_Edit_File(a:pat, 0) - return - endif - - " No filenames matching the specified pattern are found - call s:MRU_Warn_Msg("MRU file list doesn't contain " . - \ "files matching " . a:pat) - return - endif - + endif + if len(m) > 0 if len(m) == 1 && !g:MRU_Window_Open_Always - call s:MRU_Edit_File(m[0], 0) - return + call s:MRU_Edit_File(m[0], 0, a:splitdir) + return endif - call s:MRU_Open_Window(a:pat) + " 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, a:splitdir) + return + endif + + " Couldn't find an exact match, open the MRU window with all the + " files matching the pattern. + call s:MRU_Open_Window(a:pat, a:splitdir, a:winsz) + return + endif + + " Use the specified string as a regular expression pattern and search + " for filenames matching the pattern + let m = filter(copy(s:MRU_files), 'v:val =~? a:pat') + + if len(m) == 0 + " If an existing file (not present in the MRU list) is specified, + " then open the file. + if filereadable(a:pat) + call s:MRU_Edit_File(a:pat, 0, a:splitdir) + return + endif + + " No filenames matching the specified pattern are found + call s:MRU_Warn_Msg("MRU file list doesn't contain " . + \ 'files matching ' . a:pat) + return + endif + + if len(m) == 1 && !g:MRU_Window_Open_Always + call s:MRU_Edit_File(m[0], 0, a:splitdir) + return + endif + + call s:MRU_Open_Window(a:pat, a:splitdir, a:winsz) +endfunc + +" MRU_Toggle {{{1 +" Toggle MRU +" pat - File name pattern passed to the MRU command +func! s:MRU_Toggle(pat, splitdir) abort + " If the MRU window is open, close it + let winnum = bufwinnr(s:MRU_buf_name) + if winnum != -1 + exe winnum . 'wincmd w' + if g:MRU_Use_Current_Window && !empty(expand('#')) + silent! b # + else + silent! close + endif + else + call s:MRU_Cmd(a:pat, a:splitdir, '') + endif endfunction " MRU_add_files_to_menu {{{1 " Adds a list of files to the "Recent Files" sub menu under the "File" menu. " prefix - Prefix to use for each of the menu entries " file_list - List of file names to add to the menu -function! s:MRU_add_files_to_menu(prefix, file_list) - for fname in a:file_list - " Escape special characters in the filename - let esc_fname = escape(fnamemodify(fname, ':t'), ".\\" . - \ s:esc_filename_chars) - let esc_fname = substitute(esc_fname, '&', '&&', 'g') +func! s:MRU_add_files_to_menu(prefix, file_list) abort + for fname in a:file_list + " Escape special characters in the filename + let esc_fname = escape(fnamemodify(fname, ':t'), ".\\" . + \ s:esc_filename_chars) + let esc_fname = substitute(esc_fname, '&', '&&', 'g') - " Truncate the directory name if it is long - let dir_name = fnamemodify(fname, ':h') - let len = strlen(dir_name) - " Shorten long file names by adding only few characters from - " the beginning and end. - if len > 30 - let dir_name = strpart(dir_name, 0, 10) . - \ '...' . - \ strpart(dir_name, len - 20) - endif - let esc_dir_name = escape(dir_name, ".\\" . s:esc_filename_chars) - let esc_dir_name = substitute(esc_dir_name, '&', '&&', 'g') + " Truncate the directory name if it is long + let dir_name = fnamemodify(fname, ':h') + if v:version >= 800 || has('patch-7.4.1730') + let len = strchars(dir_name) + " Shorten long file names by adding only few characters from + " the beginning and end. + if len > 30 + let dir_name = strcharpart(dir_name, 0, 10) . + \ '...' . + \ strcharpart(dir_name, len - 20) + endif + else + let len = strlen(dir_name) + " Shorten long file names by adding only few characters from + " the beginning and end. + if len > 30 + let dir_name = strpart(dir_name, 0, 10) . + \ '...' . + \ strpart(dir_name, len - 20) + endif + endif + let esc_dir_name = escape(dir_name, ".\\" . s:esc_filename_chars) + let esc_dir_name = substitute(esc_dir_name, '&', '&&', 'g') - let menu_path = '&File.&Recent\ Files.' . a:prefix . esc_fname . - \ '\ (' . esc_dir_name . ')' - let esc_mfname = s:MRU_escape_filename(fname) - exe 'anoremenu ' . menu_path . - \ " :call MRU_Edit_File('" . esc_mfname . "', 1)" - exe 'tmenu ' . menu_path . ' Edit file ' . esc_mfname - endfor -endfunction + let menu_path = '&File.&Recent\ Files.' . a:prefix . esc_fname . + \ '\ (' . esc_dir_name . ')' + let esc_mfname = s:MRU_escape_filename(fname) + exe 'anoremenu ' . menu_path . + \ " :call MRU_Edit_File('" . esc_mfname . "', 1, '')" + exe 'tmenu ' . menu_path . ' Edit file ' . esc_mfname + endfor +endfunc " MRU_Refresh_Menu {{{1 " Refresh the MRU menu -function! s:MRU_Refresh_Menu() - if !has('menu') || !g:MRU_Add_Menu - " No support for menus - return +func! s:MRU_Refresh_Menu() abort + if !has('menu') || !g:MRU_Add_Menu + " No support for menus + return + endif + + " Setup the cpoptions properly for the maps to work + let old_cpoptions = &cpoptions + set cpoptions&vim + + " Remove the MRU menu + " To retain the teared-off MRU menu, we need to add a dummy entry + silent! unmenu &File.&Recent\ Files + " The menu priority of the File menu is 10. If the MRU plugin runs + " first before menu.vim, the File menu order may not be correct. + " So specify the priority of the File menu here. + 10noremenu &File.&Recent\ Files.Dummy + silent! unmenu! &File.&Recent\ Files + + anoremenu &File.&Recent\ Files.Refresh\ list + \ :call MRU_LoadList() + exe 'tmenu File.&Recent\ Files.Refresh\ list Reload the MRU file list from ' + \ . s:MRU_escape_filename(s:MRU_File) + anoremenu File.&Recent\ Files.-SEP1- : + + " Add the filenames in the MRU list to the menu + let entry_cnt = len(s:MRU_files) + if entry_cnt > g:MRU_Max_Menu_Entries + " Show only MRU_Max_Menu_Entries file names in the menu + let mru_list = s:MRU_files[0 : g:MRU_Max_Menu_Entries - 1] + let entry_cnt = g:MRU_Max_Menu_Entries + else + let mru_list = s:MRU_files + endif + if entry_cnt > g:MRU_Max_Submenu_Entries + " Split the MRU menu into sub-menus + for start_idx in range(0, entry_cnt, g:MRU_Max_Submenu_Entries) + let last_idx = start_idx + g:MRU_Max_Submenu_Entries - 1 + if last_idx >= entry_cnt + let last_idx = entry_cnt - 1 + endif + let prefix = 'Files\ (' . (start_idx + 1) . '\.\.\.' . + \ (last_idx + 1) . ').' + call s:MRU_add_files_to_menu(prefix, + \ mru_list[start_idx : last_idx]) + endfor + else + call s:MRU_add_files_to_menu('', mru_list) + endif + + " Remove the dummy menu entry + unmenu &File.&Recent\ Files.Dummy + + " Restore the previous cpoptions settings + let &cpoptions = old_cpoptions +endfunc + +" MRU_Refresh {{{1 +" Remove non-existing files from the MRU list +func s:MRU_Refresh() + call filter(s:MRU_files, 'filereadable(v:val)') + call s:MRU_SaveList() + call s:MRU_Refresh_Menu() +endfunc + +" MRU_Delete_From_List {{{1 +" remove the entry under cursor in the MRU window from the MRU list +func s:MRU_Delete_From_List() + call filter(s:MRU_files, + \ 'v:val != matchstr(getline("."), g:MRU_Filename_Format.parser)') + setlocal modifiable + del _ + setlocal nomodifiable + call s:MRU_SaveList() + call s:MRU_Refresh_Menu() +endfunc + +" Return the list of file names in the MRU list {{{1 +func MruGetFiles(...) + " Load the latest MRU list + call s:MRU_LoadList() + if a:0 == 1 + if g:MRU_FuzzyMatch + " Return only the files fuzzy matching the specified pattern + return matchfuzzy(s:MRU_files, a:1) endif - - " Setup the cpoptions properly for the maps to work - let old_cpoptions = &cpoptions - set cpoptions&vim - - " Remove the MRU menu - " To retain the teared-off MRU menu, we need to add a dummy entry - silent! unmenu &File.&Recent\ Files - " The menu priority of the File menu is 10. If the MRU plugin runs - " first before menu.vim, the File menu order may not be correct. - " So specify the priority of the File menu here. - 10noremenu &File.&Recent\ Files.Dummy - silent! unmenu! &File.&Recent\ Files - - anoremenu &File.&Recent\ Files.Refresh\ list - \ :call MRU_LoadList() - exe 'tmenu File.&Recent\ Files.Refresh\ list Reload the MRU file list from ' - \ . s:MRU_escape_filename(g:MRU_File) - anoremenu File.&Recent\ Files.-SEP1- : - - " Add the filenames in the MRU list to the menu - let entry_cnt = len(s:MRU_files) - if entry_cnt > g:MRU_Max_Menu_Entries - " Show only MRU_Max_Menu_Entries file names in the menu - let mru_list = s:MRU_files[0 : g:MRU_Max_Menu_Entries - 1] - let entry_cnt = g:MRU_Max_Menu_Entries - else - let mru_list = s:MRU_files - endif - if entry_cnt > g:MRU_Max_Submenu_Entries - " Split the MRU menu into sub-menus - for start_idx in range(0, entry_cnt, g:MRU_Max_Submenu_Entries) - let last_idx = start_idx + g:MRU_Max_Submenu_Entries - 1 - if last_idx >= entry_cnt - let last_idx = entry_cnt - 1 - endif - let prefix = 'Files\ (' . (start_idx + 1) . '\.\.\.' . - \ (last_idx + 1) . ').' - call s:MRU_add_files_to_menu(prefix, - \ mru_list[start_idx : last_idx]) - endfor - else - call s:MRU_add_files_to_menu('', mru_list) - endif - - " Remove the dummy menu entry - unmenu &File.&Recent\ Files.Dummy - - " Restore the previous cpoptions settings - let &cpoptions = old_cpoptions -endfunction + " Return only the files matching the specified pattern + return filter(copy(s:MRU_files), 'v:val =~? a:1') + endif + return copy(s:MRU_files) +endfunc " Load the MRU list on plugin startup call s:MRU_LoadList() +" Set the first entry in the MRU list as the alternate file +" Credit to Martin Roa Villescas (https://github.com/mroavi) for the patch. +" bufadd() is available starting from Vim 8.1.1610 +if g:MRU_Set_Alternate_File == 1 && + \ (v:version >= 802 || has('patch-8.1.1610') || has('nvim')) + if !empty(s:MRU_files) + let first_mru_file = s:MRU_files[0] + if filereadable(first_mru_file) + call bufadd(first_mru_file) + let @# = first_mru_file + endif + endif +endif + " MRU autocommands {{{1 -" Autocommands to detect the most recently used files -autocmd BufRead * call s:MRU_AddFile(expand('')) -autocmd BufNewFile * call s:MRU_AddFile(expand('')) -autocmd BufWritePost * call s:MRU_AddFile(expand('')) +" Autocommands to update the most recently used files +augroup MRUAutoCmds + au! + autocmd BufRead * call s:MRU_AddFile(expand('')) + autocmd BufWritePost * call s:MRU_AddFile(expand('')) + autocmd BufEnter * call s:MRU_AddFile(expand('')) -" The ':vimgrep' command adds all the files searched to the buffer list. -" This also modifies the MRU list, even though the user didn't edit the -" files. Use the following autocmds to prevent this. -autocmd QuickFixCmdPre *vimgrep* let s:mru_list_locked = 1 -autocmd QuickFixCmdPost *vimgrep* let s:mru_list_locked = 0 + " The ':vimgrep' command adds all the files searched to the buffer list. + " This also modifies the MRU list, even though the user didn't edit the + " files. Use the following autocmds to prevent this. + autocmd QuickFixCmdPre *vimgrep* let s:mru_list_locked = 1 + autocmd QuickFixCmdPost *vimgrep* let s:mru_list_locked = 0 +augroup END -" Command to open the MRU window -command! -nargs=? -complete=customlist,s:MRU_Complete MRU - \ call s:MRU_Cmd() -command! -nargs=? -complete=customlist,s:MRU_Complete Mru - \ call s:MRU_Cmd() +" MRU custom commands {{{1 +if v:version >= 800 + command! -nargs=? -complete=customlist,s:MRU_Complete -count=0 MRU + \ call s:MRU_Cmd(, , ) + command! -nargs=? -complete=customlist,s:MRU_Complete -count=0 Mru + \ call s:MRU_Cmd(, , ) + command! -nargs=? -complete=customlist,s:MRU_Complete MRUToggle + \ call s:MRU_Toggle(, ) +else + command! -nargs=? -complete=customlist,s:MRU_Complete -count=0 MRU + \ call s:MRU_Cmd(, '', ) + command! -nargs=? -complete=customlist,s:MRU_Complete -count=0 Mru + \ call s:MRU_Cmd(, '', ) + command! -nargs=? -complete=customlist,s:MRU_Complete MRUToggle + \ call s:MRU_Toggle(, '') +endif +command! -nargs=0 MruRefresh call s:MRU_Refresh() + +" FZF (fuzzy finder) integration {{{1 +func s:MRU_FZF_EditFile(fname) abort + call s:MRU_Window_Edit_File(a:fname, 0, 'edit', 'useopen') +endfunc + +func s:MRU_FZF_Run() abort + if !exists('*fzf#run') + call s:MRU_Warn_Msg('FZF plugin is not present') + return + endif + + " Load the latest MRU list + call s:MRU_LoadList() + + call fzf#run(fzf#wrap({'source' : s:MRU_files, + \ 'options' : '--no-sort', + \ 'sink' : function('s:MRU_FZF_EditFile')}, 0)) +endfunc +command! -nargs=0 FZFMru call s:MRU_FZF_Run() " }}} -" restore 'cpo' -let &cpo = s:cpo_save +" restore 'cpoptions' +let &cpoptions = s:cpo_save unlet s:cpo_save -" vim:set foldenable foldmethod=marker: +" vim:set sw=2 sts=2 foldenable foldmethod=marker: diff --git a/sources_non_forked/mru.vim/test/.coveragerc b/sources_non_forked/mru.vim/test/.coveragerc new file mode 100644 index 00000000..2a3892b8 --- /dev/null +++ b/sources_non_forked/mru.vim/test/.coveragerc @@ -0,0 +1,3 @@ +[run] +plugins = covimerage +data_file = .coverage_covimerage diff --git a/sources_non_forked/mru.vim/test/run_mru_tests.cmd b/sources_non_forked/mru.vim/test/run_mru_tests.cmd new file mode 100644 index 00000000..f4d2501f --- /dev/null +++ b/sources_non_forked/mru.vim/test/run_mru_tests.cmd @@ -0,0 +1,18 @@ +@echo off + +REM Script to run the unit-tests for the MRU Vim plugin on MS-Windows + +SETLOCAL +SET VIMPRG="vim.exe" +REM SET VIMPRG="C:\Program Files (x86)\vim\vim82\vim.exe" +REM SET VIMPRG="C:\Program Files (x86)\vim\vim73\vim.exe" +SET VIM_CMD=%VIMPRG% -N -u NONE -U NONE -i NONE --not-a-term + +%VIM_CMD% -S unit_tests.vim + +echo MRU unit test results +type results.txt + +findstr /I FAIL results.txt > nul 2>&1 +if %ERRORLEVEL% EQU 0 echo ERROR: Some test failed. +if %ERRORLEVEL% NEQ 0 echo SUCCESS: All the tests passed. diff --git a/sources_non_forked/mru.vim/test/run_mru_tests.sh b/sources_non_forked/mru.vim/test/run_mru_tests.sh new file mode 100755 index 00000000..7c987dc7 --- /dev/null +++ b/sources_non_forked/mru.vim/test/run_mru_tests.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Script to run the unit-tests for the MRU Vim plugin + +VIMPRG=${VIMPRG:=/usr/bin/vim} +VIM_CMD="$VIMPRG -N -u NONE -U NONE -i NONE" + +$VIM_CMD -S unit_tests.vim + +echo "MRU unit test results" +echo + +if [ ! -f results.txt ] +then + echo "ERROR: Test results file 'results.txt' is not found" + exit 1 +fi + +cat results.txt + +echo +grep FAIL results.txt > /dev/null 2>&1 +if [ $? -eq 0 ] +then + echo "ERROR: Some test(s) failed." + exit 1 +fi + +echo "SUCCESS: All the tests passed." +exit 0 diff --git a/sources_non_forked/mru.vim/test/unit_tests.vim b/sources_non_forked/mru.vim/test/unit_tests.vim new file mode 100644 index 00000000..40f510ea --- /dev/null +++ b/sources_non_forked/mru.vim/test/unit_tests.vim @@ -0,0 +1,1830 @@ +" MRU plugin unit-tests + +" MRU plugin settings +let MRU_File='vim_mru_file' +let MRU_Auto_Close=1 +let MRU_Max_Entries=10 +let MRU_buffer_name = '-RecentFiles-' + +" Set the $MRU_PROFILE environment variable to profile the MRU plugin +let s:do_profile = 0 +if exists('$MRU_PROFILE') + let s:do_profile = 1 +endif + +" Profile the MRU plugin +if s:do_profile + profile start mru_profile.txt + profile! file */mru.vim +endif + +" Tests assume that 'hidden' option is not set +set nohidden + +source ../plugin/mru.vim + +" Function to log test results +func! LogResult(test, result) + call add(g:results, a:test . ': ' . a:result) +endfunc + +" ========================================================================== +" Test1 +" When the MRU list is empty, invoking the MRU command should return an error +" ========================================================================== +func Test_01() + let test_name = 'test1' + + redir => msg + MRU + redir END + if msg =~# "MRU file list is empty" + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test2 +" Open the MRU window and check the order of files listed in the window +" Open the MRU window when the window is already opened. +" ========================================================================== +func Test_02() + let test_name = 'test2' + + edit file1.txt + edit file2.txt + edit file3.txt + edit file2.txt + edit file1.txt + + MRU + MRU + + let l = getline(1, "$") + if l[0] =~# "file1.txt" && l[1] =~# "file2.txt" && l[2] =~# "file3.txt" + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test3 +" Select a file from the MRU window and check whether it is opened +" ========================================================================== +func Test_03() + let test_name = 'test3' + + " Go to the last but one line + $ + + " Select the last file in the MRU window + exe "normal \" + + if fnamemodify(@%, ':p:t') !=# 'file3.txt' + call LogResult(test_name, "FAIL (1)") + else + " Make sure the MRU window is closed + if bufwinnr(g:MRU_buffer_name) == -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, "FAIL (2)") + endif + endif +endfunc + +" ========================================================================== +" Test4 +" MRU opens a selected file in the previous/last window +" ========================================================================== +func Test_04() + let test_name = 'test4' + + " Edit a file and then open a new window, open the MRU window and select the + " file + split file1.txt + only + below new + + MRU + call search('file2.txt') + exe "normal \" + + if winnr() == 2 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test5 +" MRU opens a selected file in the same window if the file is already opened +" ========================================================================== +func Test_05() + let test_name = 'test5' + + edit file1.txt + only + below split file2.txt + below split file3.txt + + MRU + call search('file1.txt') + exe "normal \" + + if winnr() != 1 || fnamemodify(@%, ':p:t') !=# 'file1.txt' + call LogResult(test_name, "FAIL (1)") + else + MRU + call search('file2.txt') + exe "normal \" + if winnr() != 2 || fnamemodify(@%, ':p:t') !=# 'file2.txt' + call LogResult(test_name, "FAIL (2)") + else + MRU + call search('file3.txt') + exe "normal \" + if winnr() != 3 || fnamemodify(@%, ':p:t') !=# 'file3.txt' + call LogResult(test_name, "FAIL (3)") + else + call LogResult(test_name, 'pass') + endif + endif + endif +endfunc + +" ========================================================================== +" Test6 +" MRU opens a file selected with 'o' command in a new window +" ========================================================================== +func Test_06() + let test_name = 'test6' + enew | only + + edit file1.txt + below new + + MRU + normal o + + if winnr() == 3 && fnamemodify(@%, ':p:t') ==# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test7 +" MRU opens the selected file in a new window if the previous buffer is +" modified. +" ========================================================================== +func Test_07() + let test_name = 'test7' + enew | only + + insert + MRU plugin test +. + MRU + call search('file3.txt') + exe "normal \" + if winnr() == 1 && winnr('$') == 2 && + \ fnamemodify(@%, ':p:t') ==# 'file3.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + " Discard changes in the new buffer + wincmd b + enew! + only +endfunc + +" ========================================================================== +" Test8 +" MRU opens a file selected with 'v' command in read-only mode in the current +" window. +" ========================================================================== +func Test_08() + let test_name = 'test8' + enew | only + + MRU + call search('file1.txt') + normal v + let r1 = &readonly + MRU + call search('file2.txt') + exe "normal \" + let r2 = &readonly + MRU + call search('file1.txt') + exe "normal \" + let r3 = &readonly + if r1 == 1 && r2 == 0 && r3 == 1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test9 +" Use 'O' in the MRU window to open a file in a vertically split window +" ========================================================================== +func Test_09() + let test_name = 'test9' + enew | only + + edit file1.txt + MRU + call search('file2.txt') + normal O + let b1 = @% + wincmd h + let b2 = @% + wincmd l + let b3 = @% + if winnr('$') == 2 && b1 ==# 'file2.txt' && + \ b2 ==# 'file1.txt' && b3 ==# 'file2.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test10 +" Use 'p' in the MRU window to open a file in the preview window +" ========================================================================== +func Test_10() + let test_name = 'test10' + enew | only + + MRU + call search('file3.txt') + normal p + wincmd P + let p1 = &previewwindow + let b1 = @% + if winnr('$') == 2 && &previewwindow && @% =~# 'file3.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + pclose +endfunc + +" ========================================================================== +" Test11 +" MRU opens a file selected with 't' command in a new tab and the tab +" is opened at the end +" ========================================================================== +func Test_11() + let test_name = 'test11' + enew | only + + edit a1.txt + tabnew a2.txt + tabnew a3.txt + tabnew a4.txt + tabfirst + MRU + call search('file3.txt') + normal t + if fnamemodify(@%, ':p:t') ==# 'file3.txt' && tabpagenr() == 5 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + call LogResult(test_name, "file = " . fnamemodify(@%, ':p:t')) + call LogResult(test_name, "tab page = " . tabpagenr()) + endif + + tabonly +endfunc + +" ========================================================================== +" Test12 +" The 'q' command closes the MRU window +" ========================================================================== +func Test_12() + let test_name = 'test12' + enew | only + + MRU + normal q + if bufwinnr(g:MRU_buffer_name) == -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test13 +" A selected file is opened in a new window if the previous window is a +" preview window +" ========================================================================== +func Test_13() + let test_name = 'test13' + enew | only + + setlocal previewwindow + MRU + call search('file2.txt') + exe "normal \" + if winnr() == 1 && winnr('$') == 2 && + \ &previewwindow == 0 && + \ fnamemodify(@%, ':p:t') ==# 'file2.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + " Close the preview window created by this test + new + only +endfunc + +" ========================================================================== +" Test14 +" A selected file is opened in a new window if the previous window contains +" a special buffer (used by some other plugin) +" ========================================================================== +func Test_14() + let test_name = 'test14' + enew | only + + setlocal buftype=nofile + MRU + call search('file3.txt') + exe "normal \" + if winnr() == 1 && winnr('$') == 2 && + \ &buftype == '' && + \ fnamemodify(@%, ':p:t') ==# 'file3.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + " Discard the special buffer + enew +endfunc + +" ========================================================================== +" Test15 +" If a file selected using the 't' command is already opened in a tab, +" then jump to that tab (instead of opening a new tab) +" ========================================================================== +func Test_15() + let test_name = 'test15' + enew | only + + " Open the test files in the middle window with empty windows at the top and + " bottom + edit file1.txt + above new + botright new + tabedit file2.txt + above new + botright new + tabedit file3.txt + above new + botright new + tabfirst + + MRU + call search('file3.txt') + exe "normal t" + if tabpagenr() != 3 + \ || fnamemodify(@%, ':p:t') !=# 'file3.txt' + \ || winnr() != 2 + call LogResult(test_name, "FAIL (1)") + else + MRU + call search('file1.txt') + exe "normal t" + if tabpagenr() != 1 + \ || fnamemodify(@%, ':p:t') !=# 'file1.txt' + \ || winnr() != 2 + call LogResult(test_name, "FAIL (2)") + else + MRU + call search('file2.txt') + exe "normal t" + if tabpagenr() != 2 + \ || fnamemodify(@%, ':p:t') !=# 'file2.txt' + \ || winnr() != 2 + call LogResult(test_name, "FAIL (3)") + else + call LogResult(test_name, 'pass') + endif + endif + endif + + " Close all the other tabs + tabonly + enew + only +endfunc + +" ========================================================================== +" Test16 +" Open multiple files from the MRU window using the visual mode and by using a +" count. Each file should be opened in a separate window. +" ========================================================================== +func Test_16() + let test_name = 'test16' + enew | only + + edit file3.txt + edit file2.txt + edit file1.txt + enew + MRU + exe "normal 3\" + if winnr('$') == 3 && + \ bufwinnr('file3.txt') == 1 && + \ bufwinnr('file2.txt') == 2 && + \ bufwinnr('file1.txt') == 3 + let test_result = 'pass' + else + let test_result = 'FAIL' + endif + + only | enew + + if test_result == 'pass' + MRU + exe "normal V2j\" + if winnr('$') == 3 && + \ bufwinnr('file1.txt') == 1 && + \ bufwinnr('file2.txt') == 2 && + \ bufwinnr('file3.txt') == 3 + let test_result = 'pass' + else + let test_result = 'FAIL' + endif + endif + + if test_result == 'pass' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test17 +" When the MRU list is updated, the MRU file also should updated. +" ========================================================================== +func Test_17() + let test_name = 'test17' + enew | only + + edit file1.txt + let l = readfile(g:MRU_File) + if l[1] =~# 'file1.txt' + edit file2.txt + let l = readfile(g:MRU_File) + if l[1] =~# 'file2.txt' + edit file3.txt + let l = readfile(g:MRU_File) + if l[1] =~# 'file3.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, "FAIL (3)") + endif + else + call LogResult(test_name, "FAIL (2)") + endif + else + call LogResult(test_name, "FAIL (1)") + endif +endfunc + +" MRU_Test_Add_Files +" Add the supplied List of files to the beginning of the MRU file +func! s:MRU_Test_Add_Files(fnames) + let l = readfile(g:MRU_File) + call extend(l, a:fnames, 1) + call writefile(l, g:MRU_File) +endfunc + +" ========================================================================== +" Test18 +" When the MRU file is updated by another Vim instance, the MRU plugin +" should update the MRU list +" ========================================================================== +func Test_18() + let test_name = 'test18' + enew | only + + call s:MRU_Test_Add_Files(['/software/editors/vim', + \ '/software/editors/emacs', + \ '/software/editors/nano']) + MRU + if getline(1) ==# 'vim (/software/editors/vim)' + \ && getline(2) ==# 'emacs (/software/editors/emacs)' + \ && getline(3) ==# 'nano (/software/editors/nano)' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + " Close the MRU window + close +endfunc + +" ========================================================================== +" Test19 +" When the MRU file is updated by another Vim instance, the MRU file names +" from the current instance should be merged with that list +" ========================================================================== +func Test_19() + let test_name = 'test19' + enew | only + + " Remove all the files from the MRU file + let l = readfile(g:MRU_File) + call remove(l, 1, -1) + call writefile(l, g:MRU_File) + edit file1.txt + call s:MRU_Test_Add_Files(['/software/os/unix']) + edit file2.txt + call s:MRU_Test_Add_Files(['/software/os/windows']) + edit file3.txt + call s:MRU_Test_Add_Files(['/software/os/osx']) + MRU + if getline(1) ==# 'osx (/software/os/osx)' + \ && getline(2) =~# 'file3.txt' + \ && getline(3) ==# 'windows (/software/os/windows)' + \ && getline(4) =~# 'file2.txt' + \ && getline(5) ==# 'unix (/software/os/unix)' + \ && getline(6) =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + close +endfunc + +" ========================================================================== +" Test20 +" When the MRU list has more than g:MRU_Max_Entries, the list should be +" trimmed. The last entries should be removed. +" ========================================================================== +func Test_20() + let test_name = 'test20' + enew | only + + " Create a MRU list with MRU_Max_Entries + let flist = [] + for i in range(1, g:MRU_Max_Entries) + let flist += ['/usr/share/mru_test/mru_file' . i . '.abc'] + endfor + + " Modify the MRU file to contain max entries + let l = readfile(g:MRU_File) + call remove(l, 1, -1) + call extend(l, flist) + call writefile(l, g:MRU_File) + + enew + edit file1.txt + let l = readfile(g:MRU_File) + if len(l) == (g:MRU_Max_Entries + 1) && + \ l[g:MRU_Max_Entries] != '/usr/share/mru_test/mru_file9.abc' + call LogResult(test_name, "FAIL (1)") + else + edit file2.txt + let l = readfile(g:MRU_File) + if len(l) == (g:MRU_Max_Entries + 1) && + \ l[g:MRU_Max_Entries] != '/usr/share/mru_test/mru_file8.abc' + call LogResult(test_name, "FAIL (2)") + else + edit file3.txt + let l = readfile(g:MRU_File) + if len(l) == (g:MRU_Max_Entries + 1) && + \ l[g:MRU_Max_Entries] != '/usr/share/mru_test/mru_file7.abc' + call LogResult(test_name, "FAIL (3)") + else + call LogResult(test_name, 'pass') + endif + endif + endif +endfunc + +" ========================================================================== +" Test21 +" When an filename (already present in the MRU list) is specified to the MRU +" command, it should edit the file. +" ========================================================================== +func Test_21() + let test_name = 'test21' + enew | only + + edit file1.txt + edit file2.txt + edit file3.txt + enew + MRU file2.txt + if fnamemodify(@%, ':p:t') ==# 'file2.txt' && winnr('$') == 1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test22 +" When a pattern (matching multiple filenames) is specified to the MRU +" command, then the MRU window should be opened with all the matching +" filenames +" ========================================================================== +func Test_22() + let test_name = 'test22' + enew | only + + edit file1.txt + edit file2.txt + edit file3.txt + only + MRU file.* + if @% != g:MRU_buffer_name + call LogResult(test_name, 'FAIL') + else + let l = getline(1, "$") + if l[0] =~# "file3.txt" && l[1] =~# "file2.txt" && l[2] =~# "file1.txt" + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + endif + close +endfunc + +" ========================================================================== +" Test23 +" When a partial filename (matching multiple filenames) is specified to the +" MRU command, then the MRU window should be opened with all the matching +" filenames +" ========================================================================== +func Test_23() + let test_name = 'test23' + enew | only + + let g:MRU_FuzzyMatch = 0 + edit file1.txt + edit file2.txt + edit file3.txt + only + MRU file + if @% != g:MRU_buffer_name + call LogResult(test_name, 'FAIL') + else + let l = getline(1, "$") + if l[0] =~# "file3.txt" && l[1] =~# "file2.txt" && l[2] =~# "file1.txt" + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + endif + close +endfunc + +" ========================================================================== +" Test24 +" When a non-existing filename is specified to the MRU command, an error +" message should be displayed. +" ========================================================================== +func Test_24() + let test_name = 'test24' + + let g:MRU_FuzzyMatch = 0 + redir => msg + MRU nonexistingfile.txt + redir END + if @% == g:MRU_buffer_name || + \ msg !~# "MRU file list doesn't contain files " . + \ "matching nonexistingfile.txt" + call LogResult(test_name, 'FAIL') + else + call LogResult(test_name, 'pass') + endif +endfunc + +" ========================================================================== +" Test25 +" The MRU command should support filename completion. Supply a partial file +" name to the MRU command and complete the filenames. +" ========================================================================== +func Test_25() + let test_name = 'test25' + enew | only + + edit file1.txt + edit file2.txt + edit file3.txt + exe 'normal! :MRU file' . "\" . "\let m='\'\" + let fnames = split(m) + if fnames[1] =~# 'file3.txt' && fnames[2] =~# 'file2.txt' && + \ fnames[3] =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test26 +" When trying to complete filenames for the MRU command without specifying +" any text should return the entire MRU list. +" ========================================================================== +func Test_26() + let test_name = 'test26' + enew | only + + call delete(g:MRU_File) + edit file1.txt + edit file2.txt + edit file3.txt + + exe 'normal! :MRU ' . "\" . "\let m='\'\" + let fnames = split(m) + if fnames[1] =~# 'file3.txt' && fnames[2] =~# 'file2.txt' && + \ fnames[3] =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test27 +" When the current file/buffer has unsaved changes, MRU should open a selected +" file in a new window (if the 'hidden' option is not set) +" ========================================================================== +func Test_27() + let test_name = 'test27' + enew | only + + edit file1.txt + edit file2.txt + call append(line('$'), 'Temporary changes to buffer') + MRU + call search('file1.txt') + exe "normal \" + if winnr() == 1 && winnr('$') == 2 && + \ fnamemodify(@%, ':p:t') ==# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + close + edit! +endfunc + +" ========================================================================== +" Test28 +" When the current file/buffer has unsaved changes and the 'hidden' option is +" set, then MRU should open a selected file in the current window +" ========================================================================== +func Test_28() + let test_name = 'test28' + enew | only + + edit file2.txt + edit file1.txt + call append(line('$'), 'Temporary changes to buffer') + set hidden + + MRU + call search('file2.txt') + exe "normal \" + if winnr('$') == 1 && + \ fnamemodify(@%, ':p:t') ==# 'file2.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + edit file1.txt + edit! + set nohidden + %bw! +endfunc + +" ========================================================================== +" Test29 +" Every edited file is added to the top of the MRU list. If a file is already +" present in the MRU list, then it is moved to the top of the list. +" ========================================================================== +func Test_29() + let test_name = 'test29' + enew | only + + edit file1.txt + let f1 = readfile(g:MRU_File, '', 2) + edit file2.txt + let f2 = readfile(g:MRU_File, '', 2) + edit file3.txt + let f3 = readfile(g:MRU_File, '', 2) + edit file1.txt + let f4 = readfile(g:MRU_File, '', 2) + if f1[1] =~# 'file1.txt' && f2[1] =~# 'file2.txt' && f3[1] =~# 'file3.txt' && + \ f4[1] =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test30 +" Only file names matching the regular expression in the MRU_Include_Files +" variable should be added to the MRU list. +" ========================================================================== +func Test_30() + let test_name = 'test30' + enew | only + + edit file1.txt + let g:MRU_Include_Files='\.c' + edit abc.c + let f1 = readfile(g:MRU_File, '', 2) + edit file1.txt + let f2 = readfile(g:MRU_File, '', 2) + edit def.c + let f3 = readfile(g:MRU_File, '', 2) + if f1[1] =~# 'abc.c' && f2[1] =~# 'abc.c' && f3[1] =~# 'def.c' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + let g:MRU_Include_Files='' +endfunc + +" ========================================================================== +" Test31 +" File names matching the regular expression in the MRU_Exclude_Files +" variable should not be added to the MRU list. +" ========================================================================== +func Test_31() + let test_name = 'test31' + enew | only + + let g:MRU_Exclude_Files='\.txt' + edit abc.c + let f1 = readfile(g:MRU_File, '', 2) + edit file1.txt + edit file2.txt + edit file3.txt + let f2 = readfile(g:MRU_File, '', 2) + edit def.c + let f3 = readfile(g:MRU_File, '', 2) + let g:MRU_Exclude_Files='' + edit file1.txt + let f4 = readfile(g:MRU_File, '', 2) + if f1[1] =~# 'abc.c' && f2[1] =~# 'abc.c' && f3[1] =~# 'def.c' && + \ f4[1] =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test32 +" If the MRU window is open, when adding a file name to the list, the MRU +" window should be refreshed. +" ========================================================================== +func Test_32() + let test_name = 'test32' + enew | only + + MRU + wincmd p + edit abc.c + wincmd p + let s1 = getline(1) + wincmd p + edit file1.txt + wincmd p + let s2 = getline(1) + close + if s1 =~# 'abc.c' && s2 =~# 'file1.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test33 +" When MRU_Use_Current_Window is set, the MRU list should be displayed in +" the current window. +" Selecting a file from the MRU window should replace +" the MRU buffer with the selected file. +" ========================================================================== +func Test_33() + let test_name = 'test33' + enew | only + + edit file1.txt + let g:MRU_Use_Current_Window=1 + MRU + if winnr('$') == 1 && @% == g:MRU_buffer_name + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + let g:MRU_Use_Current_Window=0 +endfunc + +" ========================================================================== +" Test34 +" When MRU_Use_Current_Window is set, selecting a file from the MRU window +" should replace the MRU buffer with the selected file. +" ========================================================================== +func Test_34() + let test_name = 'test34' + enew | only + + let g:MRU_Use_Current_Window=1 + let w:marker=1 + MRU + if winnr('$') == 1 && w:marker && @% == g:MRU_buffer_name + call search('file2.txt') + exe "normal \" + if winnr('$') == 1 && w:marker && @% == 'file2.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + else + call LogResult(test_name, 'FAIL') + endif + unlet w:marker + let g:MRU_Use_Current_Window=0 +endfunc + +" ========================================================================== +" Test35 +" When MRU_Use_Current_Window is set, if the current buffer has unsaved +" changes, then the MRU window should be opened in a split window +" ========================================================================== +func Test_35() + let test_name = 'test35' + enew | only + + let g:MRU_Use_Current_Window=1 + set modified + MRU + if winnr('$') == 2 && winnr() == 2 && @% == g:MRU_buffer_name + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + close + set nomodified + let g:MRU_Use_Current_Window=0 + enew | only +endfunc + +" ========================================================================== +" Test36 +" When MRU_Auto_Close is not set, the MRU window should not automatically +" close when a file is selected. The MRU window should be kept open. +" ========================================================================== +func Test_36() + let test_name = 'test36' + enew | only + + let g:MRU_Auto_Close=0 + new + MRU + call search('file1.txt') + exe "normal \" + 2wincmd w + MRU + call search('file2.txt') + exe "normal \" + if winnr('$') == 3 && + \ bufwinnr('file1.txt') == 1 && + \ bufwinnr('file2.txt') == 2 && + \ bufwinnr(g:MRU_buffer_name) == 3 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + wincmd b + close + let g:MRU_Auto_Close=1 + only +endfunc + +" ========================================================================== +" Test37 +" When MRU_Open_File_Use_Tabs is set, a selected file should be opened in a +" tab. If the file is already opened in a tab, then the focus should be moved +" to that tab. +" ========================================================================== +func Test_37() + let test_name = 'test37' + enew | only + + let g:MRU_Open_File_Use_Tabs=1 + edit file1.txt + MRU + call search('file2.txt') + exe "normal \" + MRU + call search('file3.txt') + exe "normal \" + MRU file1.txt + let t1 = tabpagenr() + MRU + call search('file2.txt') + exe "normal \" + let t2 = tabpagenr() + MRU + call search('file3.txt') + exe "normal \" + let t3 = tabpagenr() + + tabonly | enew + + if t1 == 1 && t2 == 2 && t3 == 3 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + + let g:MRU_Open_File_Use_Tabs=0 +endfunc + +" ========================================================================== +" Test38 +" If the MRU_Window_Open_Always is set to 0, when the MRU command finds a +" single matching file name, then it should open the MRU window. If this +" variable is set to 1, then the file should be opened without opening the MRU +" window. +" ========================================================================== +func Test_38() + let test_name = 'test38' + enew | only + + edit file3.txt + enew + + let g:MRU_Window_Open_Always=1 + MRU file3.txt + if winnr('$') == 2 && + \ bufwinnr(g:MRU_buffer_name) == 2 + let test_result = 'pass' + else + let test_result = 'FAIL' + endif + close + + enew | only + + if test_result == 'pass' + let g:MRU_Window_Open_Always=0 + MRU file3.txt + if winnr('$') == 1 && + \ bufwinnr('file3.txt') == 1 + let test_result = 'pass' + else + let test_result = 'FAIL' + endif + endif + + let g:MRU_Window_Open_Always=0 + + if test_result == 'pass' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test39 +" If the current tabpage is empty, then pressing 't' in the MRU window +" should open the file in the current tabpage. +" ========================================================================== +func Test_39() + let test_name = 'test39' + enew | only | tabonly + tabnew + tabnew + tabnext 2 + MRU + call search('file2.txt') + normal t + if fnamemodify(@%, ':p:t') ==# 'file2.txt' && tabpagenr() == 2 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + call LogResult(test_name, "file = " . fnamemodify(@%, ':p:t')) + call LogResult(test_name, "tab page = " . tabpagenr()) + endif + + tabonly +endfunc + +" ========================================================================== +" Test40 +" Pressing 'd' in the MRU window should delete the file under the cursor +" from the MRU list +" ========================================================================== +func Test_40() + let test_name = 'test40' + edit file2.txt + enew + MRU + call search('file2.txt') + normal d + close + let l = readfile(g:MRU_File) + if match(l, 'file2.txt') == -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif +endfunc + +" ========================================================================== +" Test41 +" Running the :vimgrep command should not add the files to the MRU list +" ========================================================================== +func Test_41() + let test_name = 'test41' + call writefile(['bright'], 'dummy1.txt') + call writefile(['bright'], 'dummy2.txt') + vimgrep /bright/j dummy* + let l = readfile(g:MRU_File) + if match(l, 'dummy') == -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + call delete('dummy1.txt') + call delete('dummy2.txt') +endfunc + +" ========================================================================== +" Test42 +" Using a command modifier with the MRU command to open the MRU window +" ========================================================================== +func Test_42() + if v:version < 800 + " The command modifier is supported only by Vim 8.0 and above + return + endif + let test_name = 'test42' + enew | only + topleft MRU + if winnr() == 1 && winnr('$') == 2 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + enew | only + botright MRU + if winnr() == 2 && winnr('$') == 2 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + enew | only + botright MRU + if winnr() == 2 && winnr('$') == 2 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + enew | only +endfunc + +" ========================================================================== +" Test43 +" Opening a file using the MRU command should jump to the window containing +" the file (if it is already opened). +" ========================================================================== +func Test_43() + let test_name = 'test43' + only + edit file3.txt + below split file2.txt + below split file1.txt + wincmd t + MRU file1.txt + if winnr() != 3 || fnamemodify(@%, ':p:t') !=# 'file1.txt' + call LogResult(test_name, 'FAIL (1)') + else + MRU file2.txt + if winnr() != 2 && fnamemodify(@%, ':p:t') !=# 'file2.txt' + call LogResult(test_name, 'FAIL (2)') + else + MRU file3.txt + if winnr() != 1 && fnamemodify(@%, ':p:t') !=# 'file3.txt' + call LogResult(test_name, 'FAIL (3)') + else + call LogResult(test_name, 'pass') + endif + endif + endif + enew | only +endfunc + +" ========================================================================== +" Test44 +" Opening a file using the MRU command should open the file in a new window if +" the current buffer has unsaved changes. +" ========================================================================== +func Test_44() + let test_name = 'test44' + only + set modified + MRU file2.txt + if winnr('$') == 2 && winnr() == 1 && + \ fnamemodify(@%, ':p:t') ==# 'file2.txt' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + close + set nomodified +endfunc + +" ========================================================================== +" Test45 +" Opening a file from the MRU window using 'v' should open the file in a new +" window if the current buffer has unsaved changes. +" ========================================================================== +func Test_45() + let test_name = 'test45' + only + set modified + MRU + call search('file3.txt') + normal v + if winnr('$') == 2 && winnr() == 1 + \ && fnamemodify(@%, ':p:t') ==# 'file3.txt' + \ && &readonly + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + close + set nomodified +endfunc + +" ========================================================================== +" Test46 +" Specify a count to the :MRU command to set the MRU window height/width +" ========================================================================== +func Test_46() + let test_name = 'test46' + only + " default height is 8 + MRU + if winnr() != 2 || winheight(0) != 8 + call LogResult(test_name, 'FAIL (1)') + return + endif + close + + " use a specific height value + 15MRU + if winnr() != 2 || winheight(0) != 15 + call LogResult(test_name, 'FAIL (2)') + return + endif + close + + if v:version >= 800 + " use a specific height value with a command modifier + topleft 12MRU + if winnr() != 1 || winheight(0) != 12 + call LogResult(test_name, 'FAIL (3)') + return + endif + close + + " check for the width (leftmost window) + vertical topleft 20MRU + if winnr() != 1 || winwidth(0) != 20 + call LogResult(test_name, 'FAIL (4)') + return + endif + close + + " check for the width (rightmost window) + vertical botright 25MRU + if winnr() != 2 || winwidth(0) != 25 + call LogResult(test_name, 'FAIL (5)') + return + endif + close + endif + + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test47 +" The height of the MRU window should be MRU_Window_Height +" ========================================================================== +func Test_47() + let test_name = 'test47' + only + + " default height is 8 + MRU + if winheight(0) != 8 + call LogResult(test_name, 'FAIL (1)') + return + endif + close + + let g:MRU_Window_Height = 2 + MRU + if winheight(0) != 2 + call LogResult(test_name, 'FAIL (2)') + return + endif + close + let g:MRU_Window_Height = 12 + MRU + if winheight(0) != 12 + call LogResult(test_name, 'FAIL (3)') + return + endif + close + + call LogResult(test_name, 'pass') + let g:MRU_Window_Height = 8 +endfunc + +" ========================================================================== +" Test48 +" Fuzzy search file names with MRU_FuzzyMatch set to 1. +" ========================================================================== +func Test_48() + if !exists('*matchfuzzy') + return + endif + + let test_name = 'test48' + enew | only + + let g:MRU_FuzzyMatch = 1 + MRU F1 + if fnamemodify(@%, ':p:t') ==# 'file1.txt' && winnr('$') == 1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL (1)') + endif + + let g:MRU_FuzzyMatch = 0 + redir => msg + MRU F1 + redir END + if msg =~# "MRU file list doesn't contain files matching F1" + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL (2)') + endif + let g:MRU_FuzzyMatch = 1 +endfunc + +" ========================================================================== +" Test49 +" Test for creating a new file by saving an unnamed buffer. +" ========================================================================== +func Test_49() + let test_name = 'test49' + enew | only + call setline(1, 'sample file') + write sample.txt + let l = readfile(g:MRU_File) + if match(l, 'sample.txt') != -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL') + endif + call delete('sample.txt') + bwipe sample.txt +endfunc + +" ========================================================================== +" Test50 +" Test for the MruGetFiles() function +" ========================================================================== +func Test_50() + let test_name = 'test50' + enew | only + let list1 = MruGetFiles() + let list2 = readfile(g:MRU_File) + if list1 != list2[1:] + call LogResult(test_name, 'FAIL (1)') + return + endif + + if MruGetFiles('x1y2z3') == [] + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL (2)') + endif +endfunc + +" ========================================================================== +" Test51 +" Test for the :MruRefresh command +" ========================================================================== +func Test_51() + let test_name = 'test51' + enew | only + if match(MruGetFiles(), 'sample.txt') == -1 + call LogResult(test_name, 'FAIL (1)') + return + endif + MruRefresh + if match(MruGetFiles(), 'sample.txt') == -1 + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL (2)') + endif +endfunc + +" ========================================================================== +" Test52 +" Test for the re-opening a deleted buffer from the MRU list +" ========================================================================== +func Test_52() + let test_name = 'test52' + edit file1.txt + edit file2.txt + bd + " select the file from the MRU window + MRU + call search('file2.txt') + exe "normal \" + if !&buflisted || fnamemodify(@%, ':p:t') !=# 'file2.txt' + call LogResult(test_name, 'FAIL (1)') + return + endif + " open the file directly using the command + bw file1.txt file2.txt + edit file2.txt + edit file1.txt + bd + MRU file1.txt + if !&buflisted || fnamemodify(@%, ':p:t') !=# 'file1.txt' + call LogResult(test_name, 'FAIL (2)') + return + endif + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test53 +" Test for using a command modifier when directly opening a file using the +" MRU command. +" ========================================================================== +func Test_53() + if v:version < 800 + return + endif + let test_name = 'test53' + %bw! + topleft MRU file2.txt + if winnr('$') == 2 && winnr() == 1 && fnamemodify(@%, ':p:t') ==# 'file2.txt' + wincmd j + if winnr() != 2 + call LogResult(test_name, 'FAIL (1)') + return + endif + else + call LogResult(test_name, 'FAIL (2)') + return + endif + %bw + belowright MRU file2.txt + if winnr('$') == 2 && winnr() == 2 && fnamemodify(@%, ':p:t') ==# 'file2.txt' + wincmd k + if winnr() != 1 + call LogResult(test_name, 'FAIL (3)') + return + endif + else + call LogResult(test_name, 'FAIL (4)') + return + endif + %bw + vertical topleft MRU file2.txt + if winnr('$') == 2 && winnr() == 1 && fnamemodify(@%, ':p:t') ==# 'file2.txt' + wincmd l + if winnr() != 2 + call LogResult(test_name, 'FAIL (5)') + return + endif + else + call LogResult(test_name, 'FAIL (6)') + return + endif + %bw + vertical belowright MRU file2.txt + if winnr('$') == 2 && winnr() == 2 && fnamemodify(@%, ':p:t') ==# 'file2.txt' + wincmd h + if winnr() != 1 + call LogResult(test_name, 'FAIL (7)') + return + endif + else + call LogResult(test_name, 'FAIL (8)') + return + endif + %bw + tab MRU file2.txt + if tabpagenr() != 2 || fnamemodify(@%, ':p:t') !=# 'file2.txt' + call LogResult(test_name, 'FAIL (9)') + return + endif + %bw + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test54 +" Test for the :MRUToggle command. +" ========================================================================== +func Test_54() + let test_name = 'test54' + only + " open the MRU window + MRUToggle + if bufwinnr(g:MRU_buffer_name) != 2 || winnr() != 2 + call LogResult(test_name, 'FAIL (1)') + return + endif + " close the MRU window + MRUToggle + if bufwinnr(g:MRU_buffer_name) != -1 || winnr() != 1 + call LogResult(test_name, 'FAIL (2)') + return + endif + " close the MRU window from some other window + MRUToggle + wincmd k + MRUToggle + if bufwinnr(g:MRU_buffer_name) != -1 || winnr() != 1 + call LogResult(test_name, 'FAIL (3)') + return + endif + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test55 +" Editing a file selected from the MRU window should set the current file to +" be the alternate file. +" ========================================================================== +func Test_55() + let test_name = 'test55' + silent! bw file1.txt file2.txt file3.txt + new + edit file1.txt + edit file2.txt + MRU + call search('file3.txt') + exe "normal \" + if fnamemodify(@%, ':p:t') !=# 'file3.txt' + \ || fnamemodify(@#, ':p:t') !=# 'file2.txt' + call LogResult(test_name, 'FAIL') + return + endif + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test56 +" With MRU_Use_Current_Window set to 1, editing a file from the MRU list +" should not change the alternate file. +" ========================================================================== +func Test_56() + let test_name = 'test56' + let g:MRU_Use_Current_Window = 1 + bw file1.txt file2.txt file3.txt + new + edit file3.txt + edit file1.txt + edit file2.txt + MRU + call search('file3.txt') + exe "normal \" + if fnamemodify(@%, ':p:t') !=# 'file3.txt' + \ || fnamemodify(@#, ':p:t') !=# 'file2.txt' + call LogResult(test_name, 'FAIL (1)') + return + endif + " try viewing a file + MRU + call search('file1.txt') + normal v + if fnamemodify(@%, ':p:t') !=# 'file1.txt' + \ || fnamemodify(@#, ':p:t') !=# 'file3.txt' + \ || !&readonly + call LogResult(test_name, 'FAIL (2)') + return + endif + " try opening a wiped out buffer + bw file2.txt + MRU + call search('file2.txt') + exe "normal \" + if fnamemodify(@%, ':p:t') !=# 'file2.txt' + \ || fnamemodify(@#, ':p:t') !=# 'file1.txt' + \ || &readonly + call LogResult(test_name, 'FAIL (3)') + return + endif + let g:MRU_Use_Current_Window = 0 + bw! + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test57 +" When the MRU window is closed, the MRU buffer should be unloaded. +" If 'MRU_Use_Current_Window' is set, then the MRU buffer should be wiped out. +" ========================================================================== +func Test_57() + let test_name = 'test57' + MRU + let mrubnum = bufnr('') + close + if bufloaded(mrubnum) + call LogResult(test_name, 'FAIL (1)') + return + endif + let g:MRU_Use_Current_Window = 1 + new + edit Xfile + MRU + let mrubnum = bufnr('') + edit # + if bufexists(mrubnum) || @% != 'Xfile' + call LogResult(test_name, 'FAIL (2)') + return + endif + let g:MRU_Use_Current_Window = 0 + bw! + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test58 +" When the MRU window is toggled with MRU_Use_Current_Window set to 1, the +" previous buffer should be loaded. +" ========================================================================== +func Test_58() + let test_name = 'test58' + let g:MRU_Use_Current_Window = 1 + new + edit Xfile + MRUToggle + if @% != g:MRU_buffer_name || winnr('$') != 2 + call LogResult(test_name, 'FAIL (1)') + return + endif + MRUToggle + if @% != 'Xfile' || winnr('$') != 2 + call LogResult(test_name, 'FAIL (2)') + return + endif + let g:MRU_Use_Current_Window = 0 + bw! + call LogResult(test_name, 'pass') +endfunc + +" ========================================================================== +" Test59 +" When the MRU_Set_Alternate_File is set to 1, on plugin startup, the +" alternate file should be set to the first file in the MRU list. +" ========================================================================== +func Test_59() + if v:version < 802 + return + endif + let test_name = 'test59' + call writefile([], 'Xfirstfile') + edit Xfirstfile + call writefile([ + \ "let MRU_File='vim_mru_file'", + \ "let MRU_Set_Alternate_File=1", + \ "source ../plugin/mru.vim", + \ "call writefile([@#], 'Xoutput')" + \ ], 'Xscript') + silent! !vim -u NONE --noplugin i NONE -N -S Xscript -c "qa" + if !filereadable('Xoutput') + call LogResult(test_name, 'FAIL (1)') + else + let lines = readfile('Xoutput') + if len(lines) == 1 && lines[0] =~ 'Xfirstfile$' + call LogResult(test_name, 'pass') + else + call LogResult(test_name, 'FAIL (2)') + endif + endif + call delete('Xscript') + call delete('Xoutput') + call delete('Xfirstfile') +endfunc + +" ========================================================================== +" Test60 +" With MRU_Use_Current_Window set to 1, MRU opens a selected file in the +" current window, even when the file is already open in another window +" ========================================================================== +func Test_60() + let test_name = 'test60' + let g:MRU_Use_Current_Window = 1 + + edit file1.txt + let bnum = bufnr() + only + below split file2.txt + + MRU + call search('file1.txt') + exe "normal \" + + if winnr() == 2 && winbufnr(1) == bnum && winbufnr(2) == bnum + call LogResult(test_name, "pass") + else + call LogResult(test_name, "FAIL") + endif + let g:MRU_Use_Current_Window = 0 +endfunc + +" ========================================================================== + +" Create the files used by the tests +call writefile(['MRU test file1'], 'file1.txt') +call writefile(['MRU test file2'], 'file2.txt') +call writefile(['MRU test file3'], 'file3.txt') + +call writefile(['#include