Skip to content

Commit dcf2442

Browse files
committed
Add g:jsonpath_use_python option which enables python implementation
1 parent a735e5a commit dcf2442

4 files changed

Lines changed: 79 additions & 5 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ au FileType json noremap <buffer> <silent> <expr> <leader>p jsonpath#echo()
2222
au FileType json noremap <buffer> <silent> <expr> <leader>g jsonpath#goto()
2323
```
2424

25+
### Python support in vim
26+
27+
While not required it is recommended to use a Vim environment with the
28+
`+python3` feature enabled, since the plugin provides a python implementation
29+
that is much faster than the vimscript variant. You can check the availability
30+
using:
31+
```vim
32+
:echo has("python3")
33+
```
34+
2535
## Mappings
2636

2737
Mappings are not provided by default but can easily be added to your `.vimrc`.

autoload/jsonpath.vim

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
" autoload/jsonpath.vim
22
" Author: Victor Hallberg <https://hallberg.cc>
33

4-
if exists("g:autoloaded_jsonpath")
4+
if exists('g:autoloaded_jsonpath')
55
finish
66
endif
77
let g:autoloaded_jsonpath = 1
88

9+
let s:plugin_dir = expand('<sfile>:p:h:h')
10+
911
let s:escapes = {
1012
\ 'b': "\b",
1113
\ 'f': "\f",
@@ -45,12 +47,27 @@ function! jsonpath#scan_buffer(search_for, ...) "{{{
4547
endif
4648
let is_searching = !empty(search_for)
4749

50+
let to_column = max([0, get(a:, 2)])
51+
4852
let to_line = get(a:, 1)
4953
if to_line < 1 || to_line > line('$')
5054
let to_line = line('$')
55+
let to_column = strchars(getline('$'))
5156
endif
5257

53-
let to_column = max([0, get(a:, 2)])
58+
if g:jsonpath_use_python
59+
if has('python3')
60+
return jsonpath#scan_buffer_python(search_for, to_line, to_column)
61+
endif
62+
63+
echom 'g:jsonpath_use_python set but python not found, falling back to vimscript'
64+
endif
65+
66+
return jsonpath#scan_buffer_vimscript(search_for, to_line, to_column)
67+
endfunction "}}}
68+
69+
function! jsonpath#scan_buffer_vimscript(search_for, to_line, to_column) "{{{
70+
let is_searching = !empty(a:search_for)
5471

5572
" Parser state
5673
let stack = []
@@ -63,7 +80,7 @@ function! jsonpath#scan_buffer(search_for, ...) "{{{
6380

6481
try
6582
let lnr = 1
66-
while lnr <= to_line "{{{
83+
while lnr <= a:to_line "{{{
6784
let line = getline(lnr)
6885
let line_length = len(line)
6986
let cnr = 1
@@ -129,13 +146,13 @@ function! jsonpath#scan_buffer(search_for, ...) "{{{
129146
\})
130147

131148
" Check if the sought search_for path has been reached?
132-
if stack_modified == 1 && is_searching && s:is_equal_lists(stack, search_for)
149+
if stack_modified == 1 && is_searching && s:is_equal_lists(stack, a:search_for)
133150
return [bufnr('%'), lnr, cnr, 0]
134151
endif
135152
endif
136153

137154
" Abort if end position has been reached
138-
if !parsing_key && lnr >= to_line && cnr + 1 >= to_column
155+
if !parsing_key && lnr >= a:to_line && cnr + 1 >= a:to_column
139156
let finished = !is_searching " search failed if we reached end
140157
break
141158
endif
@@ -185,6 +202,32 @@ function! jsonpath#scan_buffer(search_for, ...) "{{{
185202
return []
186203
endfunction "}}}
187204

205+
function! jsonpath#scan_buffer_python(search_for, to_line, to_column) "{{{
206+
py3 << EOF
207+
import sys
208+
import vim
209+
sys.path.insert(0, vim.eval('s:plugin_dir'))
210+
import jsonpath
211+
212+
stream = jsonpath.CountingLines(vim.current.buffer)
213+
result = jsonpath.scan_stream(
214+
stream,
215+
path=vim.eval('a:search_for'),
216+
line=int(vim.eval('a:to_line')),
217+
column=int(vim.eval('a:to_column')),
218+
)
219+
EOF
220+
221+
let result = py3eval('result')
222+
if empty(result)
223+
return []
224+
elseif !empty(a:search_for)
225+
return [bufnr('%'), result[0], result[1], 0]
226+
endif
227+
228+
return result
229+
endfunction "}}}
230+
188231
" Attempts to place the cursor on identifier for the given path
189232
function! jsonpath#goto(...) "{{{
190233
let search_for = get(a:, 1)

doc/jsonpath.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ INTRODUCTION *jsonpath*
1111

1212
This plugin provides ways of navigating JSON document buffers.
1313

14+
While not required it is recommended to use a Vim environment with the
15+
|+python3| feature enabled, since the python implementation is much faster
16+
than the vimscript variant. You can check the availability using: >
17+
:echo has("python3")
18+
<
19+
1420
*jsonpath-dot-notation*
1521
Paths should be entered (and will be output) using dot notation, consisting of
1622
properties separated by dots (configurable, see |g:jsonpath_delimeter|).
@@ -63,6 +69,17 @@ Set using >
6369
let g:jsonpath_register = '*'
6470
<
6571

72+
|g:jsonpath_use_python| *g:jsonpath_use_python*
73+
Type: |int|
74+
Default: `has('python3')`
75+
76+
Set this value to `0` to prevent the plugin from using python to scan the
77+
buffer. This option should generally be left alone as the python
78+
implementation is much faster.
79+
Override using >
80+
let g:jsonpath_use_python = 0
81+
<
82+
6683
==============================================================================
6784
COMMANDS *jsonpath-commands*
6885

plugin/jsonpath.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ if !exists('g:jsonpath_delimeter')
1010
let g:jsonpath_delimeter = '.'
1111
endif
1212

13+
if !exists('g:jsonpath_use_python')
14+
let g:jsonpath_use_python = has('python3')
15+
endif
16+
1317
command! -nargs=? JsonPath call jsonpath#command(<q-args>)
1418

1519
" au FileType json noremap <buffer> <silent> <expr> <leader>g jsonpath#goto()

0 commit comments

Comments
 (0)