├── .gitignore ├── LICENSE ├── README.md ├── autoload └── neovim_rpc.vim └── pythonx ├── neovim_rpc_methods.py ├── neovim_rpc_protocol.py ├── neovim_rpc_server.py └── neovim_rpc_server_api_info.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2018 roxma@qq.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # vim-hug-neovim-rpc 3 | 4 | This is an **experimental project**, trying to build a compatibility layer for 5 | [neovim rpc client](https://github.com/neovim/python-client) working on vim8. 6 | I started this project because I want to fix the [vim8 7 | support](https://github.com/roxma/nvim-completion-manager/issues/14) issue for 8 | [nvim-completion-manager](https://github.com/roxma/nvim-completion-manager). 9 | 10 | Since this is a general purpose module, other plugins needing rpc support may 11 | benefit from this project. However, there're many neovim rpc methods I haven't 12 | implemented yet, which make this an experimental plugin. **Please fork and 13 | open a PR if you get any idea on improving it**. 14 | 15 | ***Tip: for porting neovim rplugin to vim8, you might need 16 | [roxma/nvim-yarp](https://github.com/roxma/nvim-yarp)*** 17 | 18 | ![screencast](https://cloud.githubusercontent.com/assets/4538941/23102626/9e1bd928-f6e7-11e6-8fa2-2776f70819d9.gif) 19 | 20 | ## Requirements 21 | 22 | 23 | 1. vim8 24 | 2. If `has('pythonx')` and `set pyxversion=3` 25 | - same requirements as `4. has('python3')` 26 | 2. Else if `has('pythonx')` and `set pyxversion=2` 27 | - same requirements as `5. has('python')` 28 | 4. Else if `has('python3')` 29 | - [pynvim](https://github.com/neovim/pynvim) 30 | - Pynvim is normally installed by `:py3 import pip; pip.main(['install', 31 | '--user', 'pynvim'])` or `python3 -m pip install pynvim`. 32 | If you are a win32 user, be careful that your python install and your 33 | vim install should both the same architecture (both 64bit or both 32). 34 | - There should be no error for at least one of `:python3 import pynvim` and 35 | `:python3 import neovim` 36 | 5. Else if `has('python')` 37 | - [pynvim](https://github.com/neovim/pynvim) 38 | - Pynvim is normally installed by `:py import pip; pip.main(['install', 39 | '--user', 'pynvim'])` or `python2 -m pip install pynvim`. 40 | - There should be no error for at least one of `:python3 import pynvim` and 41 | `:python3 import neovim` 42 | 6. `set encoding=utf-8` in your vimrc. 43 | 44 | ***Use `:echo neovim_rpc#serveraddr()` to test the installation***. It should print 45 | something like `127.0.0.1:51359` or `/tmp/vmrUX9X/2`. 46 | 47 | ## API 48 | 49 | | Function | Similar to neovim's | 50 | |----------------------------------------------|------------------------------------------------| 51 | | `neovim_rpc#serveraddr()` | `v:servername` | 52 | | `neovim_rpc#jobstart(cmd,...)` | `jobstart({cmd}[, {opts}])` | 53 | | `neovim_rpc#jobstop(jobid)` | `jobstop({job})` | 54 | | `neovim_rpc#rpcnotify(channel,event,...)` | `rpcnotify({channel}, {event}[, {args}...])` | 55 | | `neovim_rpc#rpcrequest(channel, event, ...)` | `rpcrequest({channel}, {method}[, {args}...])` | 56 | 57 | Note that `neovim_rpc#jobstart` only support these options: 58 | 59 | - `on_stdout` 60 | - `on_stderr` 61 | - `on_exit` 62 | - `detach` 63 | 64 | ## Incompatibility issues 65 | 66 | - Cannot pass `Funcref` object to python client. Pass function name instead. 67 | - Python `None` will be converted to `''` instead of `v:null` into vimscript. 68 | See [vim#2246](https://github.com/vim/vim/issues/2246) 69 | - The following neovim-only API will be ignored quietly: 70 | - `nvim_buf_add_highlight` 71 | - `nvim_buf_clear_highlight` 72 | 73 | ## Overall Implementation 74 | 75 | ``` 76 | "vim-hug-neovim-rpc - Sequence Diagram" 77 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 78 | 79 | 80 | ┌───┐ ┌──────────┐ ┌───────────┐ ┌──────┐ 81 | │VIM│ │VIM Server│ │NVIM Server│ │Client│ 82 | └─┬─┘ └────┬─────┘ └─────┬─────┘ └──┬───┘ 83 | │ Launch thread │ │ │ 84 | │───────────────────> │ │ 85 | │ │ │ │ 86 | │ Launch thread │ │ 87 | │─────────────────────────────────────────────────>│ │ 88 | │ │ │ │ 89 | │ `ch_open` connect │ │ │ 90 | │───────────────────> │ │ 91 | │ │ │ │ 92 | │ │────┐ │ │ 93 | │ │ │ Launch VimHandler thread│ │ 94 | │ │<───┘ │ │ 95 | │ │ │ │ 96 | │ │ │ Connect │ 97 | │ │ │<───────────────────────────── 98 | │ │ │ │ 99 | │ │ ────┐ 100 | │ │ │ Launch NvimHandler thread 101 | │ │ <───┘ 102 | │ │ │ │ 103 | │ │ │ Request (msgpack rpc) │ 104 | │ │ │<───────────────────────────── 105 | │ │ │ │ 106 | │ │ ────┐ │ 107 | │ │ │ Request enqueue │ 108 | │ │ <───┘ │ 109 | │ │ │ │ 110 | │ │ notify (method call) │ │ 111 | │ │ <────────────────────────────│ │ 112 | │ │ │ │ 113 | │ notify (json rpc) │ │ │ 114 | │<─────────────────── │ │ 115 | │ │ │ │ 116 | ────┐ │ │ 117 | │ Request dequeue │ │ 118 | <───┘ │ │ 119 | │ │ │ │ 120 | ────┐ │ │ │ 121 | │ Process │ │ │ 122 | <───┘ │ │ │ 123 | │ │ │ │ 124 | │ │ Send response (msgpack rpc) │ 125 | │────────────────────────────────────────────────────────────────────────────────> 126 | ┌─┴─┐ ┌────┴─────┐ ┌─────┴─────┐ ┌──┴───┐ 127 | │VIM│ │VIM Server│ │NVIM Server│ │Client│ 128 | └───┘ └──────────┘ └───────────┘ └──────┘ 129 | ``` 130 | 131 | 153 | 154 | ## Debugging 155 | 156 | Add logging settigns to your vimrc. Log files will be generated with prefix 157 | `/tmp/nvim_log`. An alternative is to export environment variables before 158 | starting vim/nvim. 159 | 160 | ```vim 161 | let $NVIM_PYTHON_LOG_FILE="/tmp/nvim_log" 162 | let $NVIM_PYTHON_LOG_LEVEL="DEBUG" 163 | ``` 164 | 165 | -------------------------------------------------------------------------------- /autoload/neovim_rpc.vim: -------------------------------------------------------------------------------- 1 | 2 | if has('pythonx') 3 | let g:neovim_rpc#py = 'pythonx' 4 | let s:pyeval = function('pyxeval') 5 | elseif has('python3') 6 | let g:neovim_rpc#py = 'python3' 7 | let s:pyeval = function('py3eval') 8 | else 9 | let g:neovim_rpc#py = 'python' 10 | let s:pyeval = function('pyeval') 11 | endif 12 | 13 | func! s:py(cmd) 14 | execute g:neovim_rpc#py a:cmd 15 | endfunc 16 | 17 | func! neovim_rpc#serveraddr() 18 | if exists('g:_neovim_rpc_nvim_server') 19 | return g:_neovim_rpc_nvim_server 20 | endif 21 | 22 | if &encoding !=? "utf-8" 23 | throw '[vim-hug-neovim-rpc] requires `:set encoding=utf-8`' 24 | endif 25 | 26 | try 27 | call s:py('import pynvim') 28 | catch 29 | try 30 | call s:py('import neovim') 31 | catch 32 | call neovim_rpc#_error("failed executing: " . 33 | \ g:neovim_rpc#py . " import [pynvim|neovim]") 34 | call neovim_rpc#_error(v:exception) 35 | throw '[vim-hug-neovim-rpc] requires one of `:' . g:neovim_rpc#py . 36 | \ ' import [pynvim|neovim]` command to work' 37 | endtry 38 | endtry 39 | 40 | call s:py('import neovim_rpc_server') 41 | let l:servers = s:pyeval('neovim_rpc_server.start()') 42 | 43 | let g:_neovim_rpc_nvim_server = l:servers[0] 44 | let g:_neovim_rpc_vim_server = l:servers[1] 45 | 46 | let g:_neovim_rpc_main_channel = ch_open(g:_neovim_rpc_vim_server) 47 | 48 | " identify myself 49 | call ch_sendexpr(g:_neovim_rpc_main_channel,'neovim_rpc_setup') 50 | 51 | return g:_neovim_rpc_nvim_server 52 | endfunc 53 | 54 | " elegant python function call wrapper 55 | func! neovim_rpc#pyxcall(func,...) 56 | call s:py('import vim, json') 57 | let g:neovim_rpc#_tmp_args = copy(a:000) 58 | let l:ret = s:pyeval(a:func . '(*vim.vars["neovim_rpc#_tmp_args"])') 59 | unlet g:neovim_rpc#_tmp_args 60 | return l:ret 61 | endfunc 62 | 63 | " supported opt keys: 64 | " - on_stdout 65 | " - on_stderr 66 | " - on_exit 67 | " - detach 68 | func! neovim_rpc#jobstart(cmd,...) 69 | 70 | let l:opts = {} 71 | if len(a:000) 72 | let l:opts = a:1 73 | endif 74 | 75 | let l:opts['_close'] = 0 76 | let l:opts['_exit'] = 0 77 | 78 | let l:real_opts = {'mode': 'raw'} 79 | if has_key(l:opts,'detach') && l:opts['detach'] 80 | let l:real_opts['stoponexit'] = '' 81 | endif 82 | 83 | if has_key(l:opts,'on_stdout') 84 | let l:real_opts['out_cb'] = function('neovim_rpc#_on_stdout') 85 | endif 86 | if has_key(l:opts,'on_stderr') 87 | let l:real_opts['err_cb'] = function('neovim_rpc#_on_stderr') 88 | endif 89 | let l:real_opts['exit_cb'] = function('neovim_rpc#_on_exit') 90 | let l:real_opts['close_cb'] = function('neovim_rpc#_on_close') 91 | 92 | let l:job = job_start(a:cmd, l:real_opts) 93 | let l:jobid = ch_info(l:job)['id'] 94 | 95 | let g:_neovim_rpc_jobs[l:jobid] = {'cmd':a:cmd, 'opts': l:opts, 'job': l:job} 96 | 97 | return l:jobid 98 | endfunc 99 | 100 | func! neovim_rpc#jobstop(jobid) 101 | let l:job = g:_neovim_rpc_jobs[a:jobid]['job'] 102 | return job_stop(l:job) 103 | endfunc 104 | 105 | func! neovim_rpc#rpcnotify(channel,event,...) 106 | call neovim_rpc#pyxcall('neovim_rpc_server.rpcnotify',a:channel,a:event,a:000) 107 | endfunc 108 | 109 | let s:rspid = 1 110 | func! neovim_rpc#rpcrequest(channel, event, ...) 111 | let s:rspid = s:rspid + 1 112 | 113 | " a unique key for storing response 114 | let rspid = '' . s:rspid 115 | 116 | " neovim's rpcrequest doesn't have timeout 117 | let opt = {'timeout': 24 * 60 * 60 * 1000} 118 | let args = ['rpcrequest', a:channel, a:event, a:000, rspid] 119 | call ch_evalexpr(g:_neovim_rpc_main_channel, args, opt) 120 | 121 | let expr = 'neovim_rpc_server.responses.pop("' . rspid . '")' 122 | 123 | call s:py('import neovim_rpc_server, json') 124 | let [err, result] = s:pyeval(expr) 125 | if err 126 | if type(err) == type('') 127 | throw err 128 | endif 129 | throw err[1] 130 | endif 131 | return result 132 | endfunc 133 | 134 | func! neovim_rpc#_on_stdout(job,data) 135 | let l:jobid = ch_info(a:job)['id'] 136 | let l:opts = g:_neovim_rpc_jobs[l:jobid]['opts'] 137 | " convert to neovim style function call 138 | call call(l:opts['on_stdout'],[l:jobid,split(a:data,"\n",1),'stdout'],l:opts) 139 | endfunc 140 | 141 | func! neovim_rpc#_on_stderr(job,data) 142 | let l:jobid = ch_info(a:job)['id'] 143 | let l:opts = g:_neovim_rpc_jobs[l:jobid]['opts'] 144 | " convert to neovim style function call 145 | call call(l:opts['on_stderr'],[l:jobid,split(a:data,"\n",1),'stderr'],l:opts) 146 | endfunc 147 | 148 | func! neovim_rpc#_on_exit(job,status) 149 | let l:jobid = ch_info(a:job)['id'] 150 | let l:opts = g:_neovim_rpc_jobs[l:jobid]['opts'] 151 | let l:opts['_exit'] = 1 152 | " cleanup when both close_cb and exit_cb is called 153 | if l:opts['_close'] && l:opts['_exit'] 154 | unlet g:_neovim_rpc_jobs[l:jobid] 155 | endif 156 | if has_key(l:opts, 'on_exit') 157 | " convert to neovim style function call 158 | call call(l:opts['on_exit'],[l:jobid,a:status,'exit'],l:opts) 159 | endif 160 | endfunc 161 | 162 | func! neovim_rpc#_on_close(job) 163 | let l:jobid = ch_info(a:job)['id'] 164 | let l:opts = g:_neovim_rpc_jobs[l:jobid]['opts'] 165 | let l:opts['_close'] = 1 166 | " cleanup when both close_cb and exit_cb is called 167 | if l:opts['_close'] && l:opts['_exit'] 168 | unlet g:_neovim_rpc_jobs[l:jobid] 169 | endif 170 | endfunc 171 | 172 | func! neovim_rpc#_callback() 173 | execute g:neovim_rpc#py . ' neovim_rpc_server.process_pending_requests()' 174 | endfunc 175 | 176 | let g:_neovim_rpc_main_channel = -1 177 | let g:_neovim_rpc_jobs = {} 178 | 179 | let s:leaving = 0 180 | 181 | func! neovim_rpc#_error(msg) 182 | if mode() == 'i' 183 | " NOTE: side effect, sorry, but this is necessary 184 | set nosmd 185 | endif 186 | echohl ErrorMsg 187 | echom '[vim-hug-neovim-rpc] ' . a:msg 188 | echohl None 189 | endfunc 190 | 191 | func! neovim_rpc#_nvim_err_write(msg) 192 | if mode() == 'i' 193 | " NOTE: side effect, sorry, but this is necessary 194 | set nosmd 195 | endif 196 | echohl ErrorMsg 197 | let g:error = a:msg 198 | echom a:msg 199 | echohl None 200 | endfunc 201 | 202 | func! neovim_rpc#_nvim_out_write(msg) 203 | echom a:msg 204 | endfunc 205 | -------------------------------------------------------------------------------- /pythonx/neovim_rpc_methods.py: -------------------------------------------------------------------------------- 1 | # vim:set et sw=4 ts=8: 2 | import vim 3 | 4 | # vim's python binding doesn't have the `call` method, wrap it here 5 | 6 | 7 | def nvim_call_function(method, args): 8 | vim.vars['_neovim_rpc_tmp_args'] = args 9 | # vim.eval('getcurpos()') return an array of string, it should be an array 10 | # of int. Use json_encode to workaround this 11 | return vim.bindeval('call("%s",g:_neovim_rpc_tmp_args)' % method) 12 | 13 | 14 | def nvim_get_current_buf(): 15 | return vim.current.buffer 16 | 17 | 18 | def nvim_list_bufs(): 19 | return list(vim.buffers) 20 | 21 | 22 | def nvim_buf_get_number(buf): 23 | return buf.number 24 | 25 | 26 | def nvim_buf_get_mark(buffer, name): 27 | return buffer.mark(name) 28 | 29 | 30 | def nvim_buf_get_name(buffer): 31 | return buffer.name 32 | 33 | 34 | def nvim_get_var(name): 35 | return vim.vars[name] 36 | 37 | 38 | def nvim_get_vvar(name): 39 | return vim.vvars[name] 40 | 41 | 42 | def nvim_set_var(name, val): 43 | vim.vars[name] = val 44 | return val 45 | 46 | 47 | def nvim_buf_get_var(buffer, name): 48 | return buffer.vars[name] 49 | 50 | 51 | def nvim_buf_set_var(buffer, name, val): 52 | buffer.vars[name] = val 53 | 54 | 55 | def nvim_buf_get_lines(buffer, start, end, *args): 56 | if start < 0: 57 | start = len(buffer) + 1 + start 58 | if end < 0: 59 | end = len(buffer) + 1 + end 60 | return buffer[start:end] 61 | 62 | 63 | def nvim_eval(expr): 64 | return nvim_call_function('eval', [expr]) 65 | 66 | 67 | def nvim_buf_set_lines(buffer, start, end, err, lines): 68 | if start < 0: 69 | start = len(buffer) + 1 + start 70 | if end < 0: 71 | end = len(buffer) + 1 + end 72 | buffer[start:end] = lines 73 | 74 | if nvim_call_function('bufwinnr', [buffer.number]) != -1: 75 | # vim needs' redraw to update the screen, it seems to be a bug 76 | vim.command('redraw') 77 | 78 | 79 | buffer_set_lines = nvim_buf_set_lines 80 | 81 | 82 | def buffer_line_count(buffer): 83 | return len(buffer) 84 | 85 | 86 | def nvim_buf_line_count(buffer): 87 | return len(buffer) 88 | 89 | 90 | def nvim_get_option(name): 91 | return vim.options[name] 92 | 93 | 94 | def nvim_buf_get_option(buf, name): 95 | return buf.options[name] 96 | 97 | 98 | def nvim_set_option(name, val): 99 | vim.options[name] = val 100 | 101 | 102 | def nvim_buf_set_option(buf, name, val): 103 | buf.options[name] = val 104 | 105 | 106 | def nvim_command(cmd): 107 | vim.command(cmd) 108 | 109 | 110 | def nvim_get_current_line(): 111 | return vim.current.line 112 | 113 | 114 | def nvim_get_current_win(): 115 | return vim.current.window 116 | 117 | 118 | def nvim_list_wins(): 119 | return list(vim.windows) 120 | 121 | 122 | def nvim_win_get_cursor(window): 123 | return window.cursor 124 | 125 | 126 | def nvim_win_get_buf(window): 127 | return window.buffer 128 | 129 | 130 | def nvim_win_get_width(window): 131 | return window.width 132 | 133 | 134 | def nvim_win_set_width(window, width): 135 | window.width = width 136 | 137 | 138 | def nvim_win_get_height(window): 139 | return window.height 140 | 141 | 142 | def nvim_win_set_height(window, height): 143 | window.height = height 144 | 145 | 146 | def nvim_win_get_var(window, name): 147 | return window.vars[name] 148 | 149 | 150 | def nvim_win_set_var(window, name, val): 151 | window.vars[name] = val 152 | 153 | 154 | def nvim_win_get_option(window, name): 155 | return window.options[name] 156 | 157 | 158 | def nvim_win_set_option(window, name, val): 159 | window.options[name] = val 160 | 161 | 162 | def nvim_win_get_position(window): 163 | return (window.row, window.col) 164 | 165 | 166 | def nvim_win_get_number(window): 167 | return window.number 168 | 169 | 170 | def nvim_win_is_valid(window): 171 | return window.valid 172 | 173 | 174 | def nvim_out_write(s): 175 | nvim_call_function('neovim_rpc#_nvim_out_write', [s]) 176 | 177 | 178 | def nvim_err_write(s): 179 | nvim_call_function('neovim_rpc#_nvim_err_write', [s]) 180 | 181 | 182 | def nvim_buf_add_highlight(buf, src_id, *args): 183 | # https://github.com/autozimu/LanguageClient-neovim/pull/151#issuecomment-339198527 184 | # FIXME 185 | return src_id 186 | 187 | 188 | def nvim_buf_clear_highlight(*args): 189 | # https://github.com/autozimu/LanguageClient-neovim/pull/151#issuecomment-339198527 190 | # FIXME 191 | pass 192 | 193 | 194 | def nvim_set_client_info(*args): 195 | # https://github.com/roxma/vim-hug-neovim-rpc/issues/61 196 | vim.vars['_neovim_rpc_client_info'] = args 197 | 198 | 199 | def nvim_get_client_info(): 200 | if '_neovim_rpc_client_info' not in vim.vars: 201 | return [] 202 | return vim.vars['_neovim_rpc_client_info'] 203 | -------------------------------------------------------------------------------- /pythonx/neovim_rpc_protocol.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import vim 3 | import msgpack 4 | import neovim_rpc_server_api_info 5 | 6 | BUFFER_TYPE = type(vim.current.buffer) 7 | BUFFER_TYPE_ID = neovim_rpc_server_api_info.API_INFO['types']['Buffer']['id'] 8 | WINDOW_TYPE = type(vim.current.window) 9 | WINDOW_TYPE_ID = neovim_rpc_server_api_info.API_INFO['types']['Window']['id'] 10 | 11 | 12 | def decode_if_bytes(obj): 13 | if isinstance(obj, bytes): 14 | return obj.decode("utf-8") 15 | return obj 16 | 17 | 18 | def walk(fn, obj): 19 | if type(obj) in [list, tuple, vim.List]: 20 | return list(walk(fn, o) for o in obj) 21 | if type(obj) in [dict, vim.Dictionary]: 22 | return dict((walk(fn, k), walk(fn, v)) for k, v in 23 | obj.items()) 24 | return fn(obj) 25 | 26 | 27 | if vim.eval("has('patch-8.0.1280')"): 28 | def from_client(msg): 29 | def handler(obj): 30 | if type(obj) is msgpack.ExtType: 31 | if obj.code == BUFFER_TYPE_ID: 32 | return vim.buffers[msgpack.unpackb(obj.data)] 33 | if obj.code == WINDOW_TYPE_ID: 34 | return vim.windows[msgpack.unpackb(obj.data) - 1] 35 | if sys.version_info.major != 2: 36 | # python3 needs decode 37 | obj = decode_if_bytes(obj) 38 | return obj 39 | return walk(handler, msg) 40 | else: 41 | def from_client(msg): 42 | def handler(obj): 43 | if type(obj) is msgpack.ExtType: 44 | if obj.code == BUFFER_TYPE_ID: 45 | return vim.buffers[msgpack.unpackb(obj.data)] 46 | if obj.code == WINDOW_TYPE_ID: 47 | return vim.windows[msgpack.unpackb(obj.data) - 1] 48 | elif obj is None: 49 | return '' 50 | if sys.version_info.major != 2: 51 | # python3 needs decode 52 | obj = decode_if_bytes(obj) 53 | return obj 54 | return walk(handler, msg) 55 | 56 | 57 | def to_client(msg): 58 | def handler(obj): 59 | if type(obj) == BUFFER_TYPE: 60 | return msgpack.ExtType(BUFFER_TYPE_ID, msgpack.packb(obj.number)) 61 | if type(obj) == WINDOW_TYPE: 62 | return msgpack.ExtType(WINDOW_TYPE_ID, msgpack.packb(obj.number)) 63 | if type(obj) == vim.Function: 64 | try: 65 | return obj.name.encode() 66 | except Exception: 67 | return "" 68 | return obj 69 | return walk(handler, msg) 70 | -------------------------------------------------------------------------------- /pythonx/neovim_rpc_server.py: -------------------------------------------------------------------------------- 1 | # vim:set et sw=4 ts=8: 2 | 3 | import json 4 | import socket 5 | import sys 6 | import os 7 | import threading 8 | import vim 9 | import logging 10 | import msgpack 11 | import neovim_rpc_server_api_info 12 | import neovim_rpc_methods 13 | import neovim_rpc_protocol 14 | 15 | vim_error = vim.Function('neovim_rpc#_error') 16 | vim_py = vim.eval('g:neovim_rpc#py') 17 | 18 | 19 | if sys.version_info.major == 2: 20 | from Queue import Queue, Empty as QueueEmpty 21 | else: 22 | from queue import Queue, Empty as QueueEmpty 23 | 24 | # NVIM_PYTHON_LOG_FILE=nvim.log NVIM_PYTHON_LOG_LEVEL=INFO vim test.md 25 | 26 | try: 27 | # Python 3 28 | import socketserver 29 | except ImportError: 30 | # Python 2 31 | import SocketServer as socketserver 32 | 33 | # globals 34 | logger = logging.getLogger(__name__) 35 | # supress the annoying error message: 36 | # No handlers could be found for logger "neovim_rpc_server" 37 | logger.addHandler(logging.NullHandler()) 38 | 39 | request_queue = Queue() 40 | responses = {} 41 | 42 | 43 | def _channel_id_new(): 44 | with _channel_id_new._lock: 45 | _channel_id_new._counter += 1 46 | return _channel_id_new._counter 47 | 48 | 49 | # static local 50 | _channel_id_new._counter = 0 51 | _channel_id_new._lock = threading.Lock() 52 | 53 | 54 | class VimHandler(socketserver.BaseRequestHandler): 55 | 56 | _lock = threading.Lock() 57 | _sock = None 58 | 59 | @classmethod 60 | def notify(cls, cmd=None): 61 | try: 62 | if cmd is None: 63 | cmd = vim_py + " neovim_rpc_server.process_pending_requests()" 64 | if not VimHandler._sock: 65 | return 66 | with VimHandler._lock: 67 | encoded = json.dumps(['ex', cmd]) 68 | logger.info("sending notification: %s", encoded) 69 | VimHandler._sock.send(encoded.encode('utf-8')) 70 | except Exception as ex: 71 | logger.exception( 72 | 'VimHandler notify exception for [%s]: %s', cmd, ex) 73 | 74 | @classmethod 75 | def notify_exited(cls, channel): 76 | try: 77 | cls.notify("call neovim_rpc#_on_exit(%s)" % channel) 78 | except Exception as ex: 79 | logger.exception( 80 | 'notify_exited for channel [%s] exception: %s', channel, ex) 81 | 82 | # each connection is a thread 83 | def handle(self): 84 | logger.info("=== socket opened ===") 85 | data = None 86 | while True: 87 | try: 88 | rcv = self.request.recv(4096) 89 | # 16k buffer by default 90 | if data: 91 | data += rcv 92 | else: 93 | data = rcv 94 | except socket.error: 95 | logger.info("=== socket error ===") 96 | break 97 | except IOError: 98 | logger.info("=== socket closed ===") 99 | break 100 | if len(rcv) == 0: 101 | logger.info("=== socket closed ===") 102 | break 103 | logger.info("received: %s", data) 104 | try: 105 | decoded = json.loads(data.decode('utf-8')) 106 | except ValueError: 107 | logger.exception("json decoding failed, wait for more data") 108 | continue 109 | data = None 110 | 111 | # Send a response if the sequence number is positive. 112 | # Negative numbers are used for "eval" responses. 113 | if (len(decoded) >= 2 and decoded[0] >= 0 and 114 | decoded[1] == 'neovim_rpc_setup'): 115 | 116 | VimHandler._sock = self.request 117 | 118 | # initial setup 119 | encoded = json.dumps(['ex', "call neovim_rpc#_callback()"]) 120 | logger.info("sending {0}".format(encoded)) 121 | self.request.send(encoded.encode('utf-8')) 122 | 123 | else: 124 | # recognize as rpcrequest 125 | reqid = decoded[0] 126 | channel = decoded[1][1] 127 | event = decoded[1][2] 128 | args = decoded[1][3] 129 | rspid = decoded[1][4] 130 | NvimHandler.request(self.request, 131 | channel, 132 | reqid, 133 | event, 134 | args, 135 | rspid) 136 | 137 | 138 | class SocketToStream(): 139 | 140 | def __init__(self, sock): 141 | self._sock = sock 142 | 143 | def read(self, cnt): 144 | if cnt > 4096: 145 | cnt = 4096 146 | return self._sock.recv(cnt) 147 | 148 | def write(self, w): 149 | return self._sock.send(w) 150 | 151 | 152 | class NvimHandler(socketserver.BaseRequestHandler): 153 | 154 | channel_sockets = {} 155 | 156 | def handle(self): 157 | 158 | logger.info("=== socket opened for client ===") 159 | 160 | channel = _channel_id_new() 161 | 162 | sock = self.request 163 | chinfo = dict(sock=sock) 164 | NvimHandler.channel_sockets[channel] = chinfo 165 | 166 | try: 167 | f = SocketToStream(sock) 168 | unpacker = msgpack.Unpacker(f) 169 | for unpacked in unpacker: 170 | logger.info("unpacked: %s", unpacked) 171 | 172 | # response format: 173 | # - msg[0]: 1 174 | # - msg[1]: the request id 175 | # - msg[2]: error(if any), format: [code,str] 176 | # - msg[3]: result(if not errored) 177 | if int(unpacked[0]) == 1: 178 | unpacked = neovim_rpc_protocol.from_client(unpacked) 179 | reqid = int(unpacked[1]) 180 | rspid, vimsock = chinfo[reqid] 181 | err = unpacked[2] 182 | result = unpacked[3] 183 | # VIM fails to parse response when there a sleep in neovim 184 | # client. I cannot figure out why. Use global responses to 185 | # workaround this issue. 186 | responses[rspid] = [err, result] 187 | content = [reqid, ''] 188 | tosend = json.dumps(content) 189 | # vimsock.send 190 | vimsock.send(tosend.encode('utf-8')) 191 | chinfo.pop(reqid) 192 | continue 193 | 194 | request_queue.put((f, channel, unpacked)) 195 | # notify vim in order to process request in main thread, and 196 | # avoiding the stupid json protocol 197 | VimHandler.notify() 198 | 199 | logger.info('channel %s closed.', channel) 200 | 201 | except Exception: 202 | logger.exception('unpacker failed.') 203 | finally: 204 | try: 205 | NvimHandler.channel_sockets.pop(channel) 206 | sock.close() 207 | except Exception: 208 | pass 209 | 210 | @classmethod 211 | def notify(cls, channel, event, args): 212 | try: 213 | channel = int(channel) 214 | if channel not in cls.channel_sockets: 215 | logger.info("channel[%s] not in NvimHandler", channel) 216 | return 217 | sock = cls.channel_sockets[channel]['sock'] 218 | 219 | # notification format: 220 | # - msg[0] type, which is 2 221 | # - msg[1] method 222 | # - msg[2] arguments 223 | content = [2, event, args] 224 | 225 | logger.info("notify channel[%s]: %s", channel, content) 226 | packed = msgpack.packb(neovim_rpc_protocol.to_client(content)) 227 | sock.send(packed) 228 | except Exception as ex: 229 | logger.exception("notify failed: %s", ex) 230 | 231 | @classmethod 232 | def request(cls, vimsock, channel, reqid, event, args, rspid): 233 | try: 234 | reqid = int(reqid) 235 | channel = int(channel) 236 | chinfo = cls.channel_sockets[channel] 237 | 238 | if channel not in cls.channel_sockets: 239 | logger.info("channel[%s] not in NvimHandler", channel) 240 | return 241 | 242 | sock = chinfo['sock'] 243 | # request format: 244 | # - msg[0] type, which is 0 245 | # - msg[1] request id 246 | # - msg[2] method 247 | # - msg[3] arguments 248 | content = [0, reqid, event, args] 249 | 250 | chinfo[reqid] = [rspid, vimsock] 251 | 252 | logger.info("request channel[%s]: %s", channel, content) 253 | packed = msgpack.packb(neovim_rpc_protocol.to_client(content)) 254 | sock.send(packed) 255 | except Exception as ex: 256 | logger.exception("request failed: %s", ex) 257 | 258 | @classmethod 259 | def shutdown(cls): 260 | # close all sockets 261 | for channel in list(cls.channel_sockets.keys()): 262 | chinfo = cls.channel_sockets.get(channel, None) 263 | if chinfo: 264 | sock = chinfo['sock'] 265 | logger.info("closing client %s", channel) 266 | # if don't shutdown the socket, vim will never exit because the 267 | # recv thread is still blocking 268 | sock.shutdown(socket.SHUT_RDWR) 269 | sock.close() 270 | 271 | 272 | # copied from neovim python-client/neovim/__init__.py 273 | def _setup_logging(name): 274 | """Setup logging according to environment variables.""" 275 | logger = logging.getLogger(__name__) 276 | if 'NVIM_PYTHON_LOG_FILE' in os.environ: 277 | prefix = os.environ['NVIM_PYTHON_LOG_FILE'].strip() 278 | major_version = sys.version_info[0] 279 | logfile = '{}_py{}_{}'.format(prefix, major_version, name) 280 | handler = logging.FileHandler(logfile, 'w', encoding='utf-8') 281 | handler.formatter = logging.Formatter( 282 | '%(asctime)s [%(levelname)s @ ' 283 | '%(filename)s:%(funcName)s:%(lineno)s] %(process)s - %(message)s') 284 | logging.root.addHandler(handler) 285 | level = logging.INFO 286 | if 'NVIM_PYTHON_LOG_LEVEL' in os.environ: 287 | lv = getattr(logging, 288 | os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(), 289 | level) 290 | if isinstance(lv, int): 291 | level = lv 292 | logger.setLevel(level) 293 | 294 | 295 | class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): 296 | pass 297 | 298 | 299 | if sys.platform in ['linux', 'darwin']: 300 | class ThreadedUnixServer(socketserver.ThreadingMixIn, 301 | socketserver.UnixStreamServer): 302 | pass 303 | has_unix = True 304 | else: 305 | has_unix = False 306 | 307 | 308 | def start(): 309 | 310 | _setup_logging('neovim_rpc_server') 311 | 312 | # 0 for random port 313 | global _vim_server 314 | global _nvim_server 315 | 316 | _vim_server = ThreadedTCPServer(("127.0.0.1", 0), VimHandler) 317 | _vim_server.daemon_threads = True 318 | vim_server_addr = "{addr[0]}:{addr[1]}".format( 319 | addr=_vim_server.server_address) 320 | 321 | if 'NVIM_LISTEN_ADDRESS' in os.environ: 322 | nvim_server_addr = os.environ['NVIM_LISTEN_ADDRESS'] 323 | if nvim_server_addr.find(':') >= 0: 324 | host, port = nvim_server_addr.split(':') 325 | port = int(port) 326 | _nvim_server = ThreadedTCPServer((host, port), NvimHandler) 327 | elif has_unix: 328 | if os.path.exists(nvim_server_addr): 329 | try: 330 | os.unlink(nvim_server_addr) 331 | except Exception: 332 | pass 333 | _nvim_server = ThreadedUnixServer(nvim_server_addr, NvimHandler) 334 | else: 335 | # FIXME named pipe server ? 336 | _nvim_server = ThreadedTCPServer(("127.0.0.1", 0), NvimHandler) 337 | nvim_server_addr = "{addr[0]}:{addr[1]}".format( 338 | addr=_nvim_server.server_address) 339 | elif not has_unix: 340 | _nvim_server = ThreadedTCPServer(("127.0.0.1", 0), NvimHandler) 341 | nvim_server_addr = "{addr[0]}:{addr[1]}".format( 342 | addr=_nvim_server.server_address) 343 | else: 344 | nvim_server_addr = vim.eval('tempname()') 345 | _nvim_server = ThreadedUnixServer(nvim_server_addr, NvimHandler) 346 | _nvim_server.daemon_threads = True 347 | 348 | # Start a thread with the server -- that thread will then start one 349 | # more thread for each request 350 | main_server_thread = threading.Thread(target=_vim_server.serve_forever) 351 | clients_server_thread = threading.Thread(target=_nvim_server.serve_forever) 352 | 353 | # Exit the server thread when the main thread terminates 354 | main_server_thread.daemon = True 355 | main_server_thread.start() 356 | clients_server_thread.daemon = True 357 | clients_server_thread.start() 358 | 359 | return [nvim_server_addr, vim_server_addr] 360 | 361 | 362 | def process_pending_requests(): 363 | 364 | logger.info("process_pending_requests") 365 | while True: 366 | 367 | item = None 368 | try: 369 | 370 | item = request_queue.get(False) 371 | 372 | f, channel, msg = item 373 | 374 | msg = neovim_rpc_protocol.from_client(msg) 375 | 376 | logger.info("get msg from channel [%s]: %s", channel, msg) 377 | 378 | # request format: 379 | # - msg[0] type, which is 0 380 | # - msg[1] request id 381 | # - msg[2] method 382 | # - msg[3] arguments 383 | 384 | # notification format: 385 | # - msg[0] type, which is 2 386 | # - msg[1] method 387 | # - msg[2] arguments 388 | 389 | if msg[0] == 0: 390 | # request 391 | 392 | req_typed, req_id, method, args = msg 393 | 394 | try: 395 | err = None 396 | result = _process_request(channel, method, args) 397 | except Exception as ex: 398 | logger.exception("process failed: %s", ex) 399 | # error uccor 400 | err = [1, str(ex)] 401 | result = None 402 | 403 | result = [1, req_id, err, result] 404 | logger.info("sending result: %s", result) 405 | packed = msgpack.packb(neovim_rpc_protocol.to_client(result)) 406 | f.write(packed) 407 | logger.info("sent") 408 | if msg[0] == 2: 409 | # notification 410 | req_typed, method, args = msg 411 | try: 412 | result = _process_request(channel, method, args) 413 | logger.info('notification process result: [%s]', result) 414 | except Exception as ex: 415 | logger.exception("process failed: %s", ex) 416 | 417 | except QueueEmpty: 418 | pass 419 | except Exception as ex: 420 | logger.exception("exception during process: %s", ex) 421 | finally: 422 | if item: 423 | request_queue.task_done() 424 | else: 425 | # item==None means the queue is empty 426 | break 427 | 428 | 429 | def _process_request(channel, method, args): 430 | if hasattr(neovim_rpc_methods, method): 431 | return getattr(neovim_rpc_methods, method)(*args) 432 | elif method in ['vim_get_api_info', 'nvim_get_api_info']: 433 | # the first request sent by neovim python client 434 | return [channel, neovim_rpc_server_api_info.API_INFO] 435 | else: 436 | logger.error("method %s not implemented", method) 437 | vim_error( 438 | "rpc method [%s] not implemented in " 439 | "pythonx/neovim_rpc_methods.py. " 440 | "Please send PR or contact the mantainer." % method) 441 | raise Exception('%s not implemented' % method) 442 | 443 | 444 | def rpcnotify(channel, method, args): 445 | NvimHandler.notify(channel, method, args) 446 | 447 | 448 | def stop(): 449 | 450 | logger.info("stop begin") 451 | 452 | # close tcp channel server 453 | _nvim_server.shutdown() 454 | _nvim_server.server_close() 455 | 456 | # close the main channel 457 | try: 458 | vim.command('call ch_close(g:_neovim_rpc_main_channel)') 459 | except Exception as ex: 460 | logger.info("ch_close failed: %s", ex) 461 | 462 | # remove all sockets 463 | NvimHandler.shutdown() 464 | 465 | try: 466 | # stop the main channel 467 | _vim_server.shutdown() 468 | except Exception as ex: 469 | logger.info("_vim_server shutodwn failed: %s", ex) 470 | 471 | try: 472 | _vim_server.server_close() 473 | except Exception as ex: 474 | logger.info("_vim_server close failed: %s", ex) 475 | -------------------------------------------------------------------------------- /pythonx/neovim_rpc_server_api_info.py: -------------------------------------------------------------------------------- 1 | # result of neovim `api_info()` 2 | API_INFO = { 3 | "version": { 4 | "major": 0, 5 | "api_level": 1, 6 | "api_prerelease": False, 7 | "patch": 7, 8 | "api_compatible": 0, 9 | "minor": 1 10 | }, 11 | "types": { 12 | "Window": { 13 | "id": 1, 14 | "prefix": "nvim_win_" 15 | }, 16 | "Tabpage": { 17 | "id": 2, 18 | "prefix": "nvim_tabpage_" 19 | }, 20 | "Buffer": { 21 | "id": 0, 22 | "prefix": "nvim_buf_" 23 | } 24 | }, 25 | "functions": [ 26 | { 27 | "method": True, 28 | "name": "nvim_buf_line_count", 29 | "return_type": "Integer", 30 | "parameters": [ 31 | [ 32 | "Buffer", 33 | "buffer" 34 | ] 35 | ], 36 | "since": 1 37 | }, 38 | { 39 | "method": False, 40 | "deprecated_since": 1, 41 | "name": "buffer_get_line", 42 | "return_type": "String", 43 | "parameters": [ 44 | [ 45 | "Buffer", 46 | "buffer" 47 | ], 48 | [ 49 | "Integer", 50 | "index" 51 | ] 52 | ], 53 | "since": 0 54 | }, 55 | { 56 | "method": False, 57 | "deprecated_since": 1, 58 | "name": "buffer_set_line", 59 | "return_type": "void", 60 | "parameters": [ 61 | [ 62 | "Buffer", 63 | "buffer" 64 | ], 65 | [ 66 | "Integer", 67 | "index" 68 | ], 69 | [ 70 | "String", 71 | "line" 72 | ] 73 | ], 74 | "since": 0 75 | }, 76 | { 77 | "method": False, 78 | "deprecated_since": 1, 79 | "name": "buffer_del_line", 80 | "return_type": "void", 81 | "parameters": [ 82 | [ 83 | "Buffer", 84 | "buffer" 85 | ], 86 | [ 87 | "Integer", 88 | "index" 89 | ] 90 | ], 91 | "since": 0 92 | }, 93 | { 94 | "method": False, 95 | "deprecated_since": 1, 96 | "name": "buffer_get_line_slice", 97 | "return_type": "ArrayOf(String)", 98 | "parameters": [ 99 | [ 100 | "Buffer", 101 | "buffer" 102 | ], 103 | [ 104 | "Integer", 105 | "start" 106 | ], 107 | [ 108 | "Integer", 109 | "end" 110 | ], 111 | [ 112 | "Boolean", 113 | "include_start" 114 | ], 115 | [ 116 | "Boolean", 117 | "include_end" 118 | ] 119 | ], 120 | "since": 0 121 | }, 122 | { 123 | "method": True, 124 | "name": "nvim_buf_get_lines", 125 | "return_type": "ArrayOf(String)", 126 | "parameters": [ 127 | [ 128 | "Buffer", 129 | "buffer" 130 | ], 131 | [ 132 | "Integer", 133 | "start" 134 | ], 135 | [ 136 | "Integer", 137 | "end" 138 | ], 139 | [ 140 | "Boolean", 141 | "strict_indexing" 142 | ] 143 | ], 144 | "since": 1 145 | }, 146 | { 147 | "method": False, 148 | "deprecated_since": 1, 149 | "name": "buffer_set_line_slice", 150 | "return_type": "void", 151 | "parameters": [ 152 | [ 153 | "Buffer", 154 | "buffer" 155 | ], 156 | [ 157 | "Integer", 158 | "start" 159 | ], 160 | [ 161 | "Integer", 162 | "end" 163 | ], 164 | [ 165 | "Boolean", 166 | "include_start" 167 | ], 168 | [ 169 | "Boolean", 170 | "include_end" 171 | ], 172 | [ 173 | "ArrayOf(String)", 174 | "replacement" 175 | ] 176 | ], 177 | "since": 0 178 | }, 179 | { 180 | "method": True, 181 | "name": "nvim_buf_set_lines", 182 | "return_type": "void", 183 | "parameters": [ 184 | [ 185 | "Buffer", 186 | "buffer" 187 | ], 188 | [ 189 | "Integer", 190 | "start" 191 | ], 192 | [ 193 | "Integer", 194 | "end" 195 | ], 196 | [ 197 | "Boolean", 198 | "strict_indexing" 199 | ], 200 | [ 201 | "ArrayOf(String)", 202 | "replacement" 203 | ] 204 | ], 205 | "since": 1 206 | }, 207 | { 208 | "method": True, 209 | "name": "nvim_buf_get_var", 210 | "return_type": "Object", 211 | "parameters": [ 212 | [ 213 | "Buffer", 214 | "buffer" 215 | ], 216 | [ 217 | "String", 218 | "name" 219 | ] 220 | ], 221 | "since": 1 222 | }, 223 | { 224 | "method": True, 225 | "name": "nvim_buf_get_mark", 226 | "return_type": "ArrayOf(Integer, 2)", 227 | "parameters": [ 228 | [ 229 | "Buffer", 230 | "buffer" 231 | ], 232 | [ 233 | "String", 234 | "name" 235 | ] 236 | ], 237 | "since": 1 238 | }, 239 | { 240 | "method": True, 241 | "name": "nvim_buf_set_var", 242 | "return_type": "void", 243 | "parameters": [ 244 | [ 245 | "Buffer", 246 | "buffer" 247 | ], 248 | [ 249 | "String", 250 | "name" 251 | ], 252 | [ 253 | "Object", 254 | "value" 255 | ] 256 | ], 257 | "since": 1 258 | }, 259 | { 260 | "method": True, 261 | "name": "nvim_buf_del_var", 262 | "return_type": "void", 263 | "parameters": [ 264 | [ 265 | "Buffer", 266 | "buffer" 267 | ], 268 | [ 269 | "String", 270 | "name" 271 | ] 272 | ], 273 | "since": 1 274 | }, 275 | { 276 | "method": False, 277 | "deprecated_since": 1, 278 | "name": "buffer_set_var", 279 | "return_type": "Object", 280 | "parameters": [ 281 | [ 282 | "Buffer", 283 | "buffer" 284 | ], 285 | [ 286 | "String", 287 | "name" 288 | ], 289 | [ 290 | "Object", 291 | "value" 292 | ] 293 | ], 294 | "since": 0 295 | }, 296 | { 297 | "method": False, 298 | "deprecated_since": 1, 299 | "name": "buffer_del_var", 300 | "return_type": "Object", 301 | "parameters": [ 302 | [ 303 | "Buffer", 304 | "buffer" 305 | ], 306 | [ 307 | "String", 308 | "name" 309 | ] 310 | ], 311 | "since": 0 312 | }, 313 | { 314 | "method": True, 315 | "name": "nvim_buf_get_option", 316 | "return_type": "Object", 317 | "parameters": [ 318 | [ 319 | "Buffer", 320 | "buffer" 321 | ], 322 | [ 323 | "String", 324 | "name" 325 | ] 326 | ], 327 | "since": 1 328 | }, 329 | { 330 | "method": True, 331 | "name": "nvim_buf_set_option", 332 | "return_type": "void", 333 | "parameters": [ 334 | [ 335 | "Buffer", 336 | "buffer" 337 | ], 338 | [ 339 | "String", 340 | "name" 341 | ], 342 | [ 343 | "Object", 344 | "value" 345 | ] 346 | ], 347 | "since": 1 348 | }, 349 | { 350 | "method": True, 351 | "name": "nvim_buf_get_number", 352 | "return_type": "Integer", 353 | "parameters": [ 354 | [ 355 | "Buffer", 356 | "buffer" 357 | ] 358 | ], 359 | "since": 1 360 | }, 361 | { 362 | "method": True, 363 | "name": "nvim_buf_get_name", 364 | "return_type": "String", 365 | "parameters": [ 366 | [ 367 | "Buffer", 368 | "buffer" 369 | ] 370 | ], 371 | "since": 1 372 | }, 373 | { 374 | "method": True, 375 | "name": "nvim_buf_set_name", 376 | "return_type": "void", 377 | "parameters": [ 378 | [ 379 | "Buffer", 380 | "buffer" 381 | ], 382 | [ 383 | "String", 384 | "name" 385 | ] 386 | ], 387 | "since": 1 388 | }, 389 | { 390 | "method": True, 391 | "name": "nvim_buf_is_valid", 392 | "return_type": "Boolean", 393 | "parameters": [ 394 | [ 395 | "Buffer", 396 | "buffer" 397 | ] 398 | ], 399 | "since": 1 400 | }, 401 | { 402 | "method": False, 403 | "deprecated_since": 1, 404 | "name": "buffer_insert", 405 | "return_type": "void", 406 | "parameters": [ 407 | [ 408 | "Buffer", 409 | "buffer" 410 | ], 411 | [ 412 | "Integer", 413 | "lnum" 414 | ], 415 | [ 416 | "ArrayOf(String)", 417 | "lines" 418 | ] 419 | ], 420 | "since": 0 421 | }, 422 | { 423 | "method": True, 424 | "name": "nvim_buf_get_mark", 425 | "return_type": "ArrayOf(Integer, 2)", 426 | "parameters": [ 427 | [ 428 | "Buffer", 429 | "buffer" 430 | ], 431 | [ 432 | "String", 433 | "name" 434 | ] 435 | ], 436 | "since": 1 437 | }, 438 | { 439 | "method": True, 440 | "name": "nvim_buf_add_highlight", 441 | "return_type": "Integer", 442 | "parameters": [ 443 | [ 444 | "Buffer", 445 | "buffer" 446 | ], 447 | [ 448 | "Integer", 449 | "src_id" 450 | ], 451 | [ 452 | "String", 453 | "hl_group" 454 | ], 455 | [ 456 | "Integer", 457 | "line" 458 | ], 459 | [ 460 | "Integer", 461 | "col_start" 462 | ], 463 | [ 464 | "Integer", 465 | "col_end" 466 | ] 467 | ], 468 | "since": 1 469 | }, 470 | { 471 | "method": True, 472 | "name": "nvim_buf_clear_highlight", 473 | "return_type": "void", 474 | "parameters": [ 475 | [ 476 | "Buffer", 477 | "buffer" 478 | ], 479 | [ 480 | "Integer", 481 | "src_id" 482 | ], 483 | [ 484 | "Integer", 485 | "line_start" 486 | ], 487 | [ 488 | "Integer", 489 | "line_end" 490 | ] 491 | ], 492 | "since": 1 493 | }, 494 | { 495 | "method": True, 496 | "name": "nvim_tabpage_list_wins", 497 | "return_type": "ArrayOf(Window)", 498 | "parameters": [ 499 | [ 500 | "Tabpage", 501 | "tabpage" 502 | ] 503 | ], 504 | "since": 1 505 | }, 506 | { 507 | "method": True, 508 | "name": "nvim_tabpage_get_var", 509 | "return_type": "Object", 510 | "parameters": [ 511 | [ 512 | "Tabpage", 513 | "tabpage" 514 | ], 515 | [ 516 | "String", 517 | "name" 518 | ] 519 | ], 520 | "since": 1 521 | }, 522 | { 523 | "method": True, 524 | "name": "nvim_tabpage_set_var", 525 | "return_type": "void", 526 | "parameters": [ 527 | [ 528 | "Tabpage", 529 | "tabpage" 530 | ], 531 | [ 532 | "String", 533 | "name" 534 | ], 535 | [ 536 | "Object", 537 | "value" 538 | ] 539 | ], 540 | "since": 1 541 | }, 542 | { 543 | "method": True, 544 | "name": "nvim_tabpage_del_var", 545 | "return_type": "void", 546 | "parameters": [ 547 | [ 548 | "Tabpage", 549 | "tabpage" 550 | ], 551 | [ 552 | "String", 553 | "name" 554 | ] 555 | ], 556 | "since": 1 557 | }, 558 | { 559 | "method": False, 560 | "deprecated_since": 1, 561 | "name": "tabpage_set_var", 562 | "return_type": "Object", 563 | "parameters": [ 564 | [ 565 | "Tabpage", 566 | "tabpage" 567 | ], 568 | [ 569 | "String", 570 | "name" 571 | ], 572 | [ 573 | "Object", 574 | "value" 575 | ] 576 | ], 577 | "since": 0 578 | }, 579 | { 580 | "method": False, 581 | "deprecated_since": 1, 582 | "name": "tabpage_del_var", 583 | "return_type": "Object", 584 | "parameters": [ 585 | [ 586 | "Tabpage", 587 | "tabpage" 588 | ], 589 | [ 590 | "String", 591 | "name" 592 | ] 593 | ], 594 | "since": 0 595 | }, 596 | { 597 | "method": True, 598 | "name": "nvim_tabpage_get_win", 599 | "return_type": "Window", 600 | "parameters": [ 601 | [ 602 | "Tabpage", 603 | "tabpage" 604 | ] 605 | ], 606 | "since": 1 607 | }, 608 | { 609 | "method": True, 610 | "name": "nvim_tabpage_get_number", 611 | "return_type": "Integer", 612 | "parameters": [ 613 | [ 614 | "Tabpage", 615 | "tabpage" 616 | ] 617 | ], 618 | "since": 1 619 | }, 620 | { 621 | "method": True, 622 | "name": "nvim_tabpage_is_valid", 623 | "return_type": "Boolean", 624 | "parameters": [ 625 | [ 626 | "Tabpage", 627 | "tabpage" 628 | ] 629 | ], 630 | "since": 1 631 | }, 632 | { 633 | "method": False, 634 | "name": "nvim_ui_attach", 635 | "return_type": "void", 636 | "parameters": [ 637 | [ 638 | "Integer", 639 | "width" 640 | ], 641 | [ 642 | "Integer", 643 | "height" 644 | ], 645 | [ 646 | "Dictionary", 647 | "options" 648 | ] 649 | ], 650 | "since": 1 651 | }, 652 | { 653 | "method": False, 654 | "deprecated_since": 1, 655 | "name": "ui_attach", 656 | "return_type": "void", 657 | "parameters": [ 658 | [ 659 | "Integer", 660 | "width" 661 | ], 662 | [ 663 | "Integer", 664 | "height" 665 | ], 666 | [ 667 | "Boolean", 668 | "enable_rgb" 669 | ] 670 | ], 671 | "since": 0 672 | }, 673 | { 674 | "method": False, 675 | "name": "nvim_ui_detach", 676 | "return_type": "void", 677 | "parameters": [], 678 | "since": 1 679 | }, 680 | { 681 | "method": False, 682 | "name": "nvim_ui_try_resize", 683 | "return_type": "void", 684 | "parameters": [ 685 | [ 686 | "Integer", 687 | "width" 688 | ], 689 | [ 690 | "Integer", 691 | "height" 692 | ] 693 | ], 694 | "since": 1 695 | }, 696 | { 697 | "method": False, 698 | "name": "nvim_ui_set_option", 699 | "return_type": "void", 700 | "parameters": [ 701 | [ 702 | "String", 703 | "name" 704 | ], 705 | [ 706 | "Object", 707 | "value" 708 | ] 709 | ], 710 | "since": 1 711 | }, 712 | { 713 | "method": False, 714 | "name": "nvim_command", 715 | "return_type": "void", 716 | "parameters": [ 717 | [ 718 | "String", 719 | "command" 720 | ] 721 | ], 722 | "since": 1 723 | }, 724 | { 725 | "method": False, 726 | "name": "nvim_feedkeys", 727 | "return_type": "void", 728 | "parameters": [ 729 | [ 730 | "String", 731 | "keys" 732 | ], 733 | [ 734 | "String", 735 | "mode" 736 | ], 737 | [ 738 | "Boolean", 739 | "escape_csi" 740 | ] 741 | ], 742 | "since": 1 743 | }, 744 | { 745 | "method": False, 746 | "name": "nvim_input", 747 | "return_type": "Integer", 748 | "parameters": [ 749 | [ 750 | "String", 751 | "keys" 752 | ] 753 | ], 754 | "since": 1 755 | }, 756 | { 757 | "method": False, 758 | "name": "nvim_replace_termcodes", 759 | "return_type": "String", 760 | "parameters": [ 761 | [ 762 | "String", 763 | "str" 764 | ], 765 | [ 766 | "Boolean", 767 | "from_part" 768 | ], 769 | [ 770 | "Boolean", 771 | "do_lt" 772 | ], 773 | [ 774 | "Boolean", 775 | "special" 776 | ] 777 | ], 778 | "since": 1 779 | }, 780 | { 781 | "method": False, 782 | "name": "nvim_command_output", 783 | "return_type": "String", 784 | "parameters": [ 785 | [ 786 | "String", 787 | "str" 788 | ] 789 | ], 790 | "since": 1 791 | }, 792 | { 793 | "method": False, 794 | "name": "nvim_eval", 795 | "return_type": "Object", 796 | "parameters": [ 797 | [ 798 | "String", 799 | "expr" 800 | ] 801 | ], 802 | "since": 1 803 | }, 804 | { 805 | "method": False, 806 | "name": "nvim_call_function", 807 | "return_type": "Object", 808 | "parameters": [ 809 | [ 810 | "String", 811 | "fname" 812 | ], 813 | [ 814 | "Array", 815 | "args" 816 | ] 817 | ], 818 | "since": 1 819 | }, 820 | { 821 | "method": False, 822 | "name": "nvim_strwidth", 823 | "return_type": "Integer", 824 | "parameters": [ 825 | [ 826 | "String", 827 | "str" 828 | ] 829 | ], 830 | "since": 1 831 | }, 832 | { 833 | "method": False, 834 | "name": "nvim_list_runtime_paths", 835 | "return_type": "ArrayOf(String)", 836 | "parameters": [], 837 | "since": 1 838 | }, 839 | { 840 | "method": False, 841 | "name": "nvim_set_current_dir", 842 | "return_type": "void", 843 | "parameters": [ 844 | [ 845 | "String", 846 | "dir" 847 | ] 848 | ], 849 | "since": 1 850 | }, 851 | { 852 | "method": False, 853 | "name": "nvim_get_current_line", 854 | "return_type": "String", 855 | "parameters": [], 856 | "since": 1 857 | }, 858 | { 859 | "method": False, 860 | "name": "nvim_set_current_line", 861 | "return_type": "void", 862 | "parameters": [ 863 | [ 864 | "String", 865 | "line" 866 | ] 867 | ], 868 | "since": 1 869 | }, 870 | { 871 | "method": False, 872 | "name": "nvim_del_current_line", 873 | "return_type": "void", 874 | "parameters": [], 875 | "since": 1 876 | }, 877 | { 878 | "method": False, 879 | "name": "nvim_get_var", 880 | "return_type": "Object", 881 | "parameters": [ 882 | [ 883 | "String", 884 | "name" 885 | ] 886 | ], 887 | "since": 1 888 | }, 889 | { 890 | "method": False, 891 | "name": "nvim_set_var", 892 | "return_type": "void", 893 | "parameters": [ 894 | [ 895 | "String", 896 | "name" 897 | ], 898 | [ 899 | "Object", 900 | "value" 901 | ] 902 | ], 903 | "since": 1 904 | }, 905 | { 906 | "method": False, 907 | "name": "nvim_del_var", 908 | "return_type": "void", 909 | "parameters": [ 910 | [ 911 | "String", 912 | "name" 913 | ] 914 | ], 915 | "since": 1 916 | }, 917 | { 918 | "method": False, 919 | "deprecated_since": 1, 920 | "name": "vim_set_var", 921 | "return_type": "Object", 922 | "parameters": [ 923 | [ 924 | "String", 925 | "name" 926 | ], 927 | [ 928 | "Object", 929 | "value" 930 | ] 931 | ], 932 | "since": 0 933 | }, 934 | { 935 | "method": False, 936 | "deprecated_since": 1, 937 | "name": "vim_del_var", 938 | "return_type": "Object", 939 | "parameters": [ 940 | [ 941 | "String", 942 | "name" 943 | ] 944 | ], 945 | "since": 0 946 | }, 947 | { 948 | "method": False, 949 | "name": "nvim_get_vvar", 950 | "return_type": "Object", 951 | "parameters": [ 952 | [ 953 | "String", 954 | "name" 955 | ] 956 | ], 957 | "since": 1 958 | }, 959 | { 960 | "method": False, 961 | "name": "nvim_get_option", 962 | "return_type": "Object", 963 | "parameters": [ 964 | [ 965 | "String", 966 | "name" 967 | ] 968 | ], 969 | "since": 1 970 | }, 971 | { 972 | "method": False, 973 | "name": "nvim_set_option", 974 | "return_type": "void", 975 | "parameters": [ 976 | [ 977 | "String", 978 | "name" 979 | ], 980 | [ 981 | "Object", 982 | "value" 983 | ] 984 | ], 985 | "since": 1 986 | }, 987 | { 988 | "method": False, 989 | "name": "nvim_out_write", 990 | "return_type": "void", 991 | "parameters": [ 992 | [ 993 | "String", 994 | "str" 995 | ] 996 | ], 997 | "since": 1 998 | }, 999 | { 1000 | "method": False, 1001 | "name": "nvim_err_write", 1002 | "return_type": "void", 1003 | "parameters": [ 1004 | [ 1005 | "String", 1006 | "str" 1007 | ] 1008 | ], 1009 | "since": 1 1010 | }, 1011 | { 1012 | "method": False, 1013 | "name": "nvim_err_writeln", 1014 | "return_type": "void", 1015 | "parameters": [ 1016 | [ 1017 | "String", 1018 | "str" 1019 | ] 1020 | ], 1021 | "since": 1 1022 | }, 1023 | { 1024 | "method": False, 1025 | "name": "nvim_list_bufs", 1026 | "return_type": "ArrayOf(Buffer)", 1027 | "parameters": [], 1028 | "since": 1 1029 | }, 1030 | { 1031 | "method": False, 1032 | "name": "nvim_get_current_buf", 1033 | "return_type": "Buffer", 1034 | "parameters": [], 1035 | "since": 1 1036 | }, 1037 | { 1038 | "method": False, 1039 | "name": "nvim_set_current_buf", 1040 | "return_type": "void", 1041 | "parameters": [ 1042 | [ 1043 | "Buffer", 1044 | "buffer" 1045 | ] 1046 | ], 1047 | "since": 1 1048 | }, 1049 | { 1050 | "method": False, 1051 | "name": "nvim_list_wins", 1052 | "return_type": "ArrayOf(Window)", 1053 | "parameters": [], 1054 | "since": 1 1055 | }, 1056 | { 1057 | "method": False, 1058 | "name": "nvim_get_current_win", 1059 | "return_type": "Window", 1060 | "parameters": [], 1061 | "since": 1 1062 | }, 1063 | { 1064 | "method": False, 1065 | "name": "nvim_set_current_win", 1066 | "return_type": "void", 1067 | "parameters": [ 1068 | [ 1069 | "Window", 1070 | "window" 1071 | ] 1072 | ], 1073 | "since": 1 1074 | }, 1075 | { 1076 | "method": False, 1077 | "name": "nvim_list_tabpages", 1078 | "return_type": "ArrayOf(Tabpage)", 1079 | "parameters": [], 1080 | "since": 1 1081 | }, 1082 | { 1083 | "method": False, 1084 | "name": "nvim_get_current_tabpage", 1085 | "return_type": "Tabpage", 1086 | "parameters": [], 1087 | "since": 1 1088 | }, 1089 | { 1090 | "method": False, 1091 | "name": "nvim_set_current_tabpage", 1092 | "return_type": "void", 1093 | "parameters": [ 1094 | [ 1095 | "Tabpage", 1096 | "tabpage" 1097 | ] 1098 | ], 1099 | "since": 1 1100 | }, 1101 | { 1102 | "method": False, 1103 | "name": "nvim_subscribe", 1104 | "return_type": "void", 1105 | "parameters": [ 1106 | [ 1107 | "String", 1108 | "event" 1109 | ] 1110 | ], 1111 | "since": 1 1112 | }, 1113 | { 1114 | "method": False, 1115 | "name": "nvim_unsubscribe", 1116 | "return_type": "void", 1117 | "parameters": [ 1118 | [ 1119 | "String", 1120 | "event" 1121 | ] 1122 | ], 1123 | "since": 1 1124 | }, 1125 | { 1126 | "method": False, 1127 | "name": "nvim_get_color_by_name", 1128 | "return_type": "Integer", 1129 | "parameters": [ 1130 | [ 1131 | "String", 1132 | "name" 1133 | ] 1134 | ], 1135 | "since": 1 1136 | }, 1137 | { 1138 | "method": False, 1139 | "name": "nvim_get_color_map", 1140 | "return_type": "Dictionary", 1141 | "parameters": [], 1142 | "since": 1 1143 | }, 1144 | { 1145 | "method": False, 1146 | "name": "nvim_get_api_info", 1147 | "return_type": "Array", 1148 | "parameters": [], 1149 | "since": 1 1150 | }, 1151 | { 1152 | "method": False, 1153 | "name": "nvim_call_atomic", 1154 | "return_type": "Array", 1155 | "parameters": [ 1156 | [ 1157 | "Array", 1158 | "calls" 1159 | ] 1160 | ], 1161 | "since": 1 1162 | }, 1163 | { 1164 | "method": True, 1165 | "name": "nvim_win_get_buf", 1166 | "return_type": "Buffer", 1167 | "parameters": [ 1168 | [ 1169 | "Window", 1170 | "window" 1171 | ] 1172 | ], 1173 | "since": 1 1174 | }, 1175 | { 1176 | "method": True, 1177 | "name": "nvim_win_get_cursor", 1178 | "return_type": "ArrayOf(Integer, 2)", 1179 | "parameters": [ 1180 | [ 1181 | "Window", 1182 | "window" 1183 | ] 1184 | ], 1185 | "since": 1 1186 | }, 1187 | { 1188 | "method": True, 1189 | "name": "nvim_win_set_cursor", 1190 | "return_type": "void", 1191 | "parameters": [ 1192 | [ 1193 | "Window", 1194 | "window" 1195 | ], 1196 | [ 1197 | "ArrayOf(Integer, 2)", 1198 | "pos" 1199 | ] 1200 | ], 1201 | "since": 1 1202 | }, 1203 | { 1204 | "method": True, 1205 | "name": "nvim_win_get_height", 1206 | "return_type": "Integer", 1207 | "parameters": [ 1208 | [ 1209 | "Window", 1210 | "window" 1211 | ] 1212 | ], 1213 | "since": 1 1214 | }, 1215 | { 1216 | "method": True, 1217 | "name": "nvim_win_set_height", 1218 | "return_type": "void", 1219 | "parameters": [ 1220 | [ 1221 | "Window", 1222 | "window" 1223 | ], 1224 | [ 1225 | "Integer", 1226 | "height" 1227 | ] 1228 | ], 1229 | "since": 1 1230 | }, 1231 | { 1232 | "method": True, 1233 | "name": "nvim_win_get_width", 1234 | "return_type": "Integer", 1235 | "parameters": [ 1236 | [ 1237 | "Window", 1238 | "window" 1239 | ] 1240 | ], 1241 | "since": 1 1242 | }, 1243 | { 1244 | "method": True, 1245 | "name": "nvim_win_set_width", 1246 | "return_type": "void", 1247 | "parameters": [ 1248 | [ 1249 | "Window", 1250 | "window" 1251 | ], 1252 | [ 1253 | "Integer", 1254 | "width" 1255 | ] 1256 | ], 1257 | "since": 1 1258 | }, 1259 | { 1260 | "method": True, 1261 | "name": "nvim_win_get_var", 1262 | "return_type": "Object", 1263 | "parameters": [ 1264 | [ 1265 | "Window", 1266 | "window" 1267 | ], 1268 | [ 1269 | "String", 1270 | "name" 1271 | ] 1272 | ], 1273 | "since": 1 1274 | }, 1275 | { 1276 | "method": True, 1277 | "name": "nvim_win_set_var", 1278 | "return_type": "void", 1279 | "parameters": [ 1280 | [ 1281 | "Window", 1282 | "window" 1283 | ], 1284 | [ 1285 | "String", 1286 | "name" 1287 | ], 1288 | [ 1289 | "Object", 1290 | "value" 1291 | ] 1292 | ], 1293 | "since": 1 1294 | }, 1295 | { 1296 | "method": True, 1297 | "name": "nvim_win_del_var", 1298 | "return_type": "void", 1299 | "parameters": [ 1300 | [ 1301 | "Window", 1302 | "window" 1303 | ], 1304 | [ 1305 | "String", 1306 | "name" 1307 | ] 1308 | ], 1309 | "since": 1 1310 | }, 1311 | { 1312 | "method": False, 1313 | "deprecated_since": 1, 1314 | "name": "window_set_var", 1315 | "return_type": "Object", 1316 | "parameters": [ 1317 | [ 1318 | "Window", 1319 | "window" 1320 | ], 1321 | [ 1322 | "String", 1323 | "name" 1324 | ], 1325 | [ 1326 | "Object", 1327 | "value" 1328 | ] 1329 | ], 1330 | "since": 0 1331 | }, 1332 | { 1333 | "method": False, 1334 | "deprecated_since": 1, 1335 | "name": "window_del_var", 1336 | "return_type": "Object", 1337 | "parameters": [ 1338 | [ 1339 | "Window", 1340 | "window" 1341 | ], 1342 | [ 1343 | "String", 1344 | "name" 1345 | ] 1346 | ], 1347 | "since": 0 1348 | }, 1349 | { 1350 | "method": True, 1351 | "name": "nvim_win_get_option", 1352 | "return_type": "Object", 1353 | "parameters": [ 1354 | [ 1355 | "Window", 1356 | "window" 1357 | ], 1358 | [ 1359 | "String", 1360 | "name" 1361 | ] 1362 | ], 1363 | "since": 1 1364 | }, 1365 | { 1366 | "method": True, 1367 | "name": "nvim_win_set_option", 1368 | "return_type": "void", 1369 | "parameters": [ 1370 | [ 1371 | "Window", 1372 | "window" 1373 | ], 1374 | [ 1375 | "String", 1376 | "name" 1377 | ], 1378 | [ 1379 | "Object", 1380 | "value" 1381 | ] 1382 | ], 1383 | "since": 1 1384 | }, 1385 | { 1386 | "method": True, 1387 | "name": "nvim_win_get_position", 1388 | "return_type": "ArrayOf(Integer, 2)", 1389 | "parameters": [ 1390 | [ 1391 | "Window", 1392 | "window" 1393 | ] 1394 | ], 1395 | "since": 1 1396 | }, 1397 | { 1398 | "method": True, 1399 | "name": "nvim_win_get_tabpage", 1400 | "return_type": "Tabpage", 1401 | "parameters": [ 1402 | [ 1403 | "Window", 1404 | "window" 1405 | ] 1406 | ], 1407 | "since": 1 1408 | }, 1409 | { 1410 | "method": True, 1411 | "name": "nvim_win_get_number", 1412 | "return_type": "Integer", 1413 | "parameters": [ 1414 | [ 1415 | "Window", 1416 | "window" 1417 | ] 1418 | ], 1419 | "since": 1 1420 | }, 1421 | { 1422 | "method": True, 1423 | "name": "nvim_win_is_valid", 1424 | "return_type": "Boolean", 1425 | "parameters": [ 1426 | [ 1427 | "Window", 1428 | "window" 1429 | ] 1430 | ], 1431 | "since": 1 1432 | }, 1433 | { 1434 | "method": True, 1435 | "deprecated_since": 1, 1436 | "name": "buffer_line_count", 1437 | "return_type": "Integer", 1438 | "parameters": [ 1439 | [ 1440 | "Buffer", 1441 | "buffer" 1442 | ] 1443 | ], 1444 | "since": 0 1445 | }, 1446 | { 1447 | "method": True, 1448 | "deprecated_since": 1, 1449 | "name": "buffer_get_lines", 1450 | "return_type": "ArrayOf(String)", 1451 | "parameters": [ 1452 | [ 1453 | "Buffer", 1454 | "buffer" 1455 | ], 1456 | [ 1457 | "Integer", 1458 | "start" 1459 | ], 1460 | [ 1461 | "Integer", 1462 | "end" 1463 | ], 1464 | [ 1465 | "Boolean", 1466 | "strict_indexing" 1467 | ] 1468 | ], 1469 | "since": 0 1470 | }, 1471 | { 1472 | "method": True, 1473 | "deprecated_since": 1, 1474 | "name": "buffer_set_lines", 1475 | "return_type": "void", 1476 | "parameters": [ 1477 | [ 1478 | "Buffer", 1479 | "buffer" 1480 | ], 1481 | [ 1482 | "Integer", 1483 | "start" 1484 | ], 1485 | [ 1486 | "Integer", 1487 | "end" 1488 | ], 1489 | [ 1490 | "Boolean", 1491 | "strict_indexing" 1492 | ], 1493 | [ 1494 | "ArrayOf(String)", 1495 | "replacement" 1496 | ] 1497 | ], 1498 | "since": 0 1499 | }, 1500 | { 1501 | "method": True, 1502 | "deprecated_since": 1, 1503 | "name": "buffer_get_var", 1504 | "return_type": "Object", 1505 | "parameters": [ 1506 | [ 1507 | "Buffer", 1508 | "buffer" 1509 | ], 1510 | [ 1511 | "String", 1512 | "name" 1513 | ] 1514 | ], 1515 | "since": 0 1516 | }, 1517 | { 1518 | "method": True, 1519 | "deprecated_since": 1, 1520 | "name": "buffer_get_option", 1521 | "return_type": "Object", 1522 | "parameters": [ 1523 | [ 1524 | "Buffer", 1525 | "buffer" 1526 | ], 1527 | [ 1528 | "String", 1529 | "name" 1530 | ] 1531 | ], 1532 | "since": 0 1533 | }, 1534 | { 1535 | "method": True, 1536 | "deprecated_since": 1, 1537 | "name": "buffer_set_option", 1538 | "return_type": "void", 1539 | "parameters": [ 1540 | [ 1541 | "Buffer", 1542 | "buffer" 1543 | ], 1544 | [ 1545 | "String", 1546 | "name" 1547 | ], 1548 | [ 1549 | "Object", 1550 | "value" 1551 | ] 1552 | ], 1553 | "since": 0 1554 | }, 1555 | { 1556 | "method": True, 1557 | "deprecated_since": 1, 1558 | "name": "buffer_get_number", 1559 | "return_type": "Integer", 1560 | "parameters": [ 1561 | [ 1562 | "Buffer", 1563 | "buffer" 1564 | ] 1565 | ], 1566 | "since": 0 1567 | }, 1568 | { 1569 | "method": True, 1570 | "deprecated_since": 1, 1571 | "name": "buffer_get_name", 1572 | "return_type": "String", 1573 | "parameters": [ 1574 | [ 1575 | "Buffer", 1576 | "buffer" 1577 | ] 1578 | ], 1579 | "since": 0 1580 | }, 1581 | { 1582 | "method": True, 1583 | "deprecated_since": 1, 1584 | "name": "buffer_set_name", 1585 | "return_type": "void", 1586 | "parameters": [ 1587 | [ 1588 | "Buffer", 1589 | "buffer" 1590 | ], 1591 | [ 1592 | "String", 1593 | "name" 1594 | ] 1595 | ], 1596 | "since": 0 1597 | }, 1598 | { 1599 | "method": True, 1600 | "deprecated_since": 1, 1601 | "name": "buffer_is_valid", 1602 | "return_type": "Boolean", 1603 | "parameters": [ 1604 | [ 1605 | "Buffer", 1606 | "buffer" 1607 | ] 1608 | ], 1609 | "since": 0 1610 | }, 1611 | { 1612 | "method": True, 1613 | "deprecated_since": 1, 1614 | "name": "buffer_get_mark", 1615 | "return_type": "ArrayOf(Integer, 2)", 1616 | "parameters": [ 1617 | [ 1618 | "Buffer", 1619 | "buffer" 1620 | ], 1621 | [ 1622 | "String", 1623 | "name" 1624 | ] 1625 | ], 1626 | "since": 0 1627 | }, 1628 | { 1629 | "method": True, 1630 | "deprecated_since": 1, 1631 | "name": "buffer_add_highlight", 1632 | "return_type": "Integer", 1633 | "parameters": [ 1634 | [ 1635 | "Buffer", 1636 | "buffer" 1637 | ], 1638 | [ 1639 | "Integer", 1640 | "src_id" 1641 | ], 1642 | [ 1643 | "String", 1644 | "hl_group" 1645 | ], 1646 | [ 1647 | "Integer", 1648 | "line" 1649 | ], 1650 | [ 1651 | "Integer", 1652 | "col_start" 1653 | ], 1654 | [ 1655 | "Integer", 1656 | "col_end" 1657 | ] 1658 | ], 1659 | "since": 0 1660 | }, 1661 | { 1662 | "method": True, 1663 | "deprecated_since": 1, 1664 | "name": "buffer_clear_highlight", 1665 | "return_type": "void", 1666 | "parameters": [ 1667 | [ 1668 | "Buffer", 1669 | "buffer" 1670 | ], 1671 | [ 1672 | "Integer", 1673 | "src_id" 1674 | ], 1675 | [ 1676 | "Integer", 1677 | "line_start" 1678 | ], 1679 | [ 1680 | "Integer", 1681 | "line_end" 1682 | ] 1683 | ], 1684 | "since": 0 1685 | }, 1686 | { 1687 | "method": True, 1688 | "deprecated_since": 1, 1689 | "name": "tabpage_get_windows", 1690 | "return_type": "ArrayOf(Window)", 1691 | "parameters": [ 1692 | [ 1693 | "Tabpage", 1694 | "tabpage" 1695 | ] 1696 | ], 1697 | "since": 0 1698 | }, 1699 | { 1700 | "method": True, 1701 | "deprecated_since": 1, 1702 | "name": "tabpage_get_var", 1703 | "return_type": "Object", 1704 | "parameters": [ 1705 | [ 1706 | "Tabpage", 1707 | "tabpage" 1708 | ], 1709 | [ 1710 | "String", 1711 | "name" 1712 | ] 1713 | ], 1714 | "since": 0 1715 | }, 1716 | { 1717 | "method": True, 1718 | "deprecated_since": 1, 1719 | "name": "tabpage_get_window", 1720 | "return_type": "Window", 1721 | "parameters": [ 1722 | [ 1723 | "Tabpage", 1724 | "tabpage" 1725 | ] 1726 | ], 1727 | "since": 0 1728 | }, 1729 | { 1730 | "method": True, 1731 | "deprecated_since": 1, 1732 | "name": "tabpage_is_valid", 1733 | "return_type": "Boolean", 1734 | "parameters": [ 1735 | [ 1736 | "Tabpage", 1737 | "tabpage" 1738 | ] 1739 | ], 1740 | "since": 0 1741 | }, 1742 | { 1743 | "method": False, 1744 | "deprecated_since": 1, 1745 | "name": "ui_detach", 1746 | "return_type": "void", 1747 | "parameters": [], 1748 | "since": 0 1749 | }, 1750 | { 1751 | "method": False, 1752 | "deprecated_since": 1, 1753 | "name": "ui_try_resize", 1754 | "return_type": "Object", 1755 | "parameters": [ 1756 | [ 1757 | "Integer", 1758 | "width" 1759 | ], 1760 | [ 1761 | "Integer", 1762 | "height" 1763 | ] 1764 | ], 1765 | "since": 0 1766 | }, 1767 | { 1768 | "method": False, 1769 | "deprecated_since": 1, 1770 | "name": "vim_command", 1771 | "return_type": "void", 1772 | "parameters": [ 1773 | [ 1774 | "String", 1775 | "command" 1776 | ] 1777 | ], 1778 | "since": 0 1779 | }, 1780 | { 1781 | "method": False, 1782 | "deprecated_since": 1, 1783 | "name": "vim_feedkeys", 1784 | "return_type": "void", 1785 | "parameters": [ 1786 | [ 1787 | "String", 1788 | "keys" 1789 | ], 1790 | [ 1791 | "String", 1792 | "mode" 1793 | ], 1794 | [ 1795 | "Boolean", 1796 | "escape_csi" 1797 | ] 1798 | ], 1799 | "since": 0 1800 | }, 1801 | { 1802 | "method": False, 1803 | "deprecated_since": 1, 1804 | "name": "vim_input", 1805 | "return_type": "Integer", 1806 | "parameters": [ 1807 | [ 1808 | "String", 1809 | "keys" 1810 | ] 1811 | ], 1812 | "since": 0 1813 | }, 1814 | { 1815 | "method": False, 1816 | "deprecated_since": 1, 1817 | "name": "vim_replace_termcodes", 1818 | "return_type": "String", 1819 | "parameters": [ 1820 | [ 1821 | "String", 1822 | "str" 1823 | ], 1824 | [ 1825 | "Boolean", 1826 | "from_part" 1827 | ], 1828 | [ 1829 | "Boolean", 1830 | "do_lt" 1831 | ], 1832 | [ 1833 | "Boolean", 1834 | "special" 1835 | ] 1836 | ], 1837 | "since": 0 1838 | }, 1839 | { 1840 | "method": False, 1841 | "deprecated_since": 1, 1842 | "name": "vim_command_output", 1843 | "return_type": "String", 1844 | "parameters": [ 1845 | [ 1846 | "String", 1847 | "str" 1848 | ] 1849 | ], 1850 | "since": 0 1851 | }, 1852 | { 1853 | "method": False, 1854 | "deprecated_since": 1, 1855 | "name": "vim_eval", 1856 | "return_type": "Object", 1857 | "parameters": [ 1858 | [ 1859 | "String", 1860 | "expr" 1861 | ] 1862 | ], 1863 | "since": 0 1864 | }, 1865 | { 1866 | "method": False, 1867 | "deprecated_since": 1, 1868 | "name": "vim_call_function", 1869 | "return_type": "Object", 1870 | "parameters": [ 1871 | [ 1872 | "String", 1873 | "fname" 1874 | ], 1875 | [ 1876 | "Array", 1877 | "args" 1878 | ] 1879 | ], 1880 | "since": 0 1881 | }, 1882 | { 1883 | "method": False, 1884 | "deprecated_since": 1, 1885 | "name": "vim_strwidth", 1886 | "return_type": "Integer", 1887 | "parameters": [ 1888 | [ 1889 | "String", 1890 | "str" 1891 | ] 1892 | ], 1893 | "since": 0 1894 | }, 1895 | { 1896 | "method": False, 1897 | "deprecated_since": 1, 1898 | "name": "vim_list_runtime_paths", 1899 | "return_type": "ArrayOf(String)", 1900 | "parameters": [], 1901 | "since": 0 1902 | }, 1903 | { 1904 | "method": False, 1905 | "deprecated_since": 1, 1906 | "name": "vim_change_directory", 1907 | "return_type": "void", 1908 | "parameters": [ 1909 | [ 1910 | "String", 1911 | "dir" 1912 | ] 1913 | ], 1914 | "since": 0 1915 | }, 1916 | { 1917 | "method": False, 1918 | "deprecated_since": 1, 1919 | "name": "vim_get_current_line", 1920 | "return_type": "String", 1921 | "parameters": [], 1922 | "since": 0 1923 | }, 1924 | { 1925 | "method": False, 1926 | "deprecated_since": 1, 1927 | "name": "vim_set_current_line", 1928 | "return_type": "void", 1929 | "parameters": [ 1930 | [ 1931 | "String", 1932 | "line" 1933 | ] 1934 | ], 1935 | "since": 0 1936 | }, 1937 | { 1938 | "method": False, 1939 | "deprecated_since": 1, 1940 | "name": "vim_del_current_line", 1941 | "return_type": "void", 1942 | "parameters": [], 1943 | "since": 0 1944 | }, 1945 | { 1946 | "method": False, 1947 | "deprecated_since": 1, 1948 | "name": "vim_get_var", 1949 | "return_type": "Object", 1950 | "parameters": [ 1951 | [ 1952 | "String", 1953 | "name" 1954 | ] 1955 | ], 1956 | "since": 0 1957 | }, 1958 | { 1959 | "method": False, 1960 | "deprecated_since": 1, 1961 | "name": "vim_get_vvar", 1962 | "return_type": "Object", 1963 | "parameters": [ 1964 | [ 1965 | "String", 1966 | "name" 1967 | ] 1968 | ], 1969 | "since": 0 1970 | }, 1971 | { 1972 | "method": False, 1973 | "deprecated_since": 1, 1974 | "name": "vim_get_option", 1975 | "return_type": "Object", 1976 | "parameters": [ 1977 | [ 1978 | "String", 1979 | "name" 1980 | ] 1981 | ], 1982 | "since": 0 1983 | }, 1984 | { 1985 | "method": False, 1986 | "deprecated_since": 1, 1987 | "name": "vim_set_option", 1988 | "return_type": "void", 1989 | "parameters": [ 1990 | [ 1991 | "String", 1992 | "name" 1993 | ], 1994 | [ 1995 | "Object", 1996 | "value" 1997 | ] 1998 | ], 1999 | "since": 0 2000 | }, 2001 | { 2002 | "method": False, 2003 | "deprecated_since": 1, 2004 | "name": "vim_out_write", 2005 | "return_type": "void", 2006 | "parameters": [ 2007 | [ 2008 | "String", 2009 | "str" 2010 | ] 2011 | ], 2012 | "since": 0 2013 | }, 2014 | { 2015 | "method": False, 2016 | "deprecated_since": 1, 2017 | "name": "vim_err_write", 2018 | "return_type": "void", 2019 | "parameters": [ 2020 | [ 2021 | "String", 2022 | "str" 2023 | ] 2024 | ], 2025 | "since": 0 2026 | }, 2027 | { 2028 | "method": False, 2029 | "deprecated_since": 1, 2030 | "name": "vim_report_error", 2031 | "return_type": "void", 2032 | "parameters": [ 2033 | [ 2034 | "String", 2035 | "str" 2036 | ] 2037 | ], 2038 | "since": 0 2039 | }, 2040 | { 2041 | "method": False, 2042 | "deprecated_since": 1, 2043 | "name": "vim_get_buffers", 2044 | "return_type": "ArrayOf(Buffer)", 2045 | "parameters": [], 2046 | "since": 0 2047 | }, 2048 | { 2049 | "method": False, 2050 | "deprecated_since": 1, 2051 | "name": "vim_get_current_buffer", 2052 | "return_type": "Buffer", 2053 | "parameters": [], 2054 | "since": 0 2055 | }, 2056 | { 2057 | "method": False, 2058 | "deprecated_since": 1, 2059 | "name": "vim_set_current_buffer", 2060 | "return_type": "void", 2061 | "parameters": [ 2062 | [ 2063 | "Buffer", 2064 | "buffer" 2065 | ] 2066 | ], 2067 | "since": 0 2068 | }, 2069 | { 2070 | "method": False, 2071 | "deprecated_since": 1, 2072 | "name": "vim_get_windows", 2073 | "return_type": "ArrayOf(Window)", 2074 | "parameters": [], 2075 | "since": 0 2076 | }, 2077 | { 2078 | "method": False, 2079 | "deprecated_since": 1, 2080 | "name": "vim_get_current_window", 2081 | "return_type": "Window", 2082 | "parameters": [], 2083 | "since": 0 2084 | }, 2085 | { 2086 | "method": False, 2087 | "deprecated_since": 1, 2088 | "name": "vim_set_current_window", 2089 | "return_type": "void", 2090 | "parameters": [ 2091 | [ 2092 | "Window", 2093 | "window" 2094 | ] 2095 | ], 2096 | "since": 0 2097 | }, 2098 | { 2099 | "method": False, 2100 | "deprecated_since": 1, 2101 | "name": "vim_get_tabpages", 2102 | "return_type": "ArrayOf(Tabpage)", 2103 | "parameters": [], 2104 | "since": 0 2105 | }, 2106 | { 2107 | "method": False, 2108 | "deprecated_since": 1, 2109 | "name": "vim_get_current_tabpage", 2110 | "return_type": "Tabpage", 2111 | "parameters": [], 2112 | "since": 0 2113 | }, 2114 | { 2115 | "method": False, 2116 | "deprecated_since": 1, 2117 | "name": "vim_set_current_tabpage", 2118 | "return_type": "void", 2119 | "parameters": [ 2120 | [ 2121 | "Tabpage", 2122 | "tabpage" 2123 | ] 2124 | ], 2125 | "since": 0 2126 | }, 2127 | { 2128 | "method": False, 2129 | "deprecated_since": 1, 2130 | "name": "vim_subscribe", 2131 | "return_type": "void", 2132 | "parameters": [ 2133 | [ 2134 | "String", 2135 | "event" 2136 | ] 2137 | ], 2138 | "since": 0 2139 | }, 2140 | { 2141 | "method": False, 2142 | "deprecated_since": 1, 2143 | "name": "vim_unsubscribe", 2144 | "return_type": "void", 2145 | "parameters": [ 2146 | [ 2147 | "String", 2148 | "event" 2149 | ] 2150 | ], 2151 | "since": 0 2152 | }, 2153 | { 2154 | "method": False, 2155 | "deprecated_since": 1, 2156 | "name": "vim_name_to_color", 2157 | "return_type": "Integer", 2158 | "parameters": [ 2159 | [ 2160 | "String", 2161 | "name" 2162 | ] 2163 | ], 2164 | "since": 0 2165 | }, 2166 | { 2167 | "method": False, 2168 | "deprecated_since": 1, 2169 | "name": "vim_get_color_map", 2170 | "return_type": "Dictionary", 2171 | "parameters": [], 2172 | "since": 0 2173 | }, 2174 | { 2175 | "method": False, 2176 | "deprecated_since": 1, 2177 | "name": "vim_get_api_info", 2178 | "return_type": "Array", 2179 | "parameters": [], 2180 | "since": 0 2181 | }, 2182 | { 2183 | "method": True, 2184 | "deprecated_since": 1, 2185 | "name": "window_get_buffer", 2186 | "return_type": "Buffer", 2187 | "parameters": [ 2188 | [ 2189 | "Window", 2190 | "window" 2191 | ] 2192 | ], 2193 | "since": 0 2194 | }, 2195 | { 2196 | "method": True, 2197 | "deprecated_since": 1, 2198 | "name": "window_get_cursor", 2199 | "return_type": "ArrayOf(Integer, 2)", 2200 | "parameters": [ 2201 | [ 2202 | "Window", 2203 | "window" 2204 | ] 2205 | ], 2206 | "since": 0 2207 | }, 2208 | { 2209 | "method": True, 2210 | "deprecated_since": 1, 2211 | "name": "window_set_cursor", 2212 | "return_type": "void", 2213 | "parameters": [ 2214 | [ 2215 | "Window", 2216 | "window" 2217 | ], 2218 | [ 2219 | "ArrayOf(Integer, 2)", 2220 | "pos" 2221 | ] 2222 | ], 2223 | "since": 0 2224 | }, 2225 | { 2226 | "method": True, 2227 | "deprecated_since": 1, 2228 | "name": "window_get_height", 2229 | "return_type": "Integer", 2230 | "parameters": [ 2231 | [ 2232 | "Window", 2233 | "window" 2234 | ] 2235 | ], 2236 | "since": 0 2237 | }, 2238 | { 2239 | "method": True, 2240 | "deprecated_since": 1, 2241 | "name": "window_set_height", 2242 | "return_type": "void", 2243 | "parameters": [ 2244 | [ 2245 | "Window", 2246 | "window" 2247 | ], 2248 | [ 2249 | "Integer", 2250 | "height" 2251 | ] 2252 | ], 2253 | "since": 0 2254 | }, 2255 | { 2256 | "method": True, 2257 | "deprecated_since": 1, 2258 | "name": "window_get_width", 2259 | "return_type": "Integer", 2260 | "parameters": [ 2261 | [ 2262 | "Window", 2263 | "window" 2264 | ] 2265 | ], 2266 | "since": 0 2267 | }, 2268 | { 2269 | "method": True, 2270 | "deprecated_since": 1, 2271 | "name": "window_set_width", 2272 | "return_type": "void", 2273 | "parameters": [ 2274 | [ 2275 | "Window", 2276 | "window" 2277 | ], 2278 | [ 2279 | "Integer", 2280 | "width" 2281 | ] 2282 | ], 2283 | "since": 0 2284 | }, 2285 | { 2286 | "method": True, 2287 | "deprecated_since": 1, 2288 | "name": "window_get_var", 2289 | "return_type": "Object", 2290 | "parameters": [ 2291 | [ 2292 | "Window", 2293 | "window" 2294 | ], 2295 | [ 2296 | "String", 2297 | "name" 2298 | ] 2299 | ], 2300 | "since": 0 2301 | }, 2302 | { 2303 | "method": True, 2304 | "deprecated_since": 1, 2305 | "name": "window_get_option", 2306 | "return_type": "Object", 2307 | "parameters": [ 2308 | [ 2309 | "Window", 2310 | "window" 2311 | ], 2312 | [ 2313 | "String", 2314 | "name" 2315 | ] 2316 | ], 2317 | "since": 0 2318 | }, 2319 | { 2320 | "method": True, 2321 | "deprecated_since": 1, 2322 | "name": "window_set_option", 2323 | "return_type": "void", 2324 | "parameters": [ 2325 | [ 2326 | "Window", 2327 | "window" 2328 | ], 2329 | [ 2330 | "String", 2331 | "name" 2332 | ], 2333 | [ 2334 | "Object", 2335 | "value" 2336 | ] 2337 | ], 2338 | "since": 0 2339 | }, 2340 | { 2341 | "method": True, 2342 | "deprecated_since": 1, 2343 | "name": "window_get_position", 2344 | "return_type": "ArrayOf(Integer, 2)", 2345 | "parameters": [ 2346 | [ 2347 | "Window", 2348 | "window" 2349 | ] 2350 | ], 2351 | "since": 0 2352 | }, 2353 | { 2354 | "method": True, 2355 | "deprecated_since": 1, 2356 | "name": "window_get_tabpage", 2357 | "return_type": "Tabpage", 2358 | "parameters": [ 2359 | [ 2360 | "Window", 2361 | "window" 2362 | ] 2363 | ], 2364 | "since": 0 2365 | }, 2366 | { 2367 | "method": True, 2368 | "deprecated_since": 1, 2369 | "name": "window_is_valid", 2370 | "return_type": "Boolean", 2371 | "parameters": [ 2372 | [ 2373 | "Window", 2374 | "window" 2375 | ] 2376 | ], 2377 | "since": 0 2378 | } 2379 | ], 2380 | "error_types": { 2381 | "Validation": { 2382 | "id": 1 2383 | }, 2384 | "Exception": { 2385 | "id": 0 2386 | } 2387 | } 2388 | } 2389 | --------------------------------------------------------------------------------