rtfm-filemanager 5.7 → 5.8

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rtfm +22 -38
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a98e564810c828a6973aa5a7b968b560ee32af1ff3a2c916a9ae31f15a30489
4
- data.tar.gz: dafe630653b09a6effb439fc0d79fce6636473b5eaa4a6104858f7311a5b01a4
3
+ metadata.gz: e2af18af3c2d05afb1baf0a58d630b81b1b391d6cbbbc5bfb61bfc2e5f9a764f
4
+ data.tar.gz: 03f96975304611a76e08db2a6d974750c667bb8c5baa2e8afac5d408345ccbf1
5
5
  SHA512:
6
- metadata.gz: 8c3ba0bbf931a118c75ce53c2388b139b8684d25c63c83df565659697daf218f59533a5506883ae24c2a79feb614973546377d57c2ab7531bb8ec63c44b49cc8
7
- data.tar.gz: 6c65eca97ca5898cbd9774564e1175ba859d29af622553a0cd93070e6d1bc3355e0d0bc08ef66d606da00b48cb5b6fd7d789909b0f95bd7e5f4966db642ccad2
6
+ metadata.gz: f1dd0f689697528ec4a66cedb712f49b4050c1014e13131d878a1ca88d72a429dd38c0b9658e614db23988dc8a8ab1cfb27cda76a3e822ff0f080f7bf7b2000b
7
+ data.tar.gz: fc69c4b4fccbfacd3ddca202403be9a55b2ba9d69149fedbac9ee1d1238d6a5f13e69e24ee48a1d1d531d76e7c99579ab0c610753d7096c89a05fffe8d5c0db6
data/bin/rtfm CHANGED
@@ -18,7 +18,7 @@
18
18
  # get a great understanding of the code itself by simply sending
19
19
  # or pasting this whole file into you favorite AI for coding with
20
20
  # a prompt like this: "Help me understand every part of this code".
21
- @version = '5.7' # Added use of @interactive on automatic opening of selected files
21
+ @version = '5.8' # Fixed bug on images with space in file name
22
22
 
23
23
  # SAVE & STORE TERMINAL {{{1
24
24
  ORIG_STTY = `stty -g`.chomp
@@ -1650,8 +1650,7 @@ def render # RENDER ALL PANES {{{2
1650
1650
  begin
1651
1651
  if @selected&.match(@imagefile)
1652
1652
  if cmd?('identify')
1653
- meta = `identify #{Shellwords.escape(@selected)} \
1654
- | awk '{printf " [%s %s %s %s] ", $3,$2,$5,$6}' 2>/dev/null`
1653
+ meta = `identify -format " [%wx%h %m %[colorspace] %[bit-depth]-bit]" #{Shellwords.escape(@selected)} 2>/dev/null`
1655
1654
  text += meta
1656
1655
  end
1657
1656
  elsif @selected&.match(@pdffile)
@@ -1872,36 +1871,26 @@ end
1872
1871
  def get_interactive_program(file_path) # HELPER FOR OPEN_SELECTED TO USE @interactive {{{2
1873
1872
  begin
1874
1873
  inter_list = (@interactive || '').split(',').map(&:strip)
1875
-
1876
1874
  if @runmailcap
1877
- # Check what run-mailcap would actually execute
1878
- # Use --norun to see the command without executing it
1875
+ # Check what run-mailcap would execute. Use --norun to see the command without executing it
1879
1876
  mailcap_output = `run-mailcap --norun #{Shellwords.escape(file_path)} 2>/dev/null`.chomp
1880
-
1881
- # Debug: log what we found
1882
- @pB.say("Debug: mailcap would run: '#{mailcap_output}'") unless mailcap_output.empty?
1883
-
1884
1877
  if !mailcap_output.empty?
1885
1878
  # Extract the program name from the command
1886
1879
  # Handle cases like "/usr/bin/mplayer file.mp4" or "mplayer %s"
1887
1880
  cmd_parts = mailcap_output.split
1888
1881
  prog = cmd_parts.first
1889
1882
  prog = File.basename(prog) if prog
1890
-
1891
- # Debug: log program detection
1892
- @pB.say("Debug: detected program = '#{prog}', in interactive list? #{inter_list.include?(prog)}")
1893
-
1894
1883
  return prog if prog && inter_list.include?(prog)
1895
1884
  end
1896
1885
  else
1897
1886
  # Check what xdg-open would use
1898
1887
  mimetype = `file --mime-type -b #{Shellwords.escape(file_path)}`.chomp
1899
1888
  desktop_file = `xdg-mime query default #{Shellwords.escape(mimetype)}`.chomp
1900
-
1889
+
1901
1890
  if desktop_file && !desktop_file.empty?
1902
1891
  # Read the desktop file to get the actual command
1903
1892
  desktop_path = nil
1904
- ['/usr/share/applications/', '/usr/local/share/applications/',
1893
+ ['/usr/share/applications/', '/usr/local/share/applications/',
1905
1894
  File.join(Dir.home, '.local/share/applications/')].each do |dir|
1906
1895
  path = File.join(dir, desktop_file)
1907
1896
  if File.exist?(path)
@@ -1909,7 +1898,6 @@ def get_interactive_program(file_path) # HELPER FOR OPEN_SELECTED TO USE @intera
1909
1898
  break
1910
1899
  end
1911
1900
  end
1912
-
1913
1901
  if desktop_path
1914
1902
  content = File.read(desktop_path)
1915
1903
  exec_line = content[/^Exec=(.*)$/m, 1]
@@ -1930,24 +1918,21 @@ end
1930
1918
 
1931
1919
  def open_selected(html = nil) # OPEN SELECTED FILE {{{2
1932
1920
  require 'tmpdir' unless Dir.respond_to?(:tmpdir)
1933
-
1934
1921
  if File.directory?(@selected) # Dir? just cd into it
1935
1922
  mark_latest
1936
1923
  Dir.chdir(@selected) rescue nil
1937
1924
  return
1938
1925
  end
1939
-
1926
+
1940
1927
  # Check if this file should use an interactive program (same as § prefix logic)
1941
1928
  if !html && (prog = get_interactive_program(@selected))
1942
1929
  cmd = "#{prog} #{Shellwords.escape(@selected)}"
1943
-
1944
1930
  # Use exactly the same logic as command_mode with § prefix (force interactive)
1945
1931
  # Restore shell tty so Ctrl-C/D work
1946
1932
  system("stty #{ORIG_STTY} < /dev/tty")
1947
1933
  # Clear to top-left
1948
1934
  system('clear < /dev/tty > /dev/tty')
1949
1935
  Cursor.show
1950
-
1951
1936
  # Spawn on real tty
1952
1937
  pid = Process.spawn(cmd,
1953
1938
  in: '/dev/tty',
@@ -1959,7 +1944,6 @@ def open_selected(html = nil) # OPEN SELECTED FILE {{{2
1959
1944
  Process.kill('TERM', pid) rescue nil
1960
1945
  retry
1961
1946
  end
1962
-
1963
1947
  # Restore raw/no-echo for RTFM
1964
1948
  system('stty raw -echo isig < /dev/tty')
1965
1949
  $stdin.raw!
@@ -1970,10 +1954,8 @@ def open_selected(html = nil) # OPEN SELECTED FILE {{{2
1970
1954
  render
1971
1955
  return
1972
1956
  end
1973
-
1974
1957
  tmpfile = File.join(Dir.tmpdir, 'rtfm_err.log')
1975
1958
  paths = (@tagged + [@selected]).uniq
1976
-
1977
1959
  if html # html mode - open in HTML-browser
1978
1960
  esc = paths.map { |p| Shellwords.escape(p) }.join(' ')
1979
1961
  shell("xdg-open #{esc} &", err: tmpfile)
@@ -1987,7 +1969,6 @@ def open_selected(html = nil) # OPEN SELECTED FILE {{{2
1987
1969
  end
1988
1970
  return
1989
1971
  end
1990
-
1991
1972
  if File.read(@selected).force_encoding('UTF-8').valid_encoding? # Pure text
1992
1973
  system("stty #{ORIG_STTY} < /dev/tty")
1993
1974
  # Clear to top-left
@@ -2003,14 +1984,12 @@ def open_selected(html = nil) # OPEN SELECTED FILE {{{2
2003
1984
  render
2004
1985
  return
2005
1986
  end
2006
-
2007
1987
  if @runmailcap # Open with run-mailcap or xdg-open
2008
1988
  arg = paths.map { |p| Shellwords.escape(p) }.join(' ')
2009
1989
  shell("run-mailcap #{arg} &", err: tmpfile)
2010
1990
  else
2011
1991
  shell("xdg-open #{Shellwords.escape(@selected)} &", err: tmpfile)
2012
1992
  end
2013
-
2014
1993
  # Clean up
2015
1994
  Rcurses.clear_screen; refresh; render
2016
1995
  if File.exist?(tmpfile)
@@ -2165,18 +2144,23 @@ def showimage(image) # SHOW THE SELECTED IMAGE IN THE RIGHT WINDOW {{{2
2165
2144
  img_max_h += 2
2166
2145
  `echo "6;#{img_x};#{img_y};#{img_max_w};#{img_max_h};\n4;\n3;" | #{@imgdisplay} 2>/dev/null`
2167
2146
  else
2168
- img_w, img_h = `identify -format "%[fx:w]x%[fx:h]" #{Shellwords.escape(image)} 2>/dev/null`.split('x')
2169
- img_w = img_w.to_i
2170
- img_h = img_h.to_i
2171
- if img_w > img_max_w
2172
- img_h = img_h * img_max_w / img_w
2173
- img_w = img_max_w
2147
+ # Use the already-escaped image for shell commands
2148
+ dimensions = `identify -format "%wx%h" #{image} 2>/dev/null`
2149
+ img_w, img_h = dimensions.split('x').map(&:to_i)
2150
+
2151
+ # Fix: Use simultaneous scaling to prevent overflow
2152
+ if img_w > img_max_w || img_h > img_max_h
2153
+ scale_w = img_max_w.to_f / img_w
2154
+ scale_h = img_max_h.to_f / img_h
2155
+ scale = [scale_w, scale_h].min
2156
+
2157
+ img_w = (img_w * scale).to_i
2158
+ img_h = (img_h * scale).to_i
2174
2159
  end
2175
- if img_h > img_max_h
2176
- img_w = img_w * img_max_h / img_h
2177
- img_h = img_max_h
2178
- end
2179
- `echo "0;1;#{img_x};#{img_y};#{img_w};#{img_h};;;;;\"#{image}\"\n4;\n3;" | #{@imgdisplay} 2>/dev/null`
2160
+
2161
+ # Fix: Unescape the filename for w3mimgdisplay protocol, then quote it
2162
+ unescaped = image.gsub(/\\(.)/, '\1') # Remove shell escaping
2163
+ `echo "0;1;#{img_x};#{img_y};#{img_w};#{img_h};;;;;\"#{unescaped}\"\n4;\n3;" | #{@imgdisplay} 2>/dev/null`
2180
2164
  end
2181
2165
  rescue
2182
2166
  @pR.text = 'Error showing image'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtfm-filemanager
3
3
  version: !ruby/object:Gem::Version
4
- version: '5.7'
4
+ version: '5.8'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geir Isene
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-01 00:00:00.000000000 Z
11
+ date: 2025-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rcurses
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '7.4'
55
55
  description: |-
56
56
  Major release - RTFM v5: Complete rewrite using rcurses (https://github.com/isene/rcurses). Massive improvements. AI integration.
57
- A full featured terminal browser with syntax highlighted files, images shown in the terminal, videos thumbnailed, etc. You can bookmark and jump around easily, delete, rename, copy, symlink and move files. RTFM is one of the most feature-packed terminal file managers. 5.7: Added use of @interactive on automatic opening of selected files.
57
+ A full featured terminal browser with syntax highlighted files, images shown in the terminal, videos thumbnailed, etc. You can bookmark and jump around easily, delete, rename, copy, symlink and move files. RTFM is one of the most feature-packed terminal file managers. 5.8: Fixed bug on images with space in file name.
58
58
  email: g@isene.com
59
59
  executables:
60
60
  - rtfm