Commits

ZyX_I committed 26cab51

Added chdir, mkdir, makedirs, unlink/remove, rmdir, removedirs, removetree, path.samefile and path.walk functions to os module, fixed path.abspath function, improved path.join function (it now accepts either list as an only argument or a list of strings)

Comments (0)

Files changed (2)

         Lists directory contents. If optional argument is given, then list of 
         absolute file names is returned, otherwise only trailing components 
         are returned.
+os.chdir :: path[, Bool] -> Bool + WD                        *frawor-os-chdir*
+        Changes current directory, returns 1 on success and 0 on failure. If 
+        optional argument is true, then only window current directory will be 
+        changed (see |:lcd|).
+os.mkdir :: path[, mode] -> Bool + FS                        *frawor-os-mkdir*
+        Creates directory with given protection bits (default 0755). Returns 
+        1 on success, 0 on failure. Not available on some systems (relies on 
+        |mkdir()| function being available).
+os.makedirs :: path[, mode] -> Bool + FS                  *frawor-os-makedirs*
+        Like |frawor-os-mkdir|, but also creates intermediate directories if 
+        they do not exist. Unlike built-in |mkdir()|, mode is applied to all 
+        intermediate directories created, not just to last directory.
+os.unlink :: path -> Bool + FS                              *frawor-os-unlink*
+os.remove :: path -> Bool + FS                              *frawor-os-remove*
+        Removes given file (not directory) returning 1 on success and 0 on 
+        failure.
+os.rmdir :: path -> Bool + FS                                *frawor-os-rmdir*
+        Remove given directory if it is empty. Only available on posix and nt 
+        systems with some tools installed (rmdir or rm for posix, rmdir or 
+        deltree for nt). Returns 1 on success and 0 on failure.
+os.removedirs :: path -> UInt + FS                      *frawor-os-removedirs*
+        Remove given directory and all empty intermediate ones (excluding 
+        current directory). Returns number of components removed.
+os.removetree :: path -> Bool + FS                      *frawor-os-removetree*
+        Remove the given file or directory including all contained files or 
+        directories (like `rm -r' on posix systems). Returns 1 on success and 
+        0 on failure. Note that removetree will first remove all files and 
+        only then will try to remove directories using |frawor-os-rmdir|.
 os.run :: [command[, arg1[, arg2[, ...]]]][, path]             *frawor-os-run*
         Runs command with given arguments and returns its exit code. Optional 
         path argument designates working directory in which command should be 
         run.
-os.path.abspath :: path + WD -> path                  *frawor-os-path-abspath*
+os.path.abspath :: path + FS -> path                  *frawor-os-path-abspath*
         Returns an absolute path.
 os.path.realpath :: path + FS -> path                *frawor-os-path-realpath*
         Returns an absolute path with all symbolic links resolved.
         Returns the directory component of a path.
 os.path.join :: [ path ] -> path                         *frawor-os-path-join*
         Joins path components into one path, removing duplicate path 
-        separators.
+        separators. The following calls are equivalent: >
+            let path=s:_r.os.path.join("foo", "bar")
+            let path=s:_r.os.path.join(["foo", "bar"])
 os.path.split :: path -> [ component ]                  *frawor-os-path-split*
-        Returns a list of path components starting either from root ('/' on 
-        posix systems) or from current directory ('.').
-os.path.exists :: path -> Bool                         *frawor-os-path-exists*
+        Returns a list of path components starting either from root ('/' 
+        represented as an empty string on posix systems) or from current 
+        directory ('.').
+os.path.samefile :: path, path + FS -> Bool          *frawor-os-path-samefile*
+        Returns 1 if both pathnames refer to the same actual file.
+os.path.exists :: path + FS -> Bool                    *frawor-os-path-exists*
         Returns 1 if file or directory with given name exists (for file: and 
         is readable), 0 otherwise.
-os.path.isdir :: path -> Bool                           *frawor-os-path-isdir*
+os.path.isdir :: path + FS -> Bool                      *frawor-os-path-isdir*
         Returns 1 if given path is existing directory, 0 otherwise.
+                                                         *frawor-os-path-walk*
+os.path.walk :: path, (arg, path, [ component ] -> _)[, arg] + FS -> _
+        Directory tree walk with callback function:
+        For each directory in the directory tree rooted at top (including top 
+        itself, but excluding '.' and '..'), call func({arg}, {dirname}, 
+        {fnames}) (func is the second argument). {dirname} is the name of the 
+        directory, and {fnames} is a list of the names of the files and 
+        subdirectories in dirname (excluding '.' and '..'). Function may 
+        modify the {fnames} list in-place (using |add()|, |remove()| and list 
+        assignment), and walk() will only recurse into the subdirectories 
+        whose names remain in {fnames}; this can be used to implement 
+        a filter, or to impose a specific order of visiting. No semantics are 
+        defined for, or required of, {arg}, beyond that {arg} is always passed 
+        to func. It can be used, e.g., to pass a filename pattern, or 
+        a mutable object designed to accumulate statistics. If additional 
+        argument is not present, then 0 will be passed in place of {arg}.
 
 ------------------------------------------------------------------------------
 4.3. py resource                                                 *frawor-r-py*

plugin/frawor/os.vim

 endif
 "▶2 os.path
 let s:os.path={}
-"▶3 os.path.abspath   :: path + wd → path
+"▶3 os.path.abspath   :: path + FS → path
 function s:os.path.abspath(path)
     let path=fnamemodify(a:path, ':p')
     " Purge trailing path separator
-    return ((len(path)>1)?(path[:-2]):(path))
+    return ((isdirectory(path) && len(path)>1)?(path[:-2]):(path))
 endfunction
-"▶3 os.path.realpath  :: path + fs → path
+"▶3 os.path.realpath  :: path + FS → path
 function s:os.path.realpath(path)
     return resolve(s:os.path.abspath(a:path))
 endfunction
 function s:os.path.dirname(path)
     return fnamemodify(a:path, ':h')
 endfunction
-"▶3 os.path.join      :: [path] → path
+"▶3 os.path.join      :: path[, path[, ...]] | [path] → path
 "▶4 s:eps
 if s:os.name==#'nt'
     let s:eps='[/\\]'
 endif
 "▲4
 function s:os.path.join(...)
-    let components=filter(copy(a:000), 'type(v:val)=='.type(""))
+    let components=copy((a:0 && type(a:1)==type([]))?
+                \           (a:1):
+                \           (a:000))
+    call filter(components, 'type(v:val)=='.type(""))
     return substitute(join(components, s:os.sep), s:eps.'\+',
                 \     escape(s:os.sep, '\&~'), 'g')
 endfunction
     endwhile
     return r
 endfunction
-"▶3 os.path.exists    :: path + fs → Bool
+"▶3 os.path.normpath  :: path → path
+function s:os.path.normpath(path)
+    return s:os.path.join(s:os.path.split(a:path))
+endfunction
+"▶3 os.path.samefile  :: path, path + FS → Bool
+function s:os.path.samefile(path1, path2)
+    return (s:os.path.normpath(s:os.path.realpath(a:path1))==
+                \s:os.path.normpath(s:os.path.realpath(a:path2)))
+endfunction
+"▶3 os.path.exists    :: path + FS → Bool
 function s:os.path.exists(path)
     return isdirectory(a:path) || filereadable(a:path)
 endfunction
-"▶3 os.path.isdir     :: path + fs → Bool
+"▶3 os.path.isdir     :: path + FS → Bool
 function s:os.path.isdir(path)
     return isdirectory(a:path)
 endfunction
-"▶2 os.listdir        :: path[, keepdirname] → [component] + fs
+"▶3 os.path.walk      :: path, F[, arg] + FS
+function s:os.path.walk(path, Func, ...)
+    let arg=get(a:000, 0, 0)
+    let path=s:os.path.abspath(a:path)
+    let files=s:os.path.listdir(path)
+    call call(a:Func, [arg, path, files], {})
+    call map(filter(map(files, 's:os.path.join(path, v:val)'),
+                \   'isdirectory(v:val)'),
+                \'s:os.path.walk(v:val, a:Func, arg)')
+endfunction
+"▶2 os.listdir        :: path[, keepdirname] + FS → [component]
 "▶3 s:F.globdir
 function s:F.globdir(directory, ...)
     return split(glob(escape(a:directory.g:os#pathSeparator, '`*[]\').
     endfor
     return r
 endfunction
+"▶2 os.chdir          :: path[, Bool] → Bool + WD
+function s:os.chdir(path, ...)
+    if isdirectory(a:path)
+        try
+            execute ((a:0 && a:1)?("lcd"):("cd")) fnameescape(a:path)
+            return 1
+        catch
+            return 0
+        endtry
+    endif
+    return 0
+endfunction
 "▶2 os.run            :: command[, cwd::path] → String + sh
 function s:os.run(command, ...)
     if s:os.name==#'nt'
     endif
     if a:0
         new
-        try
-            execute 'lcd' fnameescape(a:1)
-            call system(cmd)
-        finally
+        if !s:os.chdir(a:1, 1)
             bwipeout
-        endtry
-    else
-        call system(cmd)
+            return -1
+        endif
     endif
+    call system(cmd)
     redraw!
     return v:shell_error
 endfunction
 let s:os.run=s:_f.wrapfunc({'function': s:os.run,
             \             '@altervars': [['&g:eventignore', 'all'],
+            \                            ['&g:autowrite',     0  ],
+            \                            ['&g:autowriteall',  0  ],
             \                            ['&g:lazyredraw',    1  ]]})
+"▶2 mkdir, makedirs
+if exists("*mkdir")
+    "▶3 os.makedirs       :: path[, mode] → Bool + FS
+    function s:os.makedirs(path, ...)
+        let mode=get(a:000, 0, 0755)
+        let tocreate=[]
+        let path=a:path
+        while !isdirectory(path)
+            call insert(tocreate, path)
+            let path=s:os.dirname(path)
+        endwhile
+        try
+            call map(tocreate, 'mkdir(v:val, "", '.mode.')')
+            return 1
+        catch
+            return 0
+        endtry
+    endfunction
+    "▶3 os.mkdir          :: path[, mode] → Bool + FS
+    function s:os.mkdir(path, ...)
+        let mode=get(a:000, 0, 0755)
+        if !isdirectory(s:os.dirname(a:path))
+            return 0
+        endif
+        try
+            call mkdir(a:path, "", mode)
+            return 1
+        catch
+            return 0
+        endtry
+    endfunction
+    "▲3
+endif
+"▶2 os.unlink         :: path + FS → Bool + FS
+function s:os.unlink(path)
+    return delete(a:path) is 0
+endfunction
+let s:os.remove=s:os.unlink
+"▶2 os.rmdir          :: path → Bool + FS
+function s:os.rmdir(path)
+    let path=s:os.path.normpath(s:os.path.realpath(a:path))
+    if !(isdirectory(path) && empty(s:os.listdir(path)))
+        return 0
+    endif
+    if s:os.name is "posix"
+        if executable("rmdir")
+            return !s:os.run(["rmdir", path])
+        elseif executable("rm") && empty(s:os.listdir(path))
+            return !s:os.run(["rm", "-r", path])
+        endif
+    elseif s:os.name is "nt"
+        if executable("rmdir")
+            return !s:os.run(["rmdir", path])
+        elseif executable("deltree")
+            return !s:os.run(["deltree", path])
+        endif
+    endif
+    return 0
+endfunction
+"▶2 os.removedirs     :: path → UInt + FS
+function s:os.removedirs(path)
+    let path=s:os.normpath(a:path)
+    let prevpath=""
+    let i=0
+    while path isnot '.' && path isnot prevpath && s:os.rmdir(path)
+        let prevpath=path
+        let path=s:os.path.dirname(path)
+        let i+=1
+    endwhile
+    return i
+endfunction
+"▶2 os.removetree     :: path → Bool + FS
+function s:os.removetree(path)
+    if isdirectory(a:path)
+        let path=s:os.path.normpath(s:os.path.realpath(a:path))
+        let toremove=[]
+        let files=s:os.listdir(path, 1)
+        while !empty(files)
+            let file=remove(files, 0)
+            " Trying to unlink file before testing whether it is a directory 
+            " prevents occasinal recursion into symbolic links
+            if !s:os.unlink(file)
+                if isdirectory(file)
+                    let files+=s:os.listdir(file, 1)
+                    call insert(toremove, file)
+                else
+                    return 0
+                endif
+            endif
+        endwhile
+        for directory in toremove
+            if !s:os.rmdir(directory)
+                return 0
+            endif
+        endfor
+    else
+        return s:os.unlink(a:path)
+    endif
+endfunction
 "▶2 post resource
 call s:_f.postresource('os', s:os)
 "▶1