Skip to content

Commit

Permalink
feat(action)!: add clipboard action (#36)
Browse files Browse the repository at this point in the history
Breaking changes: removed `config.navigate_method` for `config.default_action`. Please see #36 for additional information.
  • Loading branch information
axieax committed Sep 19, 2022
1 parent 9444445 commit f91b831
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ require("urlview").setup({
-- Command or method to open links with
-- Options: "netrw", "system" (default OS browser); or "firefox", "chromium" etc.
-- By default, this is "netrw", or "system" if netrw is disabled
navigate_method = "netrw",
default_action = "netrw",
-- Ensure links shown in the picker are unique (no duplicates)
unique = true,
-- Ensure links shown in the picker are sorted alphabetically
Expand Down
59 changes: 59 additions & 0 deletions lua/urlview/actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
local M = {}

local utils = require("urlview.utils")

--- Use command to open the URL
---@param cmd string @name of executable to run
---@param raw_url string @unescaped URL to be run by the executable
local function shell_exec(cmd, raw_url)
if cmd and vim.fn.executable(cmd) then
-- NOTE: `vim.fn.system` shellescapes arguments
local err = vim.fn.system({ cmd, raw_url })
if err ~= "" then
utils.log(string.format("Could not navigate link with `%s`:\n%s", cmd, err))
end
else
utils.log(string.format("Cannot use %s to navigate links", cmd), vim.log.levels.DEBUG)
end
end

--- Use `netrw` to navigate to a URL
---@param raw_url string @unescaped URL
function M.netrw(raw_url)
local url = vim.fn.shellescape(raw_url)
local ok, err = pcall(vim.cmd, string.format("call netrw#BrowseX(%s, netrw#CheckIfRemote(%s))", url, url))
if not ok and vim.startswith(err, "Vim(call):E117: Unknown function") then
-- lazily use system action if netrw is disabled
M.system(raw_url)
end
end

--- Use the user's default browser to navigate to a URL
---@param raw_url string @unescaped URL
function M.system(raw_url)
local os = vim.loop.os_uname().sysname
if os == "Darwin" then -- MacOS
shell_exec("open", raw_url)
elseif os == "Linux" or os == "FreeBSD" then -- Linux and FreeBSD
shell_exec("xdg-open", raw_url)
else
utils.log("Unsupported operating system for `system` action. Please raise a GitHub issue for " .. os)
end
end

--- Copy URL to clipboard
---@param raw_url string @unescaped URL
function M.clipboard(raw_url)
vim.api.nvim_command(string.format("let @+ = '%s'", raw_url))
utils.log(string.format("URL %s copied to clipboard", raw_url))
end

function M.__index(_, k)
if k ~= nil then
return function(raw_url)
return shell_exec(k, raw_url)
end
end
end

return setmetatable(M, M)
2 changes: 1 addition & 1 deletion lua/urlview/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ local default_config = {
-- Command or method to open links with
-- Options: "netrw", "system" (default OS browser); or "firefox", "chromium" etc.
-- By default, this is "netrw", or "system" if netrw is disabled
navigate_method = "netrw",
default_action = "netrw",
-- Ensure links shown in the picker are unique (no duplicates)
unique = true,
-- Ensure links shown in the picker are sorted alphabetically
Expand Down
12 changes: 12 additions & 0 deletions lua/urlview/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local M = {}

local actions = require("urlview.actions")
local config = require("urlview.config")
local pickers = require("urlview.pickers")
local search = require("urlview.search")
Expand All @@ -13,6 +14,7 @@ local utils = require("urlview.utils")
function M.search(ctx, opts)
ctx = utils.fallback(ctx, "buffer")
opts = utils.fallback(opts, {})
opts.action = utils.fallback(opts.action, config.default_action)
local picker = utils.fallback(opts.picker, config.default_picker)
if not opts.title then
local should_capitalise = string.match(config.default_title, "^%u")
Expand All @@ -25,6 +27,9 @@ function M.search(ctx, opts)
local links = search[ctx](opts)
links = utils.prepare_links(links, opts)
if links and not vim.tbl_isempty(links) then
if type(opts.action) == "string" then
opts.action = actions[opts.action]
end
pickers[picker](links, opts)
else
utils.log("No links found in context " .. ctx)
Expand Down Expand Up @@ -60,12 +65,19 @@ function M.command_search(...)
M.search(args[1], opts)
end

local function check_breaking()
if config.navigate_method then
utils.log("`config.navigate_method` has been deprecated for `config.default_action`")
end
end

--- Custom setup function
--- Not required to be called unless user wants to modify the default config
---@param user_config table (optional)
function M.setup(user_config)
user_config = utils.fallback(user_config, {})
config._options = vim.tbl_deep_extend("force", config._options, user_config)
check_breaking()

search_helpers.register_custom_searches(config.custom_searches)
end
Expand Down
4 changes: 2 additions & 2 deletions lua/urlview/pickers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function M.native(items, opts)
local options = { prompt = opts.title }
local function on_choice(item, _)
if item then
utils.navigate_url(item)
opts.action(item)
end
end

Expand Down Expand Up @@ -44,7 +44,7 @@ function M.telescope(items, opts)
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
if selection[1] then
utils.navigate_url(selection[1])
opts.action(selection[1])
end
end)
return true
Expand Down
39 changes: 1 addition & 38 deletions lua/urlview/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,42 +38,6 @@ function M.extract_pattern(content, capture, format)
return captures
end

--- Opens the url in the browser
---@param raw_url string
function M.navigate_url(raw_url)
local url = vim.fn.shellescape(raw_url)
local cmd = config.navigate_method
if cmd == "netrw" then
local ok, err = pcall(vim.cmd, string.format("call netrw#BrowseX(%s, netrw#CheckIfRemote(%s))", url, url))
if not ok and vim.startswith(err, "Vim(call):E117: Unknown function") then
-- lazily update default navigate method if netrw is disabled
config.navigate_method = "system"
cmd = "system"
else
return
end
end

if cmd == "system" then
local os = vim.loop.os_uname().sysname
if os == "Darwin" then -- MacOS
cmd = "open"
elseif os == "Linux" or os == "FreeBSD" then -- Linux and FreeBSD
cmd = "xdg-open"
end
end

if cmd and vim.fn.executable(cmd) then
-- NOTE: `vim.fn.system` shellescapes arguments
local err = vim.fn.system({ cmd, raw_url })
if err ~= "" then
M.log("could not navigate link with `navigate_method: system`:\n" .. err)
end
else
M.log(string.format("Cannot use %s to navigate links", cmd), vim.log.levels.DEBUG)
end
end

--- Prepare links before being displayed
---@param links table @list of extracted links
---@param opts table @Optional options
Expand All @@ -91,8 +55,7 @@ function M.prepare_links(links, opts)
end

-- Filter duplicate links
-- NOTE: links with different protocols / www prefix / trailing slashes
-- are not filtered to ensure links do not break
-- NOTE: links with different protocols / www prefix / trailing slashes are not filtered to ensure links do not break
if M.fallback(opts.unique, config.unique) then
local map = {}
for _, link in ipairs(new_links) do
Expand Down
2 changes: 1 addition & 1 deletion plugin/urlview.vim
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function! s:UrlViewCompletion(argLead, cmdLine, cursorPos)
" opts completion
let l:context = l:head[1]
let l:accepted_opts = luaeval("require('urlview.search.validation')['" . l:context . "']()")
let l:accepted_opts = l:accepted_opts + ['title', 'picker', 'sorted', 'unique']
let l:accepted_opts = l:accepted_opts + ['title', 'picker', 'action', 'sorted', 'unique']
let l:result = map(l:accepted_opts, {_, v -> v:val . '='})
endif
return join(sort(l:result), "\n")
Expand Down

0 comments on commit f91b831

Please sign in to comment.