tfman - text file manager
tfman [-M scan] [DIR...] [OPTION...] tfman [-M parse] [FILE...] [OPTION...] tfm DIR... [OPTION...] tfm tfm -h
Tfman is text file manager managing files via textual representation of file system (being ordinary text). It can scan directories to create textual representation or parse textual representation to retrieve actions specified by user.
. Written in C for Unix-like systems.
. Does not depend on external libraries.
. Can cooperate with command-line tools, like Sed, via standard input and output streams.
. Can be integrated with text editing tools, like Vim.
Tfman has two working modes: scan mode and parse mode.
The scan mode performs scanning on specified part of file system (directory or whole tree of directories) and composes textual representation of it. Result is send to standard output (this is default) or written to a file.
Created textual representation is formatted in a manner allowing direct use in parse mode. User can edit it as normal text and add action tags.
The parse mode retrieves actions specified in textual representation and performs them on file system. Textual representation is read from standard input (default) or from file. Multiple actions of same or different types can be specified on multiple entries, whole directories and groups.
The textual representation must be in specific format (but it is still ordinary text) and actions are named by tags.
Tfm is convenience tool that combines scan mode and parse mode to make Tfman use easier. It does scanning of directories, editing textual representation and parsing result in one step.
Tfm performs scanning of specified directory, opens resulting textual representation in editor retrieved from EDITOR shell variable and performs parsing after editor is closed. It takes the same options as Tfman. Invoked without command-line arguments opens previously edited textual representation.
Scan, edit and parse Dir with recursion and names cloning:
tfm Dir -R -C
Key mappings for commands are in single quotes, assuming that your 'mapleader' is '\'.
Scan commands:
:Tsr DIR RLVL - open new or goto first existing Tfman edit window and san DIR with recursion level RLVL :Tsa DIR RLVL - same but append result to buffer :Tsw DIR RLVL - same but always open new window :Tst DIR RLVL - same in new tabpage :To 'ENTER' - scan entry under cursor :Toa - scan entry under cursor, append to buffer :Tow - scan entry under cursor, new window :Tot - scan entry under cursor, new tabpage :Tpar N '-' - scan parent of current directory, N levels up in hierarchy :Tpara N - scan parent of current directory, append to buffer :Tparw N - scan parent of current directory, new window :Tpart N - scan parent of current directory, new tabpage
History commands:
:Tr '\}' - rescan current directory :Tn '\]' - next directory in history :Tp '\[' - previous directory in history :Th N - Nth directory in history :The - show history
Parse commands:
:Tsh '\S' - show actions to perform in existing or new message window :T '\P' - parse current or first edit window in tabpage, show result in edit window :Te - mark current window as edit window
Other commands:
:Tins ... - insert command arguments under cursor, utilizes tab completion :Temv [L1 L2] '\m' - add move action tag to current line or to lines from L1 to L2 (defaults to last line) :Temvo [L1 L2] '\M' - add move-overwrite action tag to current line or to lines from L1 to L2 (defaults to last line) :Tecp [L1 L2] '\c' - add copy action tag to current line or to lines from L1 to L2 (defaults to last line) :Tecpo [L1 L2] '\C' - add copy-overwrite action tag to current line or to lines from L1 to L2 (defaults to last line) :Term [L1 L2] '\r' - add remove action tag to current line or to lines from L1 to L2 (defaults to last line) :Tecreat [L1 L2] '\t' - add create action tag to current line or to lines from L1 to L2 (defaults to last line) :Tarm [L1 L2] '\R' - remove immedaiately current line or lines from L1 to L2 (defaults to last line) '<C-F>' - ctrl-F works only in insert mode, it will complete file path inserted after '>' character (it is intended to work with copy/move/links tags)
Textual representation's basic element is line which represents one entry. Line can be inactive or active. Inactive lines are ignored, active lines are parsed for actions. Line is active when its first non-blank character is line type tag (also called line tag). Line tag determines line type. Type determines how entry name is prepared and what is affected by actions specified in line.
Parsing process is accompanied by two important concepts - current working directory and current parent directory. They are prepended to each entry name and to each operand being file name.
Current working directory is used only when name or operand begins with './'. It never changes and is ofcourse the same as directory where Tfman was invoked.
Current parent directory is used for each name and operand which name do not begin with './' or '/'. It is set to current working directory when parsing begins. Later, during parsing process, when directory entry is encountered, its value changes according to indentation. If directory is not indented at all, it becomes new value of current parent directory. If it is less indented then previous directory, it is appended to one of parent's ancestors, as many levels up the hierarchy as many indentation steps it is retracted. If it is more indented then it is simply appended to parent directory.
Line is made of beforementioned line tag (mandatory), name field (mandatory), action tags and other fields. Fields are separated by spaces. Name field must be first non-action field after line tag or be enclosed in brackets '[name]'. Order of action tags and other fields is arbitrary. Some action tags take one operand, which can be file or non-file string. There can not be space between tag and operand.
LINE TAG NAME FIELD ACTION TAGS OTHER FIELDS # Dirname ~ user group | [entry_name] ~ :rwxrwxrwx user group
Actions are performed in fixed order, type by type. Same type actions are performed in order of appearance in text. Priority actions (those in priority lines) are performed before all normal actions and not in fixed order but in order of appearance.
Indentation is important when dealing with directories. If directory ('#') is more indented then previous directory, it is considered its subdirectory. If it is equally or less indented, then it is considered subdirectory of one of its ancestors. Indentation relate directly to which ancestor it is - each indentation step means one level up in hierarchy.
For example:
# Dir NAME IS: Dir # subdirX NAME IS: Dir/subdirX # Dir2 NAME IS: Dir2 # subdirB NAME IS: Dir2/subdirB # subdirC NAME IS: Dir2/subdirB/subdirC # subdirD NAME IS: Dir/subdirD # Dir3 NAME IS: Dir3
Entry names are prepared by prepending current parent directory to them, with exception of not indented directory entries - their names are left untouched. Other exceptions are names begining with '/' (absolute path) and names begining with './' (path relative to current working directory) - their names are left untouched too.
Operands undergo exactly the same preparation procedure.
Entry names (but not operands) are subject to brace expansion and globbing. Order is: brace expansion, name preparation, globbing.
# /Dir | [ name] >>operand BECOMES /Dir/name >>/Dir/operand | [ /name] >>/operand BECOMES /name >>/operand | [ ./name] >>./operand BECOMES ./name >>./operand | [ f{1,2}*] >>operand BECOMES /Dir/f1* >>/Dir/operand AND /Dir/f2* >>/Dir/operand AND GLOBBING IS PERFORMED AS LAST
Print text representation of /home and /root to stdout:
tfman /home /root
Write text representation of /home and /root to file txtrep.tfman
tfman /home /root > txtrep.tfman
Result of scanning file system by 'tfman' may look like this:
| [ this entry is rem.]* | [ no_action] . [this line is ignored] # /parentdir | [ move_it]>>here . [ ignored]->. | [ /copy_it]))./there
or like this:
# ./ | [ ./] d rwxr-sr-x 11 mh magazyn -- 4096 4096 a.2014-04-27 11:40:16 m.2014-04-27 11:40:16 c.2014-04-27 11:40:16 (none) | [ ../] d rwxr-sr-x 9 mh magazyn -- 4096 4096 a.2014-04-26 23:38:57 m.2014-01-31 07:59:21 c.2014-01-31 07:59:21 (none) | [ .bzr/] d rwxr-sr-x 6 mh magazyn -- 4096 4096 a.2014-04-26 23:38:57 m.2013-12-05 19:09:37 c.2013-12-05 19:09:37 (none) | [ trunk.br/] d rwxr-sr-x 20 mh magazyn -- 4096 4096 a.2014-04-26 20:56:32 m.2014-04-26 20:56:32 c.2014-04-26 20:56:32 (none) | [ CHANGELOG] - rw-r--r-- mh magazyn -- 1767 4096 a.2014-04-26 23:38:57 m.2014-04-26 20:55:44 c.2014-04-26 20:55:44 (none) # ./dir | [ Design.notes] - rw-r--r-- mh magazyn -- 13kB 16kB a.2014-04-26 23:38:57 m.2014-04-26 12:19:41 c.2014-04-26 12:19:41 (none) | [ FEATURES] - rw-r--r-- mh magazyn -- 3632 4096 a.2014-04-28 07:35:03 m.2014-04-28 07:34:28 c.2014-04-28 07:34:28 (none) | [FEATURES.html] - rw-r--r-- mh magazyn -- 4164 8192 a.2014-04-27 20:13:44 m.2014-04-27 20:13:43 c.2014-04-27 20:13:43 (none) | [ FEATURES.man] - rw-r--r-- mh magazyn -- 3547 4096 a.2014-04-28 07:35:04 m.2014-04-28 07:35:03 c.2014-04-28 07:35:03 (none) | [ curr.br] l rwxrwxrwx mh magazyn _>trunk.br/ -- 9 0 a.2014-04-27 19:55:46 m.2013-12-05 19:10:07 c.2013-12-05 19:10:07 (none) | [ stable.br] l rwxrwxrwx mh magazyn _>trunk.br/ -- 9 0 a.2014-04-27 19:55:46 m.2014-01-31 07:59:45 c.2014-01-31 07:59:45 (none)
Deduce operations from txtrep1.tfman and txtrep2.tfman files and perform them on file system (both examples do the same):
tfman txtrep1.tfman txtrep2.tfman
Scan directory recursively, open text editor to edit resulting textual representation and parse it after editor is closed:
tfm /Dir -R
This will move all files (and only files, not directories) containig 'tfm' anywhere in the name to common directory. Files may lay anywhere in the given directory tree:
$ tfman DIR -R -F=name,type | sed 's,\(^|.*tfm.*[^d]$\),\1 >>/tmp/common,' | tfman
author: Maciej Helminiak <tfman.project@opmbx.org>
copyright: (C) 2014 Maciej Helminiak, GNU GPL v3