Created
July 5, 2016 15:54
-
-
Save anonymous/7878a79fccc74bbc00db6cf0c330c23f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local string = string | |
local stringformat = string.format | |
local stringrep = string.rep | |
local table = table | |
local tableappend = table.append | |
local tableconcat = table.concat | |
local unpack = unpack or table.unpack | |
local vim = vim or { } | |
local vimeval = vim.eval | |
local vimline = vim.line | |
local vimwindow = vim.window | |
local lpeg = require "lpeg" | |
local lpegmatch = lpeg.match | |
local math = math | |
local mathfloor = math.floor | |
local println = function (fmt, ...) print (stringformat (fmt, ...)) end | |
local p_comment do | |
local set = function (acc, flags, str) | |
if not flags then | |
acc [#acc + 1] = str | |
else | |
acc [#acc + 1] = { str = str, flags = flags } | |
end | |
return acc | |
end | |
local C = lpeg.C | |
local Cc = lpeg.Cc | |
local Cf = lpeg.Cf | |
local Cg = lpeg.Cg | |
local Ct = lpeg.Ct | |
local P = lpeg.P | |
local R = lpeg.R | |
local S = lpeg.S | |
local comma = P"," | |
local colon = P":" | |
local minus = P"-" | |
local digit = R"09" | |
local floff = (digit^1 + minus * digit^1) / tonumber | |
local flnum = Cg (C (S"se") * (floff + Cc (0))) | |
local fljunk = Cg (C ((P (1) - colon)) * Cc (false)) | |
local flsim = Cg (C (S"nbfmlrOx") * Cc (true)) | |
local flags = flnum + flsim + fljunk | |
local cstr = (P(1) - comma)^1 | |
local lhs = Cf (Ct"" * flags^1, rawset) | |
local rhs = C (cstr) | |
local itemflg = lhs * colon * rhs | |
local iteml = colon * Cc (false) * rhs | |
local item = Cg (itemflg) + Cg (iteml) | |
p_comment = Cf (Ct"" * item * (comma * item)^0, set) | |
end | |
local comments_parse = function (c) | |
if c == "" then return { } end | |
return lpegmatch (p_comment, c) | |
end | |
local comments_format_flag = function (flag) | |
local tflag = type (flag) | |
local ret = "<junk>" | |
if tflag == "string" then | |
ret = stringformat ("‘%s’", flag) | |
elseif tflag == "table" then | |
ret = stringformat ("‘%s’[%d]", unpack (flag)) | |
else | |
ret = stringformat ("invalid flag type %s for ‘%s’", tflag, flag) | |
end | |
return ret | |
end | |
local comments_print = function (c) | |
for i = 1, #c do | |
local ci = c [i] | |
local tci = type (ci) | |
if tci == "string" then | |
println ("[%d] “%s”", i, ci) | |
elseif tci == "table" then | |
local lst = { } | |
for fl, val in next, ci.flags do | |
local s = "" | |
if val == true then s = "+" .. fl | |
elseif val == false then s = "-" .. fl | |
elseif tonumber (val) then s = stringformat ("%s=%d", fl, val) end | |
lst [#lst + 1] = s | |
end | |
local str = ci.str | |
local nci = #ci | |
println ("[%d] “%s”; flags: %s", i, str, tableconcat (lst, ", ")) | |
end | |
end | |
end | |
if not vimeval then --- testing | |
local comdflt = [[s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-]] | |
local comrs = [[s0:/*!,m: ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://]] | |
local comc = [[sO:* -,mO:* ,exO:*/,s1:/*,mb:*,ex:*/,://]] | |
local comocaml = [[sr:(*,mb:*,ex:*)]] | |
----- comsh = [[s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-]] -- same as default | |
local comlua = [[:--]] | |
local comconf = [[:#,:; ]] --- e. g. gitconfig | |
local comviml = [[sO:" -,mO:" ,eO:"",:"]] | |
local sep = function () println ("\n%s", string.rep ("*", 80)) end | |
local test = function (c) | |
sep () | |
println ("input:%q", c) | |
comments_print (comments_parse (c)) | |
end | |
test (comdflt) | |
test (comrs) | |
test (comc) | |
test (comocaml) | |
--test (comsh) | |
test (comlua) | |
test "" | |
test (comconf) | |
test (comviml) | |
end | |
--- query first start (“s”) comment | |
local comments_triple = function (c) | |
local s = false s_fallback = false | |
local m = false m_fallback = false | |
local e = false | |
for i = 1, #c do | |
local ci = c [i] | |
if type (ci) == "string" then | |
--- Lua comments are “:--” | |
m_fallback = ci | |
elseif type (ci) == "table" then | |
local cifl = ci.flags | |
local cistr = ci.str | |
local cifls = cifl.s | |
local ciflm = cifl.m | |
local cifle = cifl.e | |
if cifls and not s then | |
--- the C comments have both “sO:* -” and “s1:/*” but only the latter | |
--- is useful for us | |
if cifls == 1 then s = cistr else s_fallback = cistr end | |
end | |
if ciflm and not m then | |
--- e. g. the C comments have both “mO:* ” and “mb:*” where the | |
--- former messes things up lest we make below distinction | |
if cifl.b then m = cistr else m_fallback = cistr end | |
end | |
if cifle and not e then | |
e = cistr | |
end | |
end | |
if s and m and e then return s, m, e end | |
end | |
return s or s_fallback, m or m_fallback, e --> maybe partial | |
end | |
local comments_block_delim = function (s, m, e, tw) | |
local nm = #m | |
local ns = #s | |
local nidt = ns - nm | |
local nreps = mathfloor (tw / nm) - ns | |
local nrepe = mathfloor (tw / nm) - #e - nidt | |
local idt = stringrep (" ", nidt) | |
local seps = s .. stringrep (m, nreps) | |
local sepe = idt .. stringrep (m, nrepe) .. e | |
return { seps, idt .. m .. " ", sepe } | |
end | |
local comments_block_eol = function (m, tw) | |
local nm = #m | |
local nrep = mathfloor (tw / nm) | |
local sep = stringrep (m, nrep) | |
return { sep, m .. " ", sep } | |
end | |
local comments_block = function (s, m, e, tw) | |
if s and m and e then | |
return comments_block_delim (s, m, e, tw) | |
elseif m then | |
return comments_block_eol (m, tw) | |
end | |
return false | |
end | |
local comments_header = function () | |
local tw = tonumber (vimeval "&textwidth") | |
local cm = comments_parse (vimeval "&comments") | |
if not cm then return false end | |
local s, m, e = comments_triple (cm) | |
return comments_block (s, m, e, tw) | |
end | |
local comments_insert = function () | |
local hdr = comments_header () | |
if not hdr then return end | |
local w = vimwindow () | |
local n = w.line - 1 | |
local thdr = type (hdr) | |
--- add lines from block builder | |
if thdr == "string" then | |
w.buffer:insert(hdr, n) | |
elseif thdr == "table" then | |
for i = #hdr, 1, -1 do | |
w.buffer:insert(hdr [i], n) | |
end | |
else | |
return stringformat ("<received junk %q from header builder>", tostring (hdr)) | |
end | |
--- reposition cursor | |
w.line = n + 2 | |
w.col = #w.buffer [w.line] | |
end | |
return function () | |
return { | |
insert = comments_insert, | |
} | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
lua << ENOUGH | |
local string = string | |
local filevim = vim.eval [[expand("<sfile>")]] | |
local filelua = string.gsub(filevim, "%.vim$", ".lua") | |
local loadmodule = function (mod) | |
local ok, data = pcall (dofile, mod) | |
if ok then return data end | |
return false | |
end | |
local init = loadmodule (filelua) | |
if init and type (init) == "function" then | |
_G.secthdr = init () | |
else | |
print (string.format ("secthdr: failed to load module from “%s”", filelua)) | |
end | |
ENOUGH | |
function! Secthdr () | |
lua secthdr.insert () | |
endfunction | |
nnoremap <Leader>h :call Secthdr()<CR>a | |
inoremap <Leader>h <ESC>:call Secthdr()<CR>a | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment