aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-08-08 11:29:30 +0530
committerAkshay Nair <phenax5@gmail.com>2025-08-08 11:29:30 +0530
commitb41d47d1f5a9b7ae922830c5bdb83e2f182d1b52 (patch)
treee6bf5749730d9c7a8c55a8be2f54c1c0876e90c9
parentf9cb560af761e10803128a06599f99bc2292b4be (diff)
downloadnull-browser-b41d47d1f5a9b7ae922830c5bdb83e2f182d1b52.tar.gz
null-browser-b41d47d1f5a9b7ae922830c5bdb83e2f182d1b52.zip
Make hints generic and handleable via lua
-rw-r--r--TODO.org5
-rw-r--r--assets/javascript/hints.js21
-rw-r--r--init.lua5
-rw-r--r--lua/null-browser/extras/hints.lua53
4 files changed, 55 insertions, 29 deletions
diff --git a/TODO.org b/TODO.org
index 92eaf8a..b807a16 100644
--- a/TODO.org
+++ b/TODO.org
@@ -13,11 +13,11 @@
- [X] On finder stop, exit find mode
- [X] Callback for result of run_js
- [X] Generate docs for api
-- [ ] Any hint action/generic (currently only url open)
+- [X] Any hint action/generic (currently only url open)
- [ ] Document events and event opts
- [ ] Embed docs in app (`null:/docs`)
- [ ] Update all api to use opts table pattern
-- [ ] web.decorations.*.set_size()
+- [X] web.decorations.*.set_size()
- [ ] web.keymap.configure_mode(modename, { passthrough = false })
- [X] Vertical tabline ui
- [ ] Fullscreen
@@ -25,6 +25,7 @@
- [ ] Remove unwanted "async"-ness in lua calls
- [ ] Api for enabling rpc api in view
- [ ] Make the asset/config/lua paths readable via lua
+- [ ] json encode/decode
** Bugs
- [ ] INVESTIGATE: Check why urlchanged doesnt fire for first url open sometimes
diff --git a/assets/javascript/hints.js b/assets/javascript/hints.js
index ce958f2..9110815 100644
--- a/assets/javascript/hints.js
+++ b/assets/javascript/hints.js
@@ -50,6 +50,8 @@
labelsRoot: null,
/** @type {boolean} */
openInNewView: false,
+ /** @type {Match | null} */
+ currentMatch: null,
stop() {
hints.matches = [];
@@ -95,29 +97,16 @@
if (hints.matches.length === 0) {
hints.stop()
- return true
+ return false
}
if (hints.matches.length === 1) {
- const match = hints.matches[0]
+ hints.currentMatch = hints.matches[0]
hints.stop();
- if (!match) {
- console.log(hints.matches);
- return true;
- }
- if (match.elem?.href) {
- if (hints.openInNewView) {
- window.open(match.elem?.href)
- } else {
- location.href = match.elem?.href
- }
- } else {
- match.elem?.click()
- }
return true
}
- return false
+ return null
},
/** @param selector {string} */
diff --git a/init.lua b/init.lua
index ae1f181..022be69 100644
--- a/init.lua
+++ b/init.lua
@@ -66,7 +66,8 @@ require 'null-browser.extras.statusline'.init {
local hints = require 'null-browser.extras.hints'
hints.init()
-web.keymap.set('n', 'f', function() hints.start('a[href], button', false) end)
-web.keymap.set('n', '<s-f>', function() hints.start('a[href], button', true) end)
+web.keymap.set('n', 'f', function() hints.start('a[href], button', hints.action.open_in_view) end)
+web.keymap.set('n', '<s-f>', function() hints.start('a[href], button', hints.action.open_in_new_view) end)
+web.keymap.set('n', 'yl', function() hints.start('a[href]', hints.action.copy_link) end)
print('ending...')
diff --git a/lua/null-browser/extras/hints.lua b/lua/null-browser/extras/hints.lua
index 33d4564..d6e32c7 100644
--- a/lua/null-browser/extras/hints.lua
+++ b/lua/null-browser/extras/hints.lua
@@ -2,8 +2,11 @@ local hints = {
config = {
mode = 'f',
},
+ action = {},
}
+local state = { action = nil }
+
local js_setup_code = ''
function hints.init(on_ready)
@@ -24,15 +27,11 @@ function hints.init(on_ready)
end)
end
-function hints.start(selector, new_view)
- local open_in_new_view = new_view and 'true' or 'false'
+function hints.start(selector, action)
+ state.action = action or hints.action.open_in_view
web.view.run_js(
js_setup_code ..
- ";_nullbrowser.hints.start('" ..
- selector ..
- "', " ..
- open_in_new_view ..
- ")"
+ ";_nullbrowser.hints.start('" .. selector .. "')"
)
web.schedule(function()
-- Trigger f mode after tick to avoid the trigger key (f) to get captured in event
@@ -42,8 +41,11 @@ end
function hints._filter_key(key)
web.view.run_js("_nullbrowser.hints.filterOutByKey('" .. key .. "')", {
- on_result = function(end_of_matches)
- if end_of_matches then hints.stop() end
+ on_result = function(find_status)
+ if find_status ~= nil then hints.stop() end
+ if find_status and state.action then
+ state.action()
+ end
end,
})
end
@@ -66,4 +68,37 @@ function hints._load_hints_js(on_ready)
end)
end
+function hints.action.open_in_new_view()
+ web.view.run_js [[
+ const match = _nullbrowser.hints.currentMatch;
+ if (match.elem?.href) {
+ window.open(match.elem.href)
+ } else {
+ match.elem?.click()
+ }
+ ]]
+end
+
+function hints.action.open_in_view()
+ web.view.run_js [[
+ const match = _nullbrowser.hints.currentMatch;
+ if (match.elem?.href) {
+ location.href = match.elem.href
+ } else {
+ match.elem?.click()
+ }
+ ]]
+end
+
+function hints.action.copy_link()
+ web.view.run_js([[_nullbrowser.hints.currentMatch.elem?.href]], {
+ on_result = function(url)
+ local pipe = io.popen('xclip -selection clipboard', 'w')
+ if not pipe then return end
+ pipe:write(url)
+ pipe:close()
+ end,
+ })
+end
+
return hints