filecon 0.7.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: 8a432bd710dcfce4c261fb29a0ae260e1114e9b47c6c191fd746542b6579282e
4
- data.tar.gz: fe87db05c3626b48bf4f7986998cec818973038bf1217f493afd2cbc342ad058
3
+ metadata.gz: 39b5d282890f2a71e7d928cd772e5e4d1c539bee82f49bd20a078f2fdb3c42d6
4
+ data.tar.gz: 654d4cecbf3fadccd929459f6488ff7795006db209d63da38b7e7387a30c312c
5
5
  SHA512:
6
- metadata.gz: 13b3822013820db54e0aa2a3e85a132caad88448e0ee50e5a31c5e7b10ecfeabb90b0fdabbf1ce410cc503f20b2df9efa26534e867cc16758bbe3d80ada2cf40
7
- data.tar.gz: d5989090b1e00c0e9aca4dfebe27ae64c2793d22de99146d68489deac175ac433e511e9e3a53b3c7c52812e4b34e65afb02d7473d16fcaac017f683b3988e387
6
+ metadata.gz: 88defb4160b8ff0d433f9de6d01a27c631f8514ac54307bf159bccc64f9506abc179e97fe66dd82a94b46d9d288654a13bd8dac28241a54912b5d403c57c43ea
7
+ data.tar.gz: 3f601ebdf45b5015199ee27d9e809d31bee82cbad121d8787562af3d9c74b56a337f6cc6157994a12f0908121bf84f741ddff90afd09e7e6304f0b673e787ab6
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
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
+
5
12
  ## [v0.7.0] — 2026-10-12
6
13
 
7
14
  ### Changed
data/filecon.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH FILECON 1 "2026-10-12" "filecon 0.7.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.7.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
 
@@ -397,9 +398,9 @@ class Filecon::App < Typr::Browser
397
398
  fmt = @prefixes&.[](cmd[0].to_s)
398
399
  if fmt
399
400
  body = cmd[1..-1]
400
- body = body.gsub(/[\\']/) { |m| "\\#{m}" } if fmt =~ /'[^']*%s/
401
+ body = body.gsub(/\\|'/, "\\" => "\\\\", "'" => %q{'"'"'}) if fmt =~ /'[^']*%s/
401
402
  result = fmt.gsub('%s') { body }
402
- result.start_with?('!') ? eval(result[1..-1]) : shell(result + " 2>/dev/null", 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")
403
404
  else
404
405
  shell(cmd + " 2>&1", "r", in: File::NULL)
405
406
  end
@@ -427,13 +428,28 @@ class Filecon::App < Typr::Browser
427
428
  text = Text.new(top: 1, right: -1, bottom: -2, header: body, margin: ' ',
428
429
  colors: { regex: :generic, border: @colors[:border] }, input: "")
429
430
  io = shell("#{body} 2>&1", "r", in: File::NULL)
431
+ pending = +"".b
430
432
  begin
431
433
  loop do
432
- chunk = io.readpartial(4096)
433
- 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
434
449
  text.show
435
450
  end
436
451
  rescue EOFError
452
+ text << pending.dup.force_encoding(Encoding::UTF_8).scrub unless pending.empty?
437
453
  end
438
454
  io.close
439
455
  text.pick(:none)
@@ -698,6 +714,7 @@ class Filecon::App < Typr::Browser
698
714
  show
699
715
  draw_hints :rows
700
716
  key = Typr.read_key
717
+ @user.reset
701
718
  next unless key
702
719
  if act = prefixed_binding( key )
703
720
  cmd = build act, nil
@@ -716,14 +733,12 @@ class Filecon::App < Typr::Browser
716
733
  value = send( key )
717
734
  open_file( value, !( key.right? or alt ) ) if value.is_a?( Integer )
718
735
  end
719
- @user.reset
720
736
  else
721
737
  alt = key.is_a?(String) && key[/\A\e(\d)\z/]
722
738
  key = key[1] if alt
723
739
  id = send( key )
724
740
  id = send( id ) while id.is_a? String
725
741
  open_file( id, !alt ) if id.is_a? Integer
726
- @user.reset
727
742
  end
728
743
  end
729
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.7.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-12 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