rtfm-filemanager 5.6 → 5.7

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/bin/rtfm +156 -57
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f544a2581e939a651b9c5f7532960fb057dc449a4a549acbec646576845c71e5
4
- data.tar.gz: 0c27c90a8b5ad28e804e15dc810837f783b37872ae1e6c45e399cf2e16b61b4e
3
+ metadata.gz: 0a98e564810c828a6973aa5a7b968b560ee32af1ff3a2c916a9ae31f15a30489
4
+ data.tar.gz: dafe630653b09a6effb439fc0d79fce6636473b5eaa4a6104858f7311a5b01a4
5
5
  SHA512:
6
- metadata.gz: 9ee6716978969d8a704647962322786f4a1fb703504600febdcf6c4dedb2c77801b9e1819b76eb5e8aa8f6d9491b6236ae14027a1112c755fa9764fcecd91e00
7
- data.tar.gz: 69f326117d1d528a36175bf16e93e79db20018bbafe784167b24058239699680c63079bb253f6979ce938b165f6c1e9de16ccd2fe6d4060463d9521e2c8a4b4c
6
+ metadata.gz: 8c3ba0bbf931a118c75ce53c2388b139b8684d25c63c83df565659697daf218f59533a5506883ae24c2a79feb614973546377d57c2ab7531bb8ec63c44b49cc8
7
+ data.tar.gz: 6c65eca97ca5898cbd9774564e1175ba859d29af622553a0cd93070e6d1bc3355e0d0bc08ef66d606da00b48cb5b6fd7d789909b0f95bd7e5f4966db642ccad2
data/README.md CHANGED
@@ -368,7 +368,9 @@ add a program to the whitelist inside RTFM, press the `+` key. All ususal
368
368
  shell comands that do not take over the full terminal such as `ls`, `touch`,
369
369
  `neofetch`, etc. will run just fine in command mode without being whitelisted.
370
370
  You can also explicitly run a program as interactive by prefixing the command
371
- with a single `§` - e.g. `:` `§saidar`.***
371
+ with a single `§` - e.g. `:` `§saidar`. Programs added to @interactive will
372
+ open as interactive also when opened via xdg-open or runmailcap (when you
373
+ press `RIGHT` on a selected item).***
372
374
 
373
375
  All the variables above that you manually add to the top of the config files are
374
376
  undisturbed by launching and exiting RTFM.
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.6' # Fixed bug with special characters in terminal after EDITOR exit
21
+ @version = '5.7' # Added use of @interactive on automatic opening of selected files
22
22
 
23
23
  # SAVE & STORE TERMINAL {{{1
24
24
  ORIG_STTY = `stty -g`.chomp
@@ -431,7 +431,7 @@ $stdin.set_encoding(Encoding::UTF_8)
431
431
  @border = 1 # Set initial border config; 0 = none, 1 = Right pane, 2 = both panes, 3 = Left pane
432
432
  @preview = true # Preview in the Right pane
433
433
  @trash = false # Delete files permanently rather than moving them to ~/.rtfm/trash
434
- @interactive = 'fzf,navi,top,htop,less,vi,vim,nvim,ncdu,sh,zsh,bash,fish,git'
434
+ @interactive = 'fzf,navi,top,htop,less,vi,vim,nvim,ncdu,sh,zsh,bash,fish,git,mplayer'
435
435
  ### Not saved (but can be set in ~/.rtfm/conf)
436
436
  @topcolor = 249 # Default Top pane bg color
437
437
  @topmatch = [['', 249]] # Default Top pane bg color for matching directories
@@ -1329,7 +1329,7 @@ end
1329
1329
  # CLIPBOARD COPY {{{2
1330
1330
  def copy_path # {{{3
1331
1331
  if @selected
1332
- clip = "xclip -selection #{_chr == 'Y' ? 'clipboard' : 'primary'} -in -loops 1"
1332
+ clip = "xclip -selection #{getchr == 'Y' ? 'clipboard' : 'primary'} -in -loops 1"
1333
1333
  @pB.say(' Path copied')
1334
1334
  shell("echo -n '#{@selected}' | #{clip}")
1335
1335
  else
@@ -1869,6 +1869,159 @@ def mark_latest # UPDATE MARKS LIST {{{2
1869
1869
  @marks["'"] = Dir.pwd
1870
1870
  end
1871
1871
 
