Skip to content

Commit

Permalink
Add package json handler (#8)
Browse files Browse the repository at this point in the history
* Add package json handler

* improve url handler

* fix linting

* extend readme.md
  • Loading branch information
chrishrb authored Mar 30, 2023
1 parent 3d40e16 commit 22dba66
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 60 deletions.
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

0 comments on commit 22dba66

Please sign in to comment.