aboutsummaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2017-02-22 21:17:48 +0100
committerMarc André Tanner <mat@brain-dump.org>2017-02-22 21:17:48 +0100
commit0cbd1b87ed4908a3675c6604a0e1780c5ef265a1 (patch)
tree8dd630f8b879ec04acccd96d2ac1763e0e3ac5c0 /lua
parent065f819487aec6382ee9f87cb9c8d16d76b4b104 (diff)
downloadvis-0cbd1b87ed4908a3675c6604a0e1780c5ef265a1.tar.gz
vis-0cbd1b87ed4908a3675c6604a0e1780c5ef265a1.tar.xz
lua: add file:match_at method to match LPeg pattern around a position
Diffstat (limited to 'lua')
-rw-r--r--lua/vis.lua31
1 files changed, 31 insertions, 0 deletions
diff --git a/lua/vis.lua b/lua/vis.lua
index 24d00bd..f18792e 100644
--- a/lua/vis.lua
+++ b/lua/vis.lua
@@ -190,4 +190,35 @@ end
vis.events = events
+---
+-- @type File
+
+--- Check whether LPeg pattern matches at a given file position.
+-- @function match_at
+-- @param pattern the LPeg pattern
+-- @tparam int the absolute position in bytes to test for a match
+-- @tparam[opt] int horizon the number of bytes around `pos` to consider (defaults to 1K)
+-- @treturn int start,end the range of the matched region or `nil`
+vis.types['vis.file'].match_at = function(file, pattern, pos, horizon)
+ horizon = horizon or 1024
+ local lpeg = vis.lpeg
+ if not lpeg then return nil end
+ local before, after = pos - horizon, pos + horizon
+ if before < 0 then before = 0 end
+ local data = file:content(before, after - before)
+ local string_pos = pos - before + 1
+
+ local I = lpeg.Cp()
+ local p = lpeg.P{ I * pattern * I + 1 * lpeg.V(1) }
+ local s, e = 1
+ while true do
+ s, e = p:match(data, s)
+ if not s then return nil end
+ if s <= string_pos and string_pos < e then
+ return before + s - 1, before + e - 1
+ end
+ s = e
+ end
+end
+
require('vis-std')