Fortran · 3630 bytes Raw Blame History
1 module preview_ops
2 use filesystem_ops, only: MAX_PATH, join_path
3 implicit none
4 private
5
6 public :: get_file_preview, check_bat_available
7 public :: MAX_PREVIEW_LINES
8
9 integer, parameter :: MAX_PREVIEW_LINES = 100
10 logical, save :: bat_available = .false.
11 logical, save :: bat_checked = .false.
12
13 contains
14
15 function check_bat_available() result(has_bat)
16 logical :: has_bat
17 integer :: stat
18
19 if (.not. bat_checked) then
20 call execute_command_line("which bat > /dev/null 2>&1", exitstat=stat, wait=.true.)
21 bat_available = (stat == 0)
22 bat_checked = .true.
23 end if
24 has_bat = bat_available
25 end function check_bat_available
26
27 subroutine get_file_preview(filepath, is_dir, lines, line_count, max_lines)
28 character(len=*), intent(in) :: filepath
29 logical, intent(in) :: is_dir
30 character(len=*), dimension(:), intent(out) :: lines
31 integer, intent(out) :: line_count
32 integer, intent(in) :: max_lines
33 character(len=MAX_PATH) :: temp_file, cmd
34 integer :: unit, ios, i
35 logical :: has_bat
36
37 line_count = 0
38
39 ! Skip special files
40 if (trim(filepath) == "." .or. trim(filepath) == "..") then
41 lines(1) = "(special directory)"
42 line_count = 1
43 return
44 end if
45
46 ! Create temp file
47 call get_environment_variable("HOME", temp_file)
48 temp_file = trim(temp_file) // "/.fortress_preview"
49
50 if (is_dir) then
51 ! Preview directory with ls
52 write(cmd, '(a,a,a,i0,a,a)') "ls -lh '", trim(filepath), "' 2>/dev/null | head -", &
53 max_lines, " > ", trim(temp_file)
54 else
55 ! Check if file is likely binary
56 call execute_command_line("file -b '" // trim(filepath) // "' | grep -q text", exitstat=ios, wait=.true.)
57
58 if (ios == 0) then
59 ! Text file - use bat or cat
60 has_bat = check_bat_available()
61 if (has_bat) then
62 ! Use bat with syntax highlighting, no line numbers, limited lines
63 write(cmd, '(a,i0,a,a,a,a)') "bat --style=plain --color=always --line-range :", &
64 max_lines, " '", trim(filepath), "' 2>/dev/null > ", trim(temp_file)
65 else
66 ! Fallback to cat with head
67 write(cmd, '(a,a,a,i0,a,a)') "cat '", trim(filepath), "' 2>/dev/null | head -", &
68 max_lines, " > ", trim(temp_file)
69 end if
70 else
71 ! Binary file - show file type info
72 cmd = "file -b '" // trim(filepath) // "' > " // trim(temp_file)
73 end if
74 end if
75
76 ! Execute preview command
77 call execute_command_line(trim(cmd), wait=.true.)
78
79 ! Read preview into lines array
80 open(newunit=unit, file=temp_file, status='old', iostat=ios)
81 if (ios == 0) then
82 do i = 1, max_lines
83 read(unit, '(a)', iostat=ios) lines(i)
84 if (ios /= 0) exit
85 line_count = line_count + 1
86 end do
87 close(unit)
88 end if
89
90 ! Cleanup
91 call execute_command_line("rm -f " // trim(temp_file) // " 2>/dev/null")
92
93 ! Handle empty result
94 if (line_count == 0) then
95 lines(1) = "(empty or unreadable)"
96 line_count = 1
97 end if
98 end subroutine get_file_preview
99
100 end module preview_ops
101