README
¶
Goful
Goful is a CUI file manager written in Go.
- Works on cross-platform such as gnome-terminal and cmd.exe
- Displays multiple windows and workspaces
- A command line to execute using such as bash and tmux
- Provides filtering search, async copy, glob, bulk rename, etc.

Install
Pre-build binaries
See releases.
Go version >= 1.16
$ go install github.com/fareedst/goful@latest
...
$ goful
Go version < 1.16
$ go get github.com/fareedst/goful
...
$ goful
Usage
| key | function |
|---|---|
C-n down j |
Move cursor down |
C-p up k |
Move cursor up |
C-a home ^ |
Move cursor top |
C-e end $ |
Move cursor bottom |
C-f C-i right l |
Move cursor right |
C-b left h |
Move cursor left |
C-d |
More move cursor down |
C-u |
More move cursor up |
C-v pgdn |
Page down (Note: On some macOS terminal configurations, Control-V may be intercepted for paste operations. Use pgdn key as an alternative.) |
M-v pgup |
Page up |
M-n |
Scroll down |
M-p |
Scroll up |
C-h backspace u |
Change to upper directory |
~ |
Change to home directory |
\ |
Change to root directory |
w |
Change to neighbor directory |
C-o |
Create directory window |
C-w |
Close directory window |
M-f |
Move next workspace |
M-b |
Move previous workspace |
M-C-o |
Create workspace |
M-C-w |
Close workspace |
space |
Toggle mark |
M-= |
Invert mark |
C-l |
Reload |
C-m o |
Open |
i |
Open by pager |
s |
Sort |
v |
View |
E |
Toggle filename excludes |
` |
Toggle comparison colors |
C |
Copy All (to all visible panes) |
M |
Move All (to all visible panes) |
S |
Sync command mode (synchronized ops) |
= |
Calculate file digest |
L or M-l |
Toggle linked navigation mode |
[ |
Start difference search |
] |
Continue difference search |
b |
Bookmark |
e |
Editor |
x |
Command |
X |
External command |
f / |
Find |
; |
Shell |
: |
Shell suspend |
n |
Make file |
K |
Make directory |
c |
Copy |
m |
Move |
r |
Rename |
R |
Bulk rename by regexp |
D |
Remove |
d |
Change directory |
g |
Glob |
G |
Glob recursive |
C-g C-[ |
Cancel |
? |
Help (keystroke catalog with color styling and mouse scroll) |
q Q |
Quit |
For more see main.go
Mouse Support [REQ:MOUSE_FILE_SELECT] [REQ:TOOLBAR_PARENT_BUTTON] [REQ:TOOLBAR_LINKED_TOGGLE] [REQ:TOOLBAR_COMPARE_BUTTON]
Goful provides mouse support for common navigation and file operations, making it accessible to users who prefer graphical interaction alongside keyboard shortcuts.
Toolbar Buttons
The header row displays clickable toolbar buttons at the left edge:
| Button | Function | Behavior |
|---|---|---|
[^] |
Parent directory | Navigate to parent directory. Respects linked mode: when ON, all windows navigate to their respective parents; when OFF, only the focused window navigates. |
[L] |
Linked mode toggle | Toggle linked navigation mode. The button style indicates current state: highlighted (reverse) when ON, normal when OFF. Click to toggle and see confirmation message. |
[=] |
Compare all digests | Calculate xxHash64 digests for all files that appear in multiple panes. Equivalent to pressing = on every shared filename. Displays a summary message with the count of files processed. |
File Selection
- Left-click on a file: Selects the file and moves the cursor. If clicking in an unfocused pane, switches focus to that pane first.
- Cross-window cursor sync: When linked mode is ON, clicking a file syncs all other panes to the same filename (if it exists). When linked mode is OFF, only the clicked pane is affected. Panes that don't contain a matching file have their cursor highlight erased to avoid confusion.
- Double-click on a directory: Navigates into the directory. When linked mode is ON, all panes that contain a matching subdirectory navigate into it.
- Double-click on a file: Opens the file using the system default application. When linked mode is ON, opens the same-named file from all panes where it exists.
Scrolling
- Mouse wheel up/down: Scrolls the file list in the pane under the cursor (3 lines per scroll).
Help Popup [REQ:HELP_POPUP_ENHANCEMENTS]
Press ? to open a styled help popup displaying the complete keystroke catalog. The help popup features:
Color Styling
- Border: Distinct color matching the current theme
- Header: Bold title with theme-aware highlighting
- Keybindings: Color-coded key combinations for easy scanning
- Descriptions: Styled command descriptions
The colors automatically adapt to the active theme (default, midnight, black, or white).
Navigation
- Keyboard:
j/kor arrow keys move the cursor,pgup/pgdnfor page scrolling,M-n/M-pfor smooth scroll - Mouse wheel: Scroll up/down through the help content
- Exit: Press
?,q,C-g, orEscto close
Linked navigation mode [REQ:LINKED_NAVIGATION]
Linked navigation synchronizes directory navigation and cursor position across all open panes. When enabled, navigating into a subdirectory, pressing backspace (parent directory), or moving the cursor in the focused window causes all other windows to sync accordingly.
Toggle: Press L (uppercase L), M-l (Alt+l), or click the [L] toolbar button to enable or disable linked mode. The [L] button in the header is always visible: highlighted when linked mode is ON, normal when OFF.
macOS note: The Option key often produces special characters instead of acting as Meta/Alt, so use uppercase
L(Shift+l) which works reliably across all platforms. On default macOS systems, Control-V works as Page Down, but some terminal or shell configurations may intercept it for paste operations; in such cases, use thepgdnkey instead.
Cursor synchronization: When you move the cursor (via keyboard j/k/arrows/page keys or mouse click), all other panes move their cursors to the same filename if it exists. Panes without a matching file have their cursor highlight erased. When linked mode is OFF, cursor movements only affect the focused pane.
Subdirectory navigation: When you enter a subdirectory named foo, all other panes that also contain a subdirectory named foo will navigate into it. Panes without a matching subdirectory stay on their current path.
Parent navigation: When you press backspace (or C-h or u), all panes navigate to their respective parent directories.
Sort synchronization: When you change the sort order (via the s menu), all panes adopt the same sort order.
Use cases:
- Comparing parallel directory structures (e.g., syncing
src/andbackup/src/) - Navigating release versions side-by-side (
v1.0/,v2.0/) - Keeping workspace panes aligned when exploring mirrored folder hierarchies
- Quickly finding matching files across panes by moving cursor in any single pane
The mode is on by default and does not persist across restarts. Press L or click the [L] toolbar button to toggle it off if you prefer independent navigation.

Difference search [REQ:DIFF_SEARCH]
Difference search finds files and directories that differ across your workspace panes. It's designed for comparing similar directory structures—like backup copies, release versions, or synced folders—by highlighting entries that are missing or have different sizes.
Start search: Press [ to begin a new difference search. Goful records the current directories in all panes and starts scanning for differences alphabetically.
Continue search: Press ] to advance to the next difference. The search resumes from the current cursor position and finds the next entry that differs.
What counts as a difference:
- A file or directory that exists in some panes but is missing from others
- A file that exists in all panes but has different sizes
How the search works:
- Files are compared first, in alphabetical order
- When all files at the current level match, the search descends into subdirectories that exist in all panes
- Subdirectories that exist in only some panes are flagged as differences
- The search continues depth-first until returning to the starting directories
Status display: While a search is active, the header shows a [DIFF: ...] indicator with either the current search progress or the last found difference.
Navigating during search: You can freely navigate within panes between ] presses. When you continue the search, it resumes from your current position and correctly traverses back through the directory tree to find the next difference.
Ending the search: The search ends automatically when all directories have been checked. You can also start a new search with [ at any time, which replaces the current search state.
Use cases:
- Finding files that failed to sync between backup and source directories
- Locating additions or deletions between release versions
- Identifying size mismatches that indicate incomplete copies or corruption
Tip: Combine with linked navigation mode (L) to keep panes synchronized as you explore differences.
Batch Diff Report (N-Way Comparison) [REQ:BATCH_DIFF_REPORT]
Goful offers a unique n-way directory comparison capability that goes beyond traditional two-directory diff tools. While most comparison utilities are limited to pairwise comparisons, goful can simultaneously compare 2, 3, 4, or more directory trees in a single operation—revealing differences that would require multiple manual comparisons with conventional tools.
Use cases for n-way comparison:
- Multi-environment validation: Compare staging, production, and development deployments simultaneously
- Parallel backup verification: Validate that local, remote, and archive copies are identical
- Multi-version analysis: Track changes across several release versions at once
- Distributed system checks: Verify configuration consistency across multiple servers

CLI command: Run a non-interactive batch comparison with YAML output:
# Compare two directories
goful --diff-report dir1 dir2
# Compare three or more directories (n-way)
goful --diff-report prod/ staging/ dev/
# Suppress progress output for scripting
goful --diff-report --quiet backup1/ backup2/ backup3/
Output format: The command produces a structured YAML report to stdout:
directories:
- /path/to/prod
- /path/to/staging
- /path/to/dev
totalFilesChecked: 1542
totalDirectoriesTraversed: 87
durationSeconds: 2.34
differences:
- name: config.json
path: app/config.json
reason: "size mismatch: 1024 vs 1048 vs 1024"
isDir: false
- name: cache/
path: cache/
reason: "missing in window 2"
isDir: true
Exit codes for scripting:
| Code | Meaning |
|---|---|
| 0 | No differences found |
| 1 | Error (invalid arguments, directory not found) |
| 2 | Differences found |
Progress reporting: By default, progress updates are printed to stderr every 2 seconds. Use --quiet to suppress these for cleaner pipeline integration.
Example pipeline:
# Check backups and alert on differences
if ! goful --diff-report --quiet /backup/daily /backup/weekly /live; then
goful --diff-report /backup/daily /backup/weekly /live > /var/log/diff-report.yaml
mail -s "Backup mismatch detected" admin@example.com < /var/log/diff-report.yaml
fi
Filename exclude list [REQ:FILER_EXCLUDE_NAMES]
- Create a newline-delimited file containing the basenames you want to hide (for example
.DS_Store,Thumbs.db). Blank lines and lines starting with#are ignored. - The list is loaded from
~/.goful/excludesby default. Override the path with-exclude-names /path/to/fileorGOFUL_EXCLUDES_FILE=/path/to/fileto share custom lists across machines. - Matching is case-insensitive and applies to every directory pane, finder result, and macro expansion while the filter is enabled.
- Press
E(or open the View menu and pressn) to toggle the filter at runtime. Goful instantly reloads every pane so you can temporarily reveal hidden files, inspect them, and re-enable the filter without restarting the UI.
Demos
Copy and Move
Copy (default c) and move (default m) mark (default space and invert
C-space) files.

First input a copy source file name (or path). The default source is a file name on the cursor. If files are marked, this step is skipped.
Second input a copy destination path and start copy processing. The default destination is a neighboring directory path.
During processing draws copying file count, size and name, progress percent, gauge, bps and estimated time of arrival.
If the source file type is a directory, recursively copy. Also copy modification time and permissions.
Rise a override confirm dialog [y/n/Y/N] if the name same as source file
exists in the destination. This dialog means:
yis overwrite only this filenis not overwrite only this fileYis overwrite all later fileNis not overwrite all later file
Copy process works asynchronously. And processed in the order if you run multiple copies.
Note that copy process can not interrupt. If you want to interrupt, please quit
the application (default q Q).
Bulk Rename
Bulk renaming (default R) for mark (default space and invert C-space)
files.
Rename by the regexp pattern. Input like the vim substituting style (regexp/replaced). Display and confirm matched files and replaced names before rename.

Finder (Filtering search)
The finder (default f /) filters files in the directory.
Input characters recognizes as the regexp. Case insensitive when inputs lowercase only, on the other hand case sensitive when contains uppercase.
Delete characters by C-h and backspace (default). Can select input
histories by M-p and M-n (default).
Other than character inputs (exclude a space) and the finder keymap pass to the main input.
Hit reset key (default C-g C-[ means Esc) to clear filtering.

Glob
Glob is matched by wild card pattern in the current directory (default g and
recursive G).
Hit reset key (default C-g C-[ means Esc) to clear glob patterns.

Layout
Directory windows position are allocated by layouts of tile, tile-top, tile-bottom, one-row, one-column and fullscreen.
View menu (default v), run layout menu and select layout:

Execute Terminal and Shell
Shell mode (default : and suspended ;) runs a terminal and execute shell
such as bash and tmux. The cmdline completion (file names and commands in
$PATH) is available (default C-i that means tab).
For example, spawns commands by bash in a gnome-terminal new tab:

The terminal immediately doesn't close when command finished because check outputs.
If goful is running in tmux, it creates a new window and executes the command.
[REQ:TERMINAL_PORTABILITY] keeps this workflow intact on macOS and alternative
terminal emulators:
- On macOS, goful now opens Terminal.app via
osascriptso commands run in a new tab/window without editingmain.go. The adapter automatically runscd "%D";before your command so relative paths match the focused window, and the command stays visible until you hit enter because the historicalread -p "HIT ENTER KEY"prompt remains—after acknowledging it, the adapter issuesexitso the temporary window closes cleanly. - Want another AppleScript-friendly terminal or shell? Set
GOFUL_TERMINAL_APP="iTerm2"(or similar) to reuse the built-in macOS branch with a different application, and setGOFUL_TERMINAL_SHELL="zsh"(or any other binary) to change the inline shell that runs inside that window—defaults remain Terminal.app + bash so existing workflows stay unchanged. - Set
GOFUL_TERMINAL_CMD="alacritty -e"(or another emulator) to override the launcher on Linux/BSD. The override is inserted before the usualbash -cinvocation, so your configured terminal still receives the expanded command and inherits the macOS working-directory preamble when applicable. - Export
GOFUL_DEBUG_TERMINAL=1to printDEBUG: [IMPL:TERMINAL_ADAPTER]messages describing which branch was selected if you need to troubleshoot environment detection.
Expand Macro
| macro | expanded string |
|---|---|
%f %F |
File name/path on cursor |
%x %X |
File name/path with extension excluded on cursor |
%m %M |
Marked file names/paths joined by spaces |
%d %D |
Directory name/path on cursor |
%d2 %D2 |
Neighbor directory name/path |
%D@ %~D@ |
Current window stays %D; both macros append the other directory paths in display order so echo %D %D@ lists every window. %D@ quotes each appended path for shell safety, while %~D@ deliberately emits the same list without quoting so advanced scripts can opt into raw arguments. |
%d@ %~d@ |
Appends the other directory names (Directory.Base()) in the same order. %d@ quotes each name so shell invocations stay safe, while %~d@ emits raw names when scripts only need lightweight labels. |
%~f ... |
Expand by non quote |
%& |
Flag to run command in background |
The macro is useful if do not want to specify a file name when run the shell.
Macros starts with % are expanded surrounded by quote, and those starts with
%~ are expanded by non quote (including %~D@ and %~d@, which return raw directory paths or names just like other tilde macros). The %~ mainly uses to for cmd.exe.
Use %& when background execute the shell such as GUI apps launching.

Customize
Most of goful is still customized by editing main.go, but [REQ:EXTERNAL_COMMAND_CONFIG] now provides a JSON or YAML file for the external-command menu so you can ship your own automation without rebuilding the binary.
Examples of customizing:
- Change and add keybindings
- Change terminal and shell
- Change file opener (editor, pager and more)
- Adding bookmarks
- Setting colors and looks
File comparison colors (` toggle)
[REQ:FILE_COMPARISON_COLORS] (implemented via [ARCH:FILE_COMPARISON_ENGINE] + [IMPL:COMPARE_COLOR_CONFIG]) adds a per-column palette that highlights files with the same name across multiple windows. The feature is on by default so you immediately see color-coded file listings; press ` (backtick) at any time (or use View → toggle comparison colors) to disable it if you prefer the standard theme, and tap ` again to re-enable. When enabled, goful rebuilds its comparison index and redraws each pane so you can immediately spot duplicates, newer backups, or size mismatches.
Default palette
- Names present in more than one pane render in bold yellow so duplicates stand out even before you inspect metadata.
- Size column colors: cyan when sizes match, red for the smallest copy, green for the largest copy.
- Time column colors: cyan for matching timestamps, red for the earliest copy, green for the latest copy.
Digest comparison (= key)
[IMPL:DIGEST_COMPARISON] extends the comparison feature with on-demand content verification. When you need to confirm whether files with identical names and sizes contain the same data, press = on any file to calculate xxHash64 digests.
How it works
- Press
=on a file (or useView → calculate file digest). - Goful finds all files with the same name (case-sensitive) across loaded directory panes.
- Files are grouped by their actual size:
- Files that share the same size with at least one other file participate in digest calculation.
- Files with a unique size (no other same-named file has that size) are skipped and continue displaying their normal size comparison colors (smallest/largest/middle).
- Within each size group (where at least two files share the same size), goful computes xxHash64 digests and compares them:
- Equal digests (identical content): the size field displays with an underline attribute.
- Different digests (different content despite same size): the size field displays with a strikethrough attribute.
- Files with unique sizes or unique names show no digest indicator—their standard comparison colors remain.
Example: If you have backup.zip in three directories with sizes 100MB, 100MB, and 150MB, pressing = will compare the two 100MB copies (showing underline if identical, strikethrough if different) while the 150MB copy keeps its normal "largest" color with no digest indicator.
Use cases
- Verify backup integrity by confirming copies match the original.
- Detect silent corruption where file sizes match but content differs.
- Quickly identify duplicates that can be safely removed.
Notes
- Digest calculation reads the entire file, so very large files may take noticeable time.
- Results persist until the comparison index is rebuilt (e.g., toggling comparison colors off/on or reloading directories).
- Terminal support for underline and strikethrough varies; most modern terminals (iTerm2, gnome-terminal, Windows Terminal) render both attributes correctly.

