Guile Scheme library for common file operations.
Fix module name in README
afae9f31 — Alexandru-Sergiu Marton 2 months ago
More docs.
401fa3d4 — Alexandru-Sergiu Marton 2 months ago
More stuff in the README.



You can also use your local clone with git send-email.


Library indented to facilitate working with files and directories (the file system in general). Initially inspired by f.el, it now resembles mostly useful functions I find myself needing from time to time when interacting with the file system.

This project is going through a rewrite at the moment, meant to clean the code and improve the user-facing API.


You can install f.scm on Guix from my public channel.

Add the channel to your ~/.config/guix/channels.scm:

 (list ;; ...
        (name 'brown121407)
        (url "https://git.sr.ht/~brown121407/guix.121407.xyz")))

Do a guix pull and then install f.scm with guix install guile-f. Note that the version from my channel might not always correspond with the latest version of the library.


f.scm provides two Guile modules: (f ports) and (f).

  • (f): this contains functions that always get passed a path and open a new port for that path.
  • (f ports): this mirrors some functions from (f), receiving already opened ports instead of paths.

It is recommended to import those modules with a prefix so they don't overwrite each other and some top-level functions.

(use-modules ((f) #:prefix f:)
             ((f ports) #:prefix p:))

If you want to read only the first line of a file, you can use the read-line from (f). If you want to read the next line from an already opened port, use the read-line from (f ports).

NOTE: All the examples below assume you imported f with the f: prefix and f ports with the p: prefix.


read-bytes path

Read binary data from path.

Return the binary data as a bytevector.

(f:read-bytes "path/to/file")

read-text path

Read text from path.

Return the text as a string.

(f:read-text "path/to/file")

read-line path

Read a single line of text from path.

Return the line as a string. It doesn't contain a newline character.

(f:read-line "path/to/file")

read-lines path

Read all the lines of a file.

Returns the lines as a list of strings.

(f:read-lines "path/to/file")

write-bytes path bytes #:key (append #f)

Write a bytevector to a file. Overwrite the contents if #:append is #f, otherwise append at the end.

(f:write-bytes "path/to/file" #vu8(1 2 3) #:append #t)

write-text path text #:key (append #f)

Write a string to a file. Overwrite the contents if #:append is #f, otherwise append at the end.

(f:write-text "path/to/file" "I'm a string" #:append #t)

write-line path text #:key (append #f)

Write string to a file and put a newline after it. Overwrite the contents if #:append is #f, otherwise append at the end.

(f:write-text "path/to/file" "I'm a string" #:append #t)

write-lines path lines #:key (append #f)

Write multiple lines to a file. The lines parameter is a list of strings. Overwrite the contents if #:append is #f, otherwise append at the end.

(f:write-lines "path/to/file" '("first line" "second line"))

mkdir path #:key (parents #f)

Create a new directory. Use #:parents #t to also create parent directories if they don't already exist.

(f:mkdir "f1/f2/f3" #:parents #t)

ls #:optional (dir (getcwd)) #:key (hidden #f)

List the files in the directory dir. If dir is not specified, it default to the current directory. To also display hidden files, use #:hidden #t. Displaying hidden files omits . (current dir) and .. (parent dir).

(f:ls)             ;; list the files in the current directory
(f:ls "other-dir") ;; list the files in other-dir
(f:ls #:hidden #t) ;; list all the files in the current directory

traverse path f #:key (files-only #f)

Walk a directory tree, applying the function f to every file and directory you meet. If you want to apply f only to files, use #:files-only #t.

;; Display every file and directory in your home dir
(f:traverse (string-append "/home/" (getlogin)) 
            (lambda (x)
              (display x)

delete path #:optional (recursive #f)

Delete the file or directory specified by path. If path is a directory and contains stuff, set recursive to #t to delete it and all its contents.

;; Delete all your porn
(f:delete (string-append "/home/" (getlogin) "/homework") #t)

copy src dest #:optional (recursive #f)

Copy something from src to dest.

(f:copy "music" "media/audio" #t)

move oldname newname

Move oldname to newname. (The parameter naming is different from copy because this is just an alias for rename-file.)

(f:move "media/audio" "media/songs")


Send suggestions and patches with what you think is useful for this library to my public mailing list.

What needs improving?

We currently need some path manipulation code (splitting, joining, extracting segments etc.). We don't want to use the file-names library, because we want just functions on strings, not complex objects, but it could prove useful as inspiration.


f.scm is licensed under the GNU GPLv3. See COPYING.