Yggdroot / LeaderF

An efficient fuzzy finder that helps to locate files, buffers, mrus, gtags, etc. on the fly for both vim and neovim.
Apache License 2.0
2.12k stars 176 forks source link

删除一些buffer之后再次执行Leaderf会触发vim.error: Vim:E315: ml_get: 无效的 lnum: 7 #756

Open roachsinai opened 3 years ago

roachsinai commented 3 years ago

Describe your question, feature request, or bug.

使用了Leaderf对asynctasks的扩展,先进行代码编译会打开一个窗口,然后进行代码执行再打开一个窗口。之后使用map同时关闭编译窗口和执行窗口。再次打开leaderf对于asynctasks的扩展时报错:

Peek 2021-01-13 11-43

minimal vimrc

.vimrc

" 定义快捷键的前缀,即<leader>
let mapleader=" "
command! BufOnly silent! execute "%bd|e#|bd#"
nnoremap <silent> <leader>bo :BufOnly<CR>

call plug#begin('~/.vim/plugged')
Plug 'Yggdroot/LeaderF', { 'do': ':LeaderfInstallCExtension' }
Plug 'skywind3000/asyncrun.vim'
Plug 'skywind3000/asynctasks.vim'
call plug#end()

set hidden
let g:Lf_RootMarkers = ['.project', '.root', '.svn', '.git', '.hg']

let g:Lf_GtagsAutoGenerate = 1
let g:Lf_Gtagslabel = 'native-pygments'
let g:Lf_GtagsSource = 2
let g:Lf_GtagsfilesCmd = {
        \ '.git': 'git ls-files --recurse-submodules',
        \ '.hg': 'hg files',
        \ 'default': 'rg --no-messages --files'
        \}

let g:Lf_DefaultExternalTool='rg'
let g:Lf_IgnoreCurrentBufferName = 1
let g:Lf_NormalMap = {
    \ "File":   [["<ESC>", ':exec g:Lf_py "fileExplManager.quit()"<CR>']],
    \ "Buffer": [["<ESC>", ':exec g:Lf_py "bufExplManager.quit()"<CR>']],
    \ "Mru":    [["<ESC>", ':exec g:Lf_py "mruExplManager.quit()"<CR>']],
    \ "Tag":    [["<ESC>", ':exec g:Lf_py "tagExplManager.quit()"<CR>']],
    \ "BufTag":    [["<ESC>", ':exec g:Lf_py "bufTagExplManager.quit()"<CR>']],
    \ "Function":    [["<ESC>", ':exec g:Lf_py "functionExplManager.quit()"<CR>']],
    \ "Colorscheme":    [["<ESC>", ':exec g:Lf_py "colorschemeExplManager.quit()"<CR>']],
    \ }

let g:Lf_MruMaxFiles = 2048
let g:Lf_StlSeparator = { 'left': "\ue0b0", 'right': "\ue0b2", 'font': ''}
let g:Lf_StlColorscheme = 'powerline'

let g:Lf_WorkingDirectoryMode = 'Ac'
let g:Lf_WindowHeight = 0.30
let g:Lf_ShowRelativePath = 1
let g:Lf_CursorBlink = 0
let g:Lf_JumpToExistingWindow = 0

let g:Lf_WildIgnore = {
            \ 'dir': ['.svn','.git','.hg'],
            \ 'file': ['*.sw?','~$*','*.bak','*.exe','*.o','*.so','*.py[co]']
            \ }

let g:Lf_MruFileExclude = ['*.so', '*.exe', '*.py[co]', '*.sw?', '~$*', '*.bak', '*.tmp', '*.dll']

if (exists('*popup_create') && has('patch-8.1.2000')) || has('nvim-0.4')
    let g:Lf_WindowPosition = 'popup'
    let g:Lf_PreviewInPopup = 1
endif

"----------------------------------------------------------------------
" keymap
"----------------------------------------------------------------------
let g:Lf_ShortcutF = '<leader>e'
" noremap <leader>el :LeaderfFile %:p:h<CR>
let g:Lf_ShortcutB = '<leader>fb'

let g:asyncrun_open = 6
let g:asyncrun_rootmarks = ['.git', '.svn', '.root', '.project', '.hg']

" https://github.com/skywind3000/asynctasks.vim/blob/master/README-cn.md#%E5%A4%9A%E7%A7%8D%E8%BF%90%E8%A1%8C%E6%A8%A1%E5%BC%8F
let g:asynctasks_term_pos = 'bottom'
let g:asynctasks_term_rows = 10    " 设置纵向切割时,高度为 10
let g:asynctasks_term_cols = 80    " 设置横向切割时,宽度为 80

