pd / f.el

Modern API for working with files and directories in Emacs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

f.el Build Status

Much inspired by @magnars's excellent s.el and dash.el, f.el is a modern API for working with files and directories in Emacs.

Installation

It's available on Melpa:

M-x package-install f

Or you can just dump f.el in your load path somewhere.

API

Paths

Destructive

Predicates

Stats

Misc

Documentation and examples

f-join (&rest args)

Join ARGS to a single path.

(f-join "path") ;; => "path"
(f-join "path" "to") ;; => "path/to"
(f-join "path" "to" "heaven") ;; => "path/to/heaven"

f-expand (path &optional dir)

Expand PATH relative to DIR (or `default-directory').

(f-expand "name") ;; => "/default/directory/name"
(f-expand "name" "other/directory") ;; => "other/directory/name"

f-filename (path)

Return the name of PATH.

(f-filename "path/to/file.ext") ;; => "file.ext"
(f-filename "path/to/directory") ;; => "directory"

f-dirname (path)

Return the parent directory to PATH.

Alias: f-parent

(f-dirname "path/to/file.ext") ;; => "path/to"
(f-dirname "path/to/directory") ;; => "path/to"

f-ext (path)

Return the file extension of PATH.

(f-ext "path/to/file.ext") ;; => "ext"
(f-ext "path/to/directory") ;; => nil

f-no-ext (path)

Return everything but the file extension of PATH.

(f-no-ext "path/to/file.ext") ;; => "path/to/file"
(f-no-ext "path/to/directory") ;; => "path/to/directory"

f-base (path)

Return the name of PATH, excluding the extension if file.

(f-base "path/to/file.ext") ;; => "file"
(f-base "path/to/directory") ;; => nil

f-relative (path &optional dir)

Return PATH relative to DIR.

(f-relative "/some/path/relative/to/my/file.txt" "/some/path/") ;; => relative/to/my/file.txt
(f-relative "/default/directory/my/file.txt") ;; => my/file.txt

f-abbrev (path)

Abbrev PATH. See `abbreviate-file-name'.

Alias: f-short

(f-abbrev "/Users/foo/Code/bar") ;; => ~/Code/bar
(f-abbrev "/path/to/Code/bar") ;; => /path/to/Code/bar

f-write (path &optional content)

Write CONTENT or nothing to PATH. If no content, just create file.

(f-write "path/to/file.txt")
(f-write "path/to/file.txt" "some-content")

f-mkdir (&rest dirs)

Create directories DIRS.

(f-mkdir "dir") ;; => /default/directory/dir
(f-mkdir "other" "dir") ;; => /default/directory/other/dir

f-delete (path &optional force)

Delete PATH, which can be file or directory.

If FORCE is t, a directory will be deleted recursively.

(f-delete "dir")
(f-delete "other/dir" t)
(f-delete "path/to/file.txt")

f-symlink (source path)

Create a symlink to source from path.

(f-symlink "path/to/source" "path/to/link")

f-move (from to)

Move or rename FROM to TO.

(f-move "path/to/file.txt" "new-file.txt")
(f-move "path/to/file.txt" "other/path")

f-exists? (path)

Return t if PATH exists, false otherwise.

(f-exists? "path/to/file.txt")
(f-exists? "path/to/dir")

f-directory? (path)

Return t if PATH is directory, false otherwise.

Alias: f-dir?

(f-directory? "path/to/file.txt") ;; => nil
(f-directory? "path/to/dir") ;; => t

f-file? (path)

Return t if PATH is file, false otherwise.

(f-directory? "path/to/file.txt") ;; => t
(f-directory? "path/to/dir") ;; => nil

f-symlink? (path)

Return t if PATH is symlink, false otherwise.

(f-symlink? "path/to/file.txt") ;; => nil
(f-symlink? "path/to/dir") ;; => nil
(f-symlink? "path/to/link") ;; => t

f-readable? (path)

Return t if PATH is readable, false otherwise.

(f-readable? "path/to/file.txt")
(f-readable? "path/to/dir")

f-writable? (path)

Return t if PATH is writable, false otherwise.

(f-writable? "path/to/file.txt")
(f-writable? "path/to/dir")

f-executable? (path)

Return t if PATH is executable, false otherwise.

(f-executable? "path/to/file.txt")
(f-executable? "path/to/dir")

f-absolute? (path)

Return t if PATH is absolute, false otherwise.

(f-absolute? "path/to/dir") ;; => nil
(f-absolute? "/full/path/to/dir") ;; => t

f-relative? (path)

Return t if PATH is relative, false otherwise.

(f-relative? "path/to/dir") ;; => t
(f-relative? "/full/path/to/dir") ;; => nil

f-root? (path)

Return t if PATH is root directory, false otherwise.

(f-root? "/") ;; => t
(f-root? "/not/root") ;; => nil

f-size (path)

Return size of PATH.

If PATH is a file, return size of that file. If PATH is directory, return sum of all files in PATH.

(f-size "path/to/file.txt")
(f-size "path/to/dir")

f-read (path)

Return content of PATH.

(f-read "path/to/file.txt")

f-glob (pattern &optional path)

Find PATTERN in PATH.

See: file-expand-wildcards

(f-glob "path/to/*.el")
(f-glob "*.el" "path/to")

f-entries (path &optional fn recursive)

Find all files and directories in PATH.

FN - called for each found file and directory. If FN returns a thruthy value, file or directory will be included. RECURSIVE - Search for files and directories recursive.

(f-entries "path/to/dir")
(f-entries "path/to/dir" (lambda (file) (equal (f-ext file) "el")))
(f-entries "path/to/dir" nil t)

f-directories (path &optional fn recursive)

Find all directories in PATH. See f-entries.

(f-directories "path/to/dir")
(f-directories "path/to/dir" (lambda (dir) ((f-filename dir) "test")))
(f-directories "path/to/dir" nil t)

f-files (path &optional fn recursive)

Find all files in PATH. See f-entries.

(f-files "path/to/dir")
(f-files "path/to/dir" (lambda (file) (equal (f-ext file) "el")))
(f-files "path/to/dir" nil t)

Example

Here's an example of a function that finds the Git project root.

Using standard Emacs builtin functions

(defun find-git-root (&optional dir)
  (unless dir (setq dir (expand-file-name (file-name-directory (buffer-file-name)))))
  (let ((parent (expand-file-name ".." dir)))
    (unless (equal parent dir)
      (if (file-exists-p (expand-file-name ".git" dir))
          dir
        (find-git-root parent)))))

Using f.el

(defun find-git-root (&optional dir)
  (interactive)
  (unless dir (setq dir (f-dirname (buffer-file-name))))
  (let ((parent (f-parent dir)))
    (unless (f-root? parent)
      (if (f-exists? (f-expand ".git" dir))
          dir
        (find-git-root parent)))))

Contribution

Be sure to!

Install Carton if you haven't already.

Run the unit tests with:

$ make test

Do not change README.md directly. If you want to change the README or if you change any function comments, update the README with:

$ make docs

About

Modern API for working with files and directories in Emacs


Languages

Language:Emacs Lisp 95.4%Language:Perl 4.1%Language:Racket 0.4%