diff --git a/README.md b/README.md index 68399e6..2b942e0 100644 --- a/README.md +++ b/README.md @@ -75,10 +75,22 @@ Compared to scratch.vim, vim-scratch-buffer provides these additional features: - See `:help :ScratchBufferOpen` and `:help :ScratchBufferOpenFile` - Customization options - - Specify filetype for syntax highlighting + - Specify filetype for syntax highlighting, for `:QuickRun`, and for etc - Choose opening method (`:split` or `:vsplit`) - Control buffer height/width - - Configurable auto-hiding behavior + - Configurable auto-hiding behavior: [scratch.vim compatibility](#sparkles-scratchvim-compatibility) + - Customize buffer file locations: + ```vim + " Configure different paths for temporary and persistent buffers + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: '/tmp/scratch-tmp-%d', " For :ScratchBufferOpen + \ when_file_buffer: expand('~/scratch/%d'), " For :ScratchBufferOpenFile + \ } + " This is useful if you want to keep a file buffer directory + " (`~/tmp` in the above case) with `.prettier`, etc. + ``` + +Please also see [doc/vim-scratch-buffer.txt](./doc/vim-scratch-buffer.txt) for other functions. ### :gear: Detailed Usage @@ -122,6 +134,8 @@ Compared to scratch.vim, vim-scratch-buffer provides these additional features: :ScratchBufferClean ``` +Please also see [doc/vim-scratch-buffer.txt](./doc/vim-scratch-buffer.txt) for other usage. + ## :keyboard: Default Keymappings When `g:scratch_buffer_use_default_keymappings` is enabled (default: `v:false`), the following keymappings are available: @@ -152,7 +166,7 @@ nnoremap s ScratchBufferOpen nnoremap S ScratchBufferOpenFile ``` -## :sparkles: scratch.vim Compatibility +## :sparkles: scratch.vim compatibility To make the plugin behave like scratch.vim, you can enable automatic buffer hiding! When enabled, scratch buffers will automatically hide when you leave the window. diff --git a/autoload/scratch_buffer.vim b/autoload/scratch_buffer.vim index 09212f1..4d5000a 100644 --- a/autoload/scratch_buffer.vim +++ b/autoload/scratch_buffer.vim @@ -1,6 +1,3 @@ -scriptencoding utf-8 -scriptversion 3 - " Params: " - (first argument) {string | undefined} (Optional) " - File extension without '.', e.g., 'md', 'ts', or 'sh' @@ -10,7 +7,7 @@ scriptversion 3 " - (third argument) {number | undefined} (Optional) A positive number to `:resize buffer_size` function! scratch_buffer#open(opening_next_fresh_buffer, ...) abort return s:open_buffer(#{ - \ opening_temporary_buffer: v:true, + \ opening_as_tmp_buffer: v:true, \ opening_next_fresh_buffer: a:opening_next_fresh_buffer, \ args: a:000, \ }) @@ -18,21 +15,43 @@ endfunction function! scratch_buffer#open_file(opening_next_fresh_buffer, ...) abort return s:open_buffer(#{ - \ opening_temporary_buffer: v:false, + \ opening_as_tmp_buffer: v:false, \ opening_next_fresh_buffer: a:opening_next_fresh_buffer, \ args: a:000, \ }) endfunction +" Initialize augroup in case options were updated +function! scratch_buffer#initialize_augroup() abort + augroup VimScratchBuffer + autocmd! + execute + \ 'autocmd' + \ 'TextChanged' + \ substitute(g:scratch_buffer_file_pattern.when_file_buffer, '%d', '*', '') + \ 'call scratch_buffer#autocmd#save_file_buffer_if_enabled()' + execute + \ 'autocmd' + \ 'WinLeave' + \ substitute(g:scratch_buffer_file_pattern.when_tmp_buffer, '%d', '*', '') + \ 'call scratch_buffer#autocmd#hide_buffer_if_enabled()' + execute + \ 'autocmd' + \ 'WinLeave' + \ substitute(g:scratch_buffer_file_pattern.when_file_buffer, '%d', '*', '') + \ 'call scratch_buffer#autocmd#hide_buffer_if_enabled()' + augroup END +endfunction + function! s:open_buffer(options) abort const args = a:options.args - const opening_temporary_buffer = a:options.opening_temporary_buffer + const opening_as_tmp_buffer = a:options.opening_as_tmp_buffer const opening_next_fresh_buffer = a:options.opening_next_fresh_buffer + call scratch_buffer#initialize_augroup() + const file_ext = get(args, 0, g:scratch_buffer_default_file_ext) - const file_pattern = (file_ext ==# '--no-file-ext' || file_ext ==# '') - \ ? $'{g:scratch_buffer_tmp_file_pattern}' - \ : $'{g:scratch_buffer_tmp_file_pattern}.{file_ext}' + const file_pattern = s:get_file_pattern(opening_as_tmp_buffer, file_ext) const index = s:find_current_index(file_pattern) + (opening_next_fresh_buffer ? 1 : 0) const file_name = expand(printf(file_pattern, index)) @@ -42,7 +61,7 @@ function! s:open_buffer(options) abort execute 'silent' open_method file_name - if opening_temporary_buffer + if opening_as_tmp_buffer setlocal buftype=nofile setlocal bufhidden=hide else @@ -55,6 +74,15 @@ function! s:open_buffer(options) abort endif endfunction +function! s:get_file_pattern(opening_as_tmp_buffer, file_ext) abort + const type = a:opening_as_tmp_buffer + \ ? 'when_tmp_buffer' + \ : 'when_file_buffer' + return a:file_ext ==# '--no-file-ext' || a:file_ext ==# '' + \ ? $'{g:scratch_buffer_file_pattern[type]}' + \ : $'{g:scratch_buffer_file_pattern[type]}.{a:file_ext}' +endfunction + function! s:find_current_index(pattern) abort " NOTE: `[]->max()` returns 0 const max_buffer_index = scratch_buffer#helper#get_all_buffer_names() @@ -72,23 +100,24 @@ function! s:extract_index_from_name(name, pattern) abort return len(matches) > 1 ? str2nr(matches[1]) : v:null endfunction -function! s:find_next_index(pattern) abort - return + 1 -endfunction - " Clean up all scratch buffers and files function! scratch_buffer#clean() abort - const files = glob( - \ substitute(g:scratch_buffer_tmp_file_pattern, '%d', '*', ''), + const persistent_files = glob( + \ substitute(g:scratch_buffer_file_pattern.when_file_buffer, '%d', '*', ''), \ v:false, \ v:true, \ ) - for file in files - call delete(file) + for persistent_file in persistent_files + call delete(persistent_file) endfor + call s:wipe_buffers(g:scratch_buffer_file_pattern.when_tmp_buffer) + call s:wipe_buffers(g:scratch_buffer_file_pattern.when_file_buffer) +endfunction + +function! s:wipe_buffers(file_pattern) abort const scratch_prefix = '^' .. substitute( - \ g:scratch_buffer_tmp_file_pattern, + \ a:file_pattern, \ '%d', \ '', \ '', diff --git a/autoload/scratch_buffer/autocmd.vim b/autoload/scratch_buffer/autocmd.vim index e1e7601..62fb00b 100644 --- a/autoload/scratch_buffer/autocmd.vim +++ b/autoload/scratch_buffer/autocmd.vim @@ -1,21 +1,10 @@ -scriptencoding utf-8 -scriptversion 3 - -function! s:is_scratch_buffer() abort - return expand('%:p') =~# substitute(g:scratch_buffer_tmp_file_pattern, '%d', '*', '') -endfunction - -function! scratch_buffer#autocmd#save_file_buffer() abort - if g:scratch_buffer_auto_save_file_buffer && (&buftype !=# 'nofile') && s:is_scratch_buffer() - silent! write +function! scratch_buffer#autocmd#save_file_buffer_if_enabled() abort + if g:scratch_buffer_auto_save_file_buffer && (&buftype !=# 'nofile') + silent write endif endfunction -function! scratch_buffer#autocmd#hide_buffer() abort - if !s:is_scratch_buffer() - return - endif - +function! scratch_buffer#autocmd#hide_buffer_if_enabled() abort if (&buftype ==# 'nofile') && g:scratch_buffer_auto_hide_buffer.when_tmp_buffer quit return diff --git a/doc/vim-scratch-buffer.txt b/doc/vim-scratch-buffer.txt index fbda861..9a0491e 100644 --- a/doc/vim-scratch-buffer.txt +++ b/doc/vim-scratch-buffer.txt @@ -18,12 +18,12 @@ CHANGELOG |scratch-buffer-changelog| ============================================================================== INTRODUCTION *scratch-buffer-introduction* -**No more hassle with file paths!** +** No more hassle with file paths! ** The fastest way to open an instant scratch buffer. Supercharge with vim-quickrun! -Combine it with [vim-quickrun](https://github.com/thinca/vim-quickrun) -to execute code instantly! +Combine it with vim-quickrun (https://github.com/thinca/vim-quickrun) to +execute code instantly! > " Open a TypeScript buffer :ScratchBufferOpen ts @@ -34,8 +34,8 @@ to execute code instantly! " ...and run it immediately! :QuickRun < -Please see the `scratch-buffer-usage` section -for usage of `:ScratchBufferOpen`. +Please see the |scratch-buffer-usage| section for usage of +|:ScratchBufferOpen|. Newer Version: https://github.com/aiya000/vim-scratch-buffer @@ -71,28 +71,71 @@ INTERFACE *scratch-buffer-interface* ------------------------------------------------------------------------------ VARIABLES *scratch-buffer-variables* -*g:scratch_buffer_tmp_file_pattern* - Default: `'/tmp/vim-scratch-buffer-%d'` +*g:scratch_buffer_file_pattern* + Type: `{ when_tmp_buffer?: string, when_file_buffer?: string }` + + A dictionary specifying file patterns for different buffer types. + Has two keys: + + .when_tmp_buffer ( Default: `'/tmp/vim-scratch-tmp-%d'` ) + Pattern used for temporary buffers + created by |:ScratchBufferOpen|. - When`ScratchBufferOpen`opens a scratch buffer, it will make a - decision based on this pattern. - Specifically,`printf($'/tmp/vim-scratch-buffer-%d.{ext}', count)` - will be opened. `ext`is the first argument of`ScratchBufferOpen`. - `count`is the number of currently open scratch buffers +1. + .when_file_buffer ( Default: `'/tmp/vim-scratch-file-%d'` ) + Pattern used for persistent buffers + created by |:ScratchBufferOpenFile|. + + Each pattern should contain '%d' which will be replaced with a number. + The number is determined by counting existing buffers of both types. + If a file extension is provided, it will be appended to the pattern. + + Example: +> + " Use different directories for temporary and persistent buffers + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: '/tmp/scratch-tmp-%d', + \ when_file_buffer: '/tmp/vim-scratch-file-%d', + \ } + " This is useful if you want to keep a file buffer directory + " (`~/tmp` in the above case) with `.prettier`, etc. + + " You can set only one of these options and leave the other as the default value. + let g:scratch_buffer_file_pattern = #{ + \ when_file_buffer: expand('~/tmp/scratch-%d'), + \ } +< + This options is recommended that these two keys have different values, + but they can also be the same. + In that case, the below following behavior occurs. +> + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: '/tmp/scratch-%d', + \ when_file_buffer: '/tmp/scratch-%d', + \ } + " Open '/tmp/scratch-{first-number}.md' as a no file (tmp) buffer + :ScratchBufferOpen md + " !! Open '/tmp/scratch-{first-number}.md' again, but as a file (no tmp) buffer + :ScratchBufferOpen md +< + The latter buffer type will overwrite the former as well if the order + is reversed. *g:scratch_buffer_default_file_ext* + Type: `string` Default: `'md'` The default file extension to use when opening a new scratch buffer. This is used when no file extension is provided as an argument. *g:scratch_buffer_default_open_method* + Type: `string` Default: `'sp'` The default method to use when opening a new scratch buffer. Can be either 'sp' for horizontal split or 'vsp' for vertical split. *g:scratch_buffer_default_buffer_size* + Type: `PositiveInt` Default: `15` The default size (height for 'sp' or width for 'vsp') of newly opened @@ -101,12 +144,15 @@ VARIABLES *scratch-buffer-variables* Also if this is specified as `v:null`, resizing is not performed. *g:scratch_buffer_auto_save_file_buffer* + Type: `boolean` Default: `v:true` When enabled, file buffers (not temporary buffers) will be automatically saved when their content changes. *g:scratch_buffer_auto_hide_buffer* + Type: `{ when_tmp_buffer?: boolean, when_file_buffer?: boolean }` + A dictionary that controls the auto-hiding behavior of scratch buffers. Has the following keys: @@ -130,6 +176,7 @@ VARIABLES *scratch-buffer-variables* < *g:scratch_buffer_use_default_keymappings* + Type: `boolean` Default: `v:false` When enabled, the following default key mappings will be set: @@ -138,6 +185,13 @@ VARIABLES *scratch-buffer-variables* nnoremap B ScratchBufferOpenFile < +*g:scratch_buffer_tmp_file_pattern* + Type: `string` + Default: + Deprecated. + Please use |g:scratch_buffer_file_pattern| instead. + + ------------------------------------------------------------------------------ COMMANDS *scratch-buffer-commands* @@ -146,7 +200,7 @@ COMMANDS *scratch-buffer-commands* Open a temporary scratch buffer with a random file name. This opens buffers by the rule - described in `g:scratch_buffer_tmp_file_pattern`. + described in |g:scratch_buffer_file_pattern|. If this command is called again, it will open the most recently used scratch buffer. @@ -165,32 +219,32 @@ COMMANDS *scratch-buffer-commands* < These settings make the buffer temporary and prevent writing to disk. The buffer content remains in memory until Vim is closed or - `:ScratchBufferClean` is called. + |:ScratchBufferClean| is called. [open-method] is an optional argument, should be `'sp'` or `'vsp'`. Open the buffer on top if `'sp'`, or open the buffer on the left if `'vsp'`. - Please also see `:split` and `:vsplit`. - Default value: see `g:scratch_buffer_default_open_method` + Please also see |:split| and |:vsplit|. + Default value: see |g:scratch_buffer_default_open_method| [buffer-size] is an optional argument, should be a positive number. - `:ScratchBufferOpen` resizes the opened buffer upon opening, - or uses the value from `g:scratch_buffer_default_buffer_size` + |:ScratchBufferOpen| resizes the opened buffer upon opening, + or uses the value from |g:scratch_buffer_default_buffer_size| if omitted. *:ScratchBufferOpenNext* :ScratchBufferOpenNext [file-extension | --no-file-ext] [open-method] [buffer-size] - Similar to `:ScratchBufferOpen` but always creates a fresh temporary buffer + Similar to |:ScratchBufferOpen| but always creates a fresh temporary buffer even if there are existing scratch buffers. This is useful when you want to create multiple scratch buffers of the same type. - Takes the same arguments as `:ScratchBufferOpen`. + Takes the same arguments as |:ScratchBufferOpen|. *:ScratchBufferOpenFile* :ScratchBufferOpenFile [file-extension | --no-file-ext] [open-method] [buffer-size] - Similar to `:ScratchBufferOpen` but creates a persistent buffer instead of + Similar to |:ScratchBufferOpen| but creates a persistent buffer instead of a temporary one. Key differences: 1. The buffer is writable and changes can be saved to disk @@ -201,17 +255,22 @@ COMMANDS *scratch-buffer-commands* This command is useful when you want to keep the content permanently or need to share the file with other programs. - Takes the same arguments as `:ScratchBufferOpen`. + Takes the same arguments as |:ScratchBufferOpen|. If you have a temporary buffer open and want to make it persistent, - you can use `:ScratchBufferOpenFile` with the same arguments - it will + you can use |:ScratchBufferOpenFile| with the same arguments - it will use the same file path but make it writable. + *:ScratchBufferOpenFileNext* +:ScratchBufferOpenFileNext [file-extension | --no-file-ext] [open-method] [buffer-size] + Similar to |:ScratchBufferOpenFile| and |:ScratchBufferOpenNext|. + + *:ScratchBufferClean* :ScratchBufferClean Delete all scratch files and buffers that - were opened by `:ScratchBufferOpen`. + were opened by |:ScratchBufferOpen|. ============================================================================== @@ -233,11 +292,11 @@ scratch_buffer#open(opening-next-fresh-buffer[, file-extension | --no-file-ext][ Optional positive number for buffer size Creates a temporary buffer that cannot be written to disk. - See `:help :ScratchBufferOpen` for more details. + See |:ScratchBufferOpen| for more details. *scratch_buffer#open_file()* scratch_buffer#open_file(opening-next-fresh-buffer[, file-extension | --no-file-ext][, open-method][, buffer-size]) - Function version of `:ScratchBufferOpenFile`. + Function version of |:ScratchBufferOpenFile|. Parameters: opening-next-fresh-buffer: @@ -251,17 +310,22 @@ scratch_buffer#open_file(opening-next-fresh-buffer[, file-extension | --no-file- Optional positive number for buffer size Creates a persistent buffer that can be written to disk. - See `:help :ScratchBufferOpenFile` for more details. + See |:ScratchBufferOpenFile| for more details. *scratch_buffer#clean()* scratch_buffer#clean() - Same as `:ScratchBufferClean`. + Same as |:ScratchBufferClean|. ============================================================================== CHANGELOG *scratch-buffer-changelog* -See https://github.com/aiya000/vim-scratch-buffer/commits/main +Also See https://github.com/aiya000/vim-scratch-buffer/commits/main + +Breaking Changes: + - 2025-04-29: + Deprecate |g:scratch_buffer_tmp_file_pattern| . + Please use |g:scratch_buffer_file_pattern| instead. ============================================================================== diff --git a/plugin/scratch_buffer.vim b/plugin/scratch_buffer.vim index f3e8c00..5cc2d4a 100644 --- a/plugin/scratch_buffer.vim +++ b/plugin/scratch_buffer.vim @@ -5,13 +5,48 @@ if exists('g:loaded_scratch_buffer') endif let g:loaded_scratch_buffer = v:true +" Functions {{{ + +function! s:define_file_pattern_using_tmp_file_pattern() abort + if !exists('g:scratch_buffer_tmp_file_pattern') + throw 'g:scratch_buffer_tmp_file_pattern required' + endif + let g:scratch_buffer_file_pattern = get(g:, 'scratch_buffer_file_pattern', #{ + \ when_tmp_buffer: g:scratch_buffer_tmp_file_pattern, + \ when_file_buffer: g:scratch_buffer_tmp_file_pattern, + \ }) +endfunction + +function! s:define_file_pattern() abort + let g:scratch_buffer_file_pattern = get(g:, 'scratch_buffer_file_pattern', #{}) + let g:scratch_buffer_file_pattern.when_tmp_buffer = get( + \ g:scratch_buffer_file_pattern, + \ 'when_tmp_buffer', + \ '/tmp/vim-scratch-tmp-%d' + \ ) + let g:scratch_buffer_file_pattern.when_file_buffer = get( + \ g:scratch_buffer_file_pattern, + \ 'when_file_buffer', + \ '/tmp/vim-scratch-file-%d' + \ ) +endfunction + +" }}} + command! -bar -nargs=* ScratchBufferOpen call scratch_buffer#open(v:false, ) command! -bar -nargs=* ScratchBufferOpenFile call scratch_buffer#open_file(v:false, ) command! -bar -nargs=* ScratchBufferOpenNext call scratch_buffer#open(v:true, ) command! -bar -nargs=* ScratchBufferOpenFileNext call scratch_buffer#open_file(v:true, ) command! -bar ScratchBufferClean call scratch_buffer#clean() -let g:scratch_buffer_tmp_file_pattern = get(g:, 'scratch_buffer_tmp_file_pattern', '/tmp/vim-scratch-buffer-%d') +if exists('g:scratch_buffer_tmp_file_pattern') && !exists('g:scratch_buffer_file_pattern') + " For backward compatibility + call s:define_file_pattern_using_tmp_file_pattern() +else + " For the newer specs + call s:define_file_pattern() +endif + let g:scratch_buffer_default_file_ext = get(g:, 'scratch_buffer_default_file_ext', 'md') let g:scratch_buffer_default_open_method = get(g:, 'scratch_buffer_default_open_method', 'sp') let g:scratch_buffer_default_buffer_size = get(g:, 'scratch_buffer_default_buffer_size', 15) @@ -22,11 +57,7 @@ let g:scratch_buffer_auto_hide_buffer = get(g:, 'scratch_buffer_auto_hide_buffer let g:scratch_buffer_auto_hide_buffer.when_tmp_buffer = get(g:scratch_buffer_auto_hide_buffer, 'when_tmp_buffer', v:false) let g:scratch_buffer_auto_hide_buffer.when_file_buffer = get(g:scratch_buffer_auto_hide_buffer, 'when_file_buffer', v:false) -augroup VimScratchBuffer - autocmd! - autocmd TextChanged * call scratch_buffer#autocmd#save_file_buffer() - autocmd WinLeave * call scratch_buffer#autocmd#hide_buffer() -augroup END +call scratch_buffer#initialize_augroup() if g:scratch_buffer_use_default_keymappings nnoremap b ScratchBufferOpen diff --git a/test/scratch_buffer.vim b/test/scratch_buffer.vim index a401608..e21f231 100644 --- a/test/scratch_buffer.vim +++ b/test/scratch_buffer.vim @@ -10,11 +10,15 @@ function! s:suite.before() abort let g:backup_scratch_buffer_auto_save_file_buffer = g:scratch_buffer_auto_save_file_buffer let g:backup_scratch_buffer_use_default_keymappings = g:scratch_buffer_use_default_keymappings let g:backup_scratch_buffer_auto_hide_buffer = g:scratch_buffer_auto_hide_buffer + let g:backup_scratch_buffer_file_pattern = g:scratch_buffer_file_pattern endfunction function! s:suite.before_each() abort " Don't waste our environment - let g:scratch_buffer_tmp_file_pattern = system('realpath "./test/tmp/scratch-%d"')[:-2] + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: fnamemodify('./test/tmp/scratch-tmp-%d', ':p'), + \ when_file_buffer: fnamemodify('./test/tmp/scratch-file-%d', ':p'), + \ } " Restore default values let g:scratch_buffer_default_file_ext = g:backup_scratch_buffer_default_file_ext let g:scratch_buffer_default_open_method = g:backup_scratch_buffer_default_open_method @@ -25,23 +29,30 @@ function! s:suite.before_each() abort " Clean all created scratch files and buffers ScratchBufferClean + + " Close opened windows + new + only endfunction function! s:suite.after_each() abort " Clean all created files - for file in glob(g:scratch_buffer_tmp_file_pattern[:-3] .. '*', v:false, v:true) - call system($'rm "{file}"') + for file in glob(g:scratch_buffer_file_pattern.when_tmp_buffer[:-3] .. '*', v:false, v:true) + call delete(file) + endfor + for file in glob(g:scratch_buffer_file_pattern.when_file_buffer[:-3] .. '*', v:false, v:true) + call delete(file) endfor endfunction -function! s:suite.scratch_buffer_open_shoud_can_make_buffer() abort +function! s:suite.ScratchBufferOpen_shoud_can_make_buffer() abort ScratchBufferOpen const file_name = expand('%:p') - const expected = printf(g:scratch_buffer_tmp_file_pattern, 0) .. '.md' + const expected = printf(g:scratch_buffer_file_pattern.when_tmp_buffer, 0) .. '.md' call s:expect(file_name).to_equal(expected) endfunction -function! s:suite.scratch_buffer_open_next_can_make_multiple_buffer() abort +function! s:suite.ScratchBufferOpenNext_can_make_multiple_buffer() abort ScratchBufferOpen const main_file = expand('%:p') ScratchBufferOpenNext @@ -49,7 +60,7 @@ function! s:suite.scratch_buffer_open_next_can_make_multiple_buffer() abort call s:expect(main_file).not.to_equal(next_file) endfunction -function! s:suite.scratch_buffer_open_should_open_recent_buffer_after_scratch_buffer_open_next() abort +function! s:suite.ScratchBufferOpen_should_open_recent_buffer_after_ScratchBufferOpenNext() abort ScratchBufferOpenNext const first_file = expand('%:p') @@ -73,10 +84,12 @@ function! s:is_scratch_buffer_open_buffer_writable() abort return is_written endfunction -function! s:suite.scratch_buffer_open_should_open_readonly_file() abort +function! s:suite.ScratchBufferOpen_should_open_readonly_file() abort call s:expect(s:is_scratch_buffer_open_buffer_writable()).to_equal(v:false) endfunction +" Try to :write a file opened by ScratchBufferOpenFile. +" @returns {boolean} - the opened file is writable function! s:is_scratch_buffer_open_file_buffer_writable() abort let is_written = v:false try @@ -88,35 +101,11 @@ function! s:is_scratch_buffer_open_file_buffer_writable() abort return is_written endfunction -function! s:suite.scratch_buffer_open_file_should_open_writable_file() abort +function! s:suite.ScratchBufferOpenFile_should_open_writable_file() abort call s:expect(s:is_scratch_buffer_open_file_buffer_writable()).to_equal(v:true) endfunction -function! s:suite.scratch_buffer_open_file_should_make_tmp_buffer_to_file_buffer() abort - const is_tmp_buffer_writable = s:is_scratch_buffer_open_buffer_writable() - const first_file = expand('%:p') - call s:expect(is_tmp_buffer_writable).to_equal(v:false) - - const is_file_buffer_writable = s:is_scratch_buffer_open_file_buffer_writable() - const second_file = expand('%:p') - call s:expect(is_file_buffer_writable).to_equal(v:true) - - call s:expect(first_file).to_equal(second_file) -endfunction - -function! s:suite.scratch_buffer_open_should_make_file_buffer_to_tmp_buffer() abort - const is_file_buffer_writable = s:is_scratch_buffer_open_file_buffer_writable() - const first_file = expand('%:p') - call s:expect(is_file_buffer_writable).to_equal(v:true) - - const is_tmp_buffer_writable = s:is_scratch_buffer_open_buffer_writable() - const second_file = expand('%:p') - call s:expect(is_tmp_buffer_writable).to_equal(v:false) - - call s:expect(first_file).to_equal(second_file) -endfunction - -function! s:suite.scratch_buffer_clean_should_wipe_opened_files_and_buffers() abort +function! s:suite.ScratchBufferClean_should_wipe_opened_files_and_buffers() abort ScratchBufferOpenFile md const first_file = expand('%:p') write @@ -125,7 +114,7 @@ function! s:suite.scratch_buffer_clean_should_wipe_opened_files_and_buffers() ab " Check the created files stil exist const all_buffer_names = scratch_buffer#helper#get_all_buffer_names() - call s:expect(filereadable(first_file)).to_equal(1) + call s:expect(filereadable(first_file)).to_be_same(1) call s:expect( \ all_buffer_names->scratch_buffer#helper#contains(first_file), \ ).not.to_equal(-1) @@ -138,7 +127,7 @@ function! s:suite.scratch_buffer_clean_should_wipe_opened_files_and_buffers() ab " Check the created files are removed const new_all_buffer_names = scratch_buffer#helper#get_all_buffer_names() - call s:expect(filereadable(first_file)).not.to_equal(1) + call s:expect(filereadable(first_file)).not.to_be_same(1) call s:expect( \ new_all_buffer_names->scratch_buffer#helper#contains(first_file), \ ).not.to_equal(-1) @@ -147,21 +136,21 @@ function! s:suite.scratch_buffer_clean_should_wipe_opened_files_and_buffers() ab \ ).not.to_equal(-1) endfunction -function! s:suite.scratch_buffer_should_accept_file_extension() abort +function! s:suite.ScratchBufferOpen_should_accept_file_extension() abort ScratchBufferOpen md endfunction -function! s:suite.scratch_buffer_should_accept_open_method() abort +function! s:suite.ScratchBufferOpen_should_accept_open_method() abort ScratchBufferOpen md sp ScratchBufferOpen md vsp endfunction -function! s:suite.scratch_buffer_should_accept_buffer_size() abort +function! s:suite.ScratchBufferOpen_should_accept_buffer_size() abort ScratchBufferOpen md sp 5 ScratchBufferOpen md vsp 50 endfunction -function! s:suite.scratch_buffer_should_use_default_values() abort +function! s:suite.ScratchBufferOpen_should_use_default_values() abort let g:scratch_buffer_default_file_ext = 'ts' let g:scratch_buffer_default_open_method = 'vsp' let g:scratch_buffer_default_buffer_size = 20 @@ -172,38 +161,120 @@ function! s:suite.scratch_buffer_should_use_default_values() abort ScratchBufferOpen const file_name = expand('%:p') - const expected = printf(g:scratch_buffer_tmp_file_pattern, 0) .. '.ts' + const expected = printf(g:scratch_buffer_file_pattern.when_tmp_buffer, 0) .. '.ts' call s:expect(file_name).to_equal(expected) call s:expect(winwidth(0)).to_be_same(20) endfunction -function! s:suite.scratch_buffer_should_support_auto_saving_file_buffer() abort +function! s:suite.ScratchBufferOpen_should_support_auto_saving_file_buffer() abort let g:scratch_buffer_auto_save_file_buffer = v:true ScratchBufferOpenFile md call setline(1, 'test content') doautocmd TextChanged const file_name = expand('%:p') - call s:expect(filereadable(file_name)).to_equal(1) + call s:expect(filereadable(file_name)).to_be_same(1) call s:expect(readfile(file_name)[0]).to_equal('test content') endfunction -function! s:suite.scratch_buffer_should_support_auto_hiding_buffer() abort - let g:scratch_buffer_auto_hide_buffer = {} +function! s:suite.ScratchBufferOpen_should_support_auto_hiding_tmp_buffer() abort + let g:scratch_buffer_auto_hide_buffer = #{ + \ when_tmp_buffer: v:true, + \ when_file_buffer: v:true, + \ } - " Temporary buffer auto-hiding - let g:scratch_buffer_auto_hide_buffer.when_tmp_buffer = v:true - let g:scratch_buffer_auto_hide_buffer.when_file_buffer = v:false - only ScratchBufferOpen md wincmd p " Trigger WinLeave call s:expect(winnr('$')).to_be_same(1) +endfunction + +function! s:suite.ScratchBufferOpen_should_support_auto_hiding_file_buffer() abort + let g:scratch_buffer_auto_hide_buffer = #{ + \ when_tmp_buffer: v:true, + \ when_file_buffer: v:true, + \ } - " File buffer auto-hiding - let g:scratch_buffer_auto_hide_buffer.when_tmp_buffer = v:false - let g:scratch_buffer_auto_hide_buffer.when_file_buffer = v:true - only ScratchBufferOpenFile md wincmd p " Trigger WinLeave call s:expect(winnr('$')).to_be_same(1) endfunction + +function! s:suite.ScratchBufferOpen_should_use_when_tmp_buffer_pattern() abort + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: fnamemodify('./test/tmp/scratch-tmp-%d', ':p'), + \ when_file_buffer: 'not specified', + \ } + + ScratchBufferOpen + const file_name = expand('%:p') + const expected = printf(g:scratch_buffer_file_pattern.when_tmp_buffer, 0) .. '.md' + call s:expect(file_name).to_equal(expected) +endfunction + +function! s:suite.ScratchBufferOpenFile_should_use_when_file_buffer_pattern() abort + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: 'not specified', + \ when_file_buffer: fnamemodify('./test/tmp/scratch-file-%d', ':p'), + \ } + + ScratchBufferOpenFile + const file_name = expand('%:p') + const expected = printf(g:scratch_buffer_file_pattern.when_file_buffer, 0) .. '.md' + call s:expect(file_name).to_equal(expected) +endfunction + +function! s:suite.ScratchBufferOpen_and_ScratchBufferOpenFile_should_make_different_buffers_when_options_is_different() abort + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: fnamemodify('./test/tmp/scratch-tmp-%d', ':p'), + \ when_file_buffer: fnamemodify('./test/tmp/scratch-file-%d', ':p'), + \ } + + ScratchBufferOpen + const tmp_file = expand('%:p') + ScratchBufferOpenFile + const persistent_file = expand('%:p') + call s:expect(tmp_file).not.to_equal(persistent_file) +endfunction + +function! s:is_current_buffer_type_tmp() abort + return &buftype ==# 'nofile' && &bufhidden ==# 'hide' +endfunction + +function! s:is_current_buffer_type_file() abort + return &buftype ==# '' && &bufhidden ==# '' +endfunction + +function! s:suite.ScratchBufferOpenFile_should_change_the_previous_buffer_type_of_the_tmp_buffer_to_file_buffer_if_file_pattern_is_same() abort + const file_pattern = fnamemodify('./test/tmp/scratch-%d', ':p') + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: file_pattern, + \ when_file_buffer: file_pattern, + \ } + + ScratchBufferOpen + const first_file = expand('%:p') + + ScratchBufferOpenFile + const second_file = expand('%:p') + + call s:expect(first_file).to_equal(second_file) + call s:expect(s:is_current_buffer_type_file()).to_be_same(1) +endfunction + +function! s:suite.ScratchBufferOpen_should_change_the_buffer_type_of_the_previous_file_buffer_to_tmp_buffer_if_file_pattern_is_same() abort + const file_pattern = fnamemodify('./test/tmp/scratch-%d', ':p') + let g:scratch_buffer_file_pattern = #{ + \ when_tmp_buffer: file_pattern, + \ when_file_buffer: file_pattern, + \ } + + ScratchBufferOpenFile + const first_file = expand('%:p') + + ScratchBufferOpen + const second_file = expand('%:p') + + call s:expect(first_file).to_equal(second_file) + call s:expect(s:is_current_buffer_type_tmp()).to_be_same(1) +endfunction +