" https://github.com/skywind3000/asynctasks.vim/wiki/UI-Integration#leaderf
noremap <tab>t :Leaderf --nowrap task<cr>
let g:asynctasks_profile = 'release'

"----------------------------------------------------------------------
" source task
"----------------------------------------------------------------------
function! LfTaskSource(...)
    let rows = asynctasks#source(&columns * 48 / 100)
    let source = []
    for row in rows
        let name = row[0]
        let source += [name . '  ' . row[1] . '  : ' . row[2]]
    endfor
    return source
endfunc

function! LfTaskAccept(line, arg)
    let pos = stridx(a:line, '<')
    if pos < 0
        return
    endif
    let name = strpart(a:line, 0, pos)
    let name = substitute(name, '^\s*\(.\{-}\)\s*$', '\1', '')
    redraw
    if name != ''
        exec "AsyncTask " . name
    endif
endfunc

function! LfTaskDigest(line, mode)
    let pos = stridx(a:line, '<')
    if pos < 0
        return [a:line, 0]
    endif
    let name = strpart(a:line, 0, pos)
    return [name, 0]
endfunc

function! LfWinInit(...)
    setlocal nonumber
    setlocal nowrap
endfunc

let g:Lf_Extensions = get(g:, 'Lf_Extensions', {})
let g:Lf_Extensions.task = {
            \ 'source': string(function('LfTaskSource'))[10:-3],
            \ 'accept': string(function('LfTaskAccept'))[10:-3],
            \ 'get_digest': string(function('LfTaskDigest'))[10:-3],
            \ 'highlights_def': {
            \     'Lf_hl_funcScope': '^\S\+',
            \     'Lf_hl_funcDirname': '^\S\+\s*\zs<.*>\ze\s*:',
            \ },
            \ 'after_enter': string(function('LfWinInit'))[10:-3],
        \ }

~/.vim/tasks.ini

# https://github.com/skywind3000/vim/blob/master/tasks.ini
# vim: set noet fenc=utf-8 sts=4 sw=4 ts=4 ft=dosini:

[file-build:release]
command:c/linux=gcc -O2 -Wall "$(VIM_FILEPATH)" -o "$(VIM_PATHNOEXT).out" -lstdc++ -lm -msse3 -ldl -lpthread
command:cpp/linux=g++ -O2 -Wall "$(VIM_FILEPATH)" -o "$(VIM_PATHNOEXT).out" -lstdc++ -lm -msse3 -ldl -lpthread
output=quickfix
# 结束时发送 QuickFixCmdPost make 触发 errormarker
auto=make
save=2

[file-build:debug]
command:c/linux=gcc "$(VIM_FILEPATH)" -o "$(VIM_PATHNOEXT).out" -lstdc++ -lm -msse3 -ldl -lpthread -g
command:cpp/linux=g++ "$(VIM_FILEPATH)" -o "$(VIM_PATHNOEXT).out" -lstdc++ -lm -msse3 -ldl -lpthread -g
output=quickfix
auto=make
save=2

[file-run]
command:c,cpp="$(VIM_PATHNOEXT).out"
output=terminal
cwd=$(VIM_FILEDIR)
save=2

[file-run-gpu]
command:python/linux=optirun /home/roach/.pyenv/versions/3.7.4/envs/nn/bin/python "$(VIM_FILENAME)"
output=terminal
cwd=$(VIM_FILEDIR)
save=2

[show-python-script-bytecode]
command:python/linux=/home/roach/.pyenv/versions/3.7.4/envs/nn/bin/python -m dis "$(VIM_FILENAME)"
output=terminal
cwd=$(VIM_FILEDIR)
save=2

[project-build:release]
command=make
cwd=$(VIM_ROOT)

[project-build:debug]
command=make debug=1
cwd=$(VIM_ROOT)

[project-run]
command=make run
cwd=$(VIM_ROOT)
output=terminal

[project-test]
command=make test
cwd=$(VIM_ROOT)
output=terminal

[project-clean]
command=make clean
cwd=$(VIM_ROOT)
output=terminal

tt.cpp

#include <iostream>
using namespace std;

class Base1 {
public:
    int ibase1;
    Base1():ibase1(10) {}
    virtual void f() { cout << "Base1::f()" << endl; }
    virtual void g() { cout << "Base1::g()" << endl; }
    virtual void h() { cout << "Base1::h()" << endl; }

};

class Base2 {
public:
    int ibase2;
    Base2():ibase2(20) {}
    virtual void f() { cout << "Base2::f()" << endl; }
    virtual void g() { cout << "Base2::g()" << endl; }
    virtual void h() { cout << "Base2::h()" << endl; }
};

