-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathutils.lua
More file actions
180 lines (154 loc) · 4.74 KB
/
utils.lua
File metadata and controls
180 lines (154 loc) · 4.74 KB
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
local notify = require("code_runner.hooks.notify")
local Singleton = require("code_runner.singleton")
local pattern = "crunner_"
-- Cache for variable replacement results
local var_cache = setmetatable({}, { __mode = "kv" }) -- weak cache table
local Utils = {}
Utils.__index = Utils
function Utils:ctor(opt)
assert(opt, "opt is required")
self.opt = opt
self.btm_number = self.opt.better_term.init
self._user_argument = {}
-- Pre-initialize mode table to avoid recreating it each time
self.modes = {
term = function(command, bufname)
self:execute(command, bufname)
end,
tab = function(command, bufname)
self:execute(command, bufname, "tabnew")
end,
float = function(command)
require("code_runner.floats").floating(command)
end,
better_term = function(command)
self:betterTerm(command)
end,
toggleterm = function(command)
local ok, toggleterm = pcall(require, "toggleterm")
if ok then
toggleterm.exec(command)
else
notify.error("The 'toggleterm' plugin is not installed.", "Toggleterm")
end
end,
vimux = function(command)
if vim.fn.exists(":VimuxRunCommand") == 2 then
vim.fn.VimuxRunCommand(command)
else
notify.error(
"The 'VimuxRunCommand' does not exist. Please add 'preservim/vimux' plugin to your dependencies.",
"Vimux"
)
end
end,
}
end
function Utils:setUserArgument(user_argument)
self._user_argument = user_argument
end
function Utils:replaceVars(command, path)
-- Process function commands
if type(command) == "function" then
local cmd = command(self._user_argument)
if type(cmd) == "string" then
command = cmd
elseif type(cmd) == "table" then
command = table.concat(cmd, " ")
else
return nil
end
end
-- Check if we already have the result cached
local cache_key = command .. ":" .. path
local cached = var_cache[cache_key]
if cached then
return cached
end
local no_sub_command = command
-- Pre-calculate replacement values to avoid multiple vim.fn calls
local file_info = {
nameWithoutExt = vim.fn.shellescape(vim.fn.fnamemodify(path, ":t:r")),
name = vim.fn.shellescape(vim.fn.fnamemodify(path, ":t")),
dir = vim.fn.shellescape(vim.fn.fnamemodify(path, ":p:h")),
}
-- Use gsub once with a replacement function
command = command:gsub("%$(%w+)", function(var)
if var == "fileNameWithoutExt" then
return file_info.nameWithoutExt
elseif var == "fileName" then
return file_info.name
elseif var == "file" then
return vim.fn.shellescape(path)
elseif var == "dir" then
return file_info.dir
elseif var == "end" then
return ""
else
return "$" .. var
end
end)
if command == no_sub_command then
command = command .. " " .. vim.fn.shellescape(path)
end
-- Store result in cache
var_cache[cache_key] = command
return command
end
function Utils:getCommand(filetype, path)
path = path or vim.fn.expand("%:p")
local command = self.opt.filetype[filetype]
return command and self:replaceVars(command, path) or nil
end
function Utils:close(bufname)
bufname = bufname or pattern .. vim.fn.expand("%:t:r")
local current_buf = vim.fn.bufname("%")
if current_buf:find(pattern, 1, true) then -- use direct search instead of string.find
vim.cmd("bwipeout!")
else
local bufid = vim.fn.bufnr(bufname)
if bufid ~= -1 then
vim.cmd("bwipeout! " .. bufid)
end
end
end
function Utils:execute(command, bufname, prefix)
prefix = prefix or self.opt.prefix
self:close(bufname)
bufname = "file " .. bufname
local current_win_id = vim.api.nvim_get_current_win()
vim.cmd(prefix)
vim.fn.termopen(command)
-- Group local operations
local buf = vim.api.nvim_get_current_buf()
vim.api.nvim_buf_set_option(buf, "relativenumber", false)
vim.api.nvim_buf_set_option(buf, "number", false)
vim.api.nvim_buf_set_option(buf, "filetype", "crunner")
vim.cmd(bufname)
if prefix ~= "tabnew" then
vim.bo.buflisted = false
end
if self.opt.focus then
vim.cmd(self.opt.insert_prefix)
else
vim.fn.win_gotoid(current_win_id)
end
end
function Utils:betterTerm(command)
local betterTerm = package.loaded["betterTerm"] or require("betterTerm")
if betterTerm then
self.btm_number = self.opt.better_term.number or (self.btm_number + 1)
betterTerm.send(command, self.btm_number, { clean = self.opt.clean })
end
end
function Utils:runMode(command, bufname, mode)
mode = mode or self.opt.mode
bufname = pattern .. bufname
local mode_func = self.modes[mode]
if not mode_func then
notify.warn(":( mode not found, Select valid mode", "Project")
return
end
mode_func(command, bufname)
end
return Singleton(Utils)