Skip to content

Commit

Permalink
Merge pull request #133 from brianhuster/dev
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
brianhuster authored Oct 21, 2024
2 parents c72845c + d745009 commit 1f0786a
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Read release notes
id: read_release_notes
run: |
RELEASE_NOTES=$(cat RELEASE.md)
RELEASE_NOTES=$(sed 's/`/\\`/g' RELEASE.md)
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
echo "$RELEASE_NOTES" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/greetings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ jobs:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: "Thank you for your issue! We appreciate your feedback and will look into it as soon as possible. Please make sure to include all necessary details to help us assist you better."
issue-message: "Thank you for your issue! We appreciate your feedback and will look into it as soon as possible. Please make sure to include all necessary details to help us assist you better. Pull requests are also welcome!"
pr-message: "Thank you for your pull request! We appreciate your contribution. Please ensure that your changes are well documented and tested."
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ You can customize the plugin by passing a table to the `opts` variable (if you u
},
port = 5500, -- Port to run the live preview server on.
browser = 'default', -- Terminal command to open the browser for live-previewing (eg. 'firefox', 'flatpak run com.vivaldi.Vivaldi'). By default, it will use the default browser.
dynamic_root = false, -- If true, the plugin will set the root directory to the previewed file's directory. If false, the root directory will be the current working directory (`:lua print(vim.uv.cwd())`).
}
```

Expand All @@ -104,6 +105,7 @@ let g:livepreview_config = {
\ },
\ 'port': 5500, " Port to run the live preview server on.
\ 'browser': 'default', " Terminal command to open the browser for live-previewing (eg. 'firefox', 'flatpak run com.vivaldi.Vivaldi'). By default, it will use the default browser.
\ 'dynamic_root': v:false " If true, the plugin will set the root directory to the previewed file's directory. If false, the root directory will be the current working directory (`:pwd`).
\ }
```

Expand Down
2 changes: 2 additions & 0 deletions README.vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Bạn có thể tùy chỉnh plugin bằng cách đưa 1 bảng vào biến `opt
},
port = 5500, -- Cổng để chạy máy chủ live-preview
browser = 'default', -- Lệnh để mở trình duyệt (ví dụ 'firefox', 'flatpak run com.vivaldi.Vivaldi'. Giá trị 'default' là trình duyệt mặc định của hệ điều hành.
dynamic_root = false, -- Nếu true, thư mục gốc của server sẽ là thư mục mẹ của file được preview. Nếu false, plugin sẽ chạy máy chủ live-preview từ thư mục làm việc hiện tại (Bạn có thể xem thư mục làm việc hiện tại bằng lệnh `:pwd`).
}
```

