Skip to content

Commit

Permalink
Merge pull request #279 from brianhuster/dev
Browse files Browse the repository at this point in the history
Fix #271
  • Loading branch information
brianhuster authored Jan 18, 2025
2 parents 9f1da87 + 8504013 commit 802f597
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 50 deletions.
22 changes: 19 additions & 3 deletions lua/livepreview/config.lua
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
local M = {}

M.config = {
picker = nil,
---@enum Picker
M.pickers = {
telescope = "telescope",
fzflua = "fzf-lua",
minipick = "mini.pick",
}

---@class Config
---@field picker Picker? picker to use to quickly open HTML/Markdown/Asciidoc/SVG files and run live-preview server
---@field autokill boolean? DEPRECATED
---@field port number? port to run the server on
---@field browser string? browser to open the preview in
---@field dynamic_root boolean? Whether to use the basename of the file as the root
---@field sync_scroll boolean? Whether to sync scroll the preview with the editor
M.default_config = {
picker = "fzf-lua",
autokill = false,
port = 5500,
browser = "default",
dynamic_root = false,
sync_scroll = true,
}

M.config = vim.deepcopy(M.default_config)

--- Configure live-preview.nvim
--- @param opts {port: number, browser: string, sync_scroll: boolean, dynamic_root: boolean, autokill: boolean, picker: string?}|nil
--- @param opts Config?
function M.set(opts)
M.config = vim.tbl_deep_extend("force", M.config, opts or {})
end
Expand Down
21 changes: 4 additions & 17 deletions lua/livepreview/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ M.nvim_ver = string.format("%d.%d.%d", nvim_ver_table.major, nvim_ver_table.mino
--- @return boolean: true if compatible, false otherwise
local function is_compatible(ver, range)
local requirement = vim.version.range(range)
return requirement:has(ver)
return requirement and requirement:has(ver) or false
end

--- Check if the current Nvim version is compatible with Live Preview
Expand Down Expand Up @@ -74,17 +74,10 @@ local function checkhealth_port(port)
end
end

---@TODO: Will check if the config is valid (only has valid keys)
local function check_config()
local config = require("livepreview.config").config
if not config then
vim.health.warn(
"Setup function not called",
"Please add `require('livepreview').setup()` to your Lua config or `lua require('livepreview').setup()` to your Vimscript config for Nvim"
)
return
else
vim.health.info(vim.inspect(config))
end
vim.health.info(vim.inspect(config))
end

--- Run checkhealth for Live Preview. This can also be called using `:checkhealth livepreview`
Expand All @@ -109,13 +102,7 @@ function M.check()
vim.health.ok(string.format("`%s` is available", shell))
end

--- Check dependant plugins
local dependencies = {
"telescope",
"fzf-lua",
"mini.pick",
}
for _, dep in ipairs(dependencies) do
for _, dep in pairs(require("livepreview.config").pickers) do
local ok, _ = pcall(require, dep)
if not ok then
vim.health.warn(string.format("`%s` (optional) is not installed", dep))
Expand Down
14 changes: 7 additions & 7 deletions lua/livepreview/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,17 @@ function M.pick()
)
end

local pickers = {
["telescope"] = picker.telescope,
["fzf-lua"] = picker.fzflua,
["mini.pick"] = picker.minipick,
}
local picker_funcs = {}
for k, v in pairs(config.pickers) do
picker_funcs[v] = picker[k]
end

if config.config.picker then
if not pickers[config.config.picker] then
if not picker_funcs[config.config.picker] then
vim.notify("Error : picker opt invalid", vim.log.levels.ERROR)
return
end
local status, err = pcall(pickers[config.config.picker], pick_callback)
local status, err = pcall(picker_funcs[config.config.picker], pick_callback)
if not status then
vim.notify("live-preview.nvim : error calling picker " .. config.config.picker, vim.log.levels.ERROR)
vim.notify(err, vim.log.levels.ERROR)
Expand Down
2 changes: 1 addition & 1 deletion lua/livepreview/server/utils/etag.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ local template_path = vim.fs.joinpath(plugin_path, "lua/livepreview/template.lua
--- Generate an ETag for a file
--- The Etag is generated based on the modification time of the file
--- @param file_path string: path to the file
--- @return string | nil: ETag
--- @return string?: ETag
function M.generate(file_path)
local etag
local attr = vim.uv.fs_stat(file_path)
Expand Down
32 changes: 20 additions & 12 deletions lua/livepreview/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@

local M = {}

local uv = vim.uv
local fs = vim.fs
local bit = require("bit")
local api = vim.api

--- Extract base path from a file path
--- Example: ```lua
--- get_relative_path("/home/user/.config/nvim/lua/livepreview/utils.lua", "/home/user/.config/nvim/")
--- ```
--- will return "lua/livepreview/utils.lua"
---
--- @TODO Use vim.fs.relpath
---
--- @param full_path string
--- @param parent_path string
--- @return string
--- @return string?
function M.get_relative_path(full_path, parent_path)
if parent_path:sub(-1) ~= "/" then
parent_path = parent_path .. "/"
Expand Down Expand Up @@ -48,6 +46,7 @@ end
--- find a html/md/adoc/svg buffer in buffer list
--- @return string|nil
function M.find_supported_buf()
local api = vim.api
for _, buf in ipairs(api.nvim_list_bufs()) do
if api.nvim_buf_is_loaded(buf) then
local buf_name = api.nvim_buf_get_name(buf)
Expand All @@ -64,7 +63,7 @@ end
--- @return table: List of relative paths (compared to `directory`) of the supported files
function M.list_supported_files(directory)
directory = vim.fn.fnamemodify(directory, ":p")
local files = fs.find(function(name, _)
local files = vim.fs.find(function(name, _)
return not not M.supported_filetype(name)
end, { limit = math.huge, type = "file" })
for i, file in ipairs(files) do
Expand All @@ -81,7 +80,7 @@ function M.get_plugin_path()
local full_path = source and source:sub(1, 1) == "@" and source:sub(2)
local subpath = "lua/livepreview/utils.lua"
local plugin_path = full_path and full_path:sub(1, -1 - #subpath)
return plugin_path and fs.normalize(plugin_path)
return plugin_path and vim.fs.normalize(plugin_path)
end

--- Read a file
Expand All @@ -102,6 +101,7 @@ end
--- @param path string: path to the file
--- @param callback function: function to call when the file is read
function M.async_read_file(path, callback)
local uv = vim.uv
uv.fs_open(path, "r", 438, function(err_open, fd)
if err_open or not fd then
return callback(err_open)
Expand All @@ -118,6 +118,11 @@ function M.async_read_file(path, callback)
end)
end

---@return boolean
function M.isWindows()
return vim.uv.os_uname().version:match("Windows")
end

--- Execute a shell commands
---@async
---@param cmd string: terminal command to execute. Term_cmd will use sh or pwsh depending on the OS
Expand All @@ -128,7 +133,7 @@ end
--- - stderr: the standard error of the command
function M.term_cmd(cmd, callback)
local shell = "sh"
if uv.os_uname().version:match("Windows") then
if M.isWindows() then
shell = "pwsh"
end

Expand All @@ -150,19 +155,22 @@ end
---@return {code: number, signal: number, stdout: string, stderr: string}: a table with fields code, stdout, stderr, signal
function M.await_term_cmd(cmd)
local shell = "sh"
if uv.os_uname().version:match("Windows") then
if M.isWindows() then
shell = "pwsh"
end
local results = vim.system({ shell, "-c", cmd }, { text = true }):wait()
return results
end

--- Compute the SHA1 hash of a string.
---@copyright (C) 2007 [Free Software Foundation, Inc](https://fsf.org/).
---@license [GPLv3](https://www.gnu.org/licenses/gpl-3.0.html).
---
--- Copyright (C) 2007 [Free Software Foundation, Inc](https://fsf.org/).
---@param val string
---@return string: SHA1 hash
function M.sha1(val)
local bit = require("bit")

local function to_32_bits_str(number)
return string.char(bit.band(bit.rshift(number, 24), 255))
.. string.char(bit.band(bit.rshift(number, 16), 255))
Expand Down Expand Up @@ -264,7 +272,7 @@ end

--- Get a list of processes listening on a port
--- @param port number
--- @return {name : string, pid : number}[]: a table with the processes listening on the port (except for the current process), including name and PID
--- @return {name : string, pid : number}[]|{}: a table with the processes listening on the port (except for the current process), including name and PID
function M.processes_listening_on_port(port)
local cmd
if vim.uv.os_uname().version:match("Windows") then
Expand Down
16 changes: 6 additions & 10 deletions plugin/livepreview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,11 @@ api.nvim_create_user_command(cmd, function(cmd_opts)
end
filepath = fs.normalize(filepath)
lp.start(filepath, Config.port)
filepath = filepath:gsub(" ", "%%20")
utils.open_browser(
("http://localhost:%d/%s"):format(
Config.port,
Config.dynamic_root and fs.basename(filepath)
or utils.get_relative_path(filepath, fs.normalize(vim.uv.cwd() or ""))
),
Config.browser
)
local urlpath = (Config.dynamic_root and fs.basename(filepath) or utils.get_relative_path(
filepath,
fs.normalize(vim.uv.cwd() or "")
)):gsub(" ", "%%20")
utils.open_browser(("http://localhost:%d/%s"):format(Config.port, urlpath), Config.browser)
elseif subcommand == "close" then
lp.close()
print("Live preview stopped")
Expand All @@ -75,7 +71,7 @@ api.nvim_create_user_command(cmd, function(cmd_opts)
end, {
nargs = "*",
complete = function(ArgLead, CmdLine, CursorPos)
local subcommands = { "start", "close", "pick", "help" }
local subcommands = { "start", "close", "pick", "-h", "--help" }
local subcommand = vim.split(CmdLine, " ")[2]
if subcommand == "" then
return subcommands
Expand Down

0 comments on commit 802f597

Please sign in to comment.