Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package json handler #8

Merged
merged 4 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

* open links without `netrw`
* normal and visual mode support
* open links with/without an explicit protocol (e.g. `google.com` will open `https://google.com`)
* links with/without an explicit protocol (e.g. `google.com` will open `https://google.com`)
* open plugins in the browser with a single command (e.g. in lazy, packer you can hover over a plugin name, simply press `gx` and you get to the github page of the plugin)
* open github issues directly in the browser (e.g. `Fixes #22` opens `https://github.com/chrishrb/gx.nvim/issues/22`)
* plugins from `package.json` (e.g. line `"express": "^4.18.2",` in the `package.json` opens `https://www.npmjs.com/package/vue-router`)
* more to come (jira issues, ..)

## ⚡️ Requirements
Expand All @@ -26,6 +27,7 @@ require("lazy").setup({
{
"chrishrb/gx.nvim",
event = { "BufEnter" },
dependencies = { "nvim-lua/plenary.nvim" },
config = true, -- default settings

-- you can specify also another config if you want
Expand All @@ -34,6 +36,7 @@ require("lazy").setup({
handlers = {
plugin = true, -- open plugin links in lua (e.g. packer, lazy, ..)
github = true, -- open github issues
package_json = true, -- open plugins from package.json
},
} end,
},
Expand All @@ -50,5 +53,4 @@ When your cursor is over a link or you mark a link or part of a link with the vi

## 📄 Acknowledgements

* Source code of `shell.lua` is partly from [lua-shell](https://github.com/ncopa/lua-shell)
* lua functions library [plenary.nvim](https://github.com/nvim-lua/plenary.nvim)
29 changes: 13 additions & 16 deletions lua/gx/handler.lua
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
local helper = require("gx.helper")
local package_json_handler = require("gx.handlers.package_json")
local plugin_handler = require("gx.handlers.plugin")
local url_handler = require("gx.handlers.url")
local github_handler = require("gx.handlers.github")

local M = {}

local function is_correct_filetype(handler_filetype, file_filetype)
if not handler_filetype then
return true
end
if handler_filetype == file_filetype then
return true
end
return false
end

local function add_handler(handlers, handler, file_filetype, active)
if not active or not is_correct_filetype(handler.filetype, file_filetype) then
local function add_handler(handlers, handler, active)
if
not active
or not helper.check_filetype(handler.filetype)
or not helper.check_filename(handler.filename)
then
return
end
table.insert(handlers, handler)
end

-- handler function
function M.get_url(mode, line, file_filetype, activated_handlers)
function M.get_url(mode, line, activated_handlers)
local url
local handlers = {}
local tkeys = {}

-- ### add here new handlers
add_handler(handlers, plugin_handler, file_filetype, activated_handlers.plugin)
add_handler(handlers, github_handler, file_filetype, activated_handlers.github)
add_handler(handlers, url_handler, file_filetype, true)
add_handler(handlers, package_json_handler, activated_handlers.package_json)
add_handler(handlers, plugin_handler, activated_handlers.plugin)
add_handler(handlers, github_handler, activated_handlers.github)
add_handler(handlers, url_handler, true)
-- ###

for k in pairs(handlers) do
Expand Down
3 changes: 2 additions & 1 deletion lua/gx/handlers/github.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ local git = require("gx.git")

local M = {}

-- every filetype
-- every filetype and filename
M.filetype = nil
M.filename = nil

-- navigate to neovim github plugin url
function M.handle(mode, line)
Expand Down
19 changes: 19 additions & 0 deletions lua/gx/handlers/package_json.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
local helper = require("gx.helper")

local M = {}

-- only package.json
M.filetype = "json"
M.filename = "package.json"

-- navigate to neovim github plugin url
function M.handle(mode, line)
local pattern = '["]([^%s]*)["]:'
local npm_package = helper.find(line, mode, pattern)
if not npm_package then
return
end
return "https://www.npmjs.com/package/" .. npm_package
end

return M
2 changes: 2 additions & 0 deletions lua/gx/handlers/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ local helper = require("gx.helper")

local M = {}

-- every filename but only lua
M.filetype = "lua"
M.filename = nil

-- navigate to neovim github plugin url
function M.handle(mode, line)
Expand Down
5 changes: 3 additions & 2 deletions lua/gx/handlers/url.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ local M = {}

-- every filetype
M.filetype = nil
M.filename = nil

-- get url from line (with http/s)
function M.handle(mode, line)
local pattern = "(https?://[a-zA-Z0-9_/%-%.~@\\+#]+)"
local pattern = "(https?://[a-zA-Z0-9_/%-%.~@\\+#=?&]+)"
local url = helper.find(line, mode, pattern)

-- match url without http(s)
if not url then
pattern = "([a-zA-Z0-9_/%-%.~@\\+#]+%.[a-zA-Z0-9_/%-%.~@\\+#]+)"
pattern = "([a-zA-Z0-9_/%-%.~@\\+#]+%.[a-zA-Z0-9_/%-%.~@\\+#%=?&]+)"
url = helper.find(line, mode, pattern)
if url then
return "https://" .. url
Expand Down
29 changes: 29 additions & 0 deletions lua/gx/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,33 @@ function M.ternary(cond, T, F)
end
end

-- check for filetype
function M.check_filetype(handler_filetype)
local file_filetype = vim.bo.filetype
if not handler_filetype then
return true
end
if handler_filetype == file_filetype then
return true
end
return false
end

-- get filename
function M.get_filename()
return vim.fn.expand("%:t")
end

-- check for filename
function M.check_filename(handler_filename)
local filename = M.get_filename()
if not handler_filename then
return true
end
if handler_filename == filename then
return true
end
return false
end

return M
8 changes: 6 additions & 2 deletions lua/gx/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ local M = {}
local function search_for_url()
local line = vim.api.nvim_get_current_line()
local mode = vim.api.nvim_get_mode().mode
local filetype = vim.bo.filetype

-- cut if in visual mode
line = helper.cut_with_visual_mode(mode, line)

-- search for url
local url = handler.get_url(mode, line, filetype, M.options.handlers)
local url = handler.get_url(mode, line, M.options.handlers)

if not url then
return
Expand Down Expand Up @@ -56,6 +55,11 @@ local function with_defaults(options)
handlers = {
plugin = helper.ternary(options.handlers.plugin ~= nil, options.handlers.plugin, true),
github = helper.ternary(options.handlers.github ~= nil, options.handlers.github, true),
package_json = helper.ternary(
options.handlers.package_json ~= nil,
options.handlers.package_json,
true
),
},
}
end
Expand Down
86 changes: 52 additions & 34 deletions test/spec/gx/handler_spec.lua
Original file line number Diff line number Diff line change
@@ -1,79 +1,97 @@
local helper = require("gx.helper")
local handler = require("gx.handler")
local stub = require("luassert.stub")

describe("test handler", function()
local activated_handlers = {
plugin = false,
github = false,
package_json = false,
}

before_each(function()
before_mock_filetype = vim.bo.filetype
end)

after_each(function()
vim.bo.filetype = before_mock_filetype
end)

it("no extra handlers on", function()
local filetype = "lua"
-- mock filetype
vim.bo.filetype = "lua"

assert.equals("https://github.com", handler.get_url("v", "github.com", activated_handlers))
assert.equals(
"https://github.com",
handler.get_url("v", "github.com", filetype, activated_handlers)
handler.get_url("v", "https://github.com", activated_handlers)
)
assert.equals(
"https://github.com",
handler.get_url("v", "https://github.com", filetype, activated_handlers)
)
assert.equals(
nil,
handler.get_url("v", '"example_user/example_plugin"', "lua", activated_handlers)
)
assert.equals(nil, handler.get_url("v", "Fixes #22", filetype, activated_handlers))
assert.equals(nil, handler.get_url("v", '"example_user/example_plugin"', activated_handlers))
assert.equals(nil, handler.get_url("v", "Fixes #22", activated_handlers))
end)

it("plugin handler on", function()
local filetype = "lua"
activated_handlers.plugin = true

-- mock filetype
vim.bo.filetype = "lua"

assert.equals("https://github.com", handler.get_url("v", "github.com", activated_handlers))
assert.equals(
"https://github.com",
handler.get_url("v", "github.com", filetype, activated_handlers)
)
assert.equals(
"https://github.com",
handler.get_url("v", "https://github.com", filetype, activated_handlers)
handler.get_url("v", "https://github.com", activated_handlers)
)
assert.equals(
"https://github.com/example_user/example_plugin",
handler.get_url("v", '"example_user/example_plugin"', filetype, activated_handlers)
handler.get_url("v", '"example_user/example_plugin"', activated_handlers)
)
end)

it("plugin handler on wrong filetype", function()
local filetype = "java"
activated_handlers.plugin = true

-- mock filetype
vim.bo.filetype = "java"

assert.equals("https://github.com", handler.get_url("v", "github.com", activated_handlers))
assert.equals(
"https://github.com",
handler.get_url("v", "github.com", filetype, activated_handlers)
)
assert.equals(
"https://github.com",
handler.get_url("v", "https://github.com", filetype, activated_handlers)
)
assert.equals(
nil,
handler.get_url("v", '"example_user/example_plugin"', filetype, activated_handlers)
handler.get_url("v", "https://github.com", activated_handlers)
)
assert.equals(nil, handler.get_url("v", '"example_user/example_plugin"', activated_handlers))
end)

it("plugin handler on", function()
local filetype = "lua"
activated_handlers.github = true

-- mock filetype
vim.bo.filetype = "lua"

assert.equals("https://github.com", handler.get_url("v", "github.com", activated_handlers))
assert.equals(
"https://github.com",
handler.get_url("v", "github.com", filetype, activated_handlers)
handler.get_url("v", "https://github.com", activated_handlers)
)
assert.equals(
"https://github.com",
handler.get_url("v", "https://github.com", filetype, activated_handlers)
"https://github.com/chrishrb/gx.nvim/issues/22",
handler.get_url("v", "Fixes #22", activated_handlers)
)
end)

it("package_json handler on", function()
activated_handlers.package_json = true

-- mock filetype
vim.bo.filetype = "json"

stub(helper, "get_filename")
helper.get_filename.on_call_with().returns("package.json")

assert.equals(
"https://github.com/chrishrb/gx.nvim/issues/22",
handler.get_url("v", "Fixes #22", filetype, activated_handlers)
"https://www.npmjs.com/package/@rushstack/eslint-patch",
handler.get_url("v", '"@rushstack/eslint-patch": "^1.2.0",', activated_handlers)
)

helper.get_filename:revert()
end)
end)
22 changes: 22 additions & 0 deletions test/spec/gx/handlers/package_json_handler_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
local handler = require("gx.handlers.package_json")

describe("package_json_handler_does_work", function()
it("package_json", function()
assert.equals(
"https://www.npmjs.com/package/@cucumber/cucumber",
handler.handle("v", '"@cucumber/cucumber": "^9.0.1",')
)
assert.equals(
"https://www.npmjs.com/package/@prisma/client",
handler.handle("v", '"@prisma/client": "^4.11.0",')
)
assert.equals(
"https://www.npmjs.com/package/express",
handler.handle("v", '"express": "^4.18.2",')
)
assert.equals(
"https://www.npmjs.com/package/vue-router",
handler.handle("v", '"vue-router": "^4.1.6"')
)
end)
end)
7 changes: 7 additions & 0 deletions test/spec/gx/handlers/url_handler_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ describe("url_parser_does_work", function()
"https://github.com/chrishrb/gx.nvim/#-installation",
handler.handle("v", "github.com/chrishrb/gx.nvim/#-installation")
)
assert.equals(
"https://signin.aws.amazon.com/switchrole?roleName=my-role&account=111111111",
handler.handle(
"v",
"https://signin.aws.amazon.com/switchrole?roleName=my-role&account=111111111"
)
)
end)

it("urls in markdown", function()
Expand Down
6 changes: 3 additions & 3 deletions test/spec/gx/helper_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ local mock = require("luassert.mock")

describe("gx.nvim:", function()
before_each(function()
get_filetype_mock = mock(vim.api, true)
m = mock(vim.api, true)
end)

after_each(function()
mock.revert(get_filetype_mock)
mock.revert(m)
end)

it("cursor is on url", function()
get_filetype_mock.nvim_win_get_cursor.on_call_with(0).returns({ _, 5 })
m.nvim_win_get_cursor.on_call_with(0).returns({ _, 5 })

assert.True(helper.check_if_cursor_on_url("n", 1, 10))
assert.True(helper.check_if_cursor_on_url("n", 1, 6))
Expand Down