Initial code commit

This commit is contained in:
Michael Kohl 2021-03-16 21:18:24 +07:00
parent cd33b8595f
commit e186a2ca05
2 changed files with 146 additions and 0 deletions

97
lua/gemini.lua Normal file
View File

@ -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
}

49
plugin/gemini.vim Normal file
View File

@ -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