(index ("path-find" 0) ("path-find-all" 2302) ("path-fold" 3129) ("make-pathfinder" 3639) ("pf:exact" 5542) ("pf:extensions" 5822) ("pf:compound" 8423) ("pf:regular-file?" 10908) ("pf:directory?" 11264) ("pf:any?" 11428) ("dirent-stat" 12018) ("dirent-pathname" 12628) ("dirent-directory" 12978) ("pathfinder-reset" 13109) ("pathfinder-stat" 13324) ("pathfinder-paths" 14019) ("pathfinder-root" 14290) ("pathfinder-matcher" 14421) ("pathfinder-test" 14561) ("pathfinder-default-test" 14692) ("pathfinder-default-matcher" 14994))
(def (sig (procedure "(path-find pf pathname #!optional matcher test)" (id path-find))) (p "Find the best (first) match for PATHNAME using pathfinder PF, and returns the absolute pathname if a match occurs or " (tt "#f") " if not.") (p "PATHNAME may be a filename such as \"bar\", which is looked for in each search path, or a relative path such as \"foo/bar\", in which \"bar\" is looked for in subdirectory \"foo\" under each search path.  It can also be an absolute path; in this case, it is considered relative to the pathfinder root, confining the search to a single directory in the search path.  If the resulting directory is not in or under the search path, " (tt "#f") " is returned.") (p "MATCHER is an optional " (int-link "#Matchers" "pathfinder matcher") " which indicates the matching method; if " (tt "#f") " or not present, the matcher assocated with the pathfinder object is used.") (p "TEST is an optional " (int-link "#Tests" "pathfinder test") " which performs an additional test before admitting the file.  If " (tt "#f") " or not present, the test associated with the pathfinder object is used.") (p "A very simple example:") (highlight scheme "; The file tree:\n; /usr/bin/ls\n; /usr/bin/rsync\n; /usr/local/bin/rsync\n\n(define pf (make-pathfinder '(\"/usr/local/bin\" \"/usr/bin\")))\n(path-find pf \"ls\")\n  ; => \"/usr/bin/ls\"\n(path-find pf \"rsync\")\n  ; => \"/usr/local/bin/rsync\"\n(path-find pf \"flotz\")\n  ; #f") (p "A more complicated example.  Here we add a pathfinder root, relative search paths and absolute pathnames into the mix:") (highlight scheme "; The file tree:\n; /home/hacker/usr/bin/ls\n; /home/hacker/usr/local/bin/ls\n; /home/hacker/usr/sbin/fsck\n\n(define pf (make-pathfinder '(\"local/bin\" \"bin\") root: \"/home/hacker/usr\")\n(path-find pf \"ls\")\n  ; => \"/home/hacker/usr/local/bin/ls\"\n(path-find pf \"/local/bin/ls\")\n  ; => \"/home/hacker/usr/local/bin/ls\"\n(path-find pf \"/bin/ls\")         ;; Absolute search of /home/hacker/usr/bin\n  ; => \"/home/hacker/usr/bin/ls\"\n(path-find pf \"/sbin/fsck\")      ;; Maps to /home/hacker/usr/sbin, but it's not in search path\n  ; => #f") (p "For further examples, see the " (int-link "#Matchers" "matchers") " " (tt "pf:exact") ", " (tt "pf:extensions") " and " (tt "pf:compound") "."))
(def (sig (procedure "(path-find-all pf pathname #!optional matcher test)" (id path-find-all))) (p "Like " (tt "path-find") ", but returns a list that also includes \"shadowed\" matches.  In other words, MATCHER gets a chance to match multiple times in multiple directories.") (highlight scheme "; The file tree:\n; /usr/bin/ls\n; /usr/bin/rsync\n; /usr/local/bin/rsync\n\n(define pf (make-pathfinder '(\"/usr/local/bin\" \"/usr/bin\")))\n(path-find-all pf \"ls\")\n  ; => (\"/usr/bin/ls\")\n(path-find-all pf \"rsync\")\n  ; => (\"/usr/bin/rsync \"/usr/local/bin/rsync\")") (p "For another example, see " (int-link "#Matchers" ((tt "pf:extensions"))) ".") (p "Note: rather than filtering the results on file type, size etc. after calling " (tt "path-find-all") ", consider using " (int-link "#Tests" "pathfinder tests") "."))
(def (sig (procedure "(path-fold pf func init pathname #!optional matcher test)" (id path-fold))) (p "Like " (tt "path-find-all") ", this finds all shadowed matches for PATHNAME, performing a " (tt "fold") " over the results.  INIT is the initial seed and FUNC is called with arguments " (tt "(X XS)") " where X is the current absolute pathname and XS is the accumulated seed.") (p "Note: filtering the results on file type, size etc. is usually better done with " (int-link "#Tests" "pathfinder tests") "."))
(def (sig (procedure "(make-pathfinder paths #!key matcher test root)" (id make-pathfinder))) (p "Construct a pathfinder object with search path PATHS.  PATHS is a list of absolute or relative pathnames; if relative, they are relative to the pathfinder ROOT.") (p "Keyword ROOT specifies the root of this pathfinder and defaults to the current directory.  ROOT specifies both the base for relative PATHS, and the base for absolute search terms (see " (tt "path-find") ").  ROOT itself can be absolute or relative; if relative, it is relative to the current directory at the time the object is created.") (p "Keyword MATCHER specifies a " (int-link "#Matchers" "pathfinder matcher") " for this object, and defaults to " (tt "(pathfinder-default-matcher)") ", usually the exact filename matcher " (tt "pf:exact") ".  This becomes the default matcher for this pathfinder object, and can be overridden later in " (tt "path-find") ".") (p "Keyword TEST specifies a " (int-link "#Tests" "pathfinder test") " for this object, and defaults to " (tt "(pathfinder-default-test)") ", usually " (tt "pf:regular-file?") ".  This becomes the default test for this pathfinder object, and can be overridden later in " (tt "path-find") ".  To avoid filtering, use the test " (tt "pf:any?") ".") (highlight scheme ";; unix path search, exact filename match\n(define pu (make-pathfinder\n            (string-split (get-environment-variable \"PATH\") \":\")))\n(path-find pu \"csi\")\n  ; => \"/usr/local/bin/csi\"\n(path-find pu \"bash\")\n  ; => \"/bin/bash\"\n\n;; windows path search, using filepath egg; extension match\n(use filepath)\n(define pw (make-pathfinder (filepath:get-search-path) \n            matcher: (pf:extensions '(\".com\" \".exe\" \".bat\"))))\n\n(path-find pw \"csi\")\n  ; => \"X:\\\\chicken4\\\\bin\\\\csi.exe\"\n(path-find pw \"command\")\n  ; => \"c:\\\\windows\\\\system32\\\\command.com\""))
(def (sig (procedure "pf:exact" (id pf:exact))) (p "A matcher object suitable for passing to " (tt "path-find") " or " (tt "path-find-all") ".  For each directory, this matcher checks that the current search term exactly matches a filename that is present under the directory."))
(def (sig (procedure "(pf:extensions exts)" (id pf:extensions))) (p "Create a matcher object suitable for passing to " (tt "path-find") " or " (tt "path-find-all") ".  For each directory, this matcher tries each extension in the EXTS list in order, by appending it to the current search term.  If the extension was already present in the search term, it is not appended again.") (p "The extensions in the EXTS list should include the dot, meaning " (tt "\".exe\"") " not " (tt "\"exe\"") ".  It is legal to include a dot in the extension itself.  The empty string " (tt "\"\"") " is allowed as well, meaning the search term itself will be tried without any extension.") (p "An example in which we search only one path, the Chicken repository path, with several extensions.") (highlight scheme "(define p (make-pathfinder (list (repository-path))))\n(define eggs (pf:extensions '(\".setup-info\" \".so\" \".import.so\")))\n\n(path-find p \"matchable\" eggs)\n  ; => \"/usr/local/lib/chicken/6/matchable.setup-info\"\n(path-find-all p \"matchable\" eggs)\n  ; => (\"/usr/local/lib/chicken/6/matchable.setup-info\"\n  ;     \"/usr/local/lib/chicken/6/matchable.so\"\n  ;     \"/usr/local/lib/chicken/6/matchable.import.so\")\n\n(path-find p \"txpath\" eggs)\n  ; => \"/usr/local/lib/chicken/6/txpath.so\"\n(path-find-all p \"txpath\" eggs)\n  ; => (\"/usr/local/lib/chicken/6/txpath.so\"\n  ;     \"/usr/local/lib/chicken/6/txpath.import.so\")\n\n(path-find p \"posix\" eggs)\n  ; => \"/usr/local/lib/chicken/6/posix.import.so\"\n(path-find-all p \"posix\" eggs)\n  ; => (\"/usr/local/lib/chicken/6/posix.import.so\")") (p "Example in which we search subdirectories in multiple paths:") (highlight scheme "(define p (make-pathfinder (list \"user\" \"template\") root: \"/var/www/htdocs\"))\n(define webs (pf:extensions '(\".css\" \".scss\" \".js\")))\n\n(path-find p \"js/jquery\" webs)\n  ; => \"/var/www/htdocs/template/js/jquery.js\"\n(path-find p \"css/screen\" webs)\n  ; => \"/var/www/htdocs/user/css/screen.css\"\n(path-find-all p \"css/screen\" webs)\n  ; => (\"/var/www/htdocs/user/css/screen.css\"\n  ;     \"/var/www/htdocs/user/css/screen.scss\"\n  ;     \"/var/www/htdocs/template/css/screen.css\"\n  ;     \"/var/www/htdocs/template/css/screen.scss\")\n(path-find p \"css/screen.scss\" webs)\n  ; => \"/var/www/htdocs/user/css/screen.scss\"\n(path-find-all p \"css/screen.scss\" webs)\n  ; => (\"/var/www/htdocs/user/css/screen.scss\"\n  ;     \"/var/www/htdocs/template/css/screen.scss\")\n(path-find p \"/template/css/screen\" webs)\n  ; => \"/var/www/htdocs/template/css/screen.css\""))
(def (sig (procedure "(pf:compound exts)" (id pf:compound))) (p "Create a matcher object suitable for passing to " (tt "path-find") " or " (tt "path-find-all") ".  For each directory, this matches any files that match the current search term and additionally have zero or more of the extensions in the EXTS list.  Furthermore, these results are returned sorted by extension priority, where the priority is higher for extensions earlier in the list.  This behavior is like that of the " (link "https://github.com/sstephenson/hike" "Hike library") " for Ruby.") (p "The extensions in the EXTS list should include the dot at the beginning, meaning " (tt "\".exe\"") " not " (tt "\"exe\"") ".  It is " (i "not") " legal to use the empty string, nor to have a dot within the extension.") (highlight scheme "(define p (make-pathfinder '(\"app/assets\" \"vendor/plugins/3e8/assets\"\n                             \"vendor/plugins/jquery\" \"template/assets\")\n           matcher: (pf:compound '(\".scss\" \".coffee\" \".sass\" \".scm\" \".php\"))\n           root: \"/var/zb-app\"))\n\n; tree under /var/zb-app\n; ./app/assets/js/app.js\n; ./app/assets/js/menu.js.coffee\n; ./template/assets/css/menu.css\n; ./template/assets/js/search.js\n; ./template/assets/js/menu.js\n; ./vendor/plugins/3e8/assets/css/menu.css.sass  \n; ./vendor/plugins/3e8/assets/css/menu.css.scss\n; ./vendor/plugins/3e8/assets/css/menu.css.scss.php\n; ./vendor/plugins/3e8/assets/css/menu.css.scss.scm\n; ./vendor/plugins/jquery/js/jquery.js\n\n(path-find p \"js/menu.js\")\n  ; => \"/var/zb-app/app/assets/js/menu.js.coffee\"\n(path-find-all p \"js/menu.js\")\n  ; => (\"/var/zb-app/app/assets/js/menu.js.coffee\"\n  ;     \"/var/zb-app/template/assets/js/menu.js\")\n(path-find p \"js/search.js\")\n  ; => \"/var/zb-app/template/assets/js/search.js\"\n(path-find p \"js/jquery.js\")\n  ; => \"/var/zb-app/vendor/plugins/jquery/js/jquery.js\"\n(path-find p \"css/menu.css\")\n  ; => \"/var/zb-app/vendor/plugins/3e8/assets/css/menu.css.scss\"\n(path-find-all p \"css/menu.css\")\n  ; => (\"/var/zb-app/vendor/plugins/3e8/assets/css/menu.css.scss\"\n  ;     \"/var/zb-app/vendor/plugins/3e8/assets/css/menu.css.sass\"\n  ;     \"/var/zb-app/vendor/plugins/3e8/assets/css/menu.css.scss.scm\"\n  ;     \"/var/zb-app/vendor/plugins/3e8/assets/css/menu.css.scss.php\"\n  ;     \"/var/zb-app/template/assets/css/menu.css\")\n(path-find p \"css/menu.css\" pf:exact)\n  ; => \"/var/zb-app/template/assets/css/menu.css\""))
(def (sig (procedure "(pf:regular-file? DIRENT FILENAME)" (id pf:regular-file?))) (p "Pathfinder test which selects regular files, to be passed to a pathfinder matcher.  This is the default filter, so specifying it is optional.") (highlight scheme ";; Find a regular file named \"ls\" in the search path.\n(path-find p \"ls\" pf:exact pf:regular-file?)"))
(def (sig (procedure "(pf:directory? DIRENT FILENAME)" (id pf:directory?))) (p "Pathfinder test which selects directories, to be passed to a pathfinder matcher."))
(def (sig (procedure "(pf:any? DIRENT FILENAME)" (id pf:any?))) (p "Pathfinder test which will pass any file.  It can be used when you don't want to filter anything.") (highlight scheme ";; Find any file or directory named \".emacs.d\" in the search path,\n;; overriding pathfinder p's default test of pf:regular-file?\n(define p (make-pathfinder paths))\n(path-find p \".emacs.d\" pf:exact pf:any?)\n\n;; Same thing, but associate the test with pathfinder p,\n;; so we don't have to specify it in each find.\n(define p (make-pathfinder paths test: pf:any?))\n(path-find p \".emacs.d\")"))
(def (sig (procedure "(dirent-stat DIRENT FILENAME)" (id dirent-stat))) (p "Return the stat vector for FILENAME in DIRENT.  If the stat fails (for example, if the file has gone missing since the dirent was populated) then " (tt "#f") " is returned.  Stat vectors are cached upon first access and subsequent stats are returned from cache.") (highlight scheme "(use posix-extras)\n(define (pf:nonempty-file? de fn)\n  (and-let* ((s (dirent-stat de fn)))\n    (and (stat-regular-file? s)    ;; or, (pf:regular-file? de fn)\n         (> (stat-size s) 0))))\n\n(path-find pf \"notes.txt\" pf:exact pf:nonempty?)"))
(def (sig (procedure "(dirent-pathname DIRENT FILENAME)" (id dirent-pathname))) (p "Return the absolute pathname associated with FILENAME in DIRENT.  You might use this when performing a query that cannot be answered by the stat cache.") (highlight scheme "(define (pf:execute-access? de fn)\n  (file-execute-access?\n   (dirent-pathname de fn)))"))
(def (sig (procedure "(dirent-directory DIRENT)" (id dirent-directory))) (p "Returns the directory name associated with DIRENT."))
(def (sig (procedure "(pathfinder-reset pf)" (id pathfinder-reset))) (p "Reset the cached directory and file stat data in pathfinder PF, allowing you to pick up any changes that have occurred in the search path."))
(def (sig (procedure "(pathfinder-stat pf pathname)" (id pathfinder-stat))) (p "Using PF's stat cache, stat absolute PATHNAME and return its stat vector (as in " (int-link "/man/4/Unit posix" "posix") "'s " (tt "file-stat") ").  For example, this could be used on the filenames returned by " (tt "path-find-all") " in order to filter them further.") (p "Note that this returns " (tt "#f") " for a file in any directory which has not yet been traversed during a search operation.") (p "It is recommended to write your own " (int-link "#Tests" "pathfinder test") " instead and use " (tt "dirent-stat") ", which is more efficient and will additionally work even with plain " (tt "path-find") "."))
(def (sig (procedure "(pathfinder-paths PF)" (id pathfinder-paths))) (p "Return the search path list of pathfinder PF.  The paths may not equal what you passed to the constructor -- they may have been adjusted for the pathfinder root, normalized, tilde expanded, etc."))
(def (sig (procedure "(pathfinder-root PF)" (id pathfinder-root))) (p "Return the root of the pathfinder, an absolute pathname."))
(def (sig (procedure "(pathfinder-matcher PF)" (id pathfinder-matcher))) (p "Return the pathfinder matcher procedure associated with PF."))
(def (sig (procedure "(pathfinder-test PF)" (id pathfinder-test))) (p "Return the pathfinder test procedure associated with PF."))
(def (sig (parameter "(pathfinder-default-test test)" (id pathfinder-default-test))) (p "Default test assigned to new pathfinder objects; it is performed after matching a filename.  The default value is " (tt "pf:regular-file?") ".  To not filter the results at all, set this to " (tt "pf:any?") "."))
(def (sig (parameter "(pathfinder-default-matcher matcher)" (id pathfinder-default-matcher))) (p "Default matcher assigned to new pathfinder objects.  The default value is " (tt "pf:exact") "."))
