Nerdtree: Can't open directory after latest update

Created on 18 Jan 2021  路  4Comments  路  Source: preservim/nerdtree

Self-Diagnosis

  • [x] I have searched the issues for an answer to my question.
  • [x] I have reviewed the NERDTree documentation. :h NERDTree
  • [x] I have reviewed the Wiki.
  • [x] I have searched the web for an answer to my question.

Environment (for bug reports)

  • [x] Operating System: macOS 10.15
  • [x] Vim/Neovim version :echo v:version: Neovim 0.5.0, Vim 8.0.0
  • [x] NERDTree version, found on 1st line in NERDTree quickhelp ?: 6.9.12
  • [x] vimrc settings

    • [ ] NERDTree variables (None)

    • Other NERDTree-dependent Plugins



      • [ ] jistr/vim-nerdtree-tabs


      • [ ] ryanoasis/vim-devicons


      • [ ] tiagofumo/vim-nerdtree-syntax-highlight


      • [ ] Xuyuanp/nerdtree-git-plugin


      • [ ] Others (specify):



    • [x] I've verified the issue occurs with only NERDTree installed.

Steps to Reproduce the Issue

  1. Install latest NERDTree (:PlugUpdate for vim-plug)
  2. Open Neovim
  3. :NERDTree
  4. Navigate down to a directory and press enter
  5. Error pops up

Current Result (Include screenshots where appropriate.)

Error pops up:

Error detected while processing function nerdtree#ui_glue#invokeKeyMap[1]..76[26]
..75[3]..<SNR>60_customOpenDir[1]..<SNR>60_initCustomOpenArgs:
line   15:
E716: Key not present in Dictionary: "file"
E116: Invalid arguments for function get
E116: Invalid arguments for function s:validateType
E15: Invalid expression: s:validateType(get(l:customOpenArgs[l:typeKey], l:option
Name, v:null), v:t_string)
Error detected while processing function nerdtree#ui_glue#invokeKeyMap[1]..76[26]
..75[3]..<SNR>60_customOpenDir:
line    1:
E121: Undefined variable: dir
E116: Invalid arguments for function <SNR>60_activateDirNode

Expected Result

Directory opens correctly without errors.

I have tested this with the last release (tag 6.9.11) and there were no issues with opening folders. NERDTree was the only plugin to be installed when testing both versions. I think this is related to #1200 but I'm not technically proficient enough to be sure.

bug

All 4 comments

@RobertAudi

Can you take another look your PR #1200? The initCustomOpenArgs function isn't working when there is no NERDTreeCustomOpenArgs variable defined. My bad for not checking that scenario.

Also, can you rewrite your type checking to be backward compatible as explained in :h type()? I'm sure some users out there will be stuck with older versions of Vim that don't have the v:t_ variables.

For backward compatibility, this method can be used: >
    :if type(myvar) == type(0)
    :if type(myvar) == type("")
    :if type(myvar) == type(function("tr"))
    :if type(myvar) == type([])
    :if type(myvar) == type({})
    :if type(myvar) == type(0.0)
    :if type(myvar) == type(v:true)

@sunnyguan I reverted the PR that introduced the bug. Another :PlugUpdate will pull it in. I've asked the PR's author to provide a proper bug fix.

Sorry @RobertAudi. I tagged the wrong person. I've been in front of the screen for too long.

@przepompownia, Please see the comment above. Thanks.

function! s:initCustomOpenArgs(customOpenArgs) abort
    let l:defaultOpenArgs = {'file': {'reuse': 'all', 'where': 'p'}, 'dir': {}}
    let l:customOpenArgs = a:customOpenArgs

    if v:false is# s:validateType(l:customOpenArgs, type({})) || empty(l:customOpenArgs)
        let g:NERDTreeCustomOpenArgs = l:customOpenArgs
        return l:defaultOpenArgs
    endif

    for l:typeKey in keys(l:defaultOpenArgs)
        if v:false is# s:validateType(get(l:customOpenArgs, l:typeKey, {}), type({}))
              \ || !has_key(l:customOpenArgs, l:typeKey)
            let l:customOpenArgs[l:typeKey] = l:defaultOpenArgs[l:typeKey]
            continue
        endif

        for l:optionName in keys(l:defaultOpenArgs[l:typeKey])
            if s:validateType(get(l:customOpenArgs[l:typeKey], l:optionName, v:null), type(''))
                continue
            endif
            let l:customOpenArgs[l:typeKey][l:optionName] = l:defaultOpenArgs[l:typeKey][l:optionName]
        endfor
    endfor

    return extend(l:customOpenArgs, l:defaultOpenArgs, 'keep')
endfunction

function! s:validateType(variable, type)
    if type(a:variable) is# a:type
        return v:true
    endif

    return v:false
endfunction

function! s:testInitCustomOpenArgs(options, expectedResult)
    call assert_equal(a:expectedResult, s:initCustomOpenArgs(a:options))
endfunction

function! s:testValidateType(variable, expectedResult)
  call assert_true(s:validateType(a:variable, a:expectedResult))
endfunction

let v:errors = []
let defaultOpenArgs = {'file': {'reuse': 'all', 'where': 'p'}, 'dir': {}}

call s:testValidateType({}, v:t_dict)
call s:testValidateType(defaultOpenArgs['file']['where'], v:t_string)

call s:testInitCustomOpenArgs(1, defaultOpenArgs)
call s:testInitCustomOpenArgs({}, defaultOpenArgs)
call s:testInitCustomOpenArgs({'file': 1}, defaultOpenArgs)
call s:testInitCustomOpenArgs({'file': {}, 'dir': 'foo'}, defaultOpenArgs)
call s:testInitCustomOpenArgs(
      \ {'file': {'reuse': [1], 'where': 'w', 'foo': []}},
      \ {'file': {'reuse': 'all', 'where': 'w', 'foo': []}, 'dir': {}}
      \ )
call s:testInitCustomOpenArgs(
      \ {'file': {'reuse': [1], 'foo': []}},
      \ {'file': {'reuse': 'all', 'where': 'p', 'foo': []}, 'dir': {}}
      \ )

call s:testInitCustomOpenArgs(
      \ {'file': {'reuse': [1], 'foo': []}},
      \ {'file': {'reuse': 'all', 'where': 'p', 'foo': []}, 'dir': {}}
      \ )


if !len(v:errors)
  echom 'Success!'
  finish
endif

echoerr v:errors

Apart from fixing it for the case when g:NERDTreeCustomOpenArgs == {} I added assigning default value on that case (like it occurs before the late return).

Was this page helpful?
0 / 5 - 0 ratings