Initial code commit
This commit is contained in:
parent
cd33b8595f
commit
e186a2ca05
|
@ -0,0 +1,97 @@
|
|||
local vim = vim
|
||||
local api = vim.api
|
||||
|
||||
socket = require("socket")
|
||||
socket.url = require("socket.url")
|
||||
ssl = require("ssl")
|
||||
pl = require("pl")
|
||||
|
||||
local ssl_params = {
|
||||
mode = "client",
|
||||
protocol = "tlsv1_2"
|
||||
}
|
||||
|
||||
local function establish_connection(url)
|
||||
-- Add scheme if missing
|
||||
if string.find(url, "://") == nil then
|
||||
url = "gemini://" .. url
|
||||
end
|
||||
-- Add empty path if needed
|
||||
if string.find(string.sub(url, 10, -1), "/") == nil then
|
||||
url = url .. "/"
|
||||
end
|
||||
parsed_url = socket.url.parse(url)
|
||||
-- Open connection
|
||||
conn = socket.tcp()
|
||||
ret, str = conn:connect(parsed_url.host, 1965)
|
||||
if ret == nil then
|
||||
vim.notify(str)
|
||||
return
|
||||
end
|
||||
conn, err = ssl.wrap(conn, ssl_params)
|
||||
if conn == nil then
|
||||
vim.notify(err)
|
||||
return
|
||||
end
|
||||
return conn
|
||||
end
|
||||
|
||||
local function gemini_open(url)
|
||||
vim.notify(string.format("Gemini open: %s", url))
|
||||
|
||||
local conn = establish_connection(url)
|
||||
if conn == nil then
|
||||
return
|
||||
end
|
||||
conn:dohandshake()
|
||||
-- Send request
|
||||
conn:send(url .. "\r\n")
|
||||
-- Parse response header
|
||||
local header = conn:receive("*l")
|
||||
local status, meta = table.unpack(utils.split(header, "%s+", false, 2))
|
||||
local lines = {}
|
||||
|
||||
api.nvim_command('enew')
|
||||
win = vim.api.nvim_get_current_win()
|
||||
buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_buf_set_option(buf, 'buftype', 'nofile')
|
||||
vim.api.nvim_buf_set_option(buf, 'swapfile', false)
|
||||
vim.fn['GmiHighlights']()
|
||||
|
||||
-- Handle sucessful response
|
||||
if string.sub(status, 1, 1) == "2" then
|
||||
if meta == "text/gemini" then
|
||||
-- Handle Geminimap
|
||||
local links = {}
|
||||
local preformatted = false
|
||||
while true do
|
||||
local line, _ = conn:receive("*l")
|
||||
if line ~= nil then
|
||||
if string.sub(line,1,3) == "```" then
|
||||
preformatted = not preformatted
|
||||
elseif preformatted then
|
||||
table.insert(lines, line)
|
||||
elseif string.sub(line,1,2) == "=>" then
|
||||
line = string.sub(line,3,-1) -- Trim off =>
|
||||
line = string.gsub(line,"^%s+","") -- Trim spaces
|
||||
local link_url, label = table.unpack(utils.split(line, "%s+", false, 2))
|
||||
if label == nil then local label = link_url end
|
||||
table.insert(links, socket.url.absolute(url, link_url))
|
||||
table.insert(lines, '[' .. #links .. '] ' .. label)
|
||||
else
|
||||
line = string.gsub(line, "\n", "")
|
||||
table.insert(lines, line)
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
||||
end
|
||||
|
||||
return {
|
||||
gemini_open = gemini_open
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
if exists('g:gemini_loaded')
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:save_cpo = &cpo " save user coptions
|
||||
set cpo&vim " reset them to defaults
|
||||
|
||||
function! GmiHighlights()
|
||||
" Handle monospaced blocks
|
||||
syn region gmiMono start=/^```/ end=/^```/
|
||||
highlight default link gmiMono PreProc
|
||||
|
||||
" Handle between one and three heading levels
|
||||
syn match gmiHeader /^#\{1,3}[^#].*$/
|
||||
highlight default link gmiHeader Constant
|
||||
|
||||
" Start a link line
|
||||
syn match gmiLinkStart /^\[\d\+\]/ nextgroup=gmiLinkUrl skipwhite
|
||||
highlight default link gmiLinkStart Special
|
||||
|
||||
" An extremely naive way of handling the URL portion of the link line
|
||||
" This is left naive in a deliberate attempt to be unambiguous about
|
||||
" what part of a link line gemini considers to be the URL, regardless
|
||||
" of whether or not it is a valid URL
|
||||
syn match gmiLinkUrl /\S\+/ contained nextgroup=gmiLinkTitle skipwhite
|
||||
highlight default link gmiLinkUrl Underlined
|
||||
|
||||
" Skipping whitespace from the URL match all text, including whitespace,
|
||||
" until the end of the line
|
||||
syn match gmiLinkTitle /.*$/ contained
|
||||
highlight default link gmiLinkTitle Comment
|
||||
|
||||
" Handle list items
|
||||
syn match gmiListItemPrefix /^\*/
|
||||
highlight default link gmiListItemPrefix Statement
|
||||
|
||||
" Handle quotes
|
||||
syn match gmiQuoteLine /^>.*/
|
||||
highlight default link gmiQuoteLine Comment
|
||||
endfunction
|
||||
|
||||
" command to run our plugin
|
||||
command! -nargs=1 GeminiOpen lua require('gemini').gemini_open(<f-args>)
|
||||
|
||||
let &cpo = s:save_cpo " and restore after
|
||||
unlet s:save_cpo
|
||||
|
||||
let g:gemini_loaded = 1
|
||||
|
Loading…
Reference in New Issue