diff --git a/lua/presser/builtins/__modules.lua b/lua/presser/builtins/__modules.lua index b02fa9e..5dfb531 100644 --- a/lua/presser/builtins/__modules.lua +++ b/lua/presser/builtins/__modules.lua @@ -1,6 +1,7 @@ -local gcm = require'presser.context_manager' -local steamers = require'presser.steamers' -local actions = require'presser.actions' +local gcm = require 'presser.context_manager' +local steamers = require 'presser.steamers' +local actions = require 'presser.actions' +local utils = require 'presser.utils' local a = vim.api @@ -80,4 +81,130 @@ modules.find_replace = function () a.nvim_feedkeys('A', 'n', false) end + +modules.hyperlink = function () + local check_url = function ( text ) + local text = string.lower( text ) + + -- string list of all possible URI schemes which have RFC specification and identified with permanent status + local patterns = "aaa|aaas|about|acap|acct|afs|cap|cid|coap|coap+tcp|coap+ws|coaps|coaps+tcp|coaps+ws|crid|data" .. + "|dav|dict|dns|dtn|example|fax|file|ftp|geo|go|gopher|h323|ham|http|https|iax|icap|im|imap|info|ipn|ipp|ipps" .. + "|iris|iris.beep|iris.lwz|iris.xpc|iris.xpcs|jms|ldap|leaptofrogans|mailserver|mailto|mid|modem|msrp|msrps" .. + "|mtqp|mupdate|news|nfs|ni|nih|nntp|opaquelocktoken|payto|pkcs11|pop|pres|prospero|reload|rsync|rtmfp|rtsp" .. + "|rtsps|rtspu|secret-token|service|session|sieve|sip|sips|sms|snews|snmp|soap.beep|soap.beeps|stun|stuns|tag" .. + "|tel|telnet|tftp|thismessage|tip|tn3270|turn|turns|tv|urn|vemmi|videotex|vnc|wais|ws|wss|xcon|xcon-userid" .. + "|xmlrpc.beep|xmlrpc.beeps|xmpp|z39.50|z39.50r|z39.50s|" + + -- check if text is a type of URI + -- @Dev: TODO, consider option of logarithmic matching (patterns already in alphabetical order) + for proto in string.gmatch( patterns, "([^|]+)" ) do + -- if so, text can be converted directly to hyperlink (return true) + if string.find( text, proto ) then + return true + end + end + + return false + end + + + local link_txt = nil + local row, col = unpack(a.nvim_win_get_cursor(0)) + local h,j,_,l = utils.get_selection() + local line = a.nvim_get_current_line() + if vim.api.nvim_get_mode()["mode"] == "n" then + if (row-1) == h and (col == j or col == l) then + print("visual mode selection") + link_txt = string.sub(line, j, l) + else + link_txt = string.sub(line, unpack(utils.subslice(line, col))) + end + else + link_txt = vim.fn.expand "" + end + + link_txt = utils.clean_buf(link_txt) + if link_txt == "" then + print("Presser.hyperlink: No text selected to convert.") + return + end + + if check_url( link_txt ) then + print("Identified URI scheme under cursor, generating hyperlink for: " .. link_txt) + if not ( col == j or col == l ) then + j, l = unpack(utils.subslice( line .. " ", col )) + end + + print(j,l) + actions.suburl( line, row, link_txt, j, l ) + return nil + end + + print("Cursor is not over an identified URI scheme: " .. link_txt .. ". Constructing UI...") + + -- define the context which these windows will belong to in the context manager. + local ctx = "hyperlink" + gcm.create( ctx ) + + local keymap = { + n = { + [""] = "lua require'presser.actions'.close()", + [""] = "lua require'presser.actions'.hyperlink_exec()", + }, + i = { + [""] = "lua require'presser.actions'.hyperlink_exec()", + } + } + + -- get the centre of the current buffer + local c_lines = math.floor( a.nvim_win_get_height(0) / 2 ) + + -- create a title buffer for the steamer + steamers + .new( ctx, { + label = "presser_title", + steamer = { + placeholder = "Hyperlink", + allowed = false, + window = { + line = c_lines - 2, + border = false, + minwidth = 82, + padding = { 0, 1, 1, 1 } + } + } + } ) + + steamers + .new( ctx, { + label = "selected_text", + steamer = { + placeholder = "Selected text: " .. link_txt, + allowed = false, + window = { + line = c_lines, + border = false, + minwidth = 82, + padding = { 0, 1, 1, 1 } + } + } + } ) + + -- create a new buffer for replace pattern + steamers + .new( ctx, { + label = "hyperlink_buf", + steamer = { + window = { + line = c_lines + 3, + title = "Hyperlink", + }, + keybinds = keymap, + } + } ) + + local result = actions.buf_put_curser_at( "hyperlink_buf" ) + a.nvim_feedkeys('A', 'n', false) +end + return modules