Skip to content

Commit 91a8088

Browse files
committed
Introduce byte offset
pos.i is actually "character offset" and it doesn't handle line-continuation, so we cannot use pos.i to extract node from the source with it. Introduce pos.offset which represents byte offset which can be used above cases. FIX #65
1 parent 7bb0f75 commit 91a8088

File tree

5 files changed

+69
-2
lines changed

5 files changed

+69
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
test/*.out
1+
*.out

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ js/test: js/vimlparser.js
2525
py/test: py/vimlparser.py
2626
test/run_command.sh python py/vimlparser.py
2727

28+
test/node_position/test_position.out: test/node_position/test_position.vim test/node_position/test_position.ok
29+
vim -u NONE -N --cmd "let &rtp .= ',' . getcwd()" -S test/node_position/test_position.vim
30+
diff -u test/node_position/test_position.ok test/node_position/test_position.out
31+
2832
.PHONY: all clean_compiled check test js/test py/test

autoload/vimlparser.vim

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3768,13 +3768,17 @@ endfunction
37683768
function! s:StringReader.__init__(lines)
37693769
let self.buf = []
37703770
let self.pos = []
3771+
let self.offset = []
37713772
let lnum = 0
3773+
let offset = 0
37723774
while lnum < len(a:lines)
37733775
let col = 0
37743776
for c in split(a:lines[lnum], '\zs')
37753777
call add(self.buf, c)
37763778
call add(self.pos, [lnum + 1, col + 1])
3779+
call add(self.offset, offset)
37773780
let col += len(c)
3781+
let offset += len(c)
37783782
endfor
37793783
while lnum + 1 < len(a:lines) && a:lines[lnum + 1] =~# '^\s*\\'
37803784
let skip = s:TRUE
@@ -3787,17 +3791,23 @@ function! s:StringReader.__init__(lines)
37873791
else
37883792
call add(self.buf, c)
37893793
call add(self.pos, [lnum + 2, col + 1])
3794+
call add(self.offset, offset)
37903795
endif
37913796
let col += len(c)
3797+
let offset += len(c)
37923798
endfor
37933799
let lnum += 1
3800+
let offset += 1
37943801
endwhile
37953802
call add(self.buf, '<EOL>')
37963803
call add(self.pos, [lnum + 1, col + 1])
3804+
call add(self.offset, offset)
37973805
let lnum += 1
3806+
let offset += 1
37983807
endwhile
37993808
" for <EOF>
38003809
call add(self.pos, [lnum + 1, 0])
3810+
call add(self.offset, offset)
38013811
let self.i = 0
38023812
endfunction
38033813

@@ -3892,7 +3902,7 @@ endfunction
38923902

38933903
function! s:StringReader.getpos()
38943904
let [lnum, col] = self.pos[self.i]
3895-
return {'i': self.i, 'lnum': lnum, 'col': col}
3905+
return {'i': self.i, 'lnum': lnum, 'col': col, 'offset': self.offset[self.i]}
38963906
endfunction
38973907

38983908
function! s:StringReader.setpos(pos)

test/node_position/test_position.ok

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function! F()
2+
let x =
3+
\ 1
4+
5+
let x = "
6+
\1
7+
\2 <- tab
8+
\3"
9+
endfunction

test/node_position/test_position.vim

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
let s:vimlparser = vimlparser#import()
2+
3+
function! s:run()
4+
let src = [
5+
\ '',
6+
\ 'function! F()',
7+
\ ' let x =',
8+
\ '\ 1',
9+
\ '',
10+
\ ' let x = "',
11+
\ ' \1',
12+
\ ' \2 <- tab',
13+
\ ' \3"',
14+
\ 'endfunction',
15+
\ '',
16+
\ '" END',
17+
\]
18+
let r = s:vimlparser.StringReader.new(src)
19+
let p = s:vimlparser.VimLParser.new(0)
20+
let c = s:vimlparser.Compiler.new()
21+
let toplevel = p.parse(r)
22+
let func = toplevel.body[0]
23+
let body = s:extract_body(func, src)
24+
echom string(split(body, "\n"))
25+
call writefile(split(body, "\n"), 'test/node_position/test_position.out')
26+
qall!
27+
endfunction
28+
29+
function! s:extract_body(func, src)
30+
let pos = a:func.pos
31+
32+
" FIXME calculating endpos is workaround. Ideally, it should have the end
33+
" position of the node.
34+
35+
let endpos = a:func.endfunction.pos
36+
let endfunc = a:func.endfunction.ea
37+
let cmdlen = endfunc.argpos.i - endfunc.cmdpos.i
38+
let endpos.i += cmdlen
39+
let endpos.offset += cmdlen
40+
41+
return join(a:src, "\n")[pos.offset : endpos.offset]
42+
endfunction
43+
44+
call s:run()

0 commit comments

Comments
 (0)