summaryrefslogtreecommitdiff
path: root/config/essentials/vis/vis-ultisnips
diff options
context:
space:
mode:
Diffstat (limited to 'config/essentials/vis/vis-ultisnips')
-rw-r--r--config/essentials/vis/vis-ultisnips/init.lua149
-rw-r--r--config/essentials/vis/vis-ultisnips/snipmate-parser.lua128
-rw-r--r--config/essentials/vis/vis-ultisnips/testlpeg-snipmate.lua160
-rw-r--r--config/essentials/vis/vis-ultisnips/testlpeg-ultisnips.lua230
-rw-r--r--config/essentials/vis/vis-ultisnips/ultisnips-parser.lua211
5 files changed, 0 insertions, 878 deletions
diff --git a/config/essentials/vis/vis-ultisnips/init.lua b/config/essentials/vis/vis-ultisnips/init.lua
deleted file mode 100644
index 52faa55..0000000
--- a/config/essentials/vis/vis-ultisnips/init.lua
+++ /dev/null
@@ -1,149 +0,0 @@
---------------------------------------------------------------------------------
--- Modules
-
-local M = {}
-local cwd = ...
-local SnipMate = require(cwd .. '.snipmate-parser')
-local UltiSnips = require(cwd .. '.ultisnips-parser')
-
-
-
---------------------------------------------------------------------------------
--- Config
-
-M.snipmate = ''
-M.ultisnips = ''
-
-
-
---------------------------------------------------------------------------------
--- Helper functions
-
--- Takes list of snippets and concatenates them into the string suitable
--- for passing to dmenu (or, very probably, vis-menu)
-local function snippetslist(snippets)
- local list = ''
-
- for k,v in pairs(snippets) do
- if not v.description then
- list = list .. k .. '\n'
- else
- list = list .. k .. ' - ' .. v.description .. '\n'
- end
- end
-
- return list
-end
-
-
-
-local function load_ultisnips()
- local snippetfile = M.ultisnips .. vis.win.syntax .. '.snippets'
- local snippets, success = UltiSnips.load_snippets(snippetfile)
- if not success then
- vis:info('Failed to load a correct UltiSnip: ' .. snippetfile)
- end
- return snippets, success
-end
-
-
-
-local function load_snipmate()
- local snippetfile = M.snipmate .. vis.win.syntax .. '.snippets'
- local snippets, success = SnipMate.load_snippets(snippetfile)
- if not success then
- vis:info('Failed to load a correct SnipMate: ' .. snippetfile)
- end
- return snippets, success
-end
-
-
-
--- Second will append to first using suffix for distinguishing
-local function merge_and_override(snips1, snips2, suffix)
- for k,v in pairs(snips2) do
- snips1[k .. suffix] = v
- end
- return snips1
-end
-
-
-
---------------------------------------------------------------------------------
--- Plugging it all in
-
-vis:map(vis.modes.INSERT, "<C-x><C-j>", function()
- local snippets = merge_and_override(load_snipmate(), load_ultisnips(), '_us')
-
- local win = vis.win
- local file = win.file
- local pos = win.selection.pos
-
- if not pos then
- return
- end
- -- TODO do something clever here
-
- -- Use prefix W if exists
- local initial = ' '
- local range = file:text_object_longword(pos > 0 and pos - 1 or pos)
- if range then
- initial = initial .. file:content(range)
- end
-
- -- Note, for one reason or another, using vis-menu corrupts my terminal
- -- (urxvt) for exact amount of lines that vis-menu takes
- -- dmenu has no such problems, but can't take initial input :-\
- --local stdout = io.popen("echo '" .. snippetslist(snippets) .. "' | dmenu -l 5", "r")
- local stdout = io.popen("echo '" .. snippetslist(snippets) .. "' | vis-menu " .. initial, "r")
- local chosen = stdout:lines()()
- local _, msg, status = stdout:close()
- if status ~= 0 or not chosen then
- vis:message(msg)
- return
- end
-
- local trigger = chosen:gmatch('[^ ]+')()
- local snipcontent = snippets[trigger].content
- if range then
- file:delete(range)
- -- Update position after deleting the range
- pos = pos - (range.finish - range.start)
- vis:redraw()
- end
-
- vis:insert(snipcontent.str)
-
-
- if #snipcontent.tags > 0 then
- vis:info("Use 'g>' and 'g<' to navigate between anchors.")
-
- -- Create selections iteratively using `:#n,#n2 p` command and `gs` to
- -- save it in the jumplist
- for _,v in ipairs(snipcontent.tags) do
- -- Can't use 'x' command because it'd select stuff across
- -- whole file
- vis:command('#' .. pos + v.selstart ..',#' .. pos + v.selend .. ' p')
- --vis:feedkeys('gs') -- Tested, works without this too, but just in case
- --vis:message('Command: ' .. cmd)
- end
-
- -- Backtrack through all selections we've made first
- -- (so that we can use g> to move us forward)...
- for _ in ipairs(snipcontent.tags) do
- vis:feedkeys('g<')
- end
-
- -- ... then set us on the first selection
- vis:feedkeys('g>')
- else
- win.selection.pos = pos + #snipcontent.str
- end
-end, "Insert a snippet")
-
-
-
---------------------------------------------------------------------------------
--- End module
-
-return M \ No newline at end of file
diff --git a/config/essentials/vis/vis-ultisnips/snipmate-parser.lua b/config/essentials/vis/vis-ultisnips/snipmate-parser.lua
deleted file mode 100644
index 9d735f1..0000000
--- a/config/essentials/vis/vis-ultisnips/snipmate-parser.lua
+++ /dev/null
@@ -1,128 +0,0 @@
---------------------------------------------------------------------------------
--- Module table
-
-local M = {}
-
-local lpeg = require('lpeg')
-
-
-
---------------------------------------------------------------------------------
--- lpeg rules
-
--- Base definitions
--- local tws = lpeg.S' ' ^ 1
-local tnewline = lpeg.S'\n'
--- local tlowcasedword = lpeg.R'az' ^ 1
-local tdigit = lpeg.locale()['digit']
-local talphanum = lpeg.locale()['alnum']
-local tanyprintable = lpeg.locale()['print']
--- local tcontrol = lpeg.locale()['cntrl']
-local ttabtrigger = tanyprintable ^ 1
-local ttag = lpeg.Cg(lpeg.Cp(), 'selstart')
- * lpeg.P'${'
- * lpeg.Cg(tdigit^1, 'tag-order')
- * (
- (lpeg.S':' * lpeg.Cg(talphanum^1, 'default-value') * lpeg.S'}')
- + lpeg.S'}'
- )
- * lpeg.Cg(lpeg.Cp(), 'selend')
-local tsnippetdecl = lpeg.P'snippet' * lpeg.S' ' * lpeg.Cg(ttabtrigger, 'tabtrigger') * tnewline
-local tsnippetcontent = lpeg.C(
- lpeg.Cp() *
- (lpeg.S'\t '^1
- * (lpeg.Ct(ttag) + tanyprintable)^1
- * tnewline
- )^1
- )
-
--- Constructs
-local tsnippet = tsnippetdecl * tsnippetcontent
-local tcomment = lpeg.S'#' * tanyprintable^0 * tnewline
-
--- The way grammar captures:
--- Every snippet gets its own table, and every table has:
--- 'tabtrigger' - the tabtrigger
--- [1] - full content
--- [2] - start of snippet content (need to subtract from selstart/selend
--- [3..n] - tags
-local tsnippetsfile = lpeg.Ct((tcomment + lpeg.Ct(tsnippet) + tnewline) ^1)
-
---------------------------------------------------------------------------------
--- Functions
-
-local function trim_tabs(content)
- local trim = function (s)
- return (string.gsub(s, "^\t(.-)$", "%1"))
- end
-
- local ret=''
- for str in string.gmatch(content, '([^\n]+)') do
- ret = ret .. trim(str) .. '\n'
- end
- return ret
-end
-
--- Tags are on the top level of th table,
--- defined starting with index '3'
--- Index '2' is start of the content
--- Structure:
--- { tag-order: int
--- , selstart: int
--- , selend: int
--- , default-value: str
--- }
-local function extract_tags(tableau)
- local tags = {}
- for k,v in ipairs(tableau) do
- if k >= 3 then -- Only process starting with ix 2
- tags[k - 2] = { selstart = v.selstart - tableau[2] - 1
- , selend = v.selend - tableau[2] - 1
- , default = v['default-value']
- , order = v['tag-order']
- }
--- vis:message('snippet ' .. tableau.tabtrigger .. ' tag ' ..
--- tostring(tags[k - 1].order) .. ' has start/end: ' ..
--- tostring(tags[k - 1].selstart) .. '/' ..
--- tostring(tags[k - 1].selend))
- end
- end
- return tags
-end
-
-M.load_snippets = function(snippetfile)
- local snippets = {}
-
- local f = io.open(snippetfile, 'r')
- if f then
- local content = f:read("*all")
-
- -- TODO hmmm, this'll make whole file unsuable, when it could
- -- in fact have usable snippets
- local m = tsnippetsfile:match(content)
- if not m then
- vis:info('Failed to parse SnipMate file: '.. snippetfile)
- return nil
- else
- -- k is index of snippet definition, v is table of snippet def
- for _,v in pairs(m) do
- snippets[v.tabtrigger] = { description = nil
- , options = {}
- , content = { str = trim_tabs(v[1])
- , tags = extract_tags(v)
- }
- }
- end
- end
-
- f:close()
- return snippets, true
- else
- return snippets, false
- end
-end
-
---------------------------------------------------------------------------------
--- End module
-
-return M
diff --git a/config/essentials/vis/vis-ultisnips/testlpeg-snipmate.lua b/config/essentials/vis/vis-ultisnips/testlpeg-snipmate.lua
deleted file mode 100644
index 997365f..0000000
--- a/config/essentials/vis/vis-ultisnips/testlpeg-snipmate.lua
+++ /dev/null
@@ -1,160 +0,0 @@
-local lpeg = require("lpeg")
-
---------------------------------------------------------------------------------
-
--- Base definitions
--- local tws = lpeg.S(" ") ^ 1
-local tnewline = lpeg.S("\n")
--- local tlowcasedword = lpeg.R("az") ^ 1
-local tdigit = lpeg.locale()["digit"]
-local talphanum = lpeg.locale()["alnum"]
-local tanyprintable = lpeg.locale()["print"]
--- local tcontrol = lpeg.locale()["cntrl"]
-local ttabtrigger = tanyprintable ^ 1
-local ttag = lpeg.Cg(lpeg.Cp(), "selstart")
- * lpeg.P("${")
- * lpeg.Cg(tdigit ^ 1, "tag-order")
- * ((lpeg.S(":") * lpeg.Cg(talphanum ^ 1, "default-value") * lpeg.S("}")) + lpeg.S("}"))
- * lpeg.Cg(lpeg.Cp(), "selend")
-local tsnippetdecl = lpeg.P("snippet") * lpeg.S(" ") * lpeg.Cg(ttabtrigger, "tabtrigger") * tnewline
-local tsnippetcontent = lpeg.C(lpeg.Cp() * (lpeg.S("\t ") ^ 1 * (lpeg.Ct(ttag) + tanyprintable) ^ 1 * tnewline) ^ 1)
-
--- Constructs
-local tsnippet = tsnippetdecl * tsnippetcontent
-local tcomment = lpeg.S("#") * tanyprintable ^ 0 * tnewline
-
--- The way grammar captures:
--- Every snippet gets its own table, and every table has:
--- 'tabtrigger' - the tabtrigger
--- [1] - full content
--- [2..n] - tags
-local tsnippetsfile = lpeg.Ct((tcomment + lpeg.Ct(tsnippet) + tnewline) ^ 1)
---------------------------------------------------------------------------------
-
--- local testsingle = [[
--- snippet sim
--- ${1:public} static int Main(string[] args)
--- {
--- ${0}
--- return 0;
--- }
--- ]]
-
--- local testmulti = [[
--- snippet sim
--- ${1:public} static int Main(string[] args)
--- {
--- ${0}
--- return 0;
--- }
--- snippet simc
--- public class Application
--- {
--- ${1:public} static int Main(string[] args)
--- {
--- ${0}
--- return 0;
--- }
--- }
--- snippet svm
--- ${1:public} static void Main(string[] args)
--- {
--- ${0}
--- }
--- ]]
-
-local testfile = [[
-# I'll most propably add more stuff in here like
-# * List/Array constructio
-# * Mostly used generics
-# * Linq
-# * Funcs, Actions, Predicates
-# * Lambda
-# * Events
-#
-# Feedback is welcome!
-#
-# Main
-snippet sim
- ${1:public} static int Main(string[] args)
- {
- ${0}
- return 0;
- }
-snippet simc
- public class Application
- {
- ${1:public} static int Main(string[] args)
- {
- ${0}
- return 0;
- }
- }
-snippet svm
- ${1:public} static void Main(string[] args)
- {
- ${0}
- }
-# if condition
-snippet if
- if (${1:true})
- {
- ${0:${VISUAL}}
- }
-snippet el
- else
- {
- ${0:${VISUAL}}
- }
-]]
-
---------------------------------------------------------------------------------
--- Test
-
-local function print_table(tableau, tabwidth)
- if tabwidth == nil then
- tabwidth = 0
- end
-
- -- Iterate
- for k, v in pairs(tableau) do
- local tabs = ("\t"):rep(tabwidth)
-
- print(tabs .. k .. ':"' .. tostring(v) .. '"')
- if type(v) == "table" then
- print_table(v, tabwidth + 1)
- end
- end
-end
-
---print("------------ header ------------------------------------")
---p = lpeg.Ct(tsnippetdecl)
---t = p:match([[
---snippet classy
---]])
---print_table(t)
---print("--------------------------------------------------------------")
-
---print("------------ tag ------------------------------------")
---print_table(
--- lpeg.Ct(ttag):match('${0:VISUAL}')
---)
---print_table(
--- lpeg.Ct(ttag):match('${12:Badonkadong}')
---)
---print_table(
--- lpeg.Ct(ttag):match('${1}')
---)
---print("--------------------------------------------------------------")
-
---print("------------ single snippet test ------------------------------------")
---print_table(lpeg.Ct(tsnippet):match(testsingle))
---print("--------------------------------------------------------------")
-
---print("------------ multi snippet test ------------------------------------")
---print_table(lpeg.Ct(tsnippetsfile):match(testmulti))
---print("--------------------------------------------------------------")
-
-print("------------ file with comments -------------------------------------")
-print_table(tsnippetsfile:match(testfile))
-print("--------------------------------------------------------------")
diff --git a/config/essentials/vis/vis-ultisnips/testlpeg-ultisnips.lua b/config/essentials/vis/vis-ultisnips/testlpeg-ultisnips.lua
deleted file mode 100644
index 79df900..0000000
--- a/config/essentials/vis/vis-ultisnips/testlpeg-ultisnips.lua
+++ /dev/null
@@ -1,230 +0,0 @@
-local lpeg = require("lpeg")
-
---------------------------------------------------------------------------------
-
-local tsep = lpeg.S(" ")
-local tws = tsep ^ 1
-local tnewline = lpeg.S("\n")
-local tlowcasedword = lpeg.R("az") ^ 1
-local tdigit = lpeg.locale()["digit"]
--- local talphanum = lpeg.locale()['alnum']
-local tanyprintable = lpeg.locale()["print"]
-local tcontrol = lpeg.locale()["cntrl"]
-local function quoted(p)
- return lpeg.S('"') * p * lpeg.S('"')
-end
-local function anythingbut(ch)
- return (tanyprintable + tcontrol) - lpeg.S(ch)
-end
-
-local ttabtriggercomplex = quoted(tlowcasedword * lpeg.S("()[]?0123456789-") ^ 1)
--- TODO This is just retarded
-local ttabtriggerweird = lpeg.S("!") * (lpeg.R("az") + lpeg.S("?()")) ^ 1 * lpeg.S("!")
-local ttabtriggerweird2 = lpeg.P("#!")
-local ttabtrigger = ttabtriggercomplex + ttabtriggerweird + ttabtriggerweird2 + tlowcasedword
-local tdescription = quoted(lpeg.Cg((tanyprintable - lpeg.S('"')) ^ 1, "description"))
-local toption = lpeg.R("az")
-
-local tstartsnippet = lpeg.P("snippet")
- * tws
- * lpeg.Cg(ttabtrigger, "tabtrigger")
- * tws
- * tdescription
- * tws ^ 0
- * lpeg.Cg(toption ^ 0, "options")
-local tendsnippet = lpeg.P("endsnippet")
-
--- The content parsing needs cleanup, its really convoluted due to me learning
--- lpeg while using it
---tcontent = ((tanyprintable + tcontrol)^1 - tendsnippet) * tnewline
-local tcontent = ((lpeg.S(" \t") + tanyprintable) ^ 1 - tendsnippet) * tnewline
-local tsnippet = tstartsnippet * tnewline * ((tendsnippet * tnewline) + lpeg.Cg(tcontent ^ 1, "content"))
-
-local tcomment = lpeg.S("#") * tanyprintable ^ 0 * tnewline
-local tpriority = lpeg.P("priority") * tws * lpeg.Cg(lpeg.S("-") ^ 0 * tdigit ^ 1, "priority")
-
--- TODO doesn't work
-local tsnippetsfile = (lpeg.Ct(tsnippet) + tpriority + tcomment + tnewline) ^ 1
-
--- TODO does parse values correctly, but parsing out nested tags will
--- require recursion at the callsite since I have no clue how to do it
-local ttag = {
- "T",
- Expr = lpeg.C((lpeg.V("T") + anythingbut("}")) ^ 1),
- Tnum = lpeg.Cg(tdigit ^ 1, "tagnum"),
- Ps = lpeg.Cg(lpeg.Cp(), "selstart"),
- Pe = lpeg.Cg(lpeg.Cp(), "selend"),
- Tc = lpeg.V("Ps")
- * lpeg.P("${")
- * lpeg.V("Tnum")
- * lpeg.S(":")
- * lpeg.Cg(lpeg.V("Expr"), "expr")
- * lpeg.V("Pe")
- * lpeg.S("}"),
- Ts = lpeg.V("Ps") * lpeg.S("$") * lpeg.V("Pe") * lpeg.V("Tnum"),
- T = lpeg.V("Tc") + lpeg.V("Ts"),
-}
-
---------------------------------------------------------------------------------
-
--- local testheader = [[
--- snippet #! "#!/usr/bin/env lua" b
--- ]]
-
-local testcontent = [[
-for ${1:idx},${2:val} in ipairs(${3:table_name}) do
- $0
-end
-]]
-
-local testsnippet = [[
-snippet fori "ipair for foop" b
-for ${1:idx},${2:val} in ipairs(${3:table_name}) do
- $0
-end
-endsnippet
-]]
-
-local luasnippetfile = [[
-priority -50
-
-#################################
-# Snippets for the Lua language #
-#################################
-snippet #! "#!/usr/bin/env lua" b
-#!/usr/bin/env lua
-$0
-endsnippet
-
-snippet !fun(ction)?! "New function" br
-local function ${1:new_function}(${2:args})
- $0
-end
-endsnippet
-
-snippet forp "pair for loop" b
-for ${1:name},${2:val} in pairs(${3:table_name}) do
- $0
-end
-endsnippet
-
-snippet fori "ipair for foop" b
-for ${1:idx},${2:val} in ipairs(${3:table_name}) do
- $0
-end
-endsnippet
-
-snippet for "numeric for loop" b
-for ${1:i}=${2:first},${3:last}${4/^..*/(?0:,:)/}${4:step} do
- $0
-end
-endsnippet
-
-snippet do "do block"
-do
- $0
-end
-endsnippet
-
-snippet repeat "repeat loop" b
-repeat
- $1
-until $0
-endsnippet
-
-snippet while "while loop" b
-while $1 do
- $0
-end
-endsnippet
-
-snippet if "if statement" b
-if $1 then
- $0
-end
-endsnippet
-
-snippet ife "if/else statement" b
-if $1 then
- $2
-else
- $0
-end
-endsnippet
-
-snippet eif "if/elseif statement" b
-if $1 then
- $2
-elseif $3 then
- $0
-end
-endsnippet
-
-snippet eife "if/elseif/else statement" b
-if $1 then
- $2
-elseif $3 then
- $4
-else
- $0
-end
-endsnippet
-
-snippet pcall "pcall statement" b
-local ok, err = pcall(${1:your_function})
-if not ok then
- handler(${2:ok, err})
-${3:else
- success(${4:ok, err})
-}end
-endsnippet
-
-snippet local "local x = 1"
-local ${1:x} = ${0:1}
-endsnippet
-
-# vim:ft=snippets:
-]]
-
---------------------------------------------------------------------------------
--- Test
-
-local function print_table(tableau, tabwidth)
- if tabwidth == nil then
- tabwidth = 0
- end
-
- -- Iterate
- for k, v in pairs(tableau) do
- local tabs = ("\t"):rep(tabwidth)
-
- print(tabs .. k .. ': "' .. tostring(v) .. '"')
- if type(v) == "table" then
- print_table(v, tabwidth + 1)
- end
- end
-end
-
-do
- print("------------ snippet test ------------------------------------")
- local p = lpeg.Ct(tsnippet)
- local t = p:match(testsnippet)
- print_table(t)
- print("--------------------------------------------------------------")
-end
-
-do
- print("------------ snippetfile test ------------------------------------")
- local p = lpeg.Ct(tsnippetsfile)
- local t = p:match(luasnippetfile)
- print_table(t)
- print("--------------------------------------------------------------")
-end
-
-do
- print("------------ tags test -------------------------------------")
- local p = lpeg.Ct((lpeg.Ct(ttag) + tanyprintable + tcontrol) ^ 1)
- local t = p:match(testcontent)
- print_table(t)
- print("--------------------------------------------------------------")
-end
diff --git a/config/essentials/vis/vis-ultisnips/ultisnips-parser.lua b/config/essentials/vis/vis-ultisnips/ultisnips-parser.lua
deleted file mode 100644
index a4240b8..0000000
--- a/config/essentials/vis/vis-ultisnips/ultisnips-parser.lua
+++ /dev/null
@@ -1,211 +0,0 @@
---------------------------------------------------------------------------------
--- Module table
-
-local M = {}
-
-local lpeg = require('lpeg')
-
-
-
---------------------------------------------------------------------------------
--- lpeg rules
-
-local tsep = lpeg.S' \t'
-local tws = tsep ^ 1
-local tnewline = lpeg.S'\n'
-local tlowcasedword = lpeg.R'az' ^ 1
-local tdigit = lpeg.locale()['digit']
--- local talphanum = lpeg.locale()['alnum']
-local tanyprintable = lpeg.locale()['print']
-local tcontrol = lpeg.locale()['cntrl']
-local function surrounded(ch, p) return lpeg.S(ch) * p * lpeg.S(ch) end
-local function anythingbut(ch) return (tanyprintable + tcontrol) - lpeg.S(ch) end
-
-local ttabtriggercomplex = surrounded ('"',
- tlowcasedword * lpeg.S'()[]?0123456789-'^1
- )
--- TODO This is just retarded
--- Check the actual grammar and see what special starting chars are
--- then relax the grammar a bit
-local ttabtriggerweird = surrounded('!',
- (lpeg.R'az' + lpeg.S'?()') ^ 1
- )
-local ttabtriggerweird2 = lpeg.P'#!'
-local ttabtriggerweird3 = surrounded('/',
- (anythingbut'/') ^1
- )
-local ttabtrigger = ttabtriggercomplex
- + ttabtriggerweird
- + ttabtriggerweird2
- + ttabtriggerweird3
- + (tlowcasedword + lpeg.S'.')
-local tdescription = surrounded ('"',
- lpeg.Cg( (tanyprintable - lpeg.S'"')^1, 'description')
- )
-local toption = lpeg.R'az'
-
-local tstartsnippet = lpeg.P'snippet'
- * tws
- * lpeg.Cg(ttabtrigger, 'tabtrigger')
- * tws
- * tdescription
- * tws ^ 0
- * lpeg.Cg(toption^0, 'options')
-local tendsnippet = lpeg.P'endsnippet'
-
--- The content parsing needs cleanup, its really convoluted due to me learning
--- lpeg while using it
---tcontent = ((tanyprintable + tcontrol)^1 - tendsnippet) * tnewline
-local tcontent = ((lpeg.S' \t' + tanyprintable)^1 - tendsnippet)
- * tnewline
-local tsnippet = tstartsnippet
- * tnewline
- * ((tendsnippet * tnewline) + lpeg.Cg(tcontent ^ 1, 'content'))
-
--- local tcomment = lpeg.S'#'
--- * tanyprintable^0
--- * tnewline
--- local tpriority = lpeg.P'priority'
--- * tws
--- * lpeg.Cg(lpeg.S('-')^0 * tdigit^1, 'priority')
-
--- TODO doesn't work
--- local tsnippetsfile = (lpeg.Ct(tsnippet) + tpriority + tcomment + tnewline) ^ 1
-
-
--- TODO does parse values correctly, but parsing out nested tags will
--- require recursion at the callsite since I have no clue how to do it
-local ttag = { 'T'
- ; Expr = lpeg.C((lpeg.V'T' + ((tanyprintable + tcontrol) - lpeg.S'}'))^1)
- , Tnum = lpeg.Cg(tdigit ^ 1, 'tagnum')
- , Ps = lpeg.Cg(lpeg.Cp(), 'selstart')
- , Pe = lpeg.Cg(lpeg.Cp(), 'selend')
- , Tc = lpeg.V'Ps'
- * lpeg.P'${'
- * lpeg.V'Tnum'
- * lpeg.S(':')
- * lpeg.Cg(lpeg.V'Expr', 'expr')
- * lpeg.V'Pe'
- * lpeg.S'}'
- , Ts = lpeg.V'Ps' * lpeg.S'$' * lpeg.V'Pe' * lpeg.V'Tnum'
- , T = lpeg.V'Tc' + lpeg.V'Ts'
- }
-
-
-
---------------------------------------------------------------------------------
--- Functions
-
--- Parses the snippet's content to create a table we later use
--- to corrently insert the text, the selections, and the default values
-local function create_content(str)
- local content = {}
- content.str = str
- content.tags = {}
-
- local p = vis.lpeg.Ct((lpeg.Ct(ttag) + tanyprintable + tcontrol) ^ 1)
- local m = p:match(str)
-
- local s = 1 -- We start from 1 to adjust position from $^0 to ^$0
- for k,v in ipairs(m) do
- content.tags[k] = v
- -- TODO recurse over tag.expr to extract nested tags
- -- Of course this will actually have to be used later on, depending
- -- on whether the tag is added or not
-
- -- We need to keep track of how much we remove, and readjust all
- -- subsequent selection points
- -- Note to self, I hate all this bookkeeping
- local tagtext = string.sub(str, v.selstart, v.selend)
- if v.expr ~= nil then
- content.str = string.gsub(content.str, tagtext, v.expr)
- content.tags[k].selstart = content.tags[k].selstart - s
- content.tags[k].selend = content.tags[k].selstart + #v.expr
- s = s + #'${' + #tostring(k) + #':' + 1
- else
- content.str = string.gsub(content.str, tagtext, '')
- content.tags[k].selstart = content.tags[k].selstart - s
- content.tags[k].selend = content.tags[k].selstart
- s = s + #'$' + 1
- end
- end
-
- return content
-end
-
-
-
--- Takes a line starting with 'snippet' and a lines iterator, and creates
--- a 'snippet' table to be used
--- If it fails it returns nil, otherwise returns two values, a tabtrigger
--- and a snippet
-local function create_snippet(start_line, linesit)
- local snippetstr = start_line .. '\n'
- -- Read content into list of lines until we hit `endsnippet`
- for line in linesit do
- local s, _ = string.find(line, 'endsnippet')
- if s == 1 then
- snippetstr = snippetstr .. 'endsnippet' .. '\n'
- break
- else
- snippetstr = snippetstr .. line .. '\n'
- end
- end
-
- local p = vis.lpeg.Ct(tsnippet)
- local m = p:match(snippetstr)
-
- if not m then
- -- Enable this when debugging, otherwise it nukes whole app
- vis:info('Failed to parse some snippets!')
- -- vis:message('Failed to parse snippet: ' .. snippetstr)
- return nil
- else
- local tabtrigger = m.tabtrigger
- local snippet = {}
- snippet.description = m.description
- snippet.options = m.options
- snippet.content = create_content(m.content)
- return tabtrigger, snippet
- end
-end
-
-
-
--- Loads all snippets from passed '.snippets' file. Should probably be
--- triggered when new file is loaded or when syntax is set/changed
-M.load_snippets = function(snippetfile)
- local snippets = {}
-
- local f = io.open(snippetfile, 'r')
- if f then
- io.input(f)
- local linesit = io.lines()
-
- for line in linesit do
- -- TODO read whole file, then apply lpeg grammar that parses all
- -- snippets out rather than being pedestrian about it like this
- local s, _ = string.find(line, 'snippet')
- -- Find lines that start with 'snippet' and enter
- -- snippet reading loop
- if s == 1 then
- local tabtrigger, snippet = create_snippet(line, linesit)
- if tabtrigger then
- snippets[tabtrigger] = snippet
- end
- end
- end
-
- io.close(f)
- return snippets, true
- else
- return snippets, false
- end
-end
-
-
-
---------------------------------------------------------------------------------
--- End module
-
-return M \ No newline at end of file