{"id":33129916,"url":"https://github.com/sophec/cfm","last_synced_at":"2025-11-20T02:01:22.651Z","repository":{"id":41813080,"uuid":"235388401","full_name":"sophec/cfm","owner":"sophec","description":"🌵 Simple and fast TUI file manager with no dependencies.","archived":true,"fork":false,"pushed_at":"2022-04-28T13:45:20.000Z","size":509,"stargazers_count":102,"open_issues_count":5,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-25T06:57:56.941Z","etag":null,"topics":["c","cactus","file-manager","tui"],"latest_commit_sha":null,"homepage":"https://cfm.atinycact.us","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sophec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["willeccles"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.warchild.org/","https://twloha.com"]}},"created_at":"2020-01-21T16:29:12.000Z","updated_at":"2025-10-04T15:40:42.000Z","dependencies_parsed_at":"2022-09-23T04:03:22.370Z","dependency_job_id":null,"html_url":"https://github.com/sophec/cfm","commit_stats":null,"previous_names":["sophec/cfm"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/sophec/cfm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sophec%2Fcfm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sophec%2Fcfm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sophec%2Fcfm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sophec%2Fcfm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sophec","download_url":"https://codeload.github.com/sophec/cfm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sophec%2Fcfm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285359022,"owners_count":27158216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-20T02:00:05.334Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cactus","file-manager","tui"],"created_at":"2025-11-15T09:00:29.616Z","updated_at":"2025-11-20T02:01:22.641Z","avatar_url":"https://github.com/sophec.png","language":"C","funding_links":["https://github.com/sponsors/willeccles","https://www.warchild.org/","https://twloha.com"],"categories":["Packages"],"sub_categories":["CLI Tools"],"readme":"# Cactus File Manager\n\n![](https://github.com/WillEccles/cfm/workflows/CFM%20Build/badge.svg)\n\nCactus File Manager (cfm) is a TUI file manager with the goal of being simple,\neasy, and bloat-free, utilizing Vi-inspired keybinds. Whether or not\nyou should use it depends on whether or not you like the name, dev, or\nscreenshot, just like with all software.\n\n![](screenshot.png)\n\n*Note: the screenshot above has a non-default pointer and no alternative\nviews enabled.*\n\n[**Demo**](https://asciinema.org/a/297087) showing off deletion, undo, marks, and basic\nnavigation.\n\n## Configuration\n\nTo configure cfm before building, you should copy `config.def.h` to `config.h`\nand then modify it to suit your needs. Each option is explained within the file.\nIf you build cfm without creating a config, it will create a default one for\nyou.\n\nThere are some options which cfm will attempt to use environment variables for.\nThese are `$EDITOR`, `$SHELL`, and `$OPENER`. If you want to specify a specific\noption just for cfm, it will first try to find these variables prefixed with\n`$CFM_`. For example, if your `$EDITOR` is set to vim but you want to tell\ncfm to use emacs, you could use `export CFM_EDITOR='emacs'`. If you installed\ncfm via a package manager, or if you are using the default configuration, you\ncan specify these environment variables to configure cfm without rebuilding.\ncfm uses a temporary directory for its deleted files (to enable undo and\ncut/paste). If it's not set in `config.h`, then cfm will attempt to use the\n`$CFM_TMP` environment variable. If this is not set either, then `/tmp/cfmtmp`\nwill be used. If a temporary directory is not specified in any way or it cannot\ncreate the directory it is attempting to use, cfm will disable undo and\ncut/paste. If `CD_ON_CLOSE` is not enabled at compile-time, cfm will look for\nthe `$CFM_CD_ON_CLOSE` environment variable, which should contain the path to a\nfile where cfm should write its current working directory when quit with\n\u003ckbd\u003eQ\u003c/kbd\u003e.\n\n## Building\n\nWhen building from source, you should get the source for the [latest\nrelease](https://github.com/WillEccles/cfm/releases) and then run `make` inside\nthe extracted source.\n\n## Installing\n\n### From Source\n\nFirst, download the [latest release](https://github.com/WillEccles/cfm/releases)'s source.\nThen, use `sudo make install`. You can specify a `PREFIX` or `DESTDIR` like with many\nmakefiles. By default, `PREFIX` is `/usr/local/`, but if you wish to install\ninto `/usr`, you can do `sudo make install PREFIX=/usr`.\n\n### With a Package Manager\n\nAt the moment, cfm is available from the following sources (not all maintained\nby me):\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/cfm.svg)](https://repology.org/project/cfm/versions)\n\n## Bugs\n\nIf you find a bug, please create an issue on GitHub.\n\n## Usage\n\nThe functions of some keys may be dependent on values set in `config.h`.\n\n| Key(s) | Function |\n| ------ | -------- |\n| \u003ckbd\u003eq\u003c/kbd\u003e, \u003ckbd\u003eEsc\u003c/kbd\u003e | Quit cfm |\n| \u003ckbd\u003eQ\u003c/kbd\u003e | Quit cfm, saving its working directory to the file specified in `CD_ON_CLOSE`, if enabled. Disabled by default. |\n| \u003ckbd\u003eh\u003c/kbd\u003e | Go up a directory[\u003csup\u003e1\u003c/sup\u003e](#1) |\n| \u003ckbd\u003ej\u003c/kbd\u003e | Move down[\u003csup\u003e1\u003c/sup\u003e](#1) |\n| \u003ckbd\u003ePgDn\u003c/kbd\u003e, \u003ckbd\u003eJ\u003c/kbd\u003e | Move down by one full screen |\n| \u003ckbd\u003ek\u003c/kbd\u003e | Move up[\u003csup\u003e1\u003c/sup\u003e](#1) |\n| \u003ckbd\u003ePgUp\u003c/kbd\u003e, \u003ckbd\u003eK\u003c/kbd\u003e | Mode down by one full screen |\n| \u003ckbd\u003e~\u003c/kbd\u003e | Navigate to user home directory |\n| \u003ckbd\u003e/\u003c/kbd\u003e | Navigate to the system root directory |\n| \u003ckbd\u003el\u003c/kbd\u003e | Enter directory, or open file in `EDITOR`[\u003csup\u003e1\u003c/sup\u003e](#1) |\n| \u003ckbd\u003edd\u003c/kbd\u003e | Delete currently selected file or directory (there is no confirmation, be careful), backing it up to the `CFM_TMP` directory if one exists, such that it can be undone with \u003ckbd\u003eu\u003c/kbd\u003e |\n| \u003ckbd\u003eAlt\u003c/kbd\u003e+\u003ckbd\u003edd\u003c/kbd\u003e | Works the same as \u003ckbd\u003edd\u003c/kbd\u003e, but is always permanent, even if a `CFM_TMP` directory exists. This is useful for huge files/directories that would take a while to copy. Be careful! |\n| \u003ckbd\u003eT\u003c/kbd\u003e | Creates a new file, opening `EDITOR` to obtain a filename[\u003csup\u003e2\u003c/sup\u003e](#2) |\n| \u003ckbd\u003eM\u003c/kbd\u003e | Creates a new directory, opening `EDITOR` to obtain a directory name[\u003csup\u003e2\u003c/sup\u003e](#2) |\n| \u003ckbd\u003eR\u003c/kbd\u003e | Renames a file, opening `EDITOR` to edit the filename[\u003csup\u003e2\u003c/sup\u003e](#2) |\n| \u003ckbd\u003egg\u003c/kbd\u003e | Move to top |\n| \u003ckbd\u003eG\u003c/kbd\u003e | Move to bottom |\n| \u003ckbd\u003em\u003c/kbd\u003e, \u003ckbd\u003eSpace\u003c/kbd\u003e | Mark for deletion |\n| \u003ckbd\u003eD\u003c/kbd\u003e | Delete marked files (does not touch unmarked files) |\n| \u003ckbd\u003eu\u003c/kbd\u003e | Undo the last deletion operation (if cfm was unable to access/create its trash directory `~/.cfmtrash`, deletion is permanent and this will not work) |\n| \u003ckbd\u003eX\u003c/kbd\u003e | Cut the current file or directory (to be pasted again with \u003ckbd\u003ep\u003c/kbd\u003e) |\n| \u003ckbd\u003eyy\u003c/kbd\u003e | Copy the current file or directory (to be pasted again with \u003ckbd\u003ep\u003c/kbd\u003e) |\n| \u003ckbd\u003ep\u003c/kbd\u003e | Paste the previously copied or cut file or directory |\n| \u003ckbd\u003ee\u003c/kbd\u003e | Open file or directory in `EDITOR` |\n| \u003ckbd\u003eo\u003c/kbd\u003e | Open file or directory in `OPENER` |\n| \u003ckbd\u003eS\u003c/kbd\u003e | Spawns a `SHELL` in the current directory |\n| \u003ckbd\u003er\u003c/kbd\u003e | Reload directory |\n| \u003ckbd\u003e.\u003c/kbd\u003e | Toggle visibility of hidden files (dotfiles) |\n| \u003ckbd\u003eReturn\u003c/kbd\u003e | Works like \u003ckbd\u003eo\u003c/kbd\u003e if `ENTER_OPENS` was enabled at compile-time, else works like \u003ckbd\u003el\u003c/kbd\u003e |\n| \u003ckbd\u003eTab\u003c/kbd\u003e | Switches to the next view |\n| \u003ckbd\u003e\\`\u003c/kbd\u003e | Switches to the previous view |\n| \u003ckbd\u003e1\u003c/kbd\u003e...\u003ckbd\u003e0\u003c/kbd\u003e | Switches to view N, up to the number specified by `VIEW_COUNT` (default 2) |\n\n---\n\n\u003ca class=\"anchor\" id=\"1\"\u003e\u003c/a\u003e\u003csup\u003e1\u003c/sup\u003e The arrow keys work the same as\n\u003ckbd\u003eh\u003c/kbd\u003e\u003ckbd\u003ej\u003c/kbd\u003e\u003ckbd\u003ek\u003c/kbd\u003e\u003ckbd\u003el\u003c/kbd\u003e.\n\n\u003ca class=\"anchor\" id=\"2\"\u003e\u003c/a\u003e\u003csup\u003e2\u003c/sup\u003e The available characters for filenames are `A-Za-z\n._-` by default, which is POSIX \"fully portable filenames\" plus spaces. If\nyou wish, you can disable spaces by setting `ALLOW_SPACES` to 0.\n\n## Scripting\n\nIf `stdin` or `stdout` are not attached to a TTY, cfm will read commands from\n`stdin` until either EOF is reached or it does not read any more data. This can\nbe used to script operations. All errors will be printed to `stderr` and are\nfatal. In scripting mode, cfm will never draw to the screen. Note: in\nnon-interactive mode, cfm will NOT backup files on deletion. This means that you\ncannot use \u003ckbd\u003edd\u003c/kbd\u003e followed by \u003ckbd\u003eu\u003c/kbd\u003e! All deletions made in\nnon-interactive mode will be final.\n\nExample:\n\n```\n$ cat script.txt\njjljjjkyyhp\n$ cfm \u003cscript.txt\n```\n\nThis example is equivalent to performing the following operations in a normal\ncfm instance:\n\n1. Go down twice with \u003ckbd\u003ej\u003c/kbd\u003e\n2. Go into the currently selected directory with \u003ckbd\u003el\u003c/kbd\u003e\n3. Go down three times with \u003ckbd\u003ej\u003c/kbd\u003e and up once with \u003ckbd\u003ek\u003c/kbd\u003e\n4. Yank the current file with \u003ckbd\u003eyy\u003c/kbd\u003e\n5. Go back to the parent directory with \u003ckbd\u003eh\u003c/kbd\u003e\n6. Paste the yanked file with \u003ckbd\u003ep\u003c/kbd\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsophec%2Fcfm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsophec%2Fcfm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsophec%2Fcfm/lists"}