diff options
author | Francesco <francesco.bbt@gmail.com> | 2021-09-17 23:08:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-17 23:08:34 +0200 |
commit | 4ca1820bac33aea51a9708f7040674b1150ceaeb (patch) | |
tree | 188ed878de7ac421409aa16edf91fd25ac89f54c | |
parent | faa205148a67d3ac9ece82fb0237283ce57ed282 (diff) | |
parent | 68461a4c89e81d651c9d9af8ffe649606d9d062e (diff) | |
download | lite-xl-plugins-4ca1820bac33aea51a9708f7040674b1150ceaeb.tar.gz lite-xl-plugins-4ca1820bac33aea51a9708f7040674b1150ceaeb.zip |
Merge pull request #64 from takase1121/open_ext
add open_ext.lua
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | plugins/open_ext.lua | 187 |
2 files changed, 188 insertions, 0 deletions
@@ -112,6 +112,7 @@ Plugin | Description [`motiontrail`](plugins/motiontrail.lua?raw=1) | Adds a motion-trail to the caret *([screenshot](https://user-images.githubusercontent.com/3920290/83256814-085ccb00-a1ab-11ea-9e35-e6633cbed1a9.gif))* ~~[`nagbar`](https://github.com/takase1121/lite-nagbar)*~~ | integrated in lite-xl ~~consistent and _beautiful_ confirmation dialogs for lite and lite-xl *([gif](https://raw.githubusercontent.com/takase1121/lite-nagbar/master/assets/preview.gif))*~~ [`navigate`](plugins/navigate.lua?raw=1) | Allows moving back and forward between document positions, reducing the amount of scrolling +[`open_ext`](plugins/open_ext.lua?raw=1) | Automatically prompts you if you tried to open a binary file in the editor [`openfilelocation`](plugins/openfilelocation.lua?raw=1) | Opens the parent directory of the current file in the file manager [`openselected`](plugins/openselected.lua?raw=1) | Opens the selected filename or url ~~[`projectmanager`](plugins/projectmanager.lua?raw=1)~~ | Integrated in lite-xl with improvements ~~Save projects and load/reload them quickly~~ diff --git a/plugins/open_ext.lua b/plugins/open_ext.lua new file mode 100644 index 0000000..f01ab85 --- /dev/null +++ b/plugins/open_ext.lua @@ -0,0 +1,187 @@ +-- mod-version:2 -- lite-xl 2.0 + +-- 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, limit) + --[[ + MIT LICENSE + Copyright (c) 2013 Enrique GarcĂa Cota + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ]] + limit = limit or math.huge + local i, p, len = 1, 1, #s + while p <= 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 + if i > limit then break end + 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 read_from_doc(doc, limit) + local l, result = 0, {} + for _, line in ipairs(doc.lines) do + result[#result+1] = line + l = l + #line + if l >= limit then break end + end + return table.concat(result, "") +end + + +local rootview_open_doc = RootView.open_doc +function RootView:open_doc(doc) + local str = read_from_doc(doc, 4 * 128) -- max size for 128 codepoints + if str == "\n" or str == "" and validate_utf8(str, 128) 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 |