mirror of
1
0
Fork 0
ultimate-vim/sources_non_forked/nerdtree/lib/nerdtree/bookmark.vim

366 lines
12 KiB
VimL
Raw Normal View History

2017-07-06 08:57:35 -04:00
" ============================================================================
" CLASS: Bookmark
"
" The Bookmark class serves two purposes:
" (1) It is the top-level prototype for new, concrete Bookmark objects.
" (2) It provides an interface for client code to query and manipulate the
" global list of Bookmark objects within the current Vim session.
" ============================================================================
let s:Bookmark = {}
let g:NERDTreeBookmark = s:Bookmark
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.activate(nerdtree) {{{1
function! s:Bookmark.activate(nerdtree, ...)
call self.open(a:nerdtree, a:0 ? a:1 : {})
endfunction
" FUNCTION: Bookmark.AddBookmark(name, path) {{{1
" Class method to add a new bookmark to the list, if a previous bookmark exists
" with the same name, just update the path for that bookmark
function! s:Bookmark.AddBookmark(name, path)
for i in s:Bookmark.Bookmarks()
if i.name ==# a:name
let i.path = a:path
return
endif
endfor
call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path))
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.Bookmarks() {{{1
" Class method to get all bookmarks. Lazily initializes the bookmarks global
" variable
function! s:Bookmark.Bookmarks()
2020-01-07 07:45:07 -05:00
if !exists('g:NERDTreeBookmarks')
let g:NERDTreeBookmarks = []
endif
return g:NERDTreeBookmarks
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.BookmarkExistsFor(name) {{{1
" class method that returns 1 if a bookmark with the given name is found, 0
" otherwise
function! s:Bookmark.BookmarkExistsFor(name)
try
call s:Bookmark.BookmarkFor(a:name)
return 1
catch /^NERDTree.BookmarkNotFoundError/
return 0
endtry
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.BookmarkFor(name) {{{1
" Class method that returns the Bookmark object having the specified name.
2020-01-07 07:45:07 -05:00
" Throws NERDTree.BookmarkNotFoundError if no Bookmark is found.
function! s:Bookmark.BookmarkFor(name)
2017-07-06 08:57:35 -04:00
let l:result = {}
for l:bookmark in s:Bookmark.Bookmarks()
if l:bookmark.name ==# a:name
let l:result = l:bookmark
break
endif
endfor
2017-07-06 08:57:35 -04:00
if empty(l:result)
throw 'NERDTree.BookmarkNotFoundError: "' . a:name . '" not found'
endif
return l:result
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.BookmarkNames() {{{1
" Class method to return an array of all bookmark names
function! s:Bookmark.BookmarkNames()
let names = []
for i in s:Bookmark.Bookmarks()
call add(names, i.name)
endfor
return names
endfunction
" FUNCTION: Bookmark.CacheBookmarks(silent) {{{1
2013-05-25 20:31:29 -04:00
" Class method to read all bookmarks from the bookmarks file initialize
" bookmark objects for each one.
"
" Args:
" silent - dont echo an error msg if invalid bookmarks are found
function! s:Bookmark.CacheBookmarks(silent)
if filereadable(g:NERDTreeBookmarksFile)
let g:NERDTreeBookmarks = []
let g:NERDTreeInvalidBookmarks = []
let bookmarkStrings = readfile(g:NERDTreeBookmarksFile)
let invalidBookmarksFound = 0
for i in bookmarkStrings
"ignore blank lines
2020-01-07 07:45:07 -05:00
if i !=# ''
let name = substitute(i, '^\(.\{-}\) .*$', '\1', '')
let path = substitute(i, '^.\{-} \(.*\)$', '\1', '')
2015-12-08 08:20:04 -05:00
let path = fnamemodify(path, ':p')
try
let bookmark = s:Bookmark.New(name, g:NERDTreePath.New(path))
call add(g:NERDTreeBookmarks, bookmark)
catch /^NERDTree.InvalidArgumentsError/
call add(g:NERDTreeInvalidBookmarks, i)
let invalidBookmarksFound += 1
endtry
endif
endfor
if invalidBookmarksFound
call s:Bookmark.Write()
if !a:silent
2020-01-07 07:45:07 -05:00
call nerdtree#echo(invalidBookmarksFound . ' invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.')
endif
endif
endif
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark) {{{1
" Class method that indicates the relative position of two bookmarks when
" placed in alphabetical order by name. Case-sensitivity is determined by an
2020-01-07 07:45:07 -05:00
" option. Supports the s:Bookmark.SortBookmarksList() method.
2017-07-06 08:57:35 -04:00
function! s:Bookmark.CompareBookmarksByName(firstBookmark, secondBookmark)
let l:result = 0
2020-01-07 07:45:07 -05:00
if g:NERDTreeBookmarksSort ==# 1
2017-07-06 08:57:35 -04:00
if a:firstBookmark.name <? a:secondBookmark.name
let l:result = -1
elseif a:firstBookmark.name >? a:secondBookmark.name
let l:result = 1
endif
2020-01-07 07:45:07 -05:00
elseif g:NERDTreeBookmarksSort ==# 2
2017-07-06 08:57:35 -04:00
if a:firstBookmark.name <# a:secondBookmark.name
let l:result = -1
elseif a:firstBookmark.name ># a:secondBookmark.name
let l:result = 1
endif
endif
return l:result
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.ClearAll() {{{1
" Class method to delete all bookmarks.
function! s:Bookmark.ClearAll()
for i in s:Bookmark.Bookmarks()
call i.delete()
endfor
call s:Bookmark.Write()
endfunction
" FUNCTION: Bookmark.delete() {{{1
" Delete this bookmark. If the node for this bookmark is under the current
" root, then recache bookmarks for its Path object
function! s:Bookmark.delete()
call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self))
call s:Bookmark.Write()
endfunction
2019-03-08 06:04:56 -05:00
" FUNCTION: s:Edit() {{{1
" opens the NERDTreeBookmarks file for manual editing
function! s:Bookmark.Edit()
2020-01-07 07:45:07 -05:00
call nerdtree#exec('wincmd w', 1)
call nerdtree#exec('edit '.g:NERDTreeBookmarksFile, 1)
2019-03-08 06:04:56 -05:00
endfunction
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.getNode(nerdtree, searchFromAbsoluteRoot) {{{1
2017-07-06 08:57:35 -04:00
" Returns the tree node object associated with this Bookmark.
2020-01-07 07:45:07 -05:00
" Throws NERDTree.BookmarkedNodeNotFoundError if the node is not found.
"
" Args:
2017-07-06 08:57:35 -04:00
" searchFromAbsoluteRoot: boolean flag, search from the highest cached node
" if true and from the current tree root if false
2015-12-08 08:20:04 -05:00
function! s:Bookmark.getNode(nerdtree, searchFromAbsoluteRoot)
2017-07-06 08:57:35 -04:00
if a:searchFromAbsoluteRoot
let l:searchRoot = a:nerdtree.root.AbsoluteTreeRoot()
else
let l:searchRoot = a:nerdtree.root
endif
let l:targetNode = l:searchRoot.findNode(self.path)
if empty(l:targetNode)
throw 'NERDTree.BookmarkedNodeNotFoundError: node for bookmark "' . self.name . '" not found'
endif
2017-07-06 08:57:35 -04:00
return l:targetNode
endfunction
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree) {{{1
2017-07-06 08:57:35 -04:00
" Class method that returns the tree node object for the Bookmark with the
2020-01-07 07:45:07 -05:00
" given name. Throws NERDTree.BookmarkNotFoundError if a Bookmark with the
" name does not exist. Throws NERDTree.BookmarkedNodeNotFoundError if a
2017-07-06 08:57:35 -04:00
" tree node for the named Bookmark could not be found.
2015-12-08 08:20:04 -05:00
function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot, nerdtree)
2017-07-06 08:57:35 -04:00
let l:bookmark = s:Bookmark.BookmarkFor(a:name)
return l:bookmark.getNode(a:nerdtree, a:searchFromAbsoluteRoot)
endfunction
" FUNCTION: Bookmark.GetSelected() {{{1
" returns the Bookmark the cursor is over, or {}
function! s:Bookmark.GetSelected()
2020-01-07 07:45:07 -05:00
let line = getline('.')
let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '')
2020-01-07 07:45:07 -05:00
if name !=# line
try
return s:Bookmark.BookmarkFor(name)
catch /^NERDTree.BookmarkNotFoundError/
return {}
endtry
endif
return {}
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.InvalidBookmarks() {{{1
" Class method to get all invalid bookmark strings read from the bookmarks
" file
function! s:Bookmark.InvalidBookmarks()
2020-01-07 07:45:07 -05:00
if !exists('g:NERDTreeInvalidBookmarks')
let g:NERDTreeInvalidBookmarks = []
endif
return g:NERDTreeInvalidBookmarks
endfunction
" FUNCTION: Bookmark.mustExist() {{{1
function! s:Bookmark.mustExist()
if !self.path.exists()
call s:Bookmark.CacheBookmarks(1)
2020-01-07 07:45:07 -05:00
throw 'NERDTree.BookmarkPointsToInvalidLocationError: the bookmark "'.
\ self.name .'" points to a non existing location: "'. self.path.str()
endif
endfunction
" FUNCTION: Bookmark.New(name, path) {{{1
" Create a new bookmark object with the given name and path object
function! s:Bookmark.New(name, path)
if a:name =~# ' '
2020-01-07 07:45:07 -05:00
throw 'NERDTree.IllegalBookmarkNameError: illegal name:' . a:name
endif
let newBookmark = copy(self)
let newBookmark.name = a:name
let newBookmark.path = a:path
return newBookmark
endfunction
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.open(nerdtree, [options]) {{{1
"Args:
2015-12-08 08:20:04 -05:00
"
"nerdtree: the tree to load open the bookmark in
"
"A dictionary containing the following keys (all optional):
" 'where': Specifies whether the node should be opened in new split/tab or in
" the previous window. Can be either 'v' (vertical split), 'h'
" (horizontal split), 't' (new tab) or 'p' (previous window).
" 'reuse': if a window is displaying the file then jump the cursor there
" 'keepopen': dont close the tree window
" 'stay': open the file, but keep the cursor in the tree win
"
2015-12-08 08:20:04 -05:00
function! s:Bookmark.open(nerdtree, ...)
let opts = a:0 ? a:1 : {}
2019-05-17 10:09:13 -04:00
if nerdtree#and(g:NERDTreeQuitOnOpen,2)
2019-03-08 06:04:56 -05:00
call a:nerdtree.ui.toggleShowBookmarks()
endif
if self.path.isDirectory && !has_key(opts, 'where')
2015-12-08 08:20:04 -05:00
call self.toRoot(a:nerdtree)
else
let opener = g:NERDTreeOpener.New(self.path, opts)
call opener.open(self)
endif
endfunction
" FUNCTION: Bookmark.openInNewTab(options) {{{1
" Create a new bookmark object with the given name and path object
function! s:Bookmark.openInNewTab(options)
call nerdtree#deprecated('Bookmark.openInNewTab', 'is deprecated, use open() instead')
call self.open(a:options)
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.setPath(path) {{{1
" makes this bookmark point to the given path
function! s:Bookmark.setPath(path)
let self.path = a:path
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.SortBookmarksList() {{{1
" Class method that sorts the global list of bookmarks alphabetically by name.
" Note that case-sensitivity is determined by a user option.
function! s:Bookmark.SortBookmarksList()
call sort(s:Bookmark.Bookmarks(), s:Bookmark.CompareBookmarksByName, s:Bookmark)
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.str() {{{1
" Get the string that should be rendered in the view for this bookmark
function! s:Bookmark.str()
2018-06-14 06:31:12 -04:00
let pathStrMaxLen = winwidth(g:NERDTree.GetWinNum()) - 4 - strdisplaywidth(self.name)
2020-01-07 07:45:07 -05:00
if &number
let pathStrMaxLen = pathStrMaxLen - &numberwidth
endif
let pathStr = self.path.str({'format': 'UI'})
2018-06-14 06:31:12 -04:00
if strdisplaywidth(pathStr) > pathStrMaxLen
while strdisplaywidth(pathStr) > pathStrMaxLen && strchars(pathStr) > 0
let pathStr = substitute(pathStr, '^.', '', '')
endwhile
let pathStr = '<' . pathStr
endif
return '>' . self.name . ' ' . pathStr
endfunction
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.toRoot(nerdtree) {{{1
2017-09-02 06:43:18 -04:00
" Set the root of the given NERDTree to the node for this Bookmark. If a node
" for this Bookmark does not exist, a new one is initialized.
2015-12-08 08:20:04 -05:00
function! s:Bookmark.toRoot(nerdtree)
if self.validate()
try
2017-09-02 06:43:18 -04:00
let l:targetNode = self.getNode(a:nerdtree, 1)
call l:targetNode.closeChildren()
catch /^NERDTree.BookmarkedNodeNotFoundError/
2017-09-02 06:43:18 -04:00
let l:targetNode = g:NERDTreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path, a:nerdtree)
endtry
2017-09-02 06:43:18 -04:00
call a:nerdtree.changeRoot(l:targetNode)
endif
endfunction
2015-12-08 08:20:04 -05:00
" FUNCTION: Bookmark.ToRoot(name, nerdtree) {{{1
2017-09-02 06:43:18 -04:00
" Class method that makes the Bookmark with the given name the root of
" specified NERDTree.
2015-12-08 08:20:04 -05:00
function! s:Bookmark.ToRoot(name, nerdtree)
2017-09-02 06:43:18 -04:00
let l:bookmark = s:Bookmark.BookmarkFor(a:name)
call l:bookmark.toRoot(a:nerdtree)
endfunction
" FUNCTION: Bookmark.validate() {{{1
function! s:Bookmark.validate()
if self.path.exists()
return 1
else
call s:Bookmark.CacheBookmarks(1)
2020-01-07 07:45:07 -05:00
call nerdtree#echo(self.name . 'now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.')
return 0
endif
endfunction
2017-07-06 08:57:35 -04:00
" FUNCTION: Bookmark.Write() {{{1
" Class method to write all bookmarks to the bookmarks file
function! s:Bookmark.Write()
let bookmarkStrings = []
for i in s:Bookmark.Bookmarks()
2015-12-08 08:20:04 -05:00
call add(bookmarkStrings, i.name . ' ' . fnamemodify(i.path.str(), ':~'))
endfor
"add a blank line before the invalid ones
2020-01-07 07:45:07 -05:00
call add(bookmarkStrings, '')
for j in s:Bookmark.InvalidBookmarks()
call add(bookmarkStrings, j)
endfor
2018-09-24 20:40:17 -04:00
try
call writefile(bookmarkStrings, g:NERDTreeBookmarksFile)
catch
2020-01-07 07:45:07 -05:00
call nerdtree#echoError('Failed to write bookmarks file. Make sure g:NERDTreeBookmarksFile points to a valid location.')
2018-09-24 20:40:17 -04:00
endtry
endfunction
" vim: set sw=4 sts=4 et fdm=marker: