GithubHelp home page GithubHelp logo

f.el's Introduction

f.el Build Status Coverage 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

I/O

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-split (path)

Split PATH and return list containing parts.

(f-split "path") ;; => '("path")
(f-split "path/to") ;; => '("path" "to")
(f-split "/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-dirname "/") ;; => nil

f-common-parent (paths)

Return the deepest common parent directory of PATHS.

(f-common-parent '("foo/bar/baz" "foo/bar/qux" "foo/bar/mux")) ;; => "foo/bar/"
(f-common-parent '("/foo/bar/baz" "/foo/bar/qux" "/foo/bax/mux")) ;; => "/foo/"
(f-common-parent '("foo/bar/baz" "quack/bar/qux" "lack/bar/mux")) ;; => ""

f-ext (path)

Return the file extension of PATH.

The extension, in a file name, is the part that follows the last '.', excluding version numbers and backup suffixes.

(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-swap-ext (path ext)

Return PATH but with EXT as the new extension. EXT must not be nil or empty.

(f-swap-ext "path/to/file.ext" "org") ;; => "path/to/file.org"
(f-swap-ext "path/to/file.ext" "") ;; => error

f-base (path)

Return the name of PATH, excluding the extension of 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-short (path)

Return abbrev of PATH. See `abbreviate-file-name'.

Alias: f-abbrev

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

f-long (path)

Return long version of PATH.

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

f-canonical (path)

Return the canonical name of PATH.

(f-canonical "/path/to/real/file") ;; => /path/to/real/file
(f-canonical "/link/to/file") ;; => /path/to/real/file

f-slash (path)

Append slash to PATH unless one already.

Some functions, such as `call-process' requires there to be an ending slash.

(f-slash "/path/to/file") ;; => /path/to/file
(f-slash "/path/to/dir") ;; => /path/to/dir/
(f-slash "/path/to/dir/") ;; => /path/to/dir/

f-full (path)

Return absolute path to PATH, with ending slash.

(f-full "~/path/to/file") ;; => /home/path/to/file
(f-full "~/path/to/dir") ;; => /home/path/to/dir/
(f-full "~/path/to/dir/") ;; => /home/path/to/dir/

f-uniquify (paths)

Return unique suffixes of PATHS.

This function expects no duplicate paths.

(f-uniquify '("/foo/bar" "/foo/baz" "/foo/quux")) ;; => '("bar" "baz" "quux")
(f-uniquify '("/foo/bar" "/www/bar" "/foo/quux")) ;; => '("foo/bar" "www/bar" "quux")
(f-uniquify '("/foo/bar" "/www/bar" "/www/bar/quux")) ;; => '("foo/bar" "www/bar" "quux")
(f-uniquify '("/foo/bar" "/foo/baz" "/home/www/bar" "/home/www/baz" "/var/foo" "/opt/foo/www/baz")) ;; => '("foo/bar" "www/bar" "foo/baz" "home/www/baz" "foo/www/baz" "foo")

f-uniquify-alist (paths)

Return alist mapping PATHS to unique suffixes of PATHS.

This function expects no duplicate paths.

(f-uniquify-alist '("/foo/bar" "/foo/baz" "/foo/quux")) ;; => '(("/foo/bar" . "bar") ("/foo/baz" . "baz") ("/foo/quux" . "quux"))
(f-uniquify-alist '("/foo/bar" "/www/bar" "/foo/quux")) ;; => '(("/foo/bar" . "foo/bar") ("/www/bar" . "www/bar") ("/foo/quux" . "quux"))
(f-uniquify-alist '("/foo/bar" "/www/bar" "/www/bar/quux")) ;; => '(("/foo/bar" . "foo/bar") ("/www/bar" . "www/bar") ("/www/bar/quux" . "quux"))
(f-uniquify-alist '("/foo/bar" "/foo/baz" "/home/www/bar" "/home/www/baz" "/var/foo" "/opt/foo/www/baz")) ;; => '(("/foo/bar" . "foo/bar") ("/home/www/bar" . "www/bar") ("/foo/baz" . "foo/baz") ("/home/www/baz" . "home/www/baz") ("/opt/foo/www/baz" . "foo/www/baz") ("/var/foo" . "foo"))

f-read-bytes (path)

Read binary data from PATH.

Return the binary data as unibyte string.

(f-read-bytes "path/to/binary/data")

f-write-bytes (data path)

Write binary DATA to PATH.

DATA is a unibyte string. PATH is a file name to write to.

(f-write-bytes (unibyte-string 72 101 108 108 111 32 119 111 114 108 100) "path/to/binary/data")

f-read-text (path &optional coding)

Read text with PATH, using CODING.

CODING defaults to `utf-8'.

Return the decoded text as multibyte string.

Alias: f-read

(f-read-text "path/to/file.txt" 'utf-8)
(f-read "path/to/file.txt" 'utf-8)

f-write-text (text coding path)

Write TEXT with CODING to PATH.

TEXT is a multibyte string. CODING is a coding system to encode TEXT with. PATH is a file name to write to.

Alias: f-write

(f-write-text "Hello world" 'utf-8 "path/to/file.txt")
(f-write "Hello world" 'utf-8 "path/to/file.txt")

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-copy (from to)

Copy file or directory FROM to TO.

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

f-touch (path)

Update PATH last modification date or create if it does not exist.

(f-touch "path/to/existing/file.txt")
(f-touch "path/to/non/existing/file.txt")

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.

Aliases: f-directory-p f-dir? f-dir-p

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

f-file? (path)

Return t if PATH is file, false otherwise.

Alias: f-file-p

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

f-symlink? (path)

Return t if PATH is symlink, false otherwise.

Alias: f-symlink-p

(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.

Alias: f-readable-p

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

f-writable? (path)

Return t if PATH is writable, false otherwise.

Alias: f-writable-p

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

f-executable? (path)

Return t if PATH is executable, false otherwise.

Alias: f-executable-p

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

f-absolute? (path)

Return t if PATH is absolute, false otherwise.

Alias: f-absolute-p

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

f-relative? (path)

Return t if PATH is relative, false otherwise.

Alias: f-relative-p

(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.

Alias: f-root-p

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

f-ext? (path ext)

Return t if extension of PATH is EXT, false otherwise.

If EXT is nil or omitted, return t if PATH has any extension, false otherwise.

The extension, in a file name, is the part that follows the last '.', excluding version numbers and backup suffixes. Alias: f-ext-p

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

f-same? (path-a path-b)

Return t if PATH-A and PATH-b are references to same file.

Alias: f-same-p f-equal? f-equal-p

(f-same? "foo.txt" "foo.txt") ;; => t
(f-same? "/path/to/foo.txt" "/path/to/bar.txt") ;; => nil

f-parent-of? (path-a path-b)

Return t if PATH-A is parent of PATH-B.

Alias: f-parent-of-p

(f-parent-of? "/path/to" "/path/to/dir") ;; => t
(f-parent-of? "/path/to/dir" "/path/to") ;; => nil
(f-parent-of? "/path/to" "/path/to") ;; => nil

f-child-of? (path-a path-b)

Return t if PATH-A is child of PATH-B.

Alias: f-child-of-p

(f-child-of? "/path/to" "/path/to/dir") ;; => nil
(f-child-of? "/path/to/dir" "/path/to") ;; => t
(f-child-of? "/path/to" "/path/to") ;; => nil

f-ancestor-of? (path-a path-b)

Return t if PATH-A is ancestor of PATH-B.

Alias: f-ancestor-of-p

(f-ancestor-of? "/path/to" "/path/to/dir") ;; => t
(f-ancestor-of? "/path" "/path/to/dir") ;; => t
(f-ancestor-of? "/path/to/dir" "/path/to") ;; => nil
(f-ancestor-of? "/path/to" "/path/to") ;; => nil

f-descendant-of? (path-a path-b)

Return t if PATH-A is desendant of PATH-B.

Alias: f-descendant-of-p

(f-descendant-of? "/path/to/dir" "/path/to") ;; => t
(f-descendant-of? "/path/to/dir" "/path") ;; => t
(f-descendant-of? "/path/to" "/path/to/dir") ;; => nil
(f-descendant-of? "/path/to" "/path/to") ;; => 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-depth (path)

Return the depth of PATH.

At first, PATH is expanded with `f-expand'. Then the full path is used to detect the depth. '/' will be zero depth, '/usr' will be one depth. And so on.

(f-depth "/") ;; 0
(f-depth "/var/") ;; 1
(f-depth "/usr/local/bin") ;; 3

f-this-file ()

Return path to this file.

(f-this-file) ;; => /path/to/this/file

f-path-separator ()

Return path separator.

(f-path-separator) ;; => /

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) (s-matches? "test" file)))
(f-entries "path/to/dir" nil t)
(f--entries "path/to/dir" (s-matches? "test" it))

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) (equal (f-filename dir) "test")))
(f-directories "path/to/dir" nil t)
(f--directories "path/to/dir" (equal (f-filename it) "test"))

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)
(f--files "path/to/dir" (equal (f-ext it) "el"))

f-root ()

Return absolute root.

(f-root) ;; => "/"

f-up (fn &optional dir)

Traverse up as long as FN returns nil, starting at DIR.

Deprecated in favor of: f-traverse-upwards

(f-up
 (lambda (path)
   (f-exists? (f-expand ".git" path)))
 start-path)

(f--up (f-exists? (f-expand ".git" it)) start-path) ;; same as above

f-traverse-upwards (fn &optional path)

Traverse up as long as FN returns nil, starting at PATH.

If FN returns a non-nil value, the path sent as argument to FN is returned. If no function callback return a non-nil value, nil is returned.

(f-traverse-upwards
 (lambda (path)
   (f-exists? (f-expand ".git" path)))
 start-path)

(f--traverse-upwards (f-exists? (f-expand ".git" it)) start-path) ;; same as above

f-with-sandbox (path-or-paths &rest body)

Only allow PATH-OR-PATHS and decendants to be modified in BODY.

(f-with-sandbox foo-path
  (f-touch (f-expand "foo" foo-path)))
(f-with-sandbox (list foo-path bar-path)
  (f-touch (f-expand "foo" foo-path))
  (f-touch (f-expand "bar" bar-path)))
(f-with-sandbox foo-path
  (f-touch (f-expand "bar" bar-path))) ;; "Destructive operation outside sandbox"

Changelog

v0.18.2

  • Added -p aliases of all ? functions.

v0.18.0

  • Add f-swap-ext (by @phillord)
  • Add f-depth (by @cheunghy)

v0.17.0

  • Add f-common-parent (by @Fuco1)

v0.16.0

  • Add f-with-sandbox

v0.15.0

  • Add f-split

v0.14.0

  • Add f-traverse-upwards and its anaphoric version f--traverse-upwards
  • Deprecate f-up and its anaphoric version f--up

v0.13.0

  • Add f-uniquify and f-uniquify-alist (by @Fuco1)

v0.12.0

  • f-parent returns nil if argument is root

v0.11.0

  • Add f-descendant-of?
  • Add f-ancestor-of?
  • Add f-parent-of?
  • Add f-child-of?
  • Remove deprecation for f-read and f-write and make them aliases to f-read-text and f-write-text respectively
  • Add anaphoric function f--entries for f-entries
  • Add anaphoric function f--files for f-files
  • Add anaphoric function f--directories of f-directories
  • Add f-up and anaphoric version f--up

v0.10.0

  • Add f-root
  • Fix f-root? bug for weird syntax

v0.9.0

  • Make s-long
  • Make s-short default and f-abbrev the alias
  • Add f-full
  • Do not append path separator if file in f-slash
  • Fixed bug in f-path-separator

v0.8.0

  • Moved f-this-file to misc section
  • Add f-slash
  • Add f-path-separator

v0.7.1

  • Fix coding bug in f-read-text

v0.7.0

  • Add f-touch

v0.6.1

  • Fix f-write-text for unibyte strings

v0.6.0

  • Add f-write-text and f-write-bytes and deprecate f-write
  • Add f-read-text and f-read-bytes and deprecate f-read
  • Add f-this-file
  • Add f-canonical
  • Fix f-same? for symlinks

v0.5.0

  • Add f-same? (alias f-equal?)

v0.4.1

  • Bump s and dash versions

v0.4.0

  • Add f-copy

v0.3.0

  • Add f-ext?

v0.2.1

  • Fix f-filename when ending with slash

v0.2.0

  • Add f-root?
  • Fix f-dirname when ending with slash

v0.1.0

  • Add f-abbrev (alias f-short)

v0.0.2

  • f-join platform independent

v0.0.1

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)))))

Now, try writing it even simpler yourself. Hint, check out f-traverse-upwards.

Contribution

Be sure to!

Install Cask 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

f.el's People

Contributors

fuco1 avatar marcinant avatar pd avatar phillord-ncl avatar rejeep avatar sachac avatar seanfisk avatar silex avatar sviridov avatar swsnr avatar syohex avatar tarsius avatar tmalsburg avatar victorteokw avatar wilfred avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.