Expand All @@ -99,6 +100,7 @@ let g:livepreview_config = {
\ },
\ 'port': 5500, " Cổng để chạy máy chủ live-preview
\ 'browser': 'default', " Lệnh để mở trình duyệt (ví dụ 'firefox', 'flatpak run com.vivaldi.Vivaldi'. Giá trị 'default' là trình duyệt mặc định của hệ điều hành.
\ 'dynamic_root': v:false, " Nếu v:true, thư mục gốc của server sẽ là thư mục mẹ của file được preview. Nếu v:false, plugin sẽ chạy máy chủ live-preview từ thư mục làm việc hiện tại (Bạn có thể xem thư mục làm việc hiện tại bằng lệnh `:pwd`).
\ }
```

Expand Down
8 changes: 6 additions & 2 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
### New features
### Breaking changes
- Default configuration : Now the plugin will use `:pwd` as the server root directory by default. See `dynamic_root` below
- Checkhealth : The plugin no longer check default open command (like `xdg-open`, `open`, `start`,...) in the checkhealth as the plugin now uses `vim.ui.open()` to open default browser. Visit Neovim repository for more about this function.

Code block syntax highlighting in markdown and Asciidoc files based on Github style (both light and dark themes are supported).
### New features
- New config option : `dynamic_root` (defaut : false) : If true, the plugin will set the root directory to the previewed file's directory. If false, the root directory will be the current working directory (`:pwd`).
- Checkhealth : The plugin now can check if the server is running, and its root directory. It can also check if the port is being used by another process and tell you its PID and process name.

**⚠️ Important Notice:** You should clear the cache of the browser after updating to ensure the plugin works correctly.
48 changes: 39 additions & 9 deletions doc/livepreview.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ setup({opts}) *livepreview.setup()*
• browser: string - browser to open the preview in (default:
"default"). The "default" value will open the preview in
system default browser.
• dynamic_root: boolean - whether to use dynamic root for the
server (default: false). Using dynamic root will always make
the server root the parent directory of the file being
previewed.

stop_preview() *livepreview.stop_preview()*
Stop live preview
Expand All @@ -43,12 +47,12 @@ Server class for live-preview.nvim To call this class, do >lua
*Server*

Fields: ~
{new} (`fun(self: Server, webroot: string)`) Constructor
{new} (`fun(self: Server, webroot: string?)`) Constructor
{routes} (`fun(self: Server, path: string): string`) Handle routes
• {watch_dir} (`fun(self: Server, func: function)`) Watch a directory
for changes and send a message "reload" to a WebSocket
client
{start} (`fun(self: Server, ip: string, port: number, func: function)`)
{start} (`fun(self: Server, ip: string, port: number, func: function?)`)
Start the server
{stop} (`fun(self: Server)`) Stop the server

Expand All @@ -57,7 +61,7 @@ Server:new({webroot}) *livepreview.server.Server:new()*
Constructor

Parameters: ~
{webroot} (`string`) path to the webroot
{webroot} (`string?`) path to the webroot

Server:routes({path}) *livepreview.server.Server:routes()*
Handle routes
Expand All @@ -74,7 +78,8 @@ Server:start({ip}, {port}, {func}) *livepreview.server.Server:start()*
Parameters: ~
{ip} (`string`) IP address to bind to
{port} (`number`) port to bind to
{func} (`function`)
{func} (`function?`) Function to call when there is a change in the
watched directory
• client uv_tcp_t: The uv_tcp client passed to func

Server:stop() *livepreview.server.Server:stop()*
Expand Down Expand Up @@ -233,7 +238,23 @@ await_term_cmd({cmd}) *livepreview.utils.await_term_cmd()*
Return: ~
(`table`) a table with fields code, stdout, stderr, signal

get_parent_path *livepreview.utils.get_parent_path*
*livepreview.utils.get_base_path()*
get_base_path({full_path}, {parent_path})
Extract base path from a file path Example: ```lua
get_base_path("/home/user/.config/nvim/lua/livepreview/utils.lua",
"/home/user/.config/nvim/") >
will return "lua/livepreview/utils.lua"
<

Parameters: ~
• {full_path} (`string`)
• {parent_path} (`string`)

Return: ~
(`string`)

*livepreview.utils.get_parent_path()*
get_parent_path({full_path}, {subpath})
Get the parent path of a subpath

Example: ```lua
Expand All @@ -258,6 +279,18 @@ get_path_lua_file() *livepreview.utils.get_path_lua_file()*
get_plugin_path() *livepreview.utils.get_plugin_path()*
Get the path where live-preview.nvim is installed

joinpath({...}) *livepreview.utils.joinpath()*
Join paths using the correct separator for the OS

Parameters: ~
{...} (`string`) paths to join

Return: ~
(`string`) the joined path example: ```lua joinpath("home", "user",
"file.txt") -- returns "home/user/file.txt" joinpath("home", "user",
"folder", "../file.txt") -- returns "home/user/file.txt" >
<

kill_port({port}) *livepreview.utils.kill_port()*
Kill a process which is not Neovim running on a port

Expand Down Expand Up @@ -334,12 +367,9 @@ the commands to open browser are available.


check() *livepreview.health.check()*
Run health check for Live Preview. This can also be run using
Run checkhealth for Live Preview. This can also be called using
`:checkhealth livepreview`

See also: ~
https://neovim.io/doc/user/health.html

is_compatible({ver}, {range}) *livepreview.health.is_compatible()*
Check if the version is compatible with the range

