Files
deb-lite-xl/debian/extra/plugins/open_ext.lua
T
vhaudiquet 3bae6fd448 Bundle curated community plugins (2.1.8-4)
Vendored from upstream, pinned by commit (see debian/extra/README.source):
- gitstatus, gitopen, fontconfig, open_ext, select_colorscheme,
  smoothcaret, nerdicons (font mapping patched to DATADIR, Ships the
  Symbols Nerd Font Mono TTF, SIL OFL 1.1)
- lite-xl-lsp (complete LSP client; idle until a language server is
  configured) plus the lite-xl-widgets library it requires
- 104 language syntax plugins (none duplicate the nine bundled in core)

settings GUI left out upstream is broken: it requires a
libraries.widget.fonts widget that does not exist in
lite-xl-widgets at any revision.

Co-developed-with: ZCode (Z.ai)
2026-09-16 22:45:02 +02:00

163 lines
4.7 KiB
Lua

-- mod-version:3
-- The general idea is to check if the file opened is valid utf-8
-- since lite-xl only supports UTF8 text, others can be safely assumed
-- to be binary
local core = require "core"
local common = require "core.common"
local style = require "core.style"
local DocView = require "core.docview"
local RootView = require "core.rootview"
local View = require "core.view"
local function validate_utf8(s, max_len)
local i, p, len = 1, 1, #s
while p <= len and i <= max_len do
if p == s:find("[%z\1-\127]", p) then p = p + 1
elseif p == s:find("[\194-\223][\128-\191]", p) then p = p + 2
elseif p == s:find( "\224[\160-\191][\128-\191]", p)
or p == s:find("[\225-\236][\128-\191][\128-\191]", p)
or p == s:find( "\237[\128-\159][\128-\191]", p)
or p == s:find("[\238-\239][\128-\191][\128-\191]", p) then p = p + 3
elseif p == s:find( "\240[\144-\191][\128-\191][\128-\191]", p)
or p == s:find("[\241-\243][\128-\191][\128-\191][\128-\191]", p)
or p == s:find( "\244[\128-\143][\128-\191][\128-\191]", p) then p = p + 4
else
return false
end
i = i + 1
end
return true
end
local function replace_view(this, that)
local node = core.root_view.root_node:get_node_for_view(this)
local idx = node:get_view_idx(this)
node:remove_view(core.root_view.root_node, this)
node:add_view(that, idx)
core.root_view.root_node:update_layout()
core.redraw = true
end
local msg = "This file is not displayed because it is either binary or uses an unsupported text encoding."
local cmd -- here's evil code again...
if PLATFORM == "Windows" then
cmd = "start %q"
elseif PLATFORM == "Linux" then
cmd = "xdg-open %q"
else
cmd = "open %q"
end
local opt = { "Open anyway", "Open with other program", "Close" }
local opt_actions = {
function(self)
-- open anyway
local view = DocView(core.open_doc(self.filename))
replace_view(self, view)
end,
function(self)
-- open externally
local node = core.root_view.root_node:get_node_for_view(self)
node:close_view(core.root_view.root_node, self)
system.exec(string.format(cmd, self.filename))
end,
function(self)
local node = core.root_view.root_node:get_node_for_view(self)
node:close_view(core.root_view.root_node, self)
end
}
local OpenExtView = View:extend()
function OpenExtView:new(filename)
OpenExtView.super.new(self)
self.filename = filename
end
function OpenExtView:get_name()
return common.basename(self.filename)
end
function OpenExtView:each_option()
return coroutine.wrap(function()
local w = (self.size.x - style.padding.x * (#opt + 1)) / #opt
local h = style.font:get_height() + style.padding.y
local x, y = self:get_content_offset()
x = x + style.padding.x
y = y + self.size.y / 2 + style.padding.y
for i, o in ipairs(opt) do
coroutine.yield(i, o, x, y, w, h)
x = x + w + style.padding.x
end
end)
end
function OpenExtView:on_mouse_moved(px, py, dx, dy)
OpenExtView.super.on_mouse_moved(self, px, py, dx, dy)
self.hovered = nil
for i, _, x, y, w, h in self:each_option() do
if px > x and px <= x + w and py > y and py <= y + h then
self.hovered = i
break
end
end
end
function OpenExtView:on_mouse_pressed(button, x, y, clicks)
if OpenExtView.super.on_mouse_pressed(self, button, x, y, clicks) then return end
if self.hovered then
opt_actions[self.hovered](self)
end
end
function OpenExtView:draw()
self:draw_background(style.background)
local x, y = self:get_content_offset()
local lh = style.font:get_height()
y = y + self.size.y / 2 - style.padding.y - lh
common.draw_text(style.font, style.text, msg, "center", x, y, self.size.x, lh)
for i, opt, x, y, w, h in self:each_option() do
local text_color = i == self.hovered and style.background or style.text
renderer.draw_rect(x, y, w, h, style.accent)
if i ~= self.hovered then
renderer.draw_rect(x + 1, y + 1, w - 2, h - 2, style.background)
end
common.draw_text(style.font, text_color, opt, "center", x, y, w, h)
end
end
local function validate_doc(doc)
local f = io.open(doc.abs_filename or "")
if not f then return true end
local str = f:read(128 * 4) -- max bytes for 128 codepoints
f:close()
return validate_utf8(str or "", 128)
end
local rootview_open_doc = RootView.open_doc
function RootView:open_doc(doc)
-- 128 * 4 == max number of bytes for 128 codepoints
if validate_doc(doc) then
return rootview_open_doc(self, doc)
else
local node = self:get_active_node_default()
local view = OpenExtView(doc.abs_filename or doc.filename)
node:add_view(view)
self.root_node:update_layout()
return view
end
end