class Base3 {
public:
    int ibase3;
    Base3():ibase3(30) {}
    virtual void f() { cout << "Base3::f()" << endl; }
    virtual void g() { cout << "Base3::g()" << endl; }
    virtual void h() { cout << "Base3::h()" << endl; }
};

class Derive : public Base1, public Base2, public Base3 {
public:
    int iderive;
    Derive():iderive(100) {}
    virtual void f() { cout << "Derive::f()" << endl; }
    virtual void g1() { cout << "Derive::g1()" << endl; }
};

int main()
{
    Derive d;
    cout << (void*)&d << endl;
    Base1* p;
    p = (Base1*) &d;
    cout << (void*)p << endl;

    return 0;
}

Steps to reproduce

  1. vim tt.cpp
  2. 执行快捷键<tab>t调出leaderf对asynctask的扩展窗口直接<Enter>进行编译
  3. 同样调出扩展窗口执行第二选项,执行编译的结果
  4. <C-W>k切换到tt.cpp对应的窗口,执行映射<leader>bo关闭其他的buffer
  5. <tab>t报错

More infos

操作系统 Manjaro Linux,安装的vim包含了最新的vim提交。

Yggdroot commented 3 years ago

我在我的环境上用你的配置没有复现。vim用的是8.2.2282.

Yggdroot commented 3 years ago

8.2.2339也没有复现。

roachsinai commented 3 years ago

Y大,你用的是哪个发行版,还有终端。我看看能不能找到对应的环境试试。因为我这里目前是稳定复现的。

Yggdroot commented 3 years ago

centOS 7, gnome. 我觉得跟这些可能没关系。 既然你那里可以稳定复现,可以尝试不用LeaderF能不能复现,就像https://github.com/vim/vim/issues/7598 里面的做法。

roachsinai commented 3 years ago

嗯嗯。

roachsinai commented 3 years ago

BufOnly换成下面的命令没有错误,

" https://github.com/vim-scripts/BufOnly.vim/blob/master/plugin/BufOnly.vim

command! -nargs=? -complete=buffer -bang Bonly
    \ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang BOnly
    \ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang Bufonly
    \ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang BufOnly
    \ :call BufOnly('<args>', '<bang>')

function! BufOnly(buffer, bang)
    if a:buffer == ''
        " No buffer provided, use the current buffer.
        let buffer = bufnr('%')
    elseif (a:buffer + 0) > 0
        " A buffer number was provided.
        let buffer = bufnr(a:buffer + 0)
    else
        " A buffer name was provided.
        let buffer = bufnr(a:buffer)
    endif

    if buffer == -1
        echohl ErrorMsg
        echomsg "No matching buffer for" a:buffer
        echohl None
        return
    endif

    let last_buffer = bufnr('$')

    let delete_count = 0
    let n = 1
    while n <= last_buffer
        if n != buffer && buflisted(n)
            if a:bang == '' && getbufvar(n, '&modified')
                echohl ErrorMsg
                echomsg 'No write since last change for buffer'
                            \ n '(add ! to override)'
                echohl None
            else
                silent exe 'bdel' . a:bang . ' ' . n
                if ! buflisted(n)
                    let delete_count = delete_count+1
                endif
            endif
        endif
        let n = n+1
    endwhile

    if delete_count == 1
        echomsg delete_count "buffer deleted"
    elseif delete_count > 1
        echomsg delete_count "buffers deleted"
    endif

endfunction
Yggdroot commented 3 years ago

你的这个.vimrc,我不设一下set nocp都没法跑,你确定你那边没问题?

roachsinai commented 3 years ago

Peek 2021-01-15 12-30

我这里第一次打开vimrc,可看到内容是完全一样的,应该是没有问题,用的gvim.

然后是复现。


我这里还有一种情况在:Leaderf file会遇到ml_get. 情况有点特殊,存在某些文件名组合的时候会出现。感觉和 https://github.com/vim/vim/issues/7598 有点像,但是用那里的方法没有办法脱离leaderf复现。

Yggdroot commented 3 years ago

我用vim -u vimrc tt.cpp 就会报错。 vimrc就是你那个vimrc。

Yggdroot commented 3 years ago

我用vim -u vimrc tt.cpp 就会报错。 vimrc就是你那个vimrc。

-u vimrc 会把compatible 设上。

Yggdroot commented 3 years ago

非popup模式可以出现吗?

roachsinai commented 3 years ago

非popup模式可以出现吗?

非popup没有错误。

Yggdroot commented 3 years ago

终端vim可以出现吗?我一直在终端vim上试的。 换个环境能复现吗?

roachsinai commented 3 years ago

我就是在终端中用的gvim,然后卸载gvim安装vim也可以复现。


我这几天改成不用popup了,目前没有出现过ml_get的问题。因为在其他地方popup也出现过ml_get的问题。其他,发行版还没有试验。