rtfm-filemanager 6.0.0 → 6.0.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/bin/rtfm +183 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3752dbc07e02a59b08ddd5e32d5ec664cfc8b9cf167359cc953bfbe766c24cbc
|
4
|
+
data.tar.gz: 278bdf15a4b8076eeb98bd12efa29ac6564edc8110a191be6c24a8d5072308ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bb51eba0068c498583e7c3187e540f31d0b548713303f245dd78bea74f62570105f75edc8c71066a7b0afbb281b573b2c1fe39ebf6a965decc8bb992e3f388e
|
7
|
+
data.tar.gz: 7e35a9382af8a119942179eb1b5f6764c093f9fcd1b40310c3e414cdd4f4214741ef08a2ea07f8acafbeb4a0def6d632fb463a5faf3eae9822fda36d9323c345
|
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 = '6.0.
|
21
|
+
@version = '6.0.1' # Remote mode fixes: FrozenError fix, enhanced upload workflow, refresh functionality
|
22
22
|
|
23
23
|
# SAVE & STORE TERMINAL {{{1
|
24
24
|
ORIG_STTY = `stty -g`.chomp
|
@@ -1098,6 +1098,11 @@ def show_version # {{{3
|
|
1098
1098
|
end
|
1099
1099
|
|
1100
1100
|
def refresh_all # {{{3
|
1101
|
+
# Clear remote directory cache if in remote mode
|
1102
|
+
if @remote_mode
|
1103
|
+
@remote_files_cache = []
|
1104
|
+
@pL.update = true
|
1105
|
+
end
|
1101
1106
|
refresh
|
1102
1107
|
end
|
1103
1108
|
|
@@ -2448,8 +2453,7 @@ def exit_remote_mode # {{{3
|
|
2448
2453
|
end
|
2449
2454
|
|
2450
2455
|
def show_remote_file_info(file) # {{{3
|
2451
|
-
info_text = ""
|
2452
|
-
info_text << "Remote File Information\n".b.fg(156)
|
2456
|
+
info_text = "Remote File Information\n".b.fg(156)
|
2453
2457
|
info_text << "=" * 40 + "\n\n"
|
2454
2458
|
|
2455
2459
|
info_text << "Name: #{file[:name]}\n".fg(255)
|
@@ -2609,8 +2613,119 @@ end
|
|
2609
2613
|
def remote_upload_file # {{{3
|
2610
2614
|
return unless @remote_mode
|
2611
2615
|
|
2616
|
+
# Check if there are tagged files first
|
2617
|
+
unless @tagged.empty?
|
2618
|
+
# Show tagged files for upload confirmation
|
2619
|
+
upload_text = "Upload Tagged Files to Remote Directory\n\n".fg(156)
|
2620
|
+
upload_text << "Current remote path: #{@remote_path}\n\n".fg(240)
|
2621
|
+
upload_text << "Tagged files to upload:\n".fg(226)
|
2622
|
+
|
2623
|
+
@tagged.each_with_index do |file, i|
|
2624
|
+
if File.exist?(file)
|
2625
|
+
upload_text << sprintf(" %d. %s\n", i + 1, file.fg(255))
|
2626
|
+
else
|
2627
|
+
upload_text << sprintf(" %d. %s [MISSING]\n", i + 1, file.fg(196))
|
2628
|
+
end
|
2629
|
+
end
|
2630
|
+
|
2631
|
+
total_size = @tagged.sum { |f| File.exist?(f) ? File.size(f) : 0 }
|
2632
|
+
upload_text << "\nTotal size: #{(total_size.to_f / 1_000_000).round(2)}MB\n".fg(240)
|
2633
|
+
upload_text << "\nPress 'y' to upload all tagged files\n".fg(226)
|
2634
|
+
upload_text << "Press 'i' to upload individual files\n".fg(226)
|
2635
|
+
upload_text << "Press any other key to cancel\n".fg(240)
|
2636
|
+
|
2637
|
+
@pR.say(upload_text)
|
2638
|
+
@pR.update = true
|
2639
|
+
|
2640
|
+
choice = getchr
|
2641
|
+
case choice
|
2642
|
+
when 'y', 'Y'
|
2643
|
+
upload_tagged_files
|
2644
|
+
when 'i', 'I'
|
2645
|
+
upload_individual_file
|
2646
|
+
else
|
2647
|
+
@pB.say("Upload cancelled".fg(240))
|
2648
|
+
@pR.update = true
|
2649
|
+
end
|
2650
|
+
else
|
2651
|
+
# No tagged files, show instructions
|
2652
|
+
upload_text = "Upload Files to Remote Directory\n\n".fg(156)
|
2653
|
+
upload_text << "Current remote path: #{@remote_path}\n\n".fg(240)
|
2654
|
+
upload_text << "No files are currently tagged.\n\n".fg(226)
|
2655
|
+
upload_text << "Workflow:\n".fg(226)
|
2656
|
+
upload_text << " 1. Press Ctrl+E to exit remote mode\n".fg(240)
|
2657
|
+
upload_text << " 2. Navigate and tag files with 't'\n".fg(240)
|
2658
|
+
upload_text << " 3. Press Ctrl+E to return to remote mode\n".fg(240)
|
2659
|
+
upload_text << " 4. Press 'u' to upload tagged files\n\n".fg(240)
|
2660
|
+
upload_text << "Options:\n".fg(226)
|
2661
|
+
upload_text << " 'i' = Upload individual file\n".fg(240)
|
2662
|
+
upload_text << " 'l' = Show local directory for tagging\n".fg(240)
|
2663
|
+
upload_text << " Any other key = Cancel\n".fg(240)
|
2664
|
+
|
2665
|
+
@pR.say(upload_text)
|
2666
|
+
@pR.update = true
|
2667
|
+
|
2668
|
+
choice = getchr
|
2669
|
+
case choice
|
2670
|
+
when 'i', 'I'
|
2671
|
+
upload_individual_file
|
2672
|
+
when 'l', 'L'
|
2673
|
+
show_local_for_tagging
|
2674
|
+
else
|
2675
|
+
@pB.say("Upload cancelled".fg(240))
|
2676
|
+
@pR.update = true
|
2677
|
+
end
|
2678
|
+
end
|
2679
|
+
end
|
2680
|
+
|
2681
|
+
def upload_tagged_files # {{{3
|
2682
|
+
return unless @remote_mode
|
2683
|
+
|
2684
|
+
existing_files = @tagged.select { |f| File.exist?(f) }
|
2685
|
+
|
2686
|
+
if existing_files.empty?
|
2687
|
+
@pB.say("No valid tagged files to upload".fg(196))
|
2688
|
+
@pR.update = true
|
2689
|
+
return
|
2690
|
+
end
|
2691
|
+
|
2692
|
+
uploaded_count = 0
|
2693
|
+
failed_count = 0
|
2694
|
+
|
2695
|
+
existing_files.each do |local_file|
|
2696
|
+
begin
|
2697
|
+
remote_name = File.basename(local_file)
|
2698
|
+
remote_destination = File.join(@remote_path, remote_name)
|
2699
|
+
scp_cmd = build_scp_command(@current_remote, local_file, remote_destination, :upload)
|
2700
|
+
|
2701
|
+
@pB.say("Uploading #{File.basename(local_file)}...".fg(156))
|
2702
|
+
|
2703
|
+
if system(scp_cmd)
|
2704
|
+
uploaded_count += 1
|
2705
|
+
@pB.say("✓ #{File.basename(local_file)} uploaded".fg(156))
|
2706
|
+
else
|
2707
|
+
failed_count += 1
|
2708
|
+
@pB.say("✗ Failed to upload #{File.basename(local_file)}".fg(196))
|
2709
|
+
end
|
2710
|
+
rescue => e
|
2711
|
+
failed_count += 1
|
2712
|
+
@pB.say("✗ Error uploading #{File.basename(local_file)}: #{e.message}".fg(196))
|
2713
|
+
end
|
2714
|
+
end
|
2715
|
+
|
2716
|
+
@pB.say("Upload complete: #{uploaded_count} successful, #{failed_count} failed. Press 'r' to refresh if files don't appear.".fg(226))
|
2717
|
+
|
2718
|
+
# Refresh remote directory listing
|
2719
|
+
@remote_files_cache = []
|
2720
|
+
@pL.update = true
|
2721
|
+
@pR.update = true
|
2722
|
+
end
|
2723
|
+
|
2724
|
+
def upload_individual_file # {{{3
|
2725
|
+
return unless @remote_mode
|
2726
|
+
|
2612
2727
|
# Show upload prompt in right pane
|
2613
|
-
upload_text = "Upload File to Remote Directory\n\n".fg(156)
|
2728
|
+
upload_text = "Upload Individual File to Remote Directory\n\n".fg(156)
|
2614
2729
|
upload_text << "Current remote path: #{@remote_path}\n\n".fg(240)
|
2615
2730
|
upload_text << "Enter local file path to upload\n(or ESC to cancel):"
|
2616
2731
|
|
@@ -2659,7 +2774,7 @@ def remote_upload_file # {{{3
|
|
2659
2774
|
begin
|
2660
2775
|
result = system(scp_cmd)
|
2661
2776
|
if result
|
2662
|
-
@pB.say("Uploaded: #{local_file} -> #{remote_name}".fg(156))
|
2777
|
+
@pB.say("Uploaded: #{local_file} -> #{remote_name}. Press 'r' to refresh if not visible.".fg(156))
|
2663
2778
|
# Clear cache and refresh remote directory
|
2664
2779
|
connection_id = "#{@current_remote[:user]}@#{@current_remote[:host]}"
|
2665
2780
|
cache_key = "#{connection_id}:#{@remote_path}"
|
@@ -2676,6 +2791,62 @@ def remote_upload_file # {{{3
|
|
2676
2791
|
@pR.update = true # Restore normal right pane
|
2677
2792
|
end
|
2678
2793
|
|
2794
|
+
def show_local_for_tagging # {{{3
|
2795
|
+
return unless @remote_mode
|
2796
|
+
|
2797
|
+
# Temporarily exit remote mode for tagging
|
2798
|
+
@pB.say("Temporarily exiting remote mode for file tagging...".fg(156))
|
2799
|
+
|
2800
|
+
# Store current remote state
|
2801
|
+
saved_remote_mode = @remote_mode
|
2802
|
+
saved_remote_path = @remote_path
|
2803
|
+
saved_current_remote = @current_remote
|
2804
|
+
saved_remote_files_cache = @remote_files_cache
|
2805
|
+
|
2806
|
+
# Exit remote mode
|
2807
|
+
@remote_mode = false
|
2808
|
+
@current_remote = nil
|
2809
|
+
@remote_path = '~'
|
2810
|
+
@remote_files_cache = []
|
2811
|
+
|
2812
|
+
# Refresh local directory
|
2813
|
+
dirlist
|
2814
|
+
render
|
2815
|
+
|
2816
|
+
# Show tagging instructions
|
2817
|
+
tag_text = "Local File Tagging Mode\n\n".fg(156)
|
2818
|
+
tag_text << "You are now in local mode for tagging files.\n\n".fg(240)
|
2819
|
+
tag_text << "Instructions:\n".fg(226)
|
2820
|
+
tag_text << " 't' = Tag/untag files\n".fg(240)
|
2821
|
+
tag_text << " 'T' = Show tagged files\n".fg(240)
|
2822
|
+
tag_text << " 'u' = Clear all tags\n".fg(240)
|
2823
|
+
tag_text << " Navigate with arrow keys\n".fg(240)
|
2824
|
+
tag_text << " Tab/Shift+Tab = Switch tabs\n\n".fg(240)
|
2825
|
+
tag_text << "Press 'r' when done tagging to return to remote mode\n".fg(226)
|
2826
|
+
tag_text << "Press any other key to continue in local mode\n".fg(240)
|
2827
|
+
|
2828
|
+
@pR.say(tag_text)
|
2829
|
+
@pR.update = true
|
2830
|
+
|
2831
|
+
choice = getchr
|
2832
|
+
if choice == 'r' || choice == 'R'
|
2833
|
+
# Restore remote mode
|
2834
|
+
@remote_mode = saved_remote_mode
|
2835
|
+
@remote_path = saved_remote_path
|
2836
|
+
@current_remote = saved_current_remote
|
2837
|
+
@remote_files_cache = saved_remote_files_cache
|
2838
|
+
|
2839
|
+
# Refresh remote directory
|
2840
|
+
@pL.update = true
|
2841
|
+
@pR.update = true
|
2842
|
+
render
|
2843
|
+
|
2844
|
+
@pB.say("Returned to remote mode. Press 'u' to upload tagged files.".fg(156))
|
2845
|
+
else
|
2846
|
+
@pB.say("Staying in local mode. Press Ctrl+E to return to remote mode when ready.".fg(240))
|
2847
|
+
end
|
2848
|
+
end
|
2849
|
+
|
2679
2850
|
def parse_remote_connection(connection_string) # {{{3
|
2680
2851
|
# Support various formats:
|
2681
2852
|
# ssh://user@host/path
|
@@ -4655,6 +4826,13 @@ def showcontent # SHOW CONTENTS IN THE RIGHT WINDOW {{{2
|
|
4655
4826
|
@pR.clear
|
4656
4827
|
end
|
4657
4828
|
begin
|
4829
|
+
# Handle remote mode separately
|
4830
|
+
if @remote_mode && @files && @files[@index] && @remote_files_cache[@index]
|
4831
|
+
selected_file = @remote_files_cache[@index]
|
4832
|
+
show_remote_file_info(selected_file)
|
4833
|
+
return
|
4834
|
+
end
|
4835
|
+
|
4658
4836
|
if @selected && File.directory?(@selected)
|
4659
4837
|
@pR.say(dirlist(left: false))
|
4660
4838
|
else # Look up first matching handler
|