Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUGFIX: Allow ":NERDTreeFind" to reveal new files #785

Merged
merged 6 commits into from
Dec 22, 2017

Conversation

lifecrisis
Copy link
Contributor

Here, I'm addressing issue #779.

When a new file is written after the NERDTree for the current tab has been initialized, attempting to use :NERDTreeFind on that new file will fail with an error message. The reason for this is subtle, but it has to do with the following functions:

  1. NEDRTreeDirNode.reveal() (this is what really drives the :NERDTreeFind command)
  2. NERDTreeDirNode.open()
  3. NERDTreeDirNode._initChildren()

First, note that reveal() must open() all nodes along the path, starting with root, to "get to" the desired node. Also note: open() calls _initChildren() only if the node's children have not yet been initialized. This is for efficiency... but doesn't help much here because nodes will likely need to be opened anyway. It only helps if one of the dirs along the path has already been opened and has, say 200+ children.

That last point is the key. When the root is open()ed, it's children are not checked again. However, if we create a new file several dirs deep (dirs that have not yet been opened), the :NERDTreeFind call will succeed because the dirs along the path are opened after the path was created.

In effect, the find command is searching the tree, not the file system... so some mechanism is needed to "freshly open" the nodes along the search path as we go. We can be sure the path exists, we just need to make sure it's guaranteed to be in the tree when we get there!

The last commit on this branch fixes the issue in the most efficient way possible... but some may still find it undesirable... Read the comment in that commit when it shows up to see why it's most efficient...

Oh, and feed back will be appreciated!

Copy link
Member

@PhilRunninger PhilRunninger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still getting an error with this workflow:

:NERDTreeToggle
<C-W><C-W>
:w foobar
:NERDTreeFind

image


let l:node = b:NERDTree.root.reveal(l:pathObj)

if empty(l:node)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this if block left over from testing? It seems out of place.

let l:node = b:NERDTree.root.reveal(l:pathObj)

if empty(l:node)
echomsg 'l:node is totally empty...'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is to be kept, use the nerdtree function instead of echomsg.

The ":NERDTreeFind" command calls the "reveal()" method on the
NERDTree root node.  The "reveal()" method would, in turn, call the
node's "open()" method.  Since the "open()" method would only
initialize the child nodes of the root (i.e., read them from disk)
when the list of child nodes was empty, new paths would not be
included in the list.

This commit will result in the refreshing of the child node list
whenever "reveal()" is called on a directory node (unless it is the
first time the node is being opened... the most efficient option).

The result is that ":NERDTreeFind" will discover newly created paths
that exist on disk but are not cached in the NERDTree.

A stray debugging message is also removed.

Fixes issue preservim#779.
@lifecrisis
Copy link
Contributor Author

@PhilRunninger... I hadn't pushed the fix yet! Try it now!

@lifecrisis lifecrisis dismissed PhilRunninger’s stale review December 21, 2017 15:42

Hadn't pushed fix yet...

@lifecrisis
Copy link
Contributor Author

@juanibiapina ... if you want to weigh in, let me know what you think. I think this is as efficient as its gonna get.

@lifecrisis
Copy link
Contributor Author

Just a note... documentation still needs to be updated, and it looks like the function behaves improperly when the buffer doesn't have an associated path (try :NERDTreeFind in the quickfix window for example...).

@PhilRunninger
Copy link
Member

It looks like :NERDTreeFind, run from the Quickfix window, takes you to cwd(). What do you suggest it should be doing?

@PhilRunninger
Copy link
Member

Sorry. Wrong button.

@PhilRunninger PhilRunninger reopened this Dec 21, 2017
@lifecrisis
Copy link
Contributor Author

Well, previously, :NERDTreeFind would tell you that no file existed for the current buffer (if it was a new buffer, say). I think that should be the default behavior.

If you specify a directory as an arg... then it should reveal the directory as expected.

That makes the most sense to me, anyway.

Jason Franklin added 2 commits December 22, 2017 08:45
If a file does not exist for the current buffer, this function
should fail with a clear warning message.

Here, I improved the messages that this function prints so that it
fails gracefully when no path can be determined in the calling
context.
The docs for ":NERDTreeFind" are updated.  Some additional
formatting changes are made to other sections.
@lifecrisis
Copy link
Contributor Author

lifecrisis commented Dec 22, 2017

@PhilRunninger,

This pull request is O.K., but I'm not happy with the efficiency of my solution. I don't really know a better way to do it... Here, I refresh the nodes along the path, which is better than refreshing the whole tree... however, it could be more efficient if I added just the new file to the tree (a single node).

I'm ambivalent, because the file we're finding could be in an unopened, but huge directory... which will be slow no matter what you do. Thus, worrying about efficiency will be a waste of our time in probably half to three quarters of all situations.

I've tried this on a directory of 350 nodes... it takes about 1.06s. To me this is acceptable... if a developer is structuring their projects well, directories will be much smaller than this anyway.

Large directories are just always going to be a problem... basically no matter what you do...

What do you think?

@PhilRunninger
Copy link
Member

I agree. Large directories and vimscript itself both work against a perfect solution. I think we're OK to go with this.

@lifecrisis
Copy link
Contributor Author

Sounds good. I'll review and merge in the next half-hour or so.

@lifecrisis lifecrisis merged commit 57788ab into preservim:master Dec 22, 2017
@lifecrisis lifecrisis deleted the find-new-file branch December 22, 2017 14:44
lifecrisis pushed a commit to lifecrisis/nerdtree that referenced this pull request Jan 5, 2018
The small change here reverts an attempted bugfix from pull request
children of the root whenever ":NERDTreeFind" was invoked.  This was
disruptive (as reported in preservim#793), so a new method must be found to
solve the problem of ":NERDTreeFind" not opening newly created
files.

Fixes preservim#793.
lifecrisis pushed a commit to lifecrisis/nerdtree that referenced this pull request Jan 5, 2018
The small change here reverts an attempted bugfix from pull request
of the root whenever ":NERDTreeFind" was invoked.  This was
disruptive (as reported in preservim#793), so a new method must be found to
solve the problem of ":NERDTreeFind" not opening newly created
files.

Fixes preservim#793.
lifecrisis pushed a commit to lifecrisis/nerdtree that referenced this pull request Jan 5, 2018
The small change here reverts an attempted bugfix from pull request
number 785.  That change resulted in the unintended side-effect of
closing other children of the root the root whenever ":NERDTreeFind"
was invoked.  This was disruptive (as reported in preservim#793), so a new
method must be found to solve the problem of ":NERDTreeFind" not
opening newly created files.

Fixes preservim#793.
lifecrisis pushed a commit to lifecrisis/nerdtree that referenced this pull request Jan 5, 2018
The small change here reverts an attempted bugfix from preservim#785.  That
change resulted in the unintended side-effect of closing other
children of the root whenever ":NERDTreeFind" was invoked.  This was
disruptive (as reported in preservim#793), so a new method must be found to
solve the problem of ":NERDTreeFind" not opening newly created
files.

Fixes preservim#793.
lifecrisis added a commit that referenced this pull request Jan 5, 2018
Revert the bugfix from pull request #785 and reopen issue #779.
We keep the good style changes from PR #785 intact.
@lifecrisis
Copy link
Contributor Author

NOTE: This PR was reverted (but all style changes were kept) in PR #794. The reasons for the change are given there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants