1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
local micro = import("micro")
local config = import("micro/config")
local strings = import("strings")
local filepath = import("filepath")
local shell = import("micro/shell")
local util = import("micro/util")
local os = import("os")
function runTvFiles(bp)
-- Change to the project directory (or file's directory as fallback) before running tv
local originalDir = nil
local workingDir = nil
if bp.Buf.Path and bp.Buf.Path ~= "" then
originalDir, _ = os.Getwd()
local fileDir = filepath.Dir(bp.Buf.Path)
-- Try to find project directory first
local projectDir = find_project_dir(fileDir)
if projectDir then
workingDir = projectDir
os.Chdir(projectDir)
else
workingDir = fileDir
os.Chdir(fileDir)
end
end
-- Run tv files command
local output, err = shell.RunInteractiveShell("tv files", false, true)
-- Restore original directory
if originalDir then
os.Chdir(originalDir)
end
if err ~= nil then
micro.InfoBar():Error("TV files command failed: " .. tostring(err))
return
end
if output == "" or output == nil then
micro.InfoBar():Message("tv files: no files selected")
return
end
-- Split output by newlines and open each file
local files = {}
for line in output:gmatch("[^\r\n]+") do
local trimmed = line:match("^%s*(.-)%s*$") -- trim whitespace
if trimmed ~= "" then
-- Convert path relative to working directory
local finalPath = trimmed
if workingDir then
finalPath = filepath.Join(workingDir, trimmed)
end
table.insert(files, {path = finalPath, line = nil})
end
end
if #files == 0 then
micro.InfoBar():Message("tv files: no files selected")
return
end
-- Open each file in a new tab
local openedCount = 0
for _, fileInfo in ipairs(files) do
local newTab = OpenTabFromFile(bp, fileInfo.path, fileInfo.line)
if newTab then
openedCount = openedCount + 1
else
micro.InfoBar():Error("File not found: " .. fileInfo.path)
end
end
if openedCount > 0 then
micro.InfoBar():Message("Opened " .. openedCount .. " files from TV files")
end
end
function runTvText(bp, args)
local cursor = bp.Cursor
local tvCmd
-- Check if there's a selection
if cursor:HasSelection() then
-- Get the selected text as bytes and convert to string
local selectionBytes = cursor:GetSelection()
local selection = util.String(selectionBytes)
if selection ~= "" then
-- Run with selected text
local escapedSelection = strings.Replace(selection, "'", "'\"'\"'", -1)
tvCmd = "tv text --input '" .. escapedSelection .. "'"
else
-- Empty selection, run without input
tvCmd = "tv text"
end
else
-- No selection, run without input
tvCmd = "tv text"
end
-- Change to the project directory (or file's directory as fallback) before running tv
local originalDir = nil
local workingDir = nil
if bp.Buf.Path and bp.Buf.Path ~= "" then
originalDir, _ = os.Getwd()
local fileDir = filepath.Dir(bp.Buf.Path)
-- Try to find project directory first
local projectDir = find_project_dir(fileDir)
if projectDir then
workingDir = projectDir
os.Chdir(projectDir)
micro.InfoBar():Message("Running tv from project root: " .. filepath.Base(projectDir))
else
workingDir = fileDir
os.Chdir(fileDir)
end
end
-- Run the tv command
local output, err = shell.RunInteractiveShell(tvCmd, false, true)
-- Restore original directory
if originalDir then
os.Chdir(originalDir)
end
if err ~= nil then
micro.InfoBar():Error("TV command failed: " .. tostring(err))
return
end
if output == "" or output == nil then
micro.InfoBar():Message("tv: nothing selected")
return
end
-- Split output by newlines and parse file:line format
local files = {}
for line in output:gmatch("[^\r\n]+") do
local trimmed = line:match("^%s*(.-)%s*$") -- trim whitespace
if trimmed ~= "" then
-- Parse file:line format by splitting on the last colon
local filePath, lineNum = trimmed:match("^(.+):(%d+)$")
if filePath and lineNum then
-- Found file:line format, convert path relative to working directory
if workingDir then
filePath = filepath.Join(workingDir, filePath)
end
table.insert(files, {path = filePath, line = tonumber(lineNum)})
else
-- No line number, just file path, convert path relative to working directory
local finalPath = trimmed
if workingDir then
finalPath = filepath.Join(workingDir, trimmed)
end
table.insert(files, {path = finalPath, line = nil})
end
end
end
if #files == 0 then
micro.InfoBar():Message("tv: nothing selected")
return
end
-- Open each file in a new tab
local openedCount = 0
for _, fileInfo in ipairs(files) do
local newTab = OpenTabFromFile(bp, fileInfo.path, fileInfo.line)
if newTab then
openedCount = openedCount + 1
else
micro.InfoBar():Error("File not found: " .. fileInfo.path)
end
end
if openedCount > 0 then
micro.InfoBar():Message("Opened " .. openedCount .. " files from TV")
end
end
|