filecon 0.6.0 → 0.7.1
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/CHANGELOG.md +16 -0
- data/README.md +3 -3
- data/config.yaml +2 -19
- data/filecon.1 +1 -1
- data/lib/filecon/version.rb +1 -1
- data/lib/filecon.rb +23 -9
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 39b5d282890f2a71e7d928cd772e5e4d1c539bee82f49bd20a078f2fdb3c42d6
|
|
4
|
+
data.tar.gz: 654d4cecbf3fadccd929459f6488ff7795006db209d63da38b7e7387a30c312c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88defb4160b8ff0d433f9de6d01a27c631f8514ac54307bf159bccc64f9506abc179e97fe66dd82a94b46d9d288654a13bd8dac28241a54912b5d403c57c43ea
|
|
7
|
+
data.tar.gz: 3f601ebdf45b5015199ee27d9e809d31bee82cbad121d8787562af3d9c74b56a337f6cc6157994a12f0908121bf84f741ddff90afd09e7e6304f0b673e787ab6
|
data/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## [vx.y.z] — __DATE__
|
|
4
4
|
|
|
5
|
+
## [v0.7.1] — 2026-10-13
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Windowed commands with an unlaunchable terminal report on the status line (naming the binary and the `+` config key) instead of failing silently; the terminal is exec'd directly so the OS reports a missing binary
|
|
9
|
+
- `=cmd` output keeps split multibyte characters intact — pipe chunks are byte slices, so a UTF-8 character could arrive in two halves; the streaming loop now buffers trailing high bytes until the character completes (genuinely broken bytes still fall back to replacement), and every emitted span is valid UTF-8
|
|
10
|
+
- Pipe results stay on the status line — the bottom line now shows whatever the last action left until the next keypress restores the bar, so the first line of `|` output remains visible instead of being repainted over immediately
|
|
11
|
+
|
|
12
|
+
## [v0.7.0] — 2026-10-12
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Requires typr `~> 1.9` — the `!narrow` binding calls `Browser#narrow`, which does not exist in 1.8.x
|
|
16
|
+
- Dropped the two `Typr.flush_overtype` calls (custom view rebuild, command spawn) — typr's overtype guard now lives entirely behind `Grid#pick` selections, so there is nothing for filecon to arm or flush; keys typed during slow rebuilds count as intentional input at the next read
|
|
17
|
+
- `|` commands keep running after filecon exits: pipe writers spawn in their own process group (immune to the exit-time hangup) and the pipe is handed to a detached null-drainer, so writers never hit a closed pipe either
|
|
18
|
+
- Windowed (`+`) commands send the emulator's stderr to /dev/null, so terminal chatter (kitty parse errors, keyboard-protocol notices) no longer prints over the view; the inner command keeps its own terminal for its own errors
|
|
19
|
+
|
|
5
20
|
## [v0.6.0] — 2026-10-11
|
|
6
21
|
|
|
7
22
|
### Changed
|
|
23
|
+
- Bottom-bar live narrowing is labeled `[/]:narrow` and wired to `!narrow` (was `[/]:search` / `!search`), matching what it does; `search` now means only find-in-text
|
|
8
24
|
- Help panels use round borders joined by T-pieces at the seam
|
|
9
25
|
- All shell strings run under `bash -c` (never `sh`) through one `shell` helper; aliases and rc files do not resolve anywhere. Startup aborts cleanly without bash
|
|
10
26
|
- Help headers render from the configured `header:` color and command names blue from inline palette codes, which survive rebuilds and resizes under paint-once text
|
data/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Filecon is a file and command manager that lives between terminal and shell, bui
|
|
|
9
9
|
Filecon is designed to be **intuitive**, **complete**, **powerful**, and **fast**. The whole interface is built around that principle:
|
|
10
10
|
|
|
11
11
|
- **Hint navigation** — every visible row carries a number hint (1–9, 0); pressing it acts on that row immediately, no cursor movement needed.
|
|
12
|
-
- **Live
|
|
12
|
+
- **Live narrowing in popups** — popups open in `/` narrow mode; type to narrow the list, then pick one of the few remaining results with a number. return key selects the first. auto selection of a single filter result.
|
|
13
13
|
- **Frequency-ordered history** — directory and command history are ranked by use count, so the most likely choice is always near the top.
|
|
14
14
|
|
|
15
15
|
Filecon runs on Typr, whose self-contained terminal layer ships its own precompiled terminfo key table and MIME-type database in the gem — no ncurses or external tooling required — so Filecon works on any raw, ANSI-capable terminal (including Termux).
|
|
@@ -18,7 +18,7 @@ Filecon runs on Typr, whose self-contained terminal layer ships its own precompi
|
|
|
18
18
|
|
|
19
19
|
- **Directory browsing with MIME-type detection** — files are typed from a packaged MIME database and colored accordingly, with optional `file --mime-type` magic detection for unknowns
|
|
20
20
|
- **Fast navigation** — hint numbers (1–9, 0) open rows directly; TAB pages hints beyond the first ten
|
|
21
|
-
- **Default `[/]:
|
|
21
|
+
- **Default `[/]:narrow` in popups** — command and history popups open in narrow mode: start typing to narrow the list down to the matches, then press a number hint to pick from the few remaining results. The listing itself narrows the same way
|
|
22
22
|
- **Mouse support** — click a row to open it with its default action, right-click to open its command list, click a binding on the bottom bar or a filter/sort/views column to run that action; the mouse wheel scrolls the listing (pointer-only mode is planned)
|
|
23
23
|
- **Command execution modes** — commands run in one of four ways, chosen by prefix: `|` status line, `=` text viewer, `+` new terminal window, `!` Ruby eval; per-MIME-type command sets with `%name`, `%dir`, `%file`, `%cmd`, `%str` substitution
|
|
24
24
|
- **Customizable column views** — view columns run shell commands with `%name` substitution (content preview, char/word/line counts, type info, disk usage, man-page descriptions)
|
|
@@ -83,7 +83,7 @@ Click a row to open it with its default action, right-click (or Alt+click) to op
|
|
|
83
83
|
|
|
84
84
|
### Popups and search
|
|
85
85
|
|
|
86
|
-
Command and history popups open in `/`
|
|
86
|
+
Command and history popups open in `/` narrow mode. Type a few characters to **narrow** the list down to the matching entries; when only a handful remain, press the number hint of the one you want. Large lists can be narrowed in a keystroke or two. The main listing narrows the same way when you press `/`.
|
|
87
87
|
|
|
88
88
|
### Configuration
|
|
89
89
|
|
data/config.yaml
CHANGED
|
@@ -33,23 +33,6 @@ filter_dirs: true
|
|
|
33
33
|
# comment these lines out (or delete them) to use
|
|
34
34
|
# the terminal colors instead
|
|
35
35
|
#
|
|
36
|
-
# Color settings passed to Typr spaces:
|
|
37
|
-
# default global default foreground/background [fg, bg]
|
|
38
|
-
# border widget borders
|
|
39
|
-
# header column/panel headers
|
|
40
|
-
# question prompt question text
|
|
41
|
-
# answer typed input text
|
|
42
|
-
# selected highlighted / selected row background
|
|
43
|
-
# alternate alternating row background in lists
|
|
44
|
-
# hints hint numbers/digits
|
|
45
|
-
# actions named action colors: filter, sort, views
|
|
46
|
-
# commands command picker and status line: [name, args] colors
|
|
47
|
-
# search search-match highlight (text viewer)
|
|
48
|
-
# dir_history directory history picker: [name, path] columns
|
|
49
|
-
# cmd_history command history picker: [prefix, command] columns
|
|
50
|
-
# top_history top-history field background color
|
|
51
|
-
# error error popup: [fg, bg]
|
|
52
|
-
#
|
|
53
36
|
# Usage:
|
|
54
37
|
# Foreground color only: "blue"
|
|
55
38
|
# Foreground + background: ["white", "black"]
|
|
@@ -107,7 +90,7 @@ colors:
|
|
|
107
90
|
|
|
108
91
|
prefixes:
|
|
109
92
|
"!": "!StringIO.new((%s).to_s)"
|
|
110
|
-
"|": "!IO.popen('%s 2>&1', 'r', in: File::NULL)"
|
|
93
|
+
"|": "!IO.popen('%s 2>&1', 'r', in: File::NULL, pgroup: true)"
|
|
111
94
|
"=": "!Text.new(top: 1, right:-1, bottom:-2, header: '%s', colors: {regex: :generic}, input: open('|%s 2>&1')).pick :none"
|
|
112
95
|
"-": "!Text.new(top: 1, right:-1, bottom:-2, header: '%s', input: open('|%s 2>&1')).pick :none"
|
|
113
96
|
|
|
@@ -125,7 +108,7 @@ prefixes:
|
|
|
125
108
|
|
|
126
109
|
bindings:
|
|
127
110
|
"[h]elp": "!help"
|
|
128
|
-
"[/]:
|
|
111
|
+
"[/]:narrow": "!narrow"
|
|
129
112
|
"[f]ilter": "!filter_view"
|
|
130
113
|
"[s]ort": "!sort_view"
|
|
131
114
|
"[v]iews": "!views"
|
data/filecon.1
CHANGED
data/lib/filecon/version.rb
CHANGED
data/lib/filecon.rb
CHANGED
|
@@ -6,6 +6,7 @@ end
|
|
|
6
6
|
|
|
7
7
|
require "fileutils"
|
|
8
8
|
require "find"
|
|
9
|
+
require "shellwords"
|
|
9
10
|
require "yaml"
|
|
10
11
|
require "tempfile"
|
|
11
12
|
|
|
@@ -129,7 +130,6 @@ class Filecon::App < Typr::Browser
|
|
|
129
130
|
super
|
|
130
131
|
return
|
|
131
132
|
end
|
|
132
|
-
Typr.flush_overtype
|
|
133
133
|
data = @data.map.with_index{ |row, id| row + view.values.map{ |cmd|
|
|
134
134
|
next unless cmd.is_a?(String)
|
|
135
135
|
built = build cmd, id
|
|
@@ -395,13 +395,12 @@ class Filecon::App < Typr::Browser
|
|
|
395
395
|
|
|
396
396
|
def run cmd=nil
|
|
397
397
|
return unless cmd
|
|
398
|
-
Typr.flush_overtype
|
|
399
398
|
fmt = @prefixes&.[](cmd[0].to_s)
|
|
400
399
|
if fmt
|
|
401
400
|
body = cmd[1..-1]
|
|
402
|
-
body = body.gsub(
|
|
401
|
+
body = body.gsub(/\\|'/, "\\" => "\\\\", "'" => %q{'"'"'}) if fmt =~ /'[^']*%s/
|
|
403
402
|
result = fmt.gsub('%s') { body }
|
|
404
|
-
result.start_with?('!') ? eval(result[1..-1]) :
|
|
403
|
+
result.start_with?('!') ? eval(result[1..-1]) : (IO.popen(Shellwords.split(result), "r", pgroup: true, err: File::NULL) rescue @user.show "#{(t = result.split.first.to_s).start_with?("$") ? "no terminal configured" : "'#{t}' cannot launch"} — set \"+\" prefix in ~/.config/filecon/config.yaml")
|
|
405
404
|
else
|
|
406
405
|
shell(cmd + " 2>&1", "r", in: File::NULL)
|
|
407
406
|
end
|
|
@@ -426,16 +425,31 @@ class Filecon::App < Typr::Browser
|
|
|
426
425
|
end
|
|
427
426
|
if cmd[0] == ?=
|
|
428
427
|
body = cmd[1..-1]
|
|
429
|
-
text = Text.new(top: 1, right: -1, bottom: -2, header: body,
|
|
428
|
+
text = Text.new(top: 1, right: -1, bottom: -2, header: body, margin: ' ',
|
|
430
429
|
colors: { regex: :generic, border: @colors[:border] }, input: "")
|
|
431
430
|
io = shell("#{body} 2>&1", "r", in: File::NULL)
|
|
431
|
+
pending = +"".b
|
|
432
432
|
begin
|
|
433
433
|
loop do
|
|
434
|
-
|
|
435
|
-
|
|
434
|
+
pending << io.readpartial(4096)
|
|
435
|
+
s = pending.dup.force_encoding(Encoding::UTF_8)
|
|
436
|
+
unless s.valid_encoding?
|
|
437
|
+
cut = pending.bytesize
|
|
438
|
+
cut -= 1 while cut > 0 and pending.getbyte(cut - 1) >= 0x80
|
|
439
|
+
tail, head = pending.byteslice(cut..-1), pending.byteslice(0...cut).force_encoding(Encoding::UTF_8)
|
|
440
|
+
if !tail.empty? and head.valid_encoding?
|
|
441
|
+
s, pending = head, tail
|
|
442
|
+
else
|
|
443
|
+
s, pending = s.scrub, +"".b
|
|
444
|
+
end
|
|
445
|
+
else
|
|
446
|
+
pending = +"".b
|
|
447
|
+
end
|
|
448
|
+
text << s
|
|
436
449
|
text.show
|
|
437
450
|
end
|
|
438
451
|
rescue EOFError
|
|
452
|
+
text << pending.dup.force_encoding(Encoding::UTF_8).scrub unless pending.empty?
|
|
439
453
|
end
|
|
440
454
|
io.close
|
|
441
455
|
text.pick(:none)
|
|
@@ -446,6 +460,7 @@ class Filecon::App < Typr::Browser
|
|
|
446
460
|
head = name ? "#{color_code(nc)}#{name}#{color_code(ac)}:" : color_code(nc)
|
|
447
461
|
@user.show "> #{head}#{cmd[1..-1]}#{color_code(@colors[:default])} : #{line.strip}"
|
|
448
462
|
end
|
|
463
|
+
Process.detach(Process.spawn("cat", in: io, out: File::NULL, pgroup: true, close_others: true)) rescue nil
|
|
449
464
|
elsif io and io.respond_to?(:read) and
|
|
450
465
|
@prefixes&.[](cmd[0].to_s)&.start_with? '!'
|
|
451
466
|
output = io.read.to_s.scrub.strip
|
|
@@ -699,6 +714,7 @@ class Filecon::App < Typr::Browser
|
|
|
699
714
|
show
|
|
700
715
|
draw_hints :rows
|
|
701
716
|
key = Typr.read_key
|
|
717
|
+
@user.reset
|
|
702
718
|
next unless key
|
|
703
719
|
if act = prefixed_binding( key )
|
|
704
720
|
cmd = build act, nil
|
|
@@ -717,14 +733,12 @@ class Filecon::App < Typr::Browser
|
|
|
717
733
|
value = send( key )
|
|
718
734
|
open_file( value, !( key.right? or alt ) ) if value.is_a?( Integer )
|
|
719
735
|
end
|
|
720
|
-
@user.reset
|
|
721
736
|
else
|
|
722
737
|
alt = key.is_a?(String) && key[/\A\e(\d)\z/]
|
|
723
738
|
key = key[1] if alt
|
|
724
739
|
id = send( key )
|
|
725
740
|
id = send( id ) while id.is_a? String
|
|
726
741
|
open_file( id, !alt ) if id.is_a? Integer
|
|
727
|
-
@user.reset
|
|
728
742
|
end
|
|
729
743
|
end
|
|
730
744
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: filecon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kilian Reitmayr
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: typr
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '1.
|
|
18
|
+
version: '1.9'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '1.
|
|
25
|
+
version: '1.9'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: unicode-display_width
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|