You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
786 lines
22 KiB
VimL
786 lines
22 KiB
VimL
"we need to use this number many times for sorting... so we calculate it only
|
|
"once here
|
|
let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*')
|
|
" used in formating sortKey, e.g. '%04d'
|
|
if exists("log10")
|
|
let s:sortKeyFormat = "%0" . float2nr(ceil(log10(len(g:NERDTreeSortOrder)))) . "d"
|
|
else
|
|
let s:sortKeyFormat = "%04d"
|
|
endif
|
|
|
|
"CLASS: Path
|
|
"============================================================
|
|
let s:Path = {}
|
|
let g:NERDTreePath = s:Path
|
|
|
|
"FUNCTION: Path.AbsolutePathFor(str) {{{1
|
|
function! s:Path.AbsolutePathFor(str)
|
|
let prependCWD = 0
|
|
if nerdtree#runningWindows()
|
|
let prependCWD = a:str !~# '^.:\(\\\|\/\)' && a:str !~# '^\(\\\\\|\/\/\)'
|
|
else
|
|
let prependCWD = a:str !~# '^/'
|
|
endif
|
|
|
|
let toReturn = a:str
|
|
if prependCWD
|
|
let toReturn = getcwd() . s:Path.Slash() . a:str
|
|
endif
|
|
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: Path.bookmarkNames() {{{1
|
|
function! s:Path.bookmarkNames()
|
|
if !exists("self._bookmarkNames")
|
|
call self.cacheDisplayString()
|
|
endif
|
|
return self._bookmarkNames
|
|
endfunction
|
|
|
|
"FUNCTION: Path.cacheDisplayString() {{{1
|
|
function! s:Path.cacheDisplayString() abort
|
|
let self.cachedDisplayString = self.flagSet.renderToString()
|
|
|
|
let self.cachedDisplayString .= self.getLastPathComponent(1)
|
|
|
|
if self.isExecutable
|
|
let self.cachedDisplayString = self.cachedDisplayString . '*'
|
|
endif
|
|
|
|
let self._bookmarkNames = []
|
|
for i in g:NERDTreeBookmark.Bookmarks()
|
|
if i.path.equals(self)
|
|
call add(self._bookmarkNames, i.name)
|
|
endif
|
|
endfor
|
|
if !empty(self._bookmarkNames)
|
|
let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
|
|
endif
|
|
|
|
if self.isSymLink
|
|
let self.cachedDisplayString .= ' -> ' . self.symLinkDest
|
|
endif
|
|
|
|
if self.isReadOnly
|
|
let self.cachedDisplayString .= ' [RO]'
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.changeToDir() {{{1
|
|
function! s:Path.changeToDir()
|
|
let dir = self.str({'format': 'Cd'})
|
|
if self.isDirectory ==# 0
|
|
let dir = self.getParent().str({'format': 'Cd'})
|
|
endif
|
|
|
|
try
|
|
execute "cd " . dir
|
|
call nerdtree#echo("CWD is now: " . getcwd())
|
|
catch
|
|
throw "NERDTree.PathChangeError: cannot change CWD to " . dir
|
|
endtry
|
|
endfunction
|
|
|
|
"FUNCTION: Path.compareTo() {{{1
|
|
"
|
|
"Compares this Path to the given path and returns 0 if they are equal, -1 if
|
|
"this Path is "less than" the given path, or 1 if it is "greater".
|
|
"
|
|
"Args:
|
|
"path: the path object to compare this to
|
|
"
|
|
"Return:
|
|
"1, -1 or 0
|
|
function! s:Path.compareTo(path)
|
|
let thisPath = self.getLastPathComponent(1)
|
|
let thatPath = a:path.getLastPathComponent(1)
|
|
|
|
"if the paths are the same then clearly we return 0
|
|
if thisPath ==# thatPath
|
|
return 0
|
|
endif
|
|
|
|
let thisSS = self.getSortOrderIndex()
|
|
let thatSS = a:path.getSortOrderIndex()
|
|
|
|
"compare the sort sequences, if they are different then the return
|
|
"value is easy
|
|
if thisSS < thatSS
|
|
return -1
|
|
elseif thisSS > thatSS
|
|
return 1
|
|
else
|
|
if !g:NERDTreeSortHiddenFirst
|
|
let thisPath = substitute(thisPath, '^[._]', '', '')
|
|
let thatPath = substitute(thatPath, '^[._]', '', '')
|
|
endif
|
|
"if the sort sequences are the same then compare the paths
|
|
"alphabetically
|
|
let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath <? thatPath
|
|
if pathCompare
|
|
return -1
|
|
else
|
|
return 1
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.Create(fullpath) {{{1
|
|
"
|
|
"Factory method.
|
|
"
|
|
"Creates a path object with the given path. The path is also created on the
|
|
"filesystem. If the path already exists, a NERDTree.Path.Exists exception is
|
|
"thrown. If any other errors occur, a NERDTree.Path exception is thrown.
|
|
"
|
|
"Args:
|
|
"fullpath: the full filesystem path to the file/dir to create
|
|
function! s:Path.Create(fullpath)
|
|
"bail if the a:fullpath already exists
|
|
if isdirectory(a:fullpath) || filereadable(a:fullpath)
|
|
throw "NERDTree.CreatePathError: Directory Exists: '" . a:fullpath . "'"
|
|
endif
|
|
|
|
try
|
|
|
|
"if it ends with a slash, assume its a dir create it
|
|
if a:fullpath =~# '\(\\\|\/\)$'
|
|
"whack the trailing slash off the end if it exists
|
|
let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '')
|
|
|
|
call mkdir(fullpath, 'p')
|
|
|
|
"assume its a file and create
|
|
else
|
|
call s:Path.createParentDirectories(a:fullpath)
|
|
call writefile([], a:fullpath)
|
|
endif
|
|
catch
|
|
throw "NERDTree.CreatePathError: Could not create path: '" . a:fullpath . "'"
|
|
endtry
|
|
|
|
return s:Path.New(a:fullpath)
|
|
endfunction
|
|
|
|
"FUNCTION: Path.copy(dest) {{{1
|
|
"
|
|
"Copies the file/dir represented by this Path to the given location
|
|
"
|
|
"Args:
|
|
"dest: the location to copy this dir/file to
|
|
function! s:Path.copy(dest)
|
|
if !s:Path.CopyingSupported()
|
|
throw "NERDTree.CopyingNotSupportedError: Copying is not supported on this OS"
|
|
endif
|
|
|
|
call s:Path.createParentDirectories(a:dest)
|
|
|
|
let dest = s:Path.WinToUnixPath(a:dest)
|
|
|
|
let cmd = g:NERDTreeCopyCmd . " " . escape(self.str(), self._escChars()) . " " . escape(dest, self._escChars())
|
|
let success = system(cmd)
|
|
if success != 0
|
|
throw "NERDTree.CopyError: Could not copy ''". self.str() ."'' to: '" . a:dest . "'"
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.CopyingSupported() {{{1
|
|
"
|
|
"returns 1 if copying is supported for this OS
|
|
function! s:Path.CopyingSupported()
|
|
return exists('g:NERDTreeCopyCmd')
|
|
endfunction
|
|
|
|
"FUNCTION: Path.copyingWillOverwrite(dest) {{{1
|
|
"
|
|
"returns 1 if copy this path to the given location will cause files to
|
|
"overwritten
|
|
"
|
|
"Args:
|
|
"dest: the location this path will be copied to
|
|
function! s:Path.copyingWillOverwrite(dest)
|
|
if filereadable(a:dest)
|
|
return 1
|
|
endif
|
|
|
|
if isdirectory(a:dest)
|
|
let path = s:Path.JoinPathStrings(a:dest, self.getLastPathComponent(0))
|
|
if filereadable(path)
|
|
return 1
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.createParentDirectories(path) {{{1
|
|
"
|
|
"create parent directories for this path if needed
|
|
"without throwing any errors is those directories already exist
|
|
"
|
|
"Args:
|
|
"path: full path of the node whose parent directories may need to be created
|
|
function! s:Path.createParentDirectories(path)
|
|
let dir_path = fnamemodify(a:path, ':h')
|
|
if !isdirectory(dir_path)
|
|
call mkdir(dir_path, 'p')
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.delete() {{{1
|
|
"
|
|
"Deletes the file represented by this path.
|
|
"Deletion of directories is not supported
|
|
"
|
|
"Throws NERDTree.Path.Deletion exceptions
|
|
function! s:Path.delete()
|
|
if self.isDirectory
|
|
|
|
let cmd = g:NERDTreeRemoveDirCmd . self.str({'escape': 1})
|
|
let success = system(cmd)
|
|
|
|
if v:shell_error != 0
|
|
throw "NERDTree.PathDeletionError: Could not delete directory: '" . self.str() . "'"
|
|
endif
|
|
else
|
|
let success = delete(self.str())
|
|
if success != 0
|
|
throw "NERDTree.PathDeletionError: Could not delete file: '" . self.str() . "'"
|
|
endif
|
|
endif
|
|
|
|
"delete all bookmarks for this path
|
|
for i in self.bookmarkNames()
|
|
let bookmark = g:NERDTreeBookmark.BookmarkFor(i)
|
|
call bookmark.delete()
|
|
endfor
|
|
endfunction
|
|
|
|
"FUNCTION: Path.displayString() {{{1
|
|
"
|
|
"Returns a string that specifies how the path should be represented as a
|
|
"string
|
|
function! s:Path.displayString()
|
|
if self.cachedDisplayString ==# ""
|
|
call self.cacheDisplayString()
|
|
endif
|
|
|
|
return self.cachedDisplayString
|
|
endfunction
|
|
|
|
"FUNCTION: Path.edit() {{{1
|
|
function! s:Path.edit()
|
|
exec "edit " . self.str({'format': 'Edit'})
|
|
endfunction
|
|
|
|
"FUNCTION: Path.extractDriveLetter(fullpath) {{{1
|
|
"
|
|
"If running windows, cache the drive letter for this path
|
|
function! s:Path.extractDriveLetter(fullpath)
|
|
if nerdtree#runningWindows()
|
|
if a:fullpath =~ '^\(\\\\\|\/\/\)'
|
|
"For network shares, the 'drive' consists of the first two parts of the path, i.e. \\boxname\share
|
|
let self.drive = substitute(a:fullpath, '^\(\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\).*', '\1', '')
|
|
let self.drive = substitute(self.drive, '/', '\', "g")
|
|
else
|
|
let self.drive = substitute(a:fullpath, '\(^[a-zA-Z]:\).*', '\1', '')
|
|
endif
|
|
else
|
|
let self.drive = ''
|
|
endif
|
|
|
|
endfunction
|
|
|
|
"FUNCTION: Path.exists() {{{1
|
|
"return 1 if this path points to a location that is readable or is a directory
|
|
function! s:Path.exists()
|
|
let p = self.str()
|
|
return filereadable(p) || isdirectory(p)
|
|
endfunction
|
|
|
|
"FUNCTION: Path._escChars() {{{1
|
|
function! s:Path._escChars()
|
|
if nerdtree#runningWindows()
|
|
return " `\|\"#%&,?()\*^<>"
|
|
endif
|
|
|
|
return " \\`\|\"#%&,?()\*^<>[]"
|
|
endfunction
|
|
|
|
"FUNCTION: Path.getDir() {{{1
|
|
"
|
|
"Returns this path if it is a directory, else this paths parent.
|
|
"
|
|
"Return:
|
|
"a Path object
|
|
function! s:Path.getDir()
|
|
if self.isDirectory
|
|
return self
|
|
else
|
|
return self.getParent()
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.getParent() {{{1
|
|
"
|
|
"Returns a new path object for this paths parent
|
|
"
|
|
"Return:
|
|
"a new Path object
|
|
function! s:Path.getParent()
|
|
if nerdtree#runningWindows()
|
|
let path = self.drive . '\' . join(self.pathSegments[0:-2], '\')
|
|
else
|
|
let path = '/'. join(self.pathSegments[0:-2], '/')
|
|
endif
|
|
|
|
return s:Path.New(path)
|
|
endfunction
|
|
|
|
"FUNCTION: Path.getLastPathComponent(dirSlash) {{{1
|
|
"
|
|
"Gets the last part of this path.
|
|
"
|
|
"Args:
|
|
"dirSlash: if 1 then a trailing slash will be added to the returned value for
|
|
"directory nodes.
|
|
function! s:Path.getLastPathComponent(dirSlash)
|
|
if empty(self.pathSegments)
|
|
return ''
|
|
endif
|
|
let toReturn = self.pathSegments[-1]
|
|
if a:dirSlash && self.isDirectory
|
|
let toReturn = toReturn . '/'
|
|
endif
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: Path.getSortOrderIndex() {{{1
|
|
"returns the index of the pattern in g:NERDTreeSortOrder that this path matches
|
|
function! s:Path.getSortOrderIndex()
|
|
let i = 0
|
|
while i < len(g:NERDTreeSortOrder)
|
|
if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i]
|
|
return i
|
|
endif
|
|
let i = i + 1
|
|
endwhile
|
|
return s:NERDTreeSortStarIndex
|
|
endfunction
|
|
|
|
"FUNCTION: Path.getSortKey() {{{1
|
|
"returns a string used in compare function for sorting
|
|
function! s:Path.getSortKey()
|
|
if !exists("self._sortKey")
|
|
let path = self.getLastPathComponent(1)
|
|
if !g:NERDTreeSortHiddenFirst
|
|
let path = substitute(path, '^[._]', '', '')
|
|
endif
|
|
if !g:NERDTreeCaseSensitiveSort
|
|
let path = tolower(path)
|
|
endif
|
|
let self._sortKey = printf(s:sortKeyFormat, self.getSortOrderIndex()) . path
|
|
endif
|
|
|
|
return self._sortKey
|
|
endfunction
|
|
|
|
|
|
"FUNCTION: Path.isUnixHiddenFile() {{{1
|
|
"check for unix hidden files
|
|
function! s:Path.isUnixHiddenFile()
|
|
return self.getLastPathComponent(0) =~# '^\.'
|
|
endfunction
|
|
|
|
"FUNCTION: Path.isUnixHiddenPath() {{{1
|
|
"check for unix path with hidden components
|
|
function! s:Path.isUnixHiddenPath()
|
|
if self.getLastPathComponent(0) =~# '^\.'
|
|
return 1
|
|
else
|
|
for segment in self.pathSegments
|
|
if segment =~# '^\.'
|
|
return 1
|
|
endif
|
|
endfor
|
|
return 0
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.ignore() {{{1
|
|
"returns true if this path should be ignored
|
|
function! s:Path.ignore()
|
|
"filter out the user specified paths to ignore
|
|
if b:NERDTreeIgnoreEnabled
|
|
for i in g:NERDTreeIgnore
|
|
if self._ignorePatternMatches(i)
|
|
return 1
|
|
endif
|
|
endfor
|
|
|
|
for callback in g:NERDTree.PathFilters()
|
|
if {callback}({'path': self, 'nerdtree': b:NERDTree})
|
|
return 1
|
|
endif
|
|
endfor
|
|
endif
|
|
|
|
"dont show hidden files unless instructed to
|
|
if b:NERDTreeShowHidden ==# 0 && self.isUnixHiddenFile()
|
|
return 1
|
|
endif
|
|
|
|
if b:NERDTreeShowFiles ==# 0 && self.isDirectory ==# 0
|
|
return 1
|
|
endif
|
|
|
|
return 0
|
|
endfunction
|
|
|
|
"FUNCTION: Path._ignorePatternMatches(pattern) {{{1
|
|
"returns true if this path matches the given ignore pattern
|
|
function! s:Path._ignorePatternMatches(pattern)
|
|
let pat = a:pattern
|
|
if strpart(pat,len(pat)-7) == '[[dir]]'
|
|
if !self.isDirectory
|
|
return 0
|
|
endif
|
|
let pat = strpart(pat,0, len(pat)-7)
|
|
elseif strpart(pat,len(pat)-8) == '[[file]]'
|
|
if self.isDirectory
|
|
return 0
|
|
endif
|
|
let pat = strpart(pat,0, len(pat)-8)
|
|
endif
|
|
|
|
return self.getLastPathComponent(0) =~# pat
|
|
endfunction
|
|
|
|
"FUNCTION: Path.isUnder(path) {{{1
|
|
"return 1 if this path is somewhere under the given path in the filesystem.
|
|
"
|
|
"a:path should be a dir
|
|
function! s:Path.isUnder(path)
|
|
if a:path.isDirectory == 0
|
|
return 0
|
|
endif
|
|
|
|
let this = self.str()
|
|
let that = a:path.str()
|
|
return stridx(this, that . s:Path.Slash()) == 0
|
|
endfunction
|
|
|
|
"FUNCTION: Path.JoinPathStrings(...) {{{1
|
|
function! s:Path.JoinPathStrings(...)
|
|
let components = []
|
|
for i in a:000
|
|
let components = extend(components, split(i, '/'))
|
|
endfor
|
|
return '/' . join(components, '/')
|
|
endfunction
|
|
|
|
"FUNCTION: Path.equals() {{{1
|
|
"
|
|
"Determines whether 2 path objects are "equal".
|
|
"They are equal if the paths they represent are the same
|
|
"
|
|
"Args:
|
|
"path: the other path obj to compare this with
|
|
function! s:Path.equals(path)
|
|
return self.str() ==# a:path.str()
|
|
endfunction
|
|
|
|
"FUNCTION: Path.New() {{{1
|
|
"The Constructor for the Path object
|
|
function! s:Path.New(path)
|
|
let newPath = copy(self)
|
|
|
|
call newPath.readInfoFromDisk(s:Path.AbsolutePathFor(a:path))
|
|
|
|
let newPath.cachedDisplayString = ""
|
|
let newPath.flagSet = g:NERDTreeFlagSet.New()
|
|
|
|
return newPath
|
|
endfunction
|
|
|
|
"FUNCTION: Path.Slash() {{{1
|
|
"return the slash to use for the current OS
|
|
function! s:Path.Slash()
|
|
return nerdtree#runningWindows() ? '\' : '/'
|
|
endfunction
|
|
|
|
"FUNCTION: Path.Resolve() {{{1
|
|
"Invoke the vim resolve() function and return the result
|
|
"This is necessary because in some versions of vim resolve() removes trailing
|
|
"slashes while in other versions it doesn't. This always removes the trailing
|
|
"slash
|
|
function! s:Path.Resolve(path)
|
|
let tmp = resolve(a:path)
|
|
return tmp =~# '.\+/$' ? substitute(tmp, '/$', '', '') : tmp
|
|
endfunction
|
|
|
|
"FUNCTION: Path.readInfoFromDisk(fullpath) {{{1
|
|
"
|
|
"
|
|
"Throws NERDTree.Path.InvalidArguments exception.
|
|
function! s:Path.readInfoFromDisk(fullpath)
|
|
call self.extractDriveLetter(a:fullpath)
|
|
|
|
let fullpath = s:Path.WinToUnixPath(a:fullpath)
|
|
|
|
if getftype(fullpath) ==# "fifo"
|
|
throw "NERDTree.InvalidFiletypeError: Cant handle FIFO files: " . a:fullpath
|
|
endif
|
|
|
|
let self.pathSegments = split(fullpath, '/')
|
|
|
|
let self.isReadOnly = 0
|
|
if isdirectory(a:fullpath)
|
|
let self.isDirectory = 1
|
|
elseif filereadable(a:fullpath)
|
|
let self.isDirectory = 0
|
|
let self.isReadOnly = filewritable(a:fullpath) ==# 0
|
|
else
|
|
throw "NERDTree.InvalidArgumentsError: Invalid path = " . a:fullpath
|
|
endif
|
|
|
|
let self.isExecutable = 0
|
|
if !self.isDirectory
|
|
let self.isExecutable = getfperm(a:fullpath) =~# 'x'
|
|
endif
|
|
|
|
"grab the last part of the path (minus the trailing slash)
|
|
let lastPathComponent = self.getLastPathComponent(0)
|
|
|
|
"get the path to the new node with the parent dir fully resolved
|
|
let hardPath = s:Path.Resolve(self.strTrunk()) . '/' . lastPathComponent
|
|
|
|
"if the last part of the path is a symlink then flag it as such
|
|
let self.isSymLink = (s:Path.Resolve(hardPath) != hardPath)
|
|
if self.isSymLink
|
|
let self.symLinkDest = s:Path.Resolve(fullpath)
|
|
|
|
"if the link is a dir then slap a / on the end of its dest
|
|
if isdirectory(self.symLinkDest)
|
|
|
|
"we always wanna treat MS windows shortcuts as files for
|
|
"simplicity
|
|
if hardPath !~# '\.lnk$'
|
|
|
|
let self.symLinkDest = self.symLinkDest . '/'
|
|
endif
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
"FUNCTION: Path.refresh() {{{1
|
|
function! s:Path.refresh()
|
|
call self.readInfoFromDisk(self.str())
|
|
call g:NERDTreePathNotifier.NotifyListeners('refresh', self, {})
|
|
call self.cacheDisplayString()
|
|
endfunction
|
|
|
|
"FUNCTION: Path.refreshFlags() {{{1
|
|
function! s:Path.refreshFlags()
|
|
call g:NERDTreePathNotifier.NotifyListeners('refreshFlags', self, {})
|
|
call self.cacheDisplayString()
|
|
endfunction
|
|
|
|
"FUNCTION: Path.rename() {{{1
|
|
"
|
|
"Renames this node on the filesystem
|
|
function! s:Path.rename(newPath)
|
|
if a:newPath ==# ''
|
|
throw "NERDTree.InvalidArgumentsError: Invalid newPath for renaming = ". a:newPath
|
|
endif
|
|
|
|
let success = rename(self.str(), a:newPath)
|
|
if success != 0
|
|
throw "NERDTree.PathRenameError: Could not rename: '" . self.str() . "'" . 'to:' . a:newPath
|
|
endif
|
|
call self.readInfoFromDisk(a:newPath)
|
|
|
|
for i in self.bookmarkNames()
|
|
let b = g:NERDTreeBookmark.BookmarkFor(i)
|
|
call b.setPath(copy(self))
|
|
endfor
|
|
call g:NERDTreeBookmark.Write()
|
|
endfunction
|
|
|
|
"FUNCTION: Path.str() {{{1
|
|
"
|
|
"Returns a string representation of this Path
|
|
"
|
|
"Takes an optional dictionary param to specify how the output should be
|
|
"formatted.
|
|
"
|
|
"The dict may have the following keys:
|
|
" 'format'
|
|
" 'escape'
|
|
" 'truncateTo'
|
|
"
|
|
"The 'format' key may have a value of:
|
|
" 'Cd' - a string to be used with the :cd command
|
|
" 'Edit' - a string to be used with :e :sp :new :tabedit etc
|
|
" 'UI' - a string used in the NERD tree UI
|
|
"
|
|
"The 'escape' key, if specified will cause the output to be escaped with
|
|
"shellescape()
|
|
"
|
|
"The 'truncateTo' key causes the resulting string to be truncated to the value
|
|
"'truncateTo' maps to. A '<' char will be prepended.
|
|
function! s:Path.str(...)
|
|
let options = a:0 ? a:1 : {}
|
|
let toReturn = ""
|
|
|
|
if has_key(options, 'format')
|
|
let format = options['format']
|
|
if has_key(self, '_strFor' . format)
|
|
exec 'let toReturn = self._strFor' . format . '()'
|
|
else
|
|
throw 'NERDTree.UnknownFormatError: unknown format "'. format .'"'
|
|
endif
|
|
else
|
|
let toReturn = self._str()
|
|
endif
|
|
|
|
if nerdtree#has_opt(options, 'escape')
|
|
let toReturn = shellescape(toReturn)
|
|
endif
|
|
|
|
if has_key(options, 'truncateTo')
|
|
let limit = options['truncateTo']
|
|
if len(toReturn) > limit-1
|
|
let toReturn = toReturn[(len(toReturn)-limit+1):]
|
|
if len(split(toReturn, '/')) > 1
|
|
let toReturn = '</' . join(split(toReturn, '/')[1:], '/') . '/'
|
|
else
|
|
let toReturn = '<' . toReturn
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: Path._strForUI() {{{1
|
|
function! s:Path._strForUI()
|
|
let toReturn = '/' . join(self.pathSegments, '/')
|
|
if self.isDirectory && toReturn != '/'
|
|
let toReturn = toReturn . '/'
|
|
endif
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: Path._strForCd() {{{1
|
|
"
|
|
" returns a string that can be used with :cd
|
|
function! s:Path._strForCd()
|
|
return escape(self.str(), self._escChars())
|
|
endfunction
|
|
|
|
"FUNCTION: Path._strForEdit() {{{1
|
|
"
|
|
"Return: the string for this path that is suitable to be used with the :edit
|
|
"command
|
|
function! s:Path._strForEdit()
|
|
let p = escape(self.str(), self._escChars())
|
|
|
|
"make it relative
|
|
let p = fnamemodify(p, ':.')
|
|
|
|
"handle the edge case where the file begins with a + (vim interprets
|
|
"the +foo in `:e +foo` as an option to :edit)
|
|
if p[0] == "+"
|
|
let p = '\' . p
|
|
endif
|
|
|
|
if p ==# ''
|
|
let p = '.'
|
|
endif
|
|
|
|
return p
|
|
endfunction
|
|
|
|
"FUNCTION: Path._strForGlob() {{{1
|
|
function! s:Path._strForGlob()
|
|
let lead = s:Path.Slash()
|
|
|
|
"if we are running windows then slap a drive letter on the front
|
|
if nerdtree#runningWindows()
|
|
let lead = self.drive . '\'
|
|
endif
|
|
|
|
let toReturn = lead . join(self.pathSegments, s:Path.Slash())
|
|
|
|
if !nerdtree#runningWindows()
|
|
let toReturn = escape(toReturn, self._escChars())
|
|
endif
|
|
return toReturn
|
|
endfunction
|
|
|
|
"FUNCTION: Path._str() {{{1
|
|
"
|
|
"Gets the string path for this path object that is appropriate for the OS.
|
|
"EG, in windows c:\foo\bar
|
|
" in *nix /foo/bar
|
|
function! s:Path._str()
|
|
let lead = s:Path.Slash()
|
|
|
|
"if we are running windows then slap a drive letter on the front
|
|
if nerdtree#runningWindows()
|
|
let lead = self.drive . '\'
|
|
endif
|
|
|
|
return lead . join(self.pathSegments, s:Path.Slash())
|
|
endfunction
|
|
|
|
"FUNCTION: Path.strTrunk() {{{1
|
|
"Gets the path without the last segment on the end.
|
|
function! s:Path.strTrunk()
|
|
return self.drive . '/' . join(self.pathSegments[0:-2], '/')
|
|
endfunction
|
|
|
|
" FUNCTION: Path.tabnr() {{{1
|
|
" return the number of the first tab that is displaying this file
|
|
"
|
|
" return 0 if no tab was found
|
|
function! s:Path.tabnr()
|
|
let str = self.str()
|
|
for t in range(tabpagenr('$'))
|
|
for b in tabpagebuflist(t+1)
|
|
if str == expand('#' . b . ':p')
|
|
return t+1
|
|
endif
|
|
endfor
|
|
endfor
|
|
return 0
|
|
endfunction
|
|
|
|
"FUNCTION: Path.WinToUnixPath(pathstr){{{1
|
|
"Takes in a windows path and returns the unix equiv
|
|
"
|
|
"A class level method
|
|
"
|
|
"Args:
|
|
"pathstr: the windows path to convert
|
|
function! s:Path.WinToUnixPath(pathstr)
|
|
if !nerdtree#runningWindows()
|
|
return a:pathstr
|
|
endif
|
|
|
|
let toReturn = a:pathstr
|
|
|
|
"remove the x:\ of the front
|
|
let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "")
|
|
|
|
"remove the \\ network share from the front
|
|
let toReturn = substitute(toReturn, '^\(\\\\\|\/\/\)[^\\\/]*\(\\\|\/\)[^\\\/]*\(\\\|\/\)\?', '/', "")
|
|
|
|
"convert all \ chars to /
|
|
let toReturn = substitute(toReturn, '\', '/', "g")
|
|
|
|
return toReturn
|
|
endfunction
|
|
|
|
" vim: set sw=4 sts=4 et fdm=marker:
|