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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e644e2e7cc6f76bb646d0738e9d83789a558696c7341a6c6a9cd3a749c1adc7b
4
- data.tar.gz: a2d69517f4a4b7d9fc5af621440e9ca3a0bfaaf1be8987801b643725079f6256
3
+ metadata.gz: 39b5d282890f2a71e7d928cd772e5e4d1c539bee82f49bd20a078f2fdb3c42d6
4
+ data.tar.gz: 654d4cecbf3fadccd929459f6488ff7795006db209d63da38b7e7387a30c312c
5
5
  SHA512:
6
- metadata.gz: 3603c6f4aada4a2c8ff06c6e0528f6f862c6bf8e929deba8920b959c818abc21bd8c979bf1ab51795692d1922cdc81fc5aa0be239d492bb8c90fec94eefee389
7
- data.tar.gz: d4014f8166788f03d46576c195b5d4b5cb539c1ca70f28c71171db0ec196d00210a8c5f75cecc9b35f84e090eff3762913ec4ac926af75e6a9fab10de18a2a77
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 search in popups** — popups open in `/` search mode; type to distill 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.
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 `[/]:search` in popups** — command and history popups open in search mode: start typing to distill the list down to the matches, then press a number hint to pick from the few remaining results. The listing itself searches the same way
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 `/` search mode. Type a few characters to **distill** 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 searches the same way when you press `/`.
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
- "[/]:search": "!search"
111
+ "[/]:narrow": "!narrow"
129
112
  "[f]ilter": "!filter_view"
130
113
  "[s]ort": "!sort_view"
131
114
  "[v]iews": "!views"
data/filecon.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH FILECON 1 "2026-10-11" "filecon 0.6.0" "User Commands"
1
+ .TH FILECON 1 "2026-10-13" "filecon 0.7.1" "User Commands"
2
2
  .SH NAME
3
3
  filecon \- a file and command manager that lives between terminal and shell
4
4
  .SH SYNOPSIS
@@ -1,3 +1,3 @@
1
1
  module Filecon
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.1"
3
3
  end
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(/[\\']/) { |m| "\\#{m}" } if fmt =~ /'[^']*%s/
401
+ body = body.gsub(/\\|'/, "\\" => "\\\\", "'" => %q{'"'"'}) if fmt =~ /'[^']*%s/
403
402
  result = fmt.gsub('%s') { body }
404
- result.start_with?('!') ? eval(result[1..-1]) : shell(result, pgroup: true)
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
- chunk = io.readpartial(4096)
435
- text << chunk
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.6.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-11 00:00:00.000000000 Z
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.8'
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.8'
25
+ version: '1.9'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: unicode-display_width
28
28
  requirement: !ruby/object:Gem::Requirement