1872
+ def get_interactive_program(file_path) # HELPER FOR OPEN_SELECTED TO USE @interactive {{{2
1873
+ begin
1874
+ inter_list = (@interactive || '').split(',').map(&:strip)
1875
+
1876
+ if @runmailcap
1877
+ # Check what run-mailcap would actually execute
1878
+ # Use --norun to see the command without executing it
1879
+ 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
+ if !mailcap_output.empty?
1885
+ # Extract the program name from the command
1886
+ # Handle cases like "/usr/bin/mplayer file.mp4" or "mplayer %s"
1887
+ cmd_parts = mailcap_output.split
1888
+ prog = cmd_parts.first
1889
+ 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
+ return prog if prog && inter_list.include?(prog)
1895
+ end
1896
+ else
1897
+ # Check what xdg-open would use
1898
+ mimetype = `file --mime-type -b #{Shellwords.escape(file_path)}`.chomp
1899
+ desktop_file = `xdg-mime query default #{Shellwords.escape(mimetype)}`.chomp
1900
+
1901
+ if desktop_file && !desktop_file.empty?
1902
+ # Read the desktop file to get the actual command
1903
+ desktop_path = nil
1904
+ ['/usr/share/applications/', '/usr/local/share/applications/',
1905
+ File.join(Dir.home, '.local/share/applications/')].each do |dir|
1906
+ path = File.join(dir, desktop_file)
1907
+ if File.exist?(path)
1908
+ desktop_path = path
1909
+ break
1910
+ end
1911
+ end
1912
+
1913
+ if desktop_path
1914
+ content = File.read(desktop_path)
1915
+ exec_line = content[/^Exec=(.*)$/m, 1]
1916
+ if exec_line
1917
+ # Extract the program name (first word, remove path)
1918
+ prog = exec_line.split.first
1919
+ prog = File.basename(prog) if prog
1920
+ return prog if prog && inter_list.include?(prog)
1921
+ end
1922
+ end
1923
+ end
1924
+ end
1925
+ rescue
1926
+ # If detection fails, fall back to normal behavior
1927
+ end
1928
+ nil
1929
+ end
1930
+
1931
+ def open_selected(html = nil) # OPEN SELECTED FILE {{{2
1932
+ require 'tmpdir' unless Dir.respond_to?(:tmpdir)
1933
+
1934
+ if File.directory?(@selected) # Dir? just cd into it
1935
+ mark_latest
1936
+ Dir.chdir(@selected) rescue nil
1937
+ return
1938
+ end
1939
+
1940
+ # Check if this file should use an interactive program (same as § prefix logic)
1941
+ if !html && (prog = get_interactive_program(@selected))
1942
+ cmd = "#{prog} #{Shellwords.escape(@selected)}"
1943
+
1944
+ # Use exactly the same logic as command_mode with § prefix (force interactive)
1945
+ # Restore shell tty so Ctrl-C/D work
1946
+ system("stty #{ORIG_STTY} < /dev/tty")
1947
+ # Clear to top-left
1948
+ system('clear < /dev/tty > /dev/tty')
1949
+ Cursor.show
1950
+
1951
+ # Spawn on real tty
1952
+ pid = Process.spawn(cmd,
1953
+ in: '/dev/tty',
1954
+ out: '/dev/tty',
1955
+ err: '/dev/tty')
1956
+ begin
1957
+ Process.wait(pid)
1958
+ rescue Interrupt
1959
+ Process.kill('TERM', pid) rescue nil
1960
+ retry
1961
+ end
1962
+
1963
+ # Restore raw/no-echo for RTFM
1964
+ system('stty raw -echo isig < /dev/tty')
1965
+ $stdin.raw!
1966
+ $stdin.echo = false
1967
+ Cursor.hide
1968
+ Rcurses.clear_screen
1969
+ refresh
1970
+ render
1971
+ return
1972
+ end
1973
+
1974
+ tmpfile = File.join(Dir.tmpdir, 'rtfm_err.log')
1975
+ paths = (@tagged + [@selected]).uniq
1976
+
1977
+ if html # html mode - open in HTML-browser
1978
+ esc = paths.map { |p| Shellwords.escape(p) }.join(' ')
1979
+ shell("xdg-open #{esc} &", err: tmpfile)
1980
+ Rcurses.clear_screen; refresh; render
1981
+ if File.exist?(tmpfile)
1982
+ sleep 0.5
1983
+ err = File.read(tmpfile)
1984
+ showimage('clear') if @image
1985
+ @pR.say(err.fg(196))
1986
+ File.delete(tmpfile)
1987
+ end
1988
+ return
1989
+ end
1990
+
1991
+ if File.read(@selected).force_encoding('UTF-8').valid_encoding? # Pure text
1992
+ system("stty #{ORIG_STTY} < /dev/tty")
1993
+ # Clear to top-left
1994
+ system('clear < /dev/tty > /dev/tty')
1995
+ Cursor.show
1996
+ editor = ENV.fetch('EDITOR', 'vi') # Launch $EDITOR on the real TTY
1997
+ system("#{editor} #{Shellwords.escape(@selected)}")
1998
+ $stdin.raw!
1999
+ $stdin.echo = false
2000
+ Cursor.hide
2001
+ Rcurses.clear_screen # Redraw RTFM
2002
+ refresh
2003
+ render
2004
+ return
2005
+ end
2006
+
2007
+ if @runmailcap # Open with run-mailcap or xdg-open
2008
+ arg = paths.map { |p| Shellwords.escape(p) }.join(' ')
2009
+ shell("run-mailcap #{arg} &", err: tmpfile)
2010
+ else
2011
+ shell("xdg-open #{Shellwords.escape(@selected)} &", err: tmpfile)
2012
+ end
2013
+
2014
+ # Clean up
2015
+ Rcurses.clear_screen; refresh; render
2016
+ if File.exist?(tmpfile)
2017
+ sleep 0.5
2018
+ err = File.read(tmpfile)
2019
+ showimage('clear') if @image
2020
+ @pR.say(err.fg(196))
2021
+ File.delete(tmpfile)
2022
+ end
2023
+ end
2024
+
1872
2025
  def conf_write(all: false) # WRITE TO ~/.rtfm/conf {{{2
