aboutsummaryrefslogtreecommitdiff
path: root/man/krino.1
diff options
context:
space:
mode:
Diffstat (limited to 'man/krino.1')
-rw-r--r--man/krino.1348
1 files changed, 348 insertions, 0 deletions
diff --git a/man/krino.1 b/man/krino.1
new file mode 100644
index 0000000..627a2ee
--- /dev/null
+++ b/man/krino.1
@@ -0,0 +1,348 @@
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.Dd September 13, 2026
+.Dt KRINO 1
+.Os
+.Sh NAME
+.Nm krino
+.Nd sort files in a directory by rules
+.Sh SYNOPSIS
+.Nm
+.Op Fl y | Fl n
+.Op Fl v
+.Op Fl -json
+.Op Fl c Ar file
+.Op Ar name ...
+.Pp
+.Nm
+.Cm init
+.Pp
+.Nm
+.Cm new
+.Ar name path
+.Pp
+.Nm
+.Cm check
+.Op Ar name ...
+.Pp
+.Nm
+.Cm explain
+.Ar file
+.Pp
+.Nm
+.Cm log
+.Op Fl n Ar count
+.Pp
+.Nm
+.Cm undo
+.Op Ar run
+.Sh DESCRIPTION
+.Nm
+sorts the files in one or more configured directories according to rules
+kept in
+.Xr krino.conf 5 .
+For each directory in turn it scans the files, evaluates every rule against
+every file, and builds a plan: the chain of actions
+.Pq Ic copy , Ic move , Ic rename , Ic delete
+that the file's matching rules add up to.
+.Pp
+Every rule that matches a file adds its actions to that file's chain, in
+the order the rules are written;
+.Sy (stop)
+on a matching rule ends the chain for that file, so a later rule is never
+even evaluated against it.
+A rule with no actions besides
+.Sy (stop)
+is an exclusion.
+.Pp
+Every test sees the file as it was when the directory was scanned: name,
+path, size, modification time and content.
+Actions already added to a file's chain by an earlier rule never change
+what a later rule's tests see, so the whole plan for a directory can be
+computed, shown, and approved before anything is touched.
+.Pp
+With no
+.Fl y
+or
+.Fl n ,
+.Nm
+prints the plan and asks how to proceed
+.Pq Sx REVIEW .
+.Fl y
+applies the plan without asking;
+.Fl n
+prints it and changes nothing.
+If standard input is not a terminal and neither is given,
+.Nm
+refuses rather than guess.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl y
+Apply the plan without asking.
+Cannot be combined with
+.Fl n .
+.It Fl n
+Dry run: print the plan and exit without changing anything.
+.It Fl v
+Also list files that were skipped as unmatched, ignored or busy, and show
+the full reason a test matched or not.
+.It Fl -json
+With
+.Fl n ,
+print the plan as JSON instead of the table.
+Refused unless
+.Fl n
+is also given.
+The document's own
+.Ic note
+field says its shape is unstable before krino 1.0; a script that reads it
+should expect it to change before then.
+.It Fl c Ar file
+Use
+.Ar file
+in place of
+.Pa $XDG_CONFIG_HOME/krino/krino.conf .
+.It Fl h , Fl -help
+Print usage and exit.
+.It Fl -version
+Print
+.Dq krino Ar version
+and exit.
+.El
+.Sh SUBCOMMANDS
+.Bl -tag -width Ds
+.It Ic init
+Create the config directory with a commented
+.Pa krino.conf
+and
+.Pa template.conf .
+Refuses if
+.Pa krino.conf
+already exists, and leaves an existing
+.Pa template.conf
+alone.
+.It Ic new Ar name path
+Copy
+.Pa template.conf
+to
+.Pa dirs/ Ns Ar name Ns Pa .conf ,
+fill in
+.Ar path ,
+and append
+.Ar name
+to
+.Ic include
+in
+.Pa krino.conf ,
+keeping its comments.
+.It Ic check Op Ar name ...
+Validate the configuration, list each included directory's rules, and list
+which content-extraction tools
+.Pq Xr krino.conf 5 , Sx CONTENT EXTRACTION
+are available.
+With no
+.Ar name ,
+checks every included directory.
+.It Ic explain Ar file
+Evaluate every rule of
+.Ar file Ns 's
+directory against it and show each test's result, so a rule that should
+match but does not
+.Pq or the reverse
+can be diagnosed test by test.
+See
+.Sx KNOWN LIMITATIONS .
+.It Ic log Op Fl n Ar count
+List the most recent runs, newest first
+.Pq Ar count No defaults to 10 :
+the run id, its start time, the directories it touched, and what it did.
+A run that a later
+.Ic undo
+has reversed at least one file of is marked
+.Pq undone .
+.It Ic undo Op Ar run
+Reverse
+.Ar run .
+With no
+.Ar run ,
+reverse the most recent run; if that run is itself an undo, it is refused.
+An older run is undone by naming it.
+See
+.Sx UNDO .
+.El
+.Sh REVIEW
+With neither
+.Fl y
+nor
+.Fl n ,
+after showing one directory's plan
+.Nm
+asks:
+.Bd -literal -offset indent
+[a] apply all [c] choose per file [s] skip this directory [q] quit
+.Ed
+.Pp
+.Ic a
+applies every step of every chain shown.
+.Ic s
+applies nothing in this directory and moves on to the next one.
+.Ic q
+stops
+.Nm
+entirely; directories already applied earlier in this run stay applied and
+can be reversed with
+.Ic undo .
+.Pp
+.Ic c
+asks about each file in turn:
+.Bd -literal -offset indent
+ [y] yes [n] no [a] yes to this and all remaining [d] done, apply chosen so far [q] quit, apply nothing
+.Ed
+.Pp
+Approval is per file: a file's whole chain runs, or none of it.
+.Ic d
+stops asking and applies whatever was already chosen, declining the rest.
+.Ic q
+here aborts the review for this directory entirely, discarding even a file
+already marked
+.Ic yes ,
+and folds into the top-level
+.Ic q
+above.
+.Sh UNDO
+.Ic krino undo
+reverses a run's steps, last step first within each file, after building
+and showing a plan of its own
+.Pq shown and approved the same way as a sort plan; Fl y No and Fl n No apply .
+One undo plan covers every directory the run touched, so its menu has no
+per-directory skip;
+.Ic s
+and
+.Ic q
+both apply nothing:
+.Bd -literal -offset indent
+[a] apply all [c] choose per file [s] skip [q] quit
+.Ed
+.Pp
+An undo run cannot itself be undone: naming it to
+.Ic undo
+is refused.
+.Pp
+A step's reversal is refused when the world has moved on since the step ran
+.Pq its target is gone or has changed, or the original path is occupied again ;
+a refused file has nothing of its chain reversed, so no file is left half
+undone.
+An exception is a created directory found non-empty at its own turn: that
+alone does not refuse the rest of the file's reversal, since it means
+another file still lives there, not that something unexpected changed
+underfoot.
+Every created directory still empty once every file in the run has had its
+turn is then removed, deepest path first, so an undo does not leave the
+empty directories it made behind.
+.Pp
+A permanent delete,
+.Sy (delete permanent) ,
+is never undoable; it is shown in the plan with that reason and nothing is
+attempted for it.
+.Pp
+.Ic krino log
+marks a run
+.Pq undone
+once its undo run has reversed at least one file's chain \(em not that
+every file in it was restored: a run left partly reversed, because some
+files were declined during the undo's own review, is still shown as
+.Pq undone
+in full.
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev XDG_CONFIG_HOME
+Base of the configuration directory
+.Pq Pa $XDG_CONFIG_HOME/krino ;
+default
+.Pa ~/.config .
+.It Ev XDG_STATE_HOME
+Base of the log and the per-directory lock files
+.Pq Pa $XDG_STATE_HOME/krino ;
+default
+.Pa ~/.local/state .
+.It Ev XDG_DATA_HOME
+Base of the trash a
+.Sy (delete)
+step uses
+.Pq Pa $XDG_DATA_HOME/Trash ;
+default
+.Pa ~/.local/share .
+.It Ev PAGER
+Used to show a plan taller than the terminal; default
+.Dq less -FRX .
+Never used for
+.Fl -json
+output.
+.It Ev NO_COLOR
+When set, disables the ANSI colour
+.Nm
+otherwise uses on a terminal for a permanent delete and a refused undo
+step.
+.El
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa $XDG_CONFIG_HOME/krino/krino.conf
+The main configuration file: which directories run, defaults, the log
+path.
+.It Pa $XDG_CONFIG_HOME/krino/template.conf
+Copied by
+.Ic krino new
+for each new directory.
+.It Pa $XDG_CONFIG_HOME/krino/dirs/ Ns Ar name Ns Pa .conf
+One file per configured directory.
+.It Pa $XDG_STATE_HOME/krino/krino.log
+The append-only log every run writes to.
+.It Pa $XDG_STATE_HOME/krino/ Ns Ar name Ns Pa .lock
+Held for the duration of a run against directory
+.Ar name ,
+so a second
+.Nm
+against the same directory waits, or fails immediately with
+.Fl y .
+.It Pa $XDG_DATA_HOME/Trash
+The freedesktop.org trash a
+.Sy (delete)
+step moves files into.
+.El
+.Sh EXIT STATUS
+.Bl -tag -width Ds
+.It 0
+Success, including a run that found nothing to do, or one whose plan was
+entirely declined at review.
+.It 1
+A step failed, a directory's lock was already held by another
+.Nm ,
+or a configured directory could not be read.
+.It 2
+A usage mistake or a configuration error.
+Flags must come before any directory name on the command line: a flag
+found after a directory name is a usage error rather than a guess.
+.It 130
+Interrupted
+.Pq Ic Ctrl-C
+or terminated; the current step, if any, is finished and logged first.
+.El
+.Sh KNOWN LIMITATIONS
+.Ic krino explain
+evaluates every test of every rule's condition against the file, without
+the cost-ordered short-circuiting a real run uses within an
+.Sy and/or .
+It can therefore run a content-extraction tool, and report a
+.Dq content unreadable
+warning, for a test that a real run would never reach because an earlier,
+cheaper test in the same condition already decided the rule did not match.
+.Ic explain
+is a full trace of every test, not a cost-faithful preview of what
+.Fl n
+would actually spend time on.
+.Sh SEE ALSO
+.Xr krino.conf 5
+.Pp
+.Pa docs/sexp-primer.md
+in the source repository
+.Pq installed at Pa $PREFIX/share/doc/krino/sexp-primer.md
+is a short tutorial on the configuration syntax.