Expand Down
4 changes: 3 additions & 1 deletion doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ livepreview.setup() livepreview.txt /*livepreview.setup()*
livepreview.stop_preview() livepreview.txt /*livepreview.stop_preview()*
livepreview.utils livepreview.txt /*livepreview.utils*
livepreview.utils.await_term_cmd() livepreview.txt /*livepreview.utils.await_term_cmd()*
livepreview.utils.get_parent_path livepreview.txt /*livepreview.utils.get_parent_path*
livepreview.utils.get_base_path() livepreview.txt /*livepreview.utils.get_base_path()*
livepreview.utils.get_parent_path() livepreview.txt /*livepreview.utils.get_parent_path()*
livepreview.utils.get_path_lua_file() livepreview.txt /*livepreview.utils.get_path_lua_file()*
livepreview.utils.get_plugin_path() livepreview.txt /*livepreview.utils.get_plugin_path()*
livepreview.utils.joinpath() livepreview.txt /*livepreview.utils.joinpath()*
livepreview.utils.kill_port() livepreview.txt /*livepreview.utils.kill_port()*
livepreview.utils.open_browser() livepreview.txt /*livepreview.utils.open_browser()*
livepreview.utils.sha1() livepreview.txt /*livepreview.utils.sha1()*
Expand Down
74 changes: 59 additions & 15 deletions lua/livepreview/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
--- This will check if your Neovim version is compatible with Live Preview and if the commands to open browser are available.

local spec = require("livepreview.spec")
local await_term_cmd = require("livepreview.utils").await_term_cmd
local nvim_ver_range = spec().engines.nvim
local nvim_ver_table = vim.version()
local nvim_ver = string.format("%d.%d.%d", nvim_ver_table.major, nvim_ver_table.minor, nvim_ver_table.patch)
Expand All @@ -21,33 +22,76 @@ function M.is_compatible(ver, range)
return requirement:has(ver)
end

local function checkhealth_command(cmd)
if vim.fn.executable(cmd) then
vim.health.ok(cmd)
local function checkhealth_port(port)
local cmd
if vim.uv.os_uname().version:match("Windows") then
cmd = string.format([[
Get-NetTCPConnection -LocalPort %d | Where-Object { $_.State -eq 'Listen' } | ForEach-Object {
$pid = $_.OwningProcess
$process = Get-Process -Id $pid -ErrorAction SilentlyContinue
$process.Id
}
]], port)
else
vim.health.warn(cmd .. " not available")
cmd = string.format("lsof -i:%d | grep LISTEN | awk '{print $2}'", port)
end
local cmd_result = await_term_cmd(cmd)
local pid = vim.split(cmd_result.stdout, "\n")[1]

local function getProcessName(processID)
local command
if vim.uv.os_uname().version:match("Windows") then
command = string.format([[
Get-Process -Id %d | Select-Object -ExpandProperty Name
]], processID)
else
command = string.format("ps -p %d -o comm=", processID)
end
local result = await_term_cmd(command)
local name = result.stdout
if not name or #name == 0 then
return ''
else
return vim.split(name, "\n")[1]
end
end
if not pid or #pid == 0 then
vim.health.warn("Server is not running at port " .. port)
return
else
if tonumber(pid) == vim.uv.os_getpid() then
vim.health.ok("Server is healthy on port " .. port)
local serverObj = require('livepreview').serverObj
if serverObj and serverObj.webroot then
vim.health.ok("Server root: " .. serverObj.webroot)
end
else
local process_name = getProcessName(pid)
vim.health.warn(
string.format([[The port %d is being used by another process: %s (PID: %s).]],
port, process_name, pid
)
)
end
end
end


--- Run health check for Live Preview. This can also be run using `:checkhealth livepreview`
--- @see https://neovim.io/doc/user/health.html
--- Run checkhealth for Live Preview. This can also be called using `:checkhealth livepreview`
function M.check()
vim.health.start("Live Preview Health Check")
vim.health.start("Check compatibility")
if not M.is_compatible(nvim_ver, nvim_ver_range) then
vim.health.warn(
vim.health.error(
"Live Preview requires Neovim " .. nvim_ver_range .. ", but you are using " .. nvim_ver
)
else
vim.health.ok("Neovim version is compatible with Live Preview")
vim.health.ok("Neovim is compatible with Live Preview")
end

vim.health.info("\n")
vim.health.info(
"For Live Preview to open default browser, at least one of these commands must be executable. If you have specified a custom browser in your configuration, you can ignore this message.")
local open_cmds = { "xdg-open", "open", "start", "rundll32", "wslview" }
for _, cmd in ipairs(open_cmds) do
checkhealth_command(cmd)
if (require("livepreview").config.port) then
vim.health.start("Checkhealth server and process")
vim.health.info("This Nvim process's PID is " .. vim.uv.os_getpid())
checkhealth_port(require("livepreview").config.port)
end
end

Expand Down
50 changes: 26 additions & 24 deletions lua/livepreview/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,14 @@

local M = {}

M.config = {}
M.server = require("livepreview.server")
M.utils = require("livepreview.utils")
M.spec = require("livepreview.spec")
M.health = require("livepreview.health")
M.template = require("livepreview.template")

local server

local default_options = {
commands = {
start = "LivePreview",
stop = "StopPreview",
},
port = 5500,
browser = "default",
}

M.serverObj = nil

local function find_buf() -- find html/md buffer
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
Expand All @@ -40,28 +31,28 @@ end

--- Stop live preview
function M.stop_preview()
server:stop()
M.serverObj:stop()
end

--- Start live preview
---@param filepath string: path to the file
---@param port number: port to run the server on
function M.preview_file(filepath, port)
M.utils.kill_port(port)
if server then
server:stop()
if M.serverObj then
M.serverObj:stop()
end
server = M.server.Server:new(vim.fs.dirname(filepath))
M.serverObj = M.server.Server:new(vim.fs.dirname(filepath) and M.config.dynamic_root or nil)
vim.wait(50, function()
server:start("127.0.0.1", port, function(client)
M.serverObj:start("127.0.0.1", port, function(client)
if M.utils.supported_filetype(filepath) == 'html' then
M.server.websocket.send_json(client, { type = "reload" })
else
local content = M.utils.uv_read_file(filepath)
M.server.websocket.send_json(client, { type = "update", content = content })
end
end)
end, 99)
end, 98)
end

--- Setup live preview
Expand All @@ -70,10 +61,21 @@ end
--- (default: {start = "LivePreview", stop = "StopPreview"})
--- - port: number - port to run the server on (default: 5500)
--- - browser: string - browser to open the preview in (default: "default"). The "default" value will open the preview in system default browser.
--- - dynamic_root: boolean - whether to use dynamic root for the server (default: false). Using dynamic root will always make the server root the parent directory of the file being previewed.
function M.setup(opts)
opts = vim.tbl_deep_extend("force", default_options, opts or {})
local default_options = {
commands = {
start = "LivePreview",
stop = "StopPreview",
},
port = 5500,
browser = "default",
dynamic_root = false,
}

M.config = vim.tbl_deep_extend("force", default_options, opts or {})

vim.api.nvim_create_user_command(opts.commands.start, function()
vim.api.nvim_create_user_command(M.config.commands.start, function()
local filepath = vim.fn.expand('%:p')
if not M.utils.supported_filetype(filepath) then
filepath = find_buf()
Expand All @@ -85,16 +87,16 @@ function M.setup(opts)
M.utils.open_browser(
string.format(
"http://localhost:%d/%s",
opts.port,
vim.fs.basename(filepath)
M.config.port,
vim.fs.basename(filepath) and M.config.dynamic_root or M.utils.get_base_path(filepath, vim.uv.cwd())
),
opts.browser
M.config.browser
)

M.preview_file(filepath, opts.port)
M.preview_file(filepath, M.config.port)
end, {})

vim.api.nvim_create_user_command(opts.commands.stop, function()
vim.api.nvim_create_user_command(M.config.commands.stop, function()
M.stop_preview()
print("Live preview stopped")
end, {})
Expand Down
Loading

0 comments on commit 1f0786a

Please sign in to comment.