Configure the palette
The palette loads from a YAML file resolved in the usual precedence order: the -compare-colors /path/to/colors.yaml flag wins, next GOFUL_COMPARE_COLORS=/path/to/colors.yaml, then the default ~/.goful/compare_colors.yaml. Edit or create the file, restart goful so the config is reloaded during startup, and press ` to see the new scheme:
# ~/.goful/compare_colors.yaml
name:
present: yellow
size:
equal: cyan
smallest: "#ff5555" # accepts named colors or #RRGGBB hex
largest: green
time:
equal: cyan
earliest: orange
latest: "#32cd32"
All entries accept tcell color names (red, cyan, magenta, etc.) or hex values. Leave a field blank to fall back to the default. Combine this file with the runtime toggle to tailor comparison cues to whichever terminal theme you use.
Multi-target copy/move (C / M keys)
[REQ:NSYNC_MULTI_TARGET] (implemented via [ARCH:NSYNC_INTEGRATION]) provides parallel copy/move to all visible workspace panes simultaneously using the nsync SDK.
How it works
- Mark files with
Space(or use the cursor file if nothing is marked). - Press
C(Copy All) orM(Move All). - Files are copied/moved in parallel to all other visible directory panes.
- Progress is displayed via goful's standard progress bar.
- When only one pane is visible, these commands fall back to the regular single-target
c/mbehavior.
Use cases
- Deploy files to multiple directories at once (e.g., syncing assets across project folders).
- Create backups to multiple destinations simultaneously.
- Distribute configuration files to several locations.
The nsync SDK handles parallel execution, content verification, and move semantics (source deletion only after successful sync to all destinations).
Note:
C/Mcopy/move files from the focused pane to other panes. For synchronized operations on same-named files across all panes, see Sync commands below.
Sync operations (S prefix) [REQ:SYNC_COMMANDS]
Sync commands execute copy, delete, or rename operations simultaneously across all workspace panes on files with the same name as the cursor file. This is designed for managing synchronized directory structures where you need to perform identical operations on matching files in every pane.
How it works
- Position the cursor on the target file in any pane.
- Press
Sto enter sync mode. The prompt shows:Sync [c]opy [d]elete [r]ename [!]ignore: - Optionally press
!to toggle "ignore failures" mode (continues through all panes even on errors). - Press an operation key:
c– Copy: prompts for a new filename (default: current name); you must enter a different name. The file is copied to the new name in each pane's directory.d– Delete: confirms withy/n; deletes the same-named file in each pane.r– Rename: prompts for a new name; renames the same-named file in each pane.
- The operation executes sequentially starting from the focused pane, then proceeding through other panes in order.
Example: You have config.yaml in three panes (~/project-a/, ~/project-b/, ~/project-c/). Press S, then r, enter config.yaml.bak, and all three files are renamed to config.yaml.bak in one action.
Failure handling
- By default, the operation aborts on first failure and reports which pane failed.
- Press
!before the operation key to enable ignore failures mode, which continues through all panes and reports all failures at the end. - If a file with the target name doesn't exist in a pane, that pane is skipped (not treated as a failure).
Comparison with C/M (multi-target copy/move)
| Feature | C/M (Multi-target) |
S (Sync) |
|---|---|---|
| Source | Marked files or cursor file in focused pane | Same-named file in every pane |
| Destination | All other visible panes | Same directory (copy to new name) or in-place (rename/delete) |
| Use case | Distribute files from one pane to others | Synchronized operations on matching files across panes |
| Execution | Parallel (nsync SDK) | Sequential |
Use cases
- Rename a file that exists in multiple mirrored directories with a single command.
- Delete a generated file across all project folders at once.
- Create a backup copy of a config file in every workspace pane simultaneously.
Tip: Combine with linked navigation mode (L) to keep panes synchronized as you navigate, then use S commands to batch-operate on matching files.
Recommend remain original main.go and copy to own main.go for example:
Go to source directory
$ cd $GOPATH/src/github.com/fareedst/goful
Copy original main.go to my/goful directory
$ mkdir -p my/goful
$ cp main.go my/goful
$ cd my/goful
Install after edit my/goful/main.go
$ go install
External Command Config (external-command menu)
[REQ:EXTERNAL_COMMAND_CONFIG] and [ARCH:EXTERNAL_COMMAND_REGISTRY] move the external-command menu definitions into a JSON or YAML file so you can add/edit/remove shell helpers without touching Go code:
- Flag
-commands /path/to/external_commands.yamloverrides everything. - Environment variable
GOFUL_COMMANDS_FILEapplies when the CLI flag is unset. - Defaults fall back to
~/.goful/external_commands.yaml, with the historical POSIX/Windows bindings baked in if the file does not exist yet. - Omit
inheritDefaults(or set it totrue) to prepend your file-based commands ahead of the compiled defaults; setinheritDefaults: falseto replace them entirely.[IMPL:EXTERNAL_COMMAND_APPEND] - Set
GOFUL_DEBUG_COMMANDS=1to log loader diagnostics (DEBUG: [IMPL:EXTERNAL_COMMAND_LOADER] ...).
Each entry accepts (shown in JSON, but the same fields work in YAML):
[
{
"menu": "external-command", // optional; defaults to external-command
"key": "c",
"label": "copy %m to %D2 ",
"command": "cp -vai %m %D2",
"offset": -2, // optional cursor offset for g.Shell
"platforms": ["linux"], // optional GOOS filter (case-insensitive)
"disabled": false
},
{
"key": "A",
"label": "archives menu ",
"runMenu": "archive" // optional: jump into another goful menu instead of running a shell command
}
]
YAML example:
inheritDefaults: true # omit for the default prepend behavior
commands:
- key: c
label: "copy %m to %D2 "
command: "cp -vai %m %D2"
offset: -2
- key: A
label: "archives menu "
runMenu: "archive"
Need an object wrapper in JSON to drop the defaults entirely:
{
"inheritDefaults": false,
"commands": [
{
"key": "z",
"label": "zip %m",
"command": "zip -roD %x.zip %m"
}
]
}
- Use goful macros (
%f,%D@,%~m, etc.) insidecommandstrings the same way the legacymain.gomenu did. - Entries are applied in file order, and duplicate
menu/keycombinations are rejected with a descriptive error surfaced viamessage.Errorf. - If the file disables every entry, the
external-commandmenu still appears and displays a placeholder that explains how to re-enable commands.
Configuring State & History Paths
[REQ:CONFIGURABLE_STATE_PATHS] and [ARCH:STATE_PATH_SELECTION] make it possible to redirect the persisted UI state and cmdline history without editing the source:
- Defaults remain
~/.goful/state.jsonand~/.goful/history/shell. - Set
GOFUL_STATE_PATHorGOFUL_HISTORY_PATHto override the defaults for a shell/session. - Pass
-state /tmp/state.jsonor-history /tmp/historyon the command line to override everything else (flags win over environment variables). - Export
GOFUL_DEBUG_PATHS=1to log which source produced each path (DEBUG: [IMPL:STATE_PATH_RESOLVER] ...) for troubleshooting sandboxes and CI jobs.
Startup Workspace Directories
[REQ:WORKSPACE_START_DIRS] and [ARCH:WORKSPACE_BOOTSTRAP] let you pass directories after the usual CLI flags so goful opens one filer window per argument (ordered). Examples:
$ goful ~/src/dotfiles ~/src/goful ~/Downloads
# window 1 -> ~/src/dotfiles, window 2 -> ~/src/goful, window 3 -> ~/Downloads
- The arguments are normalized (tilde expansion + absolute paths) but otherwise preserved, so duplicates intentionally open multiple panes pointing at the same directory.
- If an argument does not exist or is not a directory, goful prints
message.Errorfoutput explaining the issue and continues processing the remaining entries. When every argument fails, startup falls back to the persisted workspace layout. - Set
GOFUL_DEBUG_WORKSPACE=1to emitDEBUG: [IMPL:WORKSPACE_START_DIRS] ...lines that document the parsed arguments and window assignments—useful when debugging automation scripts or verifying CI launches. - Launching without trailing directories keeps the historical behavior (state restoration or default layout), so existing workflows continue to work unchanged.
- When at least one directory is supplied, goful resizes the workspace list to match (creating or closing tabs as needed) and focuses the first entry.
Documentation
ARCHITECTURE.md–[REQ:ARCH_DOCUMENTATION]package/data-flow overview plus module validation map.CONTRIBUTING.md–[REQ:CONTRIBUTING_GUIDE]workflow, semantic token, and module-validation requirements.stdd/directory – STDD requirements, architecture decisions, implementation decisions, semantic token registry, and task tracker.
Build & Release
make lint/make testkeep local runs in sync with CI’s fmt/vet/test gates.make release([REQ:RELEASE_BUILD_MATRIX]/[IMPL:MAKE_RELEASE_TARGETS]) produces CGO-disabled binaries plus.sha256digests indist/. SetPLATFORM=linux/amd64(orlinux/arm64,darwin/arm64) to build a single target; otherwise all default platforms are generated.- CI job
release-matrix(in.github/workflows/ci.yml) reuses the same Makefile target so every PR proves artifacts remain reproducible before merge. - Tag pushes
v*trigger.github/workflows/release.yml, which re-runs the matrix, logs deterministic filenames/checksums, and publishes the binaries + digest files to the GitHub Release viasoftprops/action-gh-release.
Docker
Goful can run in Docker containers for cross-platform testing and development without requiring a local Go toolchain.
Linux Container (Alpine) [REQ:DOCKER_INTERACTIVE_SETUP]
The default Docker setup uses a minimal Alpine Linux image (~5MB runtime).
# Build and run interactively
make docker-run
# Or use the helper script
./docker-run.sh
# Or use docker-compose
docker compose run --rm goful
The container mounts the current directory at /workspace for file operations. Terminal environment variables (TERM=xterm-256color, COLORTERM=truecolor) are configured for proper color support.
Windows Container (Server Core) [REQ:DOCKER_WINDOWS_CONTAINER]
Windows container support enables testing Goful on Windows Server environments.
Note: Windows containers require a Windows host with Docker Desktop in Windows containers mode or Windows Server with the containers feature enabled. They cannot run on macOS or Linux Docker hosts.
# Using Makefile (cross-platform build command)
make docker-build-windows
make docker-run-windows
# Using PowerShell helper script
.\docker-run.ps1
# Using docker-compose
docker-compose -f docker-compose.windows.yml run --rm goful
Limitations:
- Windows Server Core base image is ~5GB (vs Alpine's ~5MB)
- Some terminal features (mouse input, resize events) may be limited in Windows containers
- nsync multi-target copy/move features are not available (darwin-only implementation)
Docker Makefile Targets
| Target | Description |
|---|---|
docker-build |
Build Linux (Alpine) Docker image |
docker-run |
Run goful in Linux container interactively |
docker-build-windows |
Build Windows (ServerCore) Docker image |
docker-run-windows |
Run goful in Windows container interactively |
docker-clean |
Remove goful Docker images |
Contributing
Read the Contributing Guide before opening a PR so you follow the STDD workflow, semantic token discipline, and module validation rules.
Documentation
¶
There is no documentation for this package.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package app is goful application components.
|
Package app is goful application components. |
|
Package cmdline is a command line widget.
|
Package cmdline is a command line widget. |
|
Package diffstatus displays a persistent status line for difference search.
|
Package diffstatus displays a persistent status line for difference search. |
|
Package filer comparison index for cross-directory file comparison.
|
Package filer comparison index for cross-directory file comparison. |
|
comparecolors
Package comparecolors provides configurable color schemes for cross-directory file comparison.
|
Package comparecolors provides configurable color schemes for cross-directory file comparison. |
|
Package help provides a Help popup widget that displays the keystroke catalog.
|
Package help provides a Help popup widget that displays the keystroke catalog. |
|
Package info displays the file information.
|
Package info displays the file information. |
|
internal
|
|
|
Package look comparison colors for cross-directory file comparison.
|
Package look comparison colors for cross-directory file comparison. |
|
Package menu provides the menu window widget.
|
Package menu provides the menu window widget. |
|
Package message provides the message window widget.
|
Package message provides the message window widget. |
|
Package progress displays the file control task progress.
|
Package progress displays the file control task progress. |
|
Package util provides misc utility functions.
|
Package util provides misc utility functions. |
|
Package widget provides base user interfaces.
|
Package widget provides base user interfaces. |
|
test/event
command
|
|
|
test/gauge
command
|
|
|
test/listbox
command
|