From 1dd6332756b38bf4bbffeef9db6599320c03ca9a Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 20 Apr 2025 21:09:48 +0530 Subject: Add search engine aliases for url input --- TODO.org | 2 + init.lua | 157 ++--------------------------- lua/null-browser/api.lua | 18 ++++ lua/null-browser/defaults/vi.lua | 141 ++++++++++++++++++++++++++ lua/null-browser/extras/history.lua | 9 ++ lua/null-browser/extras/search-engines.lua | 33 ++++++ 6 files changed, 213 insertions(+), 147 deletions(-) create mode 100644 lua/null-browser/defaults/vi.lua create mode 100644 lua/null-browser/extras/search-engines.lua diff --git a/TODO.org b/TODO.org index 3f76291..640dfc9 100644 --- a/TODO.org +++ b/TODO.org @@ -5,8 +5,10 @@ - [X] Search text in page - [X] Dev tools - [X] Configuration +- [X] Searchengines - [ ] Scroll api (for j/k/h/l/gg/G) - [ ] Tests for api +- [ ] table extend/merge - [ ] Fullscreen - [ ] Zoom in/out - [ ] Permission requests handling/persisting diff --git a/init.lua b/init.lua index e1b4308..74d85e0 100644 --- a/init.lua +++ b/init.lua @@ -1,159 +1,22 @@ print('hello starting up...') -local dmenu = require 'null-browser.extras.dmenu' -local history = require 'null-browser.extras.history' - ---- @type table -web = web ---- @type table -uv = uv - -local function get_current_view_index() - local currentView = web.view.current(); - for index, view in ipairs(web.view.list()) do - if view.id == currentView then - return index - end - end -end - web.set('new_view_url', 'https://lite.duckduckgo.com') web.set('close_window_when_no_views', true) web.set('user_agent', 'MacOS | Safari - $500 edition') web.set('downloads_dir', os.getenv('HOME') .. '/Downloads/firefox') --- Switch modes -web.keymap.set_mode('n') -- Start in normal mode -web.keymap.set('n', 'i', function() web.keymap.set_mode('i') end) -web.keymap.set('i', '', function() web.keymap.set_mode('n') end) - -web.event.add_listener('UrlChanged', { - callback = function(opts) - print('url change', web.inspect(opts)); - history.add(opts.url) - end -}) - -local function trim(s) - local res, _ = string.gsub(s, '^%s*(.-)%s*$', '%1') - return res -end - -local function to_url(url) - url = trim(url) - if string.match(url, "^https?://") then - return url - end - return "https://" .. url -end - --- Search -web.keymap.set('n', '', function() web.search.reset() end) -web.keymap.set('n', 'n', function() web.search.next() end) -web.keymap.set('n', '', function() web.search.previous() end) -web.keymap.set('n', '', function() - dmenu.input({ prompt = 'Search:', input = web.search.get_text() }, function(err, input) - if err then return end - web.search.set_text(input) - end) -end) - --- Open in new view -web.keymap.set('n', 'o', function() - print(web.get('new_view_url'), web.get('user_agent')) - dmenu.select(history.list(), { prompt = 'Open view:' }, function(err, result) - if err or not result then return end - web.view.create(to_url(result)) - end) -end) --- Open in current view -web.keymap.set('n', '', function() - dmenu.select(history.list(), { prompt = 'Open:' }, function(err, result) - if err or not result then return end - web.view.set_url(to_url(result)) - end) -end) --- Delete from history -web.keymap.set('n', 'd', function() - dmenu.select(history.list(), { prompt = 'Delete history:' }, function(err, result) - if err or not result then return end - history.delete(trim(result)) - end) -end) --- Update current url -web.keymap.set('n', '', function() - local views = web.view.list() - local view = views[get_current_view_index()]; - if view == nil then return end - dmenu.select(history.list(), { prompt = 'Set url:', input = view.url }, function(err, result) - if err or not result then return end - web.view.set_url(trim(result)) - end) -end) - --- Run lua code -web.keymap.set('n', 'q', function() - dmenu.input({ prompt = 'Lua:' }, function(err, result) - if err or not result then return end - local run, run_err = load(result) - if run_err then print(run_err) end - if run then run() end - end) -end) - --- History back/forward -web.keymap.set('n', '', function() web.history.back(); end) -web.keymap.set('n', '', function() web.history.forward(); end) - --- Close view -web.keymap.set('n', '', function() web.view.close(); end) - --- view select -web.keymap.set('n', 'b', function() - local views_list = {} - local views = web.view.list() - for index, view in ipairs(web.view.list()) do - table.insert(views_list, index .. ': ' .. view.title .. ' (' .. view.url .. ')') - end - dmenu.select(views_list, { prompt = 'Views:' }, function(err, result) - if err or not result then return end - local index_str, _ = trim(result):gsub('%s*:.*$', '') - local index = tonumber(index_str) - if views[index] then - web.view.select(views[index].id) - end - end) -end) - --- 1-0 for tab indexes 1-10 -for index = 1, 10 do - local key = index - if index >= 10 then key = 0 end - web.keymap.set('n', '' .. key, function() - local views = web.view.list() - if index > #views then return end - web.view.select(views[index].id) - end) -end +local dmenu = require 'null-browser.extras.dmenu' +local history = require 'null-browser.extras.history' +local search_engines = require 'null-browser.extras.search-engines' --- Next view -web.keymap.set('n', 'tn', function() - local views = web.view.list() - if #views <= 1 then return end - local index = get_current_view_index() + 1; - if index > #views then index = 1 end - web.view.select(views[index].id) -end) +history.attach_hooks() --- Prev view -web.keymap.set('n', 'tp', function() - local views = web.views.list() - if #views <= 1 then return end - local index = get_current_view_index() - 1; - if index <= 0 then index = #views end - web.views.select(views[index].id) -end) +search_engines.urls['ld'] = 'https://lite.duckduckgo.com/?q={}' -web.keymap.set('n', '', function() web.view.open_devtools() end) +require 'null-browser.defaults.vi'.setup { + menu = dmenu, + history = history, + preprocess_url = search_engines.preprocess_url, +} print('ending...') diff --git a/lua/null-browser/api.lua b/lua/null-browser/api.lua index 293afc5..ea7e0a7 100644 --- a/lua/null-browser/api.lua +++ b/lua/null-browser/api.lua @@ -136,6 +136,24 @@ function web.view.set_url(url, view_id) return __internals.view_set_url(url, vie --- ``` function web.view.open_devtools(view_id) return __internals.view_open_devtools(view_id) end +--- Get current view index +--- +--- @return number|nil index Current view index +--- +--- @example +--- ```lua +--- local index = web.view.current_index() +--- ``` +function web.view.current_index() + local current_view = web.view.current(); + for index, view in ipairs(web.view.list()) do + if view.id == current_view then + return index + end + end + return nil +end + --- Listen to events from the browser --- --- @class nullb.EventListenerOptions diff --git a/lua/null-browser/defaults/vi.lua b/lua/null-browser/defaults/vi.lua new file mode 100644 index 0000000..dee3bc5 --- /dev/null +++ b/lua/null-browser/defaults/vi.lua @@ -0,0 +1,141 @@ +local function trim(s) + local res, _ = string.gsub(s, '^%s*(.-)%s*$', '%1') + return res +end + +local M = {} +local config = { + menu = require 'null-browser.extras.dmenu', + history = require 'null-browser.extras.history', + preprocess_url = function(url) return url end, +} + + +function M.setup(opts) + if opts.menu then config.menu = opts.menu end + if opts.history then config.history = opts.history end + if opts.preprocess_url then config.preprocess_url = opts.preprocess_url end +end + +function M.initialize() + -- Start in normal mode + web.keymap.set_mode('n') + web.keymap.set('n', 'i', function() web.keymap.set_mode('i') end) + web.keymap.set('i', '', function() web.keymap.set_mode('n') end) + + -- Open in new view + web.keymap.set('n', 'o', function() + print(web.get('new_view_url'), web.get('user_agent')) + config.menu.select(config.history.list(), { prompt = 'Open view:' }, function(err, result) + if err or not result then return end + web.view.create(config.preprocess_url(result)) + end) + end) + -- Open in current view + web.keymap.set('n', '', function() + config.menu.select(config.history.list(), { prompt = 'Open:' }, function(err, result) + if err or not result then return end + web.view.set_url(config.preprocess_url(result)) + end) + end) + -- Delete from history + web.keymap.set('n', 'dh', function() + config.menu.select(config.history.list(), { prompt = 'Delete history:' }, function(err, result) + if err or not result then return end + config.history.delete(trim(result)) + end) + end) + + -- Search + web.keymap.set('n', '', function() + config.menu.input({ prompt = 'Search:', input = web.search.get_text() }, function(err, input) + if err then return end + web.search.set_text(input) + end) + end) + web.keymap.set('n', '', function() web.search.reset() end) + web.keymap.set('n', 'n', function() web.search.next() end) + web.keymap.set('n', '', function() web.search.previous() end) + + -- Run lua code + web.keymap.set('n', 'q', function() + config.menu.input({ prompt = 'Lua:' }, function(err, result) + if err or not result then return end + local run, run_err = load(result) + if run_err then print(run_err) end + if run then run() end + end) + end) + + -- History back/forward + web.keymap.set('n', '', function() web.history.back(); end) + web.keymap.set('n', '', function() web.history.forward(); end) + + -- Close view + web.keymap.set('n', '', function() web.view.close(); end) + web.keymap.set('n', 'dv', function() web.view.close(); end) + + -- View select + web.keymap.set('n', 'b', function() + local views_list = {} + local views = web.view.list() + for index, view in ipairs(web.view.list()) do + table.insert(views_list, index .. ': ' .. view.title .. ' (' .. view.url .. ')') + end + config.menu.select(views_list, { prompt = 'Views:' }, function(err, result) + if err or not result then return end + local index_str, _ = trim(result):gsub('%s*:.*$', '') + local index = tonumber(index_str) + if views[index] then + web.view.select(views[index].id) + end + end) + end) + + -- 1-0 for view indexes 1-10 + for index = 1, 10 do + local key = index + if index >= 10 then key = 0 end + web.keymap.set('n', '' .. key, function() + local views = web.view.list() + if index > #views then return end + web.view.select(views[index].id) + end) + end + + -- Next view + web.keymap.set('n', 'bn', function() + local views = web.view.list() + if #views <= 1 then return end + local index = web.view.current_index() + 1; + if index > #views then index = 1 end + web.view.select(views[index].id) + end) + + -- Prev view + web.keymap.set('n', 'bp', function() + local views = web.views.list() + if #views <= 1 then return end + local index = web.view.current_index() - 1; + if index <= 0 then index = #views end + web.views.select(views[index].id) + end) + + -- Update current url + web.keymap.set('n', '', function() + local views = web.view.list() + local view = views[web.view.current_index()]; + if view == nil then return end + config.menu.select(config.history.list(), { prompt = 'Set url:', input = view.url }, function(err, result) + if err or not result then return end + web.view.set_url(trim(result)) + end) + end) + + -- Open devtools + web.keymap.set('n', '', function() web.view.open_devtools() end) +end + +M.initialize() + +return M diff --git a/lua/null-browser/extras/history.lua b/lua/null-browser/extras/history.lua index f38bfa2..8c53d96 100644 --- a/lua/null-browser/extras/history.lua +++ b/lua/null-browser/extras/history.lua @@ -53,4 +53,13 @@ function history.delete(url_to_delete) end) end +function history.attach_hooks() + web.event.add_listener('UrlChanged', { + callback = function(opts) + print('url change', web.inspect(opts)); + history.add(opts.url) + end + }) +end + return history diff --git a/lua/null-browser/extras/search-engines.lua b/lua/null-browser/extras/search-engines.lua new file mode 100644 index 0000000..107e945 --- /dev/null +++ b/lua/null-browser/extras/search-engines.lua @@ -0,0 +1,33 @@ +local M = { + urls = { + g = 'https://google.com/search?q={}', + d = 'https://duckduckgo.com/?q={}', + }, + default = 'd', +} + +function M.preprocess_url(url) + local url_trimmed, _ = string.gsub(url, '^%s*(.-)%s*$', '%1') + if M.is_url(url_trimmed) then return url_trimmed end + + for key, _ in pairs(M.urls) do + local url_out, found = M.parse_search_string(key, url_trimmed) + if found then return M.substitute(key, url_out) end + end + + return M.substitute(M.default, url_trimmed) +end + +function M.is_url(str) return string.match(str, "^https?://") end + +function M.substitute(search_name, value) + local res, _ = string.gsub(M.urls[search_name], '{}', value) + return res +end + +function M.parse_search_string(search_name, value) + local res, count = string.gsub(value, '^%s*' .. search_name .. '%s+', '') + return res, count > 0 +end + +return M -- cgit v1.3.1