1873
2026
  @conf = @conf.dup # work on a mutable copy
1874
2027
  assignments = {
@@ -2052,60 +2205,6 @@ def tagged_info # SHOW THE LIST OF TAGGED ITEMS IN @pR {{{2
2052
2205
  @pR.say(info.fg(204))
2053
2206
  end
2054
2207
 
2055
- def open_selected(html = nil) # OPEN SELECTED ITEM (when pressing RIGHT or via open_force) {{{2
2056
- require 'tmpdir' unless Dir.respond_to?(:tmpdir)
2057
- if File.directory?(@selected) # Dir? just cd into it
2058
- mark_latest
2059
- Dir.chdir(@selected) rescue nil
2060
- return
2061
- end
2062
- tmpfile = File.join(Dir.tmpdir, 'rtfm_err.log')
2063
- paths = (@tagged + [@selected]).uniq
2064
- if html # html mode - open in HTML-browser
2065
- esc = paths.map { |p| Shellwords.escape(p) }.join(' ')
2066
- shell("xdg-open #{esc} &", err: tmpfile)
2067
- Rcurses.clear_screen; refresh; render
2068
- if File.exist?(tmpfile)
2069
- sleep 0.5
2070
- err = File.read(tmpfile)
2071
- showimage('clear') if @image
2072
- @pR.say(err.fg(196))
2073
- File.delete(tmpfile)
2074
- end
2075
- return
2076
- end
2077
- if File.read(@selected).force_encoding('UTF-8').valid_encoding? # Pure text
2078
- system("stty #{ORIG_STTY} < /dev/tty")
2079
- # Clear to top-left
2080
- system('clear < /dev/tty > /dev/tty')
2081
- Cursor.show
2082
- editor = ENV.fetch('EDITOR', 'vi') # Launch $EDITOR on the real TTY
2083
- system("#{editor} #{Shellwords.escape(@selected)}")
2084
- $stdin.raw!
2085
- $stdin.echo = false
2086
- Cursor.hide
2087
- Rcurses.clear_screen # Redraw RTFM
2088
- refresh
2089
- render
2090
- return
2091
- end
2092
- if @runmailcap # Open with run-mailcap or xdg-open
2093
- arg = paths.map { |p| Shellwords.escape(p) }.join(' ')
2094
- shell("run-mailcap #{arg} &", err: tmpfile)
2095
- else
2096
- shell("xdg-open #{Shellwords.escape(@selected)} &", err: tmpfile)
2097
- end
2098
- # Clean up
2099
- Rcurses.clear_screen; refresh; render
2100
- if File.exist?(tmpfile)
2101
- sleep 0.5
2102
- err = File.read(tmpfile)
2103
- showimage('clear') if @image
2104
- @pR.say(err.fg(196))
2105
- File.delete(tmpfile)
2106
- end
2107
- end
2108
-
2109
2208
  # MAIN PROGRAM {{{1
2110
2209
  ## Get terminal size {{{2
2111
2210
  @h, @w = IO.console.winsize
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.6'
4
+ version: '5.7'
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-05-19 00:00:00.000000000 Z
11
+ date: 2025-06-01 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.6: Fixed bug with special characters in terminal after EDITOR exit.
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.
58
58
  email: g@isene.com
59
59
  executables:
60
60
  - rtfm