filecon 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +16 -0
- data/README.md +95 -0
- data/bin/filecon +27 -17
- data/config.yaml +82 -10
- data/filecon.1 +39 -57
- data/lib/filecon/version.rb +1 -1
- data/lib/filecon.rb +46 -59
- metadata +9 -8
- data/config.rb +0 -91
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7999c20dbb6c7d75ff85343c955bb07794853b9bab8859132cf368b8f48735dd
|
|
4
|
+
data.tar.gz: 41bcfea5119ff2ebe534305a3eda418e825d9980dd329fb2dbf51cf783b35e29
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e0e7cb9f038a8f91adabda6258643dd9e2a11557b471740b2adb7fa42a9f93a0a027a62a659719e5370de463974083d4e5f5f3ee509ae782def11620624b2936
|
|
7
|
+
data.tar.gz: bcdc1bb5b7dfb36fe9bb43c4d8a50db175081d45aa548796e5482204056d4ae3e0d41fae0401ec547f32bd25ed840921c221e2c485d98a108285e5d21c0b5b81
|
data/LICENSE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 2, June 1991
|
|
3
|
+
|
|
4
|
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
5
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
6
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
7
|
+
of this license document, but changing it is not allowed.
|
|
8
|
+
|
|
9
|
+
Preamble
|
|
10
|
+
|
|
11
|
+
The licenses for most software are designed to take away your
|
|
12
|
+
freedom to share and change it. By contrast, the GNU General Public
|
|
13
|
+
License is intended to guarantee your freedom to share and change free
|
|
14
|
+
software--to make sure the software is free for all its users.
|
|
15
|
+
|
|
16
|
+
For the complete license text, see: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
data/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Filecon
|
|
2
|
+
|
|
3
|
+
A terminal-based file manager built on the [Typr](https://codeberg.org/typr/typr) terminal UI toolkit.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Directory browsing with MIME-type detection
|
|
8
|
+
- Customizable views (content preview, file types, line counts, etc.)
|
|
9
|
+
- Command execution with pipe support
|
|
10
|
+
- Directory and command history
|
|
11
|
+
- Configurable keybindings and colors
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gem install filecon
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or add to your Gemfile:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
gem "filecon", "~> 0.1"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
filecon [directory]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Keybindings
|
|
32
|
+
|
|
33
|
+
**Navigation**
|
|
34
|
+
- Arrow keys / Page Up/Down / Home / End — Navigate files
|
|
35
|
+
- Backspace — Go to parent directory
|
|
36
|
+
- Number keys — Open file with default command
|
|
37
|
+
- Tab — Cycle hint numbers for rows beyond the first 10
|
|
38
|
+
|
|
39
|
+
**Actions**
|
|
40
|
+
- `o` — Open list of all commands for selected file
|
|
41
|
+
- `c` — Command history
|
|
42
|
+
- `h` — Help
|
|
43
|
+
- `v` — Views
|
|
44
|
+
- `s` — Sort view
|
|
45
|
+
- `f` — Filter view
|
|
46
|
+
- `r` — Reset view
|
|
47
|
+
- `R` — Toggle recursive listing
|
|
48
|
+
|
|
49
|
+
**Marking**
|
|
50
|
+
- `m` — Mark file
|
|
51
|
+
- `M` — Mark range
|
|
52
|
+
- `a` — Mark all
|
|
53
|
+
- `i` — Invert mark
|
|
54
|
+
|
|
55
|
+
**Directory**
|
|
56
|
+
- `~` — Go to home directory
|
|
57
|
+
- `` ` `` — Open commands for current directory
|
|
58
|
+
- `d` — Directory history
|
|
59
|
+
|
|
60
|
+
**Other**
|
|
61
|
+
- Enter — Select / confirm
|
|
62
|
+
- Esc — Quit
|
|
63
|
+
|
|
64
|
+
### Configuration
|
|
65
|
+
|
|
66
|
+
Config is stored at `~/.config/filecon/config.yaml` (YAML format) and includes:
|
|
67
|
+
|
|
68
|
+
- Color settings (named colors, 8-bit palette, RGB triplets)
|
|
69
|
+
- Command definitions per MIME type
|
|
70
|
+
- View configurations
|
|
71
|
+
- History limits and terminal settings
|
|
72
|
+
|
|
73
|
+
**Command prefixes:**
|
|
74
|
+
|
|
75
|
+
- `|` — pipe output to status line
|
|
76
|
+
- `+` — run in a new terminal window
|
|
77
|
+
- `=` — display output in the text viewer
|
|
78
|
+
- `!` — evaluate as Ruby code
|
|
79
|
+
|
|
80
|
+
**Substitution variables:** `%name` (file path), `%dir` (directory picker), `%file` (file picker), `%str` (text input)
|
|
81
|
+
|
|
82
|
+
See `filecon(1)` or the installed `config.yaml` for full details.
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://codeberg.org/typr/filecon
|
|
88
|
+
cd filecon
|
|
89
|
+
bundle install
|
|
90
|
+
rake test
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
GPL-2.0-only
|
data/bin/filecon
CHANGED
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/ruby
|
|
2
2
|
|
|
3
|
+
require_relative "../lib/filecon"
|
|
4
|
+
|
|
3
5
|
begin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
path = Filecon::PATH
|
|
7
|
+
FileUtils.mkpath path unless File.exist? path
|
|
8
|
+
FileUtils.cp File.join(__dir__, "../config.yaml"), path unless File.exist? File.join(path, "config.yaml")
|
|
9
|
+
dir_history_path = File.join(path, "dir_history")
|
|
10
|
+
cmd_history_path = File.join(path, "cmd_history")
|
|
11
|
+
FileUtils.touch dir_history_path
|
|
12
|
+
FileUtils.touch cmd_history_path
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
config = YAML.safe_load(File.read(File.join(path, "config.yaml")), permitted_classes: [Symbol]) || {}
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Typr.init( color: config[:colors][:default] )
|
|
16
|
+
term = config["term"] || ENV["TERM"] || ""
|
|
17
|
+
term_hold = term + (config["term_hold"] || " --hold")
|
|
18
|
+
|
|
19
|
+
Typr.init config["colors"]["default"]
|
|
16
20
|
Typr.clear
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
|
|
22
|
+
app = Filecon::App.new( right: -1, bottom: -1,
|
|
23
|
+
dir_history: File.read(dir_history_path).split($/),
|
|
24
|
+
cmd_history: File.read(cmd_history_path).split($/),
|
|
20
25
|
directory: ARGV.first, keymap: { open_file: ?o, cmd_history: ?c },
|
|
21
|
-
colors: { cmd_history: :red }.merge( config[
|
|
22
|
-
views: config[
|
|
23
|
-
commands: config[
|
|
26
|
+
colors: { cmd_history: :red }.merge( config["colors"] || {} ),
|
|
27
|
+
views: config["views"] || {},
|
|
28
|
+
commands: config["commands"] || {},
|
|
24
29
|
term: term,
|
|
25
|
-
term_hold: term_hold
|
|
30
|
+
term_hold: term_hold,
|
|
31
|
+
max_history: config["max_history"] || 100,
|
|
32
|
+
dir_history_path: dir_history_path,
|
|
33
|
+
cmd_history_path: cmd_history_path )
|
|
34
|
+
Typr.on_resize { app.draw }
|
|
35
|
+
app.fly
|
|
26
36
|
rescue => e
|
|
27
37
|
File.write File.join(Dir.tmpdir, "filecon_error.log"),
|
|
28
38
|
"#{e.class}: #{e.message}\n#{e.backtrace.first(10).join("\n")}"
|
data/config.yaml
CHANGED
|
@@ -96,17 +96,19 @@ colors:
|
|
|
96
96
|
commands:
|
|
97
97
|
default:
|
|
98
98
|
open: "|xdg-open %name"
|
|
99
|
-
|
|
99
|
+
disk_use: "|du -hs %name"
|
|
100
100
|
info: "=file %name"
|
|
101
|
-
copy: "
|
|
101
|
+
copy: "|rsync --progress %name %dir"
|
|
102
102
|
move: "|mv %name %dir"
|
|
103
103
|
delete: "|rm %name"
|
|
104
104
|
|
|
105
105
|
directory:
|
|
106
106
|
cd: "!cd %name"
|
|
107
|
-
|
|
107
|
+
new_file: "|micro %str"
|
|
108
|
+
new_dir: "|mkdir %str"
|
|
109
|
+
|
|
108
110
|
text:
|
|
109
|
-
view: "+
|
|
111
|
+
view: "+moor %name"
|
|
110
112
|
edit: "+micro %name"
|
|
111
113
|
count: "|wc -l %name"
|
|
112
114
|
|
|
@@ -117,7 +119,7 @@ commands:
|
|
|
117
119
|
run: "+ruby %name"
|
|
118
120
|
|
|
119
121
|
html:
|
|
120
|
-
terminal: "+
|
|
122
|
+
terminal: "+cha %name"
|
|
121
123
|
graphics: "|vimb %name"
|
|
122
124
|
|
|
123
125
|
image:
|
|
@@ -138,6 +140,72 @@ commands:
|
|
|
138
140
|
help: "=%name --help"
|
|
139
141
|
manual: "+man %name"
|
|
140
142
|
|
|
143
|
+
"x-python":
|
|
144
|
+
run: "+python3 %name"
|
|
145
|
+
|
|
146
|
+
"x PERL":
|
|
147
|
+
run: "+perl %name"
|
|
148
|
+
|
|
149
|
+
"x-shellscript":
|
|
150
|
+
run: "+bash %name"
|
|
151
|
+
|
|
152
|
+
"x-javascript":
|
|
153
|
+
run: "+node %name"
|
|
154
|
+
|
|
155
|
+
"x-php":
|
|
156
|
+
run: "+php %name"
|
|
157
|
+
|
|
158
|
+
"x-go":
|
|
159
|
+
run: "+go run %name"
|
|
160
|
+
|
|
161
|
+
"x-rust":
|
|
162
|
+
run: "+rustc %name && ./a.out"
|
|
163
|
+
|
|
164
|
+
java-archive:
|
|
165
|
+
run: "+java -jar %name"
|
|
166
|
+
|
|
167
|
+
"x-c":
|
|
168
|
+
run: "+gcc %name && ./a.out"
|
|
169
|
+
|
|
170
|
+
"x-c++":
|
|
171
|
+
run: "+g++ %name && ./a.out"
|
|
172
|
+
|
|
173
|
+
markdown:
|
|
174
|
+
view: "+glow %name"
|
|
175
|
+
edit: "+micro %name"
|
|
176
|
+
|
|
177
|
+
json:
|
|
178
|
+
view: "=cat %name | jq ."
|
|
179
|
+
|
|
180
|
+
"zip":
|
|
181
|
+
list: "|unzip -l %name"
|
|
182
|
+
extract: "|unzip %name -d %dir"
|
|
183
|
+
|
|
184
|
+
"x-gzip":
|
|
185
|
+
list: "|tar -tzf %name"
|
|
186
|
+
extract: "|tar -xzf %name -C %dir"
|
|
187
|
+
|
|
188
|
+
"x-bzip2":
|
|
189
|
+
list: "|tar -tjf %name"
|
|
190
|
+
extract: "|tar -xjf %name -C %dir"
|
|
191
|
+
|
|
192
|
+
"x-xz":
|
|
193
|
+
list: "|tar -tJf %name"
|
|
194
|
+
extract: "|tar -xJf %name -C %dir"
|
|
195
|
+
|
|
196
|
+
"x-tar":
|
|
197
|
+
list: "|tar -tf %name"
|
|
198
|
+
extract: "|tar -xf %name -C %dir"
|
|
199
|
+
|
|
200
|
+
"epub+zip":
|
|
201
|
+
view: "+folio %name"
|
|
202
|
+
|
|
203
|
+
"font-ttf":
|
|
204
|
+
view: "=fc-query %name | head -20"
|
|
205
|
+
|
|
206
|
+
"font-otf":
|
|
207
|
+
view: "=fc-query %name | head -20"
|
|
208
|
+
|
|
141
209
|
|
|
142
210
|
# =============================================================================
|
|
143
211
|
# VIEWS
|
|
@@ -148,9 +216,11 @@ commands:
|
|
|
148
216
|
#
|
|
149
217
|
# View values can be:
|
|
150
218
|
# - true Use the built-in column for this field
|
|
151
|
-
# - A string
|
|
219
|
+
# - A string Command to execute (with %name substitution)
|
|
152
220
|
# - A symbol Reference to a system field (e.g., :size, :type, :subtype)
|
|
153
221
|
#
|
|
222
|
+
# Prefix ! to evaluate as Ruby, prefix | for shell commands.
|
|
223
|
+
#
|
|
154
224
|
# Available system fields:
|
|
155
225
|
# target, permissions, owner, group, size,
|
|
156
226
|
# accessed, modified, created, type, subtype
|
|
@@ -162,15 +232,17 @@ commands:
|
|
|
162
232
|
|
|
163
233
|
views:
|
|
164
234
|
content:
|
|
165
|
-
content: "
|
|
235
|
+
content: "head -n 50 %name"
|
|
166
236
|
|
|
167
237
|
filetype:
|
|
168
238
|
type: true
|
|
169
239
|
subtype: true
|
|
170
|
-
description: "
|
|
240
|
+
description: "file -b %name"
|
|
171
241
|
|
|
172
|
-
|
|
173
|
-
|
|
242
|
+
count:
|
|
243
|
+
chars: "wc -m %name"
|
|
244
|
+
words: "wc -w %name"
|
|
245
|
+
lines: "wc -l %name"
|
|
174
246
|
|
|
175
247
|
whatis:
|
|
176
248
|
whatis: "!open('|whatis %name 2>&1').read.match(/[-:]\\s(.*)$/)[1]"
|
data/filecon.1
CHANGED
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
.TH FILECON 1 "2026-07-
|
|
1
|
+
.TH FILECON 1 "2026-07-27" "filecon 0.1.1" "User Commands"
|
|
2
2
|
.SH NAME
|
|
3
|
-
filecon \- interactive terminal file manager with
|
|
3
|
+
filecon \- interactive terminal file manager with hint-based navigation
|
|
4
4
|
.SH SYNOPSIS
|
|
5
5
|
.B filecon
|
|
6
6
|
.RI [ directory ]
|
|
7
7
|
.SH DESCRIPTION
|
|
8
8
|
.B filecon
|
|
9
9
|
is a terminal-based file manager built on top of the
|
|
10
|
-
.B
|
|
10
|
+
.B Typr
|
|
11
11
|
Ruby library. It displays directory entries in a grid with columns for name,
|
|
12
12
|
symlink target, permissions, owner, group, size, timestamps, and MIME type.
|
|
13
13
|
Directories appear first in yellow; files are colored by MIME type.
|
|
14
14
|
.PP
|
|
15
|
-
Navigation is done by typing hint characters (1\-9, 0) displayed
|
|
16
|
-
start of each row, enabling fast keyboard-only operation.
|
|
15
|
+
Navigation is done by typing hint characters (1\-9, 0, then letters) displayed
|
|
16
|
+
at the start of each row, enabling fast keyboard-only operation.
|
|
17
17
|
.SH OPTIONS
|
|
18
18
|
.TP
|
|
19
19
|
.I directory
|
|
20
20
|
Starting directory to browse. Defaults to the current working directory.
|
|
21
21
|
.SH NAVIGATION KEYS
|
|
22
22
|
.TP
|
|
23
|
+
.B Arrow keys / Page Up/Down / Home / End
|
|
24
|
+
Navigate files
|
|
25
|
+
.TP
|
|
26
|
+
.B Backspace
|
|
27
|
+
Go to parent directory
|
|
28
|
+
.TP
|
|
29
|
+
.B Number keys
|
|
30
|
+
Open file with default command
|
|
31
|
+
.TP
|
|
32
|
+
.B Tab
|
|
33
|
+
Cycle hint numbers for rows beyond the first 10
|
|
34
|
+
.TP
|
|
23
35
|
.B h
|
|
24
36
|
Show help
|
|
25
37
|
.TP
|
|
@@ -48,7 +60,7 @@ Filter rows
|
|
|
48
60
|
Recurse directory tree
|
|
49
61
|
.TP
|
|
50
62
|
.B `
|
|
51
|
-
|
|
63
|
+
Open commands for current directory
|
|
52
64
|
.TP
|
|
53
65
|
.B ~
|
|
54
66
|
Navigate to home directory
|
|
@@ -61,32 +73,18 @@ Quit
|
|
|
61
73
|
.SH FILECON KEYS
|
|
62
74
|
.TP
|
|
63
75
|
.B o
|
|
64
|
-
Open
|
|
76
|
+
Open list of all commands for selected file
|
|
65
77
|
.TP
|
|
66
78
|
.B c
|
|
67
79
|
Browse command history
|
|
68
|
-
.SH COMMANDS
|
|
69
|
-
Commands are triggered by the [o]pen action on a file. The command executed
|
|
70
|
-
depends on the file's MIME type and subtype. If multiple commands match the
|
|
71
|
-
file type, a picker is shown.
|
|
72
|
-
.SS Command Prefixes
|
|
73
|
-
.TP
|
|
74
|
-
.B |
|
|
75
|
-
Internal execution (output piped to a viewer within the UI)
|
|
76
|
-
.TP
|
|
77
|
-
.B +
|
|
78
|
-
Terminal execution (spawns an external terminal program, e.g. mpv, nano)
|
|
79
|
-
.TP
|
|
80
|
-
.B !
|
|
81
|
-
Ruby code evaluation (result displayed in UI)
|
|
82
80
|
.SH CONFIGURATION
|
|
83
81
|
On first run, the default
|
|
84
|
-
.B config.
|
|
85
|
-
is copied from the installation directory to
|
|
82
|
+
.B config.yaml
|
|
83
|
+
(YAML format) is copied from the installation directory to
|
|
86
84
|
.BR ~/.config/filecon/ .
|
|
87
85
|
.SS Config File Locations
|
|
88
86
|
.TP
|
|
89
|
-
.B ~/.config/filecon/config.
|
|
87
|
+
.B ~/.config/filecon/config.yaml
|
|
90
88
|
Main configuration (colors, commands, views, term)
|
|
91
89
|
.TP
|
|
92
90
|
.B ~/.config/filecon/dir_history
|
|
@@ -94,6 +92,19 @@ Directory navigation history
|
|
|
94
92
|
.TP
|
|
95
93
|
.B ~/.config/filecon/cmd_history
|
|
96
94
|
Command execution history
|
|
95
|
+
.SS Command Prefixes
|
|
96
|
+
.TP
|
|
97
|
+
.B |
|
|
98
|
+
Pipe output to status line
|
|
99
|
+
.TP
|
|
100
|
+
.B +
|
|
101
|
+
Run in a new terminal window
|
|
102
|
+
.TP
|
|
103
|
+
.B =
|
|
104
|
+
Display output in the text viewer
|
|
105
|
+
.TP
|
|
106
|
+
.B !
|
|
107
|
+
Evaluate as Ruby code
|
|
97
108
|
.SS Command Substitutions
|
|
98
109
|
.TP
|
|
99
110
|
.B %name
|
|
@@ -107,35 +118,6 @@ Prompt to pick a file
|
|
|
107
118
|
.TP
|
|
108
119
|
.B %str
|
|
109
120
|
Prompt for a text string (line input)
|
|
110
|
-
.SH CONFIGURATION EXAMPLES
|
|
111
|
-
.nf
|
|
112
|
-
colors: {
|
|
113
|
-
types: {
|
|
114
|
-
directory: :yellow,
|
|
115
|
-
image: :blue,
|
|
116
|
-
video: :cyan,
|
|
117
|
-
audio: :green,
|
|
118
|
-
text: 146,
|
|
119
|
-
'x-pie-executable': :red
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
commands: {
|
|
124
|
-
default: { info: '|file %name', copy: '+rsync --progress %name %dir' },
|
|
125
|
-
text: { view: '+less %name', edit: '+nano %name' },
|
|
126
|
-
html: { terminal: '+w3m %name', graphics: '|vimb %name' },
|
|
127
|
-
image: { play: '|mpv %name' },
|
|
128
|
-
video: { play: '|mpv %name' },
|
|
129
|
-
pdf: { view: '|mupdf %name' },
|
|
130
|
-
'x-pie-executable': { run: '|%name', run_terminal: '+%name',
|
|
131
|
-
help: '+%name --help', manual: '+man %name' }
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
views: {
|
|
135
|
-
content: { content: '|head %name' },
|
|
136
|
-
whatis: { whatis: "!open('|whatis %name 2>&1').read.match(...)..." }
|
|
137
|
-
}
|
|
138
|
-
.fi
|
|
139
121
|
.SH VIEWS
|
|
140
122
|
Column views control which fields are shown for each file entry.
|
|
141
123
|
.TP
|
|
@@ -145,11 +127,11 @@ Displays first lines of file content via head(1)
|
|
|
145
127
|
.B whatis
|
|
146
128
|
Shows man page description via whatis(1)
|
|
147
129
|
.PP
|
|
148
|
-
Custom views can be defined in config.
|
|
130
|
+
Custom views can be defined in config.yaml by adding entries to the views hash.
|
|
149
131
|
.SH ENVIRONMENT
|
|
150
132
|
.TP
|
|
151
133
|
.B TERM
|
|
152
|
-
Terminal type used for
|
|
134
|
+
Terminal type used for terminal initialization.
|
|
153
135
|
.TP
|
|
154
136
|
.B HOME
|
|
155
137
|
Used to resolve ~ and config directory path (~/.config/filecon/).
|
|
@@ -160,12 +142,12 @@ Configuration and history directory
|
|
|
160
142
|
.SH SEE ALSO
|
|
161
143
|
.BR mpv (1),
|
|
162
144
|
.BR less (1),
|
|
163
|
-
.BR
|
|
145
|
+
.BR micro (1),
|
|
164
146
|
.BR file (1),
|
|
165
147
|
.BR rsync (1),
|
|
166
148
|
.BR whatis (1),
|
|
167
149
|
.BR typr (1)
|
|
168
150
|
.SH AUTHOR
|
|
169
|
-
|
|
151
|
+
Kilian Reitmayr
|
|
170
152
|
.SH LICENSE
|
|
171
153
|
GPL-2.0-only
|
data/lib/filecon/version.rb
CHANGED
data/lib/filecon.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require "fileutils"
|
|
2
|
-
require "open3"
|
|
3
2
|
require "yaml"
|
|
4
3
|
|
|
5
4
|
begin
|
|
@@ -12,49 +11,14 @@ require_relative "filecon/version"
|
|
|
12
11
|
|
|
13
12
|
module Filecon
|
|
14
13
|
PATH = File.join(ENV["HOME"], ".config/filecon/")
|
|
15
|
-
|
|
16
|
-
def self.dir_history_path
|
|
17
|
-
File.join(PATH, "dir_history")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.cmd_history_path
|
|
21
|
-
File.join(PATH, "cmd_history")
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def self.setup_config
|
|
25
|
-
FileUtils.mkpath PATH unless File.exist? PATH
|
|
26
|
-
FileUtils.cp File.join(__dir__, "../config.yaml"), PATH unless File.exist? File.join(PATH, "config.yaml")
|
|
27
|
-
FileUtils.touch dir_history_path
|
|
28
|
-
FileUtils.touch cmd_history_path
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.deep_symbolize_keys(obj)
|
|
32
|
-
case obj
|
|
33
|
-
when Hash
|
|
34
|
-
obj.each_with_object({}) { |(k, v), h| h[k.to_sym] = deep_symbolize_keys(v) }
|
|
35
|
-
when Array
|
|
36
|
-
obj.map { |v| deep_symbolize_keys(v) }
|
|
37
|
-
else
|
|
38
|
-
obj
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def self.config
|
|
43
|
-
config_path = File.join(PATH, "config.yaml")
|
|
44
|
-
if File.exist?(config_path)
|
|
45
|
-
deep_symbolize_keys(YAML.safe_load(File.read(config_path), permitted_classes: [Symbol]))
|
|
46
|
-
else
|
|
47
|
-
{}
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
14
|
end
|
|
51
15
|
|
|
52
16
|
class Filecon::App < Typr::Browser
|
|
53
17
|
include Typr
|
|
54
18
|
|
|
55
19
|
def cd dir, append=false; super
|
|
56
|
-
File.write
|
|
57
|
-
@dir_history[0
|
|
20
|
+
File.write @dir_history_path,
|
|
21
|
+
@dir_history[0..@max_history].join($/)
|
|
58
22
|
return
|
|
59
23
|
end
|
|
60
24
|
|
|
@@ -64,8 +28,13 @@ class Filecon::App < Typr::Browser
|
|
|
64
28
|
view = @views[id]
|
|
65
29
|
return super if view.is_a? Array
|
|
66
30
|
data = @data.map.with_index{ |row, id| row + view.values.map{ |cmd|
|
|
67
|
-
|
|
68
|
-
|
|
31
|
+
next unless cmd.is_a?(String)
|
|
32
|
+
built = build cmd, id
|
|
33
|
+
io = built[0] == ?! ?
|
|
34
|
+
StringIO.new( eval( built[1..-1] ).to_s ) :
|
|
35
|
+
open( ?| + built + " 2>&1" )
|
|
36
|
+
io.read(width).to_s.scrub.gsub(/[\n\t]/, ?|)
|
|
37
|
+
}.compact }
|
|
69
38
|
@sequence = [ NAME ] + view.keys.map{ |head|
|
|
70
39
|
@header.index(head.to_s) || (@header += [head.to_s]; @header.count-1) }
|
|
71
40
|
clear
|
|
@@ -73,15 +42,17 @@ class Filecon::App < Typr::Browser
|
|
|
73
42
|
@current = id
|
|
74
43
|
end
|
|
75
44
|
|
|
76
|
-
def open_file id=nil, default=false
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
45
|
+
def open_file id=nil, default=false, types=nil
|
|
46
|
+
unless id || types
|
|
47
|
+
return unless id ||= @selected[:rows].empty? ?
|
|
48
|
+
@user.ask( open:[self, :row] ) : @selected[:rows]
|
|
49
|
+
end
|
|
50
|
+
types ||= if id.is_a? Array
|
|
80
51
|
eval id.map{ |id| @data[id].values_at(SUBTYPE,TYPE).to_s }.join(?&)
|
|
81
52
|
else @data[id].values_at(SUBTYPE, TYPE)
|
|
82
|
-
end - [??] + [
|
|
53
|
+
end - [??] + ["default"]
|
|
83
54
|
|
|
84
|
-
commands = @commands.values_at( *types
|
|
55
|
+
commands = @commands.values_at( *types ).map(&:to_a).flatten 1
|
|
85
56
|
cmd = if default; commands.first.last
|
|
86
57
|
else move left+1,top+1
|
|
87
58
|
if id.is_a?(Array); show "#{id.count.to_s} files: (#{
|
|
@@ -94,23 +65,25 @@ class Filecon::App < Typr::Browser
|
|
|
94
65
|
commands[ cmd ].last
|
|
95
66
|
end
|
|
96
67
|
cmd = build cmd, id
|
|
97
|
-
if cmd
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
68
|
+
if cmd[0] == ?|
|
|
69
|
+
display = cmd[1..-1]
|
|
70
|
+
io = run( cmd, true )
|
|
71
|
+
output = io.read.to_s.scrub.strip
|
|
72
|
+
@user.draw "> #{display} : #{output.lines.last}"
|
|
73
|
+
Typr.read :key
|
|
74
|
+
else
|
|
75
|
+
run( cmd, cmd[0..2] != '!cd' )
|
|
76
|
+
draw
|
|
77
|
+
end
|
|
106
78
|
end
|
|
107
79
|
|
|
108
80
|
def build str, id
|
|
109
81
|
cmd = ""
|
|
110
82
|
while str[/\%(name|dir|file|str)/]
|
|
111
|
-
|
|
83
|
+
cmd += $`
|
|
112
84
|
case $&
|
|
113
|
-
when '%name'; cmd += ?"+( id.
|
|
85
|
+
when '%name'; cmd += ?"+( id.nil? ? @directory :
|
|
86
|
+
id.is_a?( Array ) ? id.map{ |id|
|
|
114
87
|
@directory + @data[id][NAME] }.join('" "') :
|
|
115
88
|
@directory + @data[id][NAME] )+?"
|
|
116
89
|
when '%dir'; cmd += ?"+(pick :directory)+?"
|
|
@@ -136,7 +109,7 @@ class Filecon::App < Typr::Browser
|
|
|
136
109
|
if store
|
|
137
110
|
@cmd_history.unshift cmd
|
|
138
111
|
@cmd_history.uniq!
|
|
139
|
-
File.write
|
|
112
|
+
File.write @cmd_history_path, @cmd_history[0..@max_history].join($/)
|
|
140
113
|
end
|
|
141
114
|
return io
|
|
142
115
|
end
|
|
@@ -145,11 +118,23 @@ class Filecon::App < Typr::Browser
|
|
|
145
118
|
colors: { columns: [ @colors[:cmd_history] ] } } ).pick(:row), true
|
|
146
119
|
end
|
|
147
120
|
|
|
121
|
+
def help
|
|
122
|
+
info = "\nFILECON - a terminal file manager\n\n" \
|
|
123
|
+
"HINTS: press a number (1-9,0) to open that file with its default action.\n" \
|
|
124
|
+
" TAB cycles pages of hints.\n\n" \
|
|
125
|
+
"CONFIG: ~/.config/filecon/config.yaml\n\n" \
|
|
126
|
+
"KEYBINDINGS:\n\n" + @user.bindings.join(?\n)
|
|
127
|
+
Text.new( input: info, top:2, left:3, right: -3, bottom: -3, header: "HELP",
|
|
128
|
+
colors: { header: [:black,:white], border:[:white,:grey10] },
|
|
129
|
+
border: :light ).pick :none
|
|
130
|
+
end
|
|
131
|
+
|
|
148
132
|
def initialize args={}
|
|
149
133
|
super
|
|
150
134
|
@user.bindings.insert 1, "[o]pen"
|
|
151
135
|
@user.bindings.insert 7, "[c]ommands"
|
|
152
136
|
@user.draw
|
|
137
|
+
|
|
153
138
|
end
|
|
154
139
|
|
|
155
140
|
def fly
|
|
@@ -157,12 +142,14 @@ class Filecon::App < Typr::Browser
|
|
|
157
142
|
draw
|
|
158
143
|
draw_hints :rows
|
|
159
144
|
key = Typr.read :key
|
|
160
|
-
|
|
145
|
+
next unless key
|
|
161
146
|
case key
|
|
162
147
|
when KEY_ESCAPE; exit
|
|
148
|
+
when ?`; open_file nil, false, ["directory", "inode"] - [??] + ["default"]
|
|
163
149
|
else
|
|
164
150
|
id = send( key )
|
|
165
151
|
open_file id, true if id.is_a? Integer
|
|
152
|
+
@user.reset
|
|
166
153
|
end
|
|
167
154
|
end
|
|
168
155
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: filecon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kilian Reitmayr
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: typr
|
|
@@ -56,16 +56,16 @@ dependencies:
|
|
|
56
56
|
name: rake
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
61
|
+
version: '13.0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
68
|
+
version: '13.0'
|
|
69
69
|
description: A terminal-based file manager with customizable views, commands, and
|
|
70
70
|
MIME-type based file operations, built on the Typr terminal UI toolkit.
|
|
71
71
|
email:
|
|
@@ -75,13 +75,14 @@ executables:
|
|
|
75
75
|
extensions: []
|
|
76
76
|
extra_rdoc_files: []
|
|
77
77
|
files:
|
|
78
|
+
- LICENSE
|
|
79
|
+
- README.md
|
|
78
80
|
- bin/filecon
|
|
79
|
-
- config.rb
|
|
80
81
|
- config.yaml
|
|
81
82
|
- filecon.1
|
|
82
83
|
- lib/filecon.rb
|
|
83
84
|
- lib/filecon/version.rb
|
|
84
|
-
homepage: https://
|
|
85
|
+
homepage: https://codeberg.org/typr/filecon
|
|
85
86
|
licenses:
|
|
86
87
|
- GPL-2.0-only
|
|
87
88
|
metadata: {}
|
data/config.rb
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
term: ENV["TERM"],
|
|
3
|
-
term_hold: ENV["TERM"] + ' --hold',
|
|
4
|
-
max_history: 100,
|
|
5
|
-
|
|
6
|
-
#########################################################################
|
|
7
|
-
#
|
|
8
|
-
# COLORS
|
|
9
|
-
#
|
|
10
|
-
# standard colors: black red green yellow blue magenta cyan white grey
|
|
11
|
-
# grey shades: grey with percentage ( e.g. :grey62 for 62% grey )
|
|
12
|
-
# 8bit color: 0 - 255
|
|
13
|
-
# rgb values: [ 0-255, 0-255, 0-255 ]
|
|
14
|
-
#
|
|
15
|
-
#########################################################################
|
|
16
|
-
|
|
17
|
-
colors: {
|
|
18
|
-
types: {
|
|
19
|
-
default: [ :white, :black ],
|
|
20
|
-
image: :blue,
|
|
21
|
-
audio: :green,
|
|
22
|
-
video: :cyan,
|
|
23
|
-
directory: :yellow,
|
|
24
|
-
'x-pie-executable': :red
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
#########################################################################
|
|
29
|
-
#
|
|
30
|
-
# COMMANDS
|
|
31
|
-
#
|
|
32
|
-
# execution type:
|
|
33
|
-
#
|
|
34
|
-
# | output in status line
|
|
35
|
-
# = output in text space
|
|
36
|
-
# + run in new terminal
|
|
37
|
-
# ! ruby code evaluation
|
|
38
|
-
#
|
|
39
|
-
# substitutions:
|
|
40
|
-
#
|
|
41
|
-
# %name - selected file name
|
|
42
|
-
# %dir - pick a directory
|
|
43
|
-
# %file - pick a file
|
|
44
|
-
# %str - read string
|
|
45
|
-
#
|
|
46
|
-
########################################################################
|
|
47
|
-
|
|
48
|
-
commands: {
|
|
49
|
-
# default: { copy: 'cp %s %s' },#, move: 'mv %s %s' },
|
|
50
|
-
# default:{ list: '!Grid.new({input: %w[%name] }).pick', open: '|xdg-open',
|
|
51
|
-
default:{ open: '|xdg-open %name', diskuse: '|du -hs %name',
|
|
52
|
-
info: '=file %name', copy: '+rsync --progress %name %dir',
|
|
53
|
-
move: '|mv %name %dir', delete: '|rm %name ' },
|
|
54
|
-
directory:{ cd: '!cd %name ' },
|
|
55
|
-
text:{ view: '+less %name', edit: '+micro %name',
|
|
56
|
-
count: '|wc -l %name' },
|
|
57
|
-
troff: { manual: '+man %name' },
|
|
58
|
-
"x-ruby":{ run: '+ruby %name' },
|
|
59
|
-
html:{terminal: '+w3m %name',graphics: '|vimb %name' },
|
|
60
|
-
image:{ play: '|mpv %name' },
|
|
61
|
-
video:{ play: '|mpv %name' },
|
|
62
|
-
audio:{ play: '|mpv %name' },
|
|
63
|
-
pdf:{ view: '|mupdf %name' },
|
|
64
|
-
# epub: :pdf
|
|
65
|
-
'x-pie-executable':{ run: '|%name', run_terminal: '+%name',
|
|
66
|
-
help: '=%name --help', manual: '+man %name' }
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
#######################################################################
|
|
70
|
-
#
|
|
71
|
-
# VIEWS
|
|
72
|
-
#
|
|
73
|
-
# system infos :
|
|
74
|
-
# target permissions owner group size accessed modified created type subtype
|
|
75
|
-
#
|
|
76
|
-
######################################################################
|
|
77
|
-
|
|
78
|
-
views: {
|
|
79
|
-
# detail_ls: { ls: '|ls -l %s' },
|
|
80
|
-
# mimetypes: { type: '!type', subtype: '!subtype' },
|
|
81
|
-
# type_detail: { info: %w[ size access ], type: '|file -b %s' },
|
|
82
|
-
# type_detail:{ size: :size, type: '|file -b %name' },
|
|
83
|
-
content:{ content: '|head -n 50 %name' },
|
|
84
|
-
filetype:{ type: true, subtype: true, description: '|file -b %name' },
|
|
85
|
-
lines:{ lines: '|wc -l %name' },
|
|
86
|
-
|
|
87
|
-
# content:{ content: '!`head -n 50 %name `.gsub $/, ?|' },
|
|
88
|
-
whatis:{ whatis: #'|whatis %name' }
|
|
89
|
-
'!open(\'|whatis %name 2>&1\').read.match(/[-:]\s(.*)$/)[1] ' }
|
|
90
|
-
# "!open(\"|whatis %name 2>&1\").read.match(/[-:]\s(.*)$/)[1] " }
|
|
91
|
-
}
|