cocopon / vaffle.vim

:file_folder: Lightweight, window-based file manager for Vim
MIT License
284 stars 20 forks source link

Do not override buffer history #49

Closed nganhkhoa closed 3 years ago

nganhkhoa commented 4 years ago

I don't know if this should be a bug. Opening Vaffle will override the buffer history, thus you cannot :b# to go to the previous buffer open for quick jump between files. Can we restore the last buffer history when opening and exit Vaffle?

Maybe we could set let @#=bufname() to the buffer when open Vaffle from a file.

nganhkhoa commented 4 years ago

So I tried to solve this myself.

" buffer.vim
function! vaffle#buffer#move_cursor_to_path(path) abort
  ...
  let g:vaffle#prev = a:path
endfunction

" file.vim
function! s:open_single(item, open_mode) abort
  ...
  let @#=bufname(g:vaffle#prev)
endfunction

It works. Opening Vaffle on a file (1) and open another file (2) will set the # register to (1).

But because I don't set any check if the user was opening a file or a directory, this still needs more work. And I use a global variable here, I don't think there will be any issue, but as Vaffle open a buffer for each chdir, I don't know how to track the variable across different files.

cocopon commented 4 years ago

I haven't use the feature :b# so I'm not sure what it should be. Could you share specific examples for preparing test cases like this?

  1. :e a.txt
  2. :e b.txt (alternate buffer should be a.txt)
  3. :Vaffle (alternate buffer should be b.txt)
  4. :b# (and then it should be what...?)
alextes commented 4 years ago

Hm, 🤔 , good question. I don't quite remember. I'll switch back to Vaffle and let you know when I run in the scenario that feels unintuitive.

nganhkhoa commented 4 years ago
let s:suite = themis#suite('vaffle_e2e_buffer_history')
let s:assert = themis#helper('assert')
let s:cwd = getcwd()

" https://github.com/cocopon/vaffle.vim/issues/49
function! s:suite.test_buffer_history() abort
  " open foo.txt
  e test/e2e/files/buffer_history/foo.txt
  " open bar.txt, previous file is foo.txt
  e test/e2e/files/buffer_history/bar.txt
  " open Vaffle and quit
  Vaffle
  normal q
  " we are at bar.txt
  " the previous file should be foo.txt
  execute ":b#"
  call s:assert.equals(
        \ bufname('%'),
        \ "test/e2e/files/buffer_history/foo.txt",
        \ ':Vaffle should not overwrite buffer history')
endfunction

I drafted a test, not sure if it works though, but it somehow goes like this. After exiting Vaffle, the previous buffer should be "foo.txt", Vaffle overwrite the history so it will open Vaffle if :b# is entered

cocopon commented 4 years ago

Thank you for providing detailed information. I have tested about this problem as below and the alternate marker seems to be removed after quitting. Should we really hold an alternate file?

" Split window to prevent quitting Vim
:split

" Open foo.txt
:e foo.txt
:ls
  1 #a   "[No Name]"                    line 1
  2 %a   "foo.txt"                      line 1  
" Alternate buffer is [No Name]

" Open bar.txt
:e bar.txt
:ls
  1  a   "[No Name]"                    line 1
  2 #    "foo.txt"                      line 1
  3 %a   "bar.txt"                      line 1  
" Alternate buffer is foo.txt

" Open baz.txt
:e baz.txt
:ls
  1  a   "[No Name]"                    line 1
  2      "foo.txt"                      line 1
  3 #    "bar.txt"                      line 1
  4 %a   "baz.txt"                      line 1 
" Alternate buffer is bar.txt

" Quit the current buffer
:q
:ls
  1 %a   "[No Name]"                    line 1
  2      "foo.txt"                      line 1
  3      "bar.txt"                      line 1
  4      "baz.txt"                      line 0 
" Alternate marker seems to be removed
alextes commented 4 years ago

It gets removed from the list but vim still remembers what your last buffer was. Consequently, :e# takes you there, even without an open buffer.

Perhaps it helps to add context. I tend to switch back and forth between files when working on things. Basically, anything that you might use split-screen for, when I'm on a smaller screen, I hop back and forth. Mostly using fzf + buffer-list, but regularly when edits are between two files, or I need to read the one to edit the other correctly, :e# is even quicker and mapped to <c-b> for me. If I used Vaffle to find that other file, I now can't hop back and forth with :e# anymore. To me, that would be the value of restoring the buffer history to what it was before Vaffle ran (: .

cocopon commented 4 years ago

It seems that :e# after https://github.com/cocopon/vaffle.vim/issues/49#issuecomment-678866282 raises error E194: No alternate file name to substitute for '#'. Please try it yourself.

I understand your situation, but I'm also concerned about...:

alextes commented 4 years ago

that's fair @cocopon !

Not following your comment though. After closing a window, Vim focuses on the split window you created initially. Vim appears to track the alternate buffer per window, that window has no alternate buffer, and so Vim tells you it can't switch to any alternate buffer. You can test this by opening two buffers in two windows, and closing one window. Now you don't get the error anymore. But I'm not sure how that changes anything when an alternate buffer is set, and Vaffle becomes the alternate buffer.

The correct behavior @nganhkhoa seemed to propose is:

Are there alternatives you have in mind that would also meet this need?

WhoIsSethDaniel commented 4 years ago

I've created pr https://github.com/cocopon/vaffle.vim/pull/53 which preserves the alternate buffer. This should allow you to switch back to the previously opened buffer using ctrl-6 or :e# or similar. Please try it out and let me know. It's a very simple patch fwiw.

WhoIsSethDaniel commented 4 years ago

Closed https://github.com/cocopon/vaffle.vim/pull/53 and now the keep alternate code is in https://github.com/cocopon/vaffle.vim/pull/55

cocopon commented 4 years ago

Merged #55, but it seems that we have to add another workaround to satisfy @nganhkhoa's use case https://github.com/cocopon/vaffle.vim/issues/49#issuecomment-675424786.

nganhkhoa commented 4 years ago

Yes, unfortunately the behavior that I specified is not working with keepalt.

I don't know about other Vim user, but it would be nice to have the # buffer untouched. Right now either I have to manually remember the last buffer which is not Vaffle and reset # on Vaffle select file or Vaffle quit.

I want to be clarified on how file command works, this command just rename the buffer? But how does Vaffle create a new buffer? Should manual code be applied here or we should try to use what Vim offers? How do other plugins implement this feature?

WhoIsSethDaniel commented 4 years ago

I guess I don't understand the problem. As best I can tell the alternate buffer is now preserved when using vaffle. I thought that's what was being described in this bug. Fwiw I wrote and submitted my pr before I ever knew this bug existed.

cocopon commented 4 years ago

The author of fern.vim taught me that they have an option about this problem.

https://github.com/lambdalisue/fern.vim/blob/5cd3e31465754dbf459b5622a8a44e42ae61acca/doc/fern.txt#L350

*g:fern#keepalt_on_edit*
    Set 1 to apply |keepalt| on the "open:edit" action to keep an
    |alternate-file| in a split windows style like:
>
        g:fern#keepalt_on_edit =      0            1
                             +---------+  +---------+
    :edit A                  |  %:A    |  |  %:A    |
                             |  #:     |  |  #:     |
                             +---------+  +---------+
                                  v            v
                             +---------+  +---------+
    :Fern .                  |  %:fern |  |  %:fern |
                             |  #:A    |  |  #:A    |
                             +---------+  +---------+
                                  v            v
                             +---------+  +---------+
    open:edit                |  %:B    |  |  %:B    |
    on 'B'                   |  #:fern |  |  #:A    |
                             +---------+  +---------+
<
    Default: 0

I think this issue is not a bug and both behaviors of above can be correct. So I should decide which is the appropriate behavior for Vaffle, or considering adding an option like fern.vim.

WhoIsSethDaniel commented 4 years ago

Thanks for pasting the explanation. I see the problem now although it isn't exclusive to splits (which is what I was thinking based on the example above).

My preference and what I would expect is for the alternate to be on A always. I would never expect :e# to go back to vaffle. If you use vaffle in the netrw or dirvish mode (i.e. not 'drawer' style like nerdtree) it seems intuitive that the alternate should be on A, right?

nganhkhoa commented 4 years ago

That's a good illustration. And yes, what I described is g:fern#keepalt_on_edit = 1.

Also, I also think that it is intuitive that the alternative be the file A not Vaffle.

cocopon commented 3 years ago

Fixed by #57 thanks to @WhoIsSethDaniel . Thank you for your help.