├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example └── example.dart ├── lib ├── dart_nvim_api.dart └── src │ ├── ext_types.dart │ ├── gen │ ├── buffer.g.dart │ ├── nvim.g.dart │ ├── tabpage.g.dart │ └── window.g.dart │ ├── neovim.dart │ └── ui_attach_options.dart ├── pubspec.yaml ├── test └── neovim_test.dart └── tool └── src ├── api_gen.dart ├── api_info.json └── api_to_json.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | pubspec.lock 5 | 6 | # Conventional directory for build outputs 7 | build/ 8 | 9 | # Directory created by dartdoc 10 | doc/api/ 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/dart-lang/shelf/blob/master/.travis.yml 2 | 3 | language: dart 4 | 5 | dart_task: 6 | - script: 7 | - dartanalyzer lib test 8 | 9 | matrix: 10 | include: 11 | # Only validate formatting using the dev release 12 | - dart: dev 13 | script: 14 | - dartfmt -n lib test 15 | 16 | # Only building master means that we don't run two builds for each pull request. 17 | branches: 18 | only: [master] 19 | 20 | cache: 21 | directories: 22 | - $HOME/.pub-cache 23 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 2 | 3 | - Initial version 4 | 5 | ## 0.1.1 6 | 7 | - Make function names for the `Buffer`, `Tabpage`, and `Window` classes 8 | camelcase. 9 | - Fix an issue where API functions which were supposed to return 10 | a `Buffer`, `Tabpage`, or `Window` would return `null` instead. 11 | 12 | ## 0.1.2 13 | 14 | - Additions 15 | - `attachUi` function in the `Neovim` class for attaching an external 16 | UI to Neovim. 17 | - Travis. 18 | - Documentation for `Neovim` class (not finished yet, mainly waiting on [neovim/neovim#1139](https://github.com/neovim/neovim/pull/11396) and a subsequent PR adding a way to get 19 | the documentation on each API function from Neovim). 20 | - Classes for each type of `ui_event` from Neovim. 21 | - `example` directory with a short example (shown in README). 22 | - Changes 23 | - Moved `Neovim` class from `lib/dart_nvim_api.dart` to `lib/src/neovim.dart` 24 | to be more consistent with idiomatic Dart library structure. 25 | - Updated README to show latest library version from [pub.dev](http://pub.dev) 26 | 27 | ## 0.1.3 28 | 29 | - Added `Session.fromCurrentStdinStdout()` function and an optional flag 30 | (`communicateWithParentProcess`) to the `Neovim` class (see docs for more 31 | info). 32 | 33 | ## 0.1.4 34 | 35 | - Fixed an issue where functions which returned `List`s (e.g. 36 | `Buffer().getLines` would throw an error saying `type 'List' 37 | is not a subtype of type 'List' in type cast` or similar. 38 | 39 | ## 0.2.0 40 | 41 | - `Neovim` class has been renamed to `Nvim` 42 | - Neovim instance is spawned via `await Nvim.spawn()` 43 | - Now a Neovim instance that communicates to Neovim via current stdin/stdout is gotten with `await Nvim.child()` 44 | - Buffer/Window/Tabpage APIs are within the Nvim API, so `await nvim.bufGetName(buf)` 45 | is used instead of `await buf.getName()`, and likewise for the window and 46 | tabpage APIs. 47 | - More/better tests 48 | - Various internal changes 49 | 50 | ## 0.2.1 51 | 52 | - Errors from Neovim when calling API functions are now forwarded to the caller 53 | via exceptions. 54 | 55 | ## 0.2.2 56 | 57 | - Add way to override onNotify and onRequest handlers after initialization of 58 | `Nvim` 59 | 60 | ## 0.3.0 61 | 62 | - Null Safety & update internal API bindings (https://github.com/smolck/dart-nvim-api/pull/5) 63 | - With `Nvim.spawn`, run nvim process in an `Isolate` (https://github.com/smolck/dart-nvim-api/pull/4) 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 smolck 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/smolck/dart-nvim-api.svg?branch=master)](https://travis-ci.org/smolck/dart-nvim-api) 2 | [![Pub](https://img.shields.io/pub/v/dart_nvim_api.svg)](https://pub.dartlang.org/packages/dart_nvim_api) 3 | # Dart Nvim API 4 | 5 | Neovim API implementation for [Dart](dart.dev), based on and inspired by [neovim-lib](https://github.com/daa84/neovim-lib). 6 | Still a WIP, so any feedback, contributions, etc. are greatly appreciated. 7 | 8 | > NOTE: Dart Nvim API is still in its early stages, so there are likely to be breaking API changes. 9 | 10 | # Example Usage 11 | ```dart 12 | import 'package:dart_nvim_api/dart_nvim_api.dart'; 13 | 14 | void main(List args) async { 15 | // Start up Neovim instance, with optional `onNotify` and `onRequest` 16 | // callbacks. 17 | // See also Nvim.child() 18 | var nvim = await Nvim.spawn(); 19 | 20 | // Run Neovim ex command. 21 | await nvim.command("echo 'hello'"); 22 | 23 | // Get ex command output. 24 | 25 | assert(await nvim.exec('echo 1 + 1', true) == '2'); 26 | 27 | // Buffer example: 28 | var buf = await nvim.createBuf(true, false); 29 | var bufNameWithoutPath = 'some name'; 30 | await nvim.bufSetName(buf, bufNameWithoutPath); 31 | var bufName = await nvim.bufGetName(buf); 32 | assert(bufName.contains(bufNameWithoutPath)); 33 | 34 | // Kill Neovim when done. 35 | nvim.kill(); 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Defines a default set of lint rules enforced for 2 | # projects at Google. For details and rationale, 3 | # see https://github.com/dart-lang/pedantic#enabled-lints. 4 | include: package:pedantic/analysis_options.yaml 5 | 6 | analyzer: 7 | exclude: 8 | - gen_bindings/dart_nvim_api.dart 9 | gen_bindings/src/buffer.dart 10 | gen_bindings/src/tabpage.dart 11 | gen_bindings/src/window.dart 12 | -------------------------------------------------------------------------------- /example/example.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_nvim_api/dart_nvim_api.dart'; 2 | 3 | void main(List args) async { 4 | // Start up Neovim instance, with optional `onNotify` and `onRequest` 5 | // callbacks. 6 | // See also Nvim.child() 7 | var nvim = await Nvim.spawn(); 8 | 9 | // Run Neovim ex command. 10 | await nvim.command("echo 'hello'"); 11 | 12 | // Get ex command output. 13 | 14 | assert(await nvim.exec('echo 1 + 1', true) == '2'); 15 | 16 | // Buffer example: 17 | var buf = await nvim.createBuf(true, false); 18 | var bufNameWithoutPath = 'some name'; 19 | await nvim.bufSetName(buf, bufNameWithoutPath); 20 | var bufName = await nvim.bufGetName(buf); 21 | assert(bufName.contains(bufNameWithoutPath)); 22 | 23 | // Kill Neovim when done. 24 | nvim.kill(); 25 | } 26 | -------------------------------------------------------------------------------- /lib/dart_nvim_api.dart: -------------------------------------------------------------------------------- 1 | export 'src/neovim.dart'; 2 | export 'src/ui_attach_options.dart'; 3 | export 'src/gen/nvim.g.dart'; 4 | export 'src/gen/buffer.g.dart'; 5 | export 'src/gen/tabpage.g.dart'; 6 | export 'src/gen/window.g.dart'; 7 | -------------------------------------------------------------------------------- /lib/src/ext_types.dart: -------------------------------------------------------------------------------- 1 | import 'package:msgpack_dart/msgpack_dart.dart'; 2 | import 'dart:typed_data'; 3 | 4 | class Buffer { 5 | final int data; 6 | 7 | Buffer(this.data); 8 | } 9 | 10 | class LuaRef { 11 | LuaRef(); 12 | } 13 | 14 | class Window { 15 | final int data; 16 | 17 | Window(this.data); 18 | } 19 | 20 | class Tabpage { 21 | final int data; 22 | 23 | Tabpage(this.data); 24 | } 25 | 26 | class ExtTypeDecoder extends ExtDecoder { 27 | @override 28 | dynamic decodeObject(int extType, Uint8List data) { 29 | switch (extType) { 30 | case 0: // ID for a `Buffer` 31 | return Buffer(deserialize(data)); 32 | case 1: // ID for a `Window` 33 | return Window(deserialize(data)); 34 | case 2: // ID for a `Tabpage` 35 | return Tabpage(deserialize(data)); 36 | } 37 | } 38 | } 39 | 40 | class ExtTypeEncoder extends ExtEncoder { 41 | @override 42 | int extTypeForObject(dynamic object) { 43 | if (object is Buffer) { 44 | return 0; 45 | } else if (object is Window) { 46 | return 1; 47 | } else if (object is Tabpage) { 48 | return 2; 49 | } 50 | 51 | throw "Can't decode object, not a Neovim type: $object"; 52 | } 53 | 54 | @override 55 | Uint8List encodeObject(dynamic object) { 56 | if (object is Buffer || object is Window || object is Tabpage) { 57 | return serialize(object.data); 58 | } 59 | 60 | throw "Object wasn't a Neovim ext type!"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/src/gen/buffer.g.dart: -------------------------------------------------------------------------------- 1 | import '../neovim.dart'; 2 | import '../ext_types.dart'; 3 | 4 | import '../ext_types.dart'; 5 | 6 | extension NvimBufferApi on Nvim { 7 | Future bufLineCount(Buffer buffer) { 8 | return call('nvim_buf_line_count', args: [ 9 | buffer, 10 | ]).then((v) => v as int); 11 | } 12 | 13 | Future bufAttach( 14 | Buffer buffer, bool send_buffer, Map opts) { 15 | return call('nvim_buf_attach', args: [ 16 | buffer, 17 | send_buffer, 18 | opts, 19 | ]).then((v) => v as bool); 20 | } 21 | 22 | Future bufDetach(Buffer buffer) { 23 | return call('nvim_buf_detach', args: [ 24 | buffer, 25 | ]).then((v) => v as bool); 26 | } 27 | 28 | Future> bufGetLines( 29 | Buffer buffer, int start, int end, bool strict_indexing) { 30 | return call('nvim_buf_get_lines', args: [ 31 | buffer, 32 | start, 33 | end, 34 | strict_indexing, 35 | ]).then>((v) => (v as List).cast()); 36 | } 37 | 38 | Future bufSetLines(Buffer buffer, int start, int end, 39 | bool strict_indexing, List replacement) { 40 | return call('nvim_buf_set_lines', args: [ 41 | buffer, 42 | start, 43 | end, 44 | strict_indexing, 45 | replacement, 46 | ]); 47 | } 48 | 49 | Future bufSetText(Buffer buffer, int start_row, int start_col, 50 | int end_row, int end_col, List replacement) { 51 | return call('nvim_buf_set_text', args: [ 52 | buffer, 53 | start_row, 54 | start_col, 55 | end_row, 56 | end_col, 57 | replacement, 58 | ]); 59 | } 60 | 61 | Future bufGetOffset(Buffer buffer, int index) { 62 | return call('nvim_buf_get_offset', args: [ 63 | buffer, 64 | index, 65 | ]).then((v) => v as int); 66 | } 67 | 68 | Future bufGetVar(Buffer buffer, String name) { 69 | return call('nvim_buf_get_var', args: [ 70 | buffer, 71 | name, 72 | ]); 73 | } 74 | 75 | Future bufGetChangedtick(Buffer buffer) { 76 | return call('nvim_buf_get_changedtick', args: [ 77 | buffer, 78 | ]).then((v) => v as int); 79 | } 80 | 81 | Future>> bufGetKeymap(Buffer buffer, String mode) { 82 | return call('nvim_buf_get_keymap', args: [ 83 | buffer, 84 | mode, 85 | ]).then>>( 86 | (v) => (v as List).cast>()); 87 | } 88 | 89 | Future bufSetKeymap(Buffer buffer, String mode, String lhs, String rhs, 90 | Map opts) { 91 | return call('nvim_buf_set_keymap', args: [ 92 | buffer, 93 | mode, 94 | lhs, 95 | rhs, 96 | opts, 97 | ]); 98 | } 99 | 100 | Future bufDelKeymap(Buffer buffer, String mode, String lhs) { 101 | return call('nvim_buf_del_keymap', args: [ 102 | buffer, 103 | mode, 104 | lhs, 105 | ]); 106 | } 107 | 108 | Future> bufGetCommands( 109 | Buffer buffer, Map opts) { 110 | return call('nvim_buf_get_commands', args: [ 111 | buffer, 112 | opts, 113 | ]).then>((v) => v as Map); 114 | } 115 | 116 | Future bufSetVar(Buffer buffer, String name, dynamic value) { 117 | return call('nvim_buf_set_var', args: [ 118 | buffer, 119 | name, 120 | value, 121 | ]); 122 | } 123 | 124 | Future bufDelVar(Buffer buffer, String name) { 125 | return call('nvim_buf_del_var', args: [ 126 | buffer, 127 | name, 128 | ]); 129 | } 130 | 131 | Future bufGetOption(Buffer buffer, String name) { 132 | return call('nvim_buf_get_option', args: [ 133 | buffer, 134 | name, 135 | ]); 136 | } 137 | 138 | Future bufSetOption(Buffer buffer, String name, dynamic value) { 139 | return call('nvim_buf_set_option', args: [ 140 | buffer, 141 | name, 142 | value, 143 | ]); 144 | } 145 | 146 | Future bufGetName(Buffer buffer) { 147 | return call('nvim_buf_get_name', args: [ 148 | buffer, 149 | ]).then((v) => v as String); 150 | } 151 | 152 | Future bufSetName(Buffer buffer, String name) { 153 | return call('nvim_buf_set_name', args: [ 154 | buffer, 155 | name, 156 | ]); 157 | } 158 | 159 | Future bufIsLoaded(Buffer buffer) { 160 | return call('nvim_buf_is_loaded', args: [ 161 | buffer, 162 | ]).then((v) => v as bool); 163 | } 164 | 165 | Future bufDelete(Buffer buffer, Map opts) { 166 | return call('nvim_buf_delete', args: [ 167 | buffer, 168 | opts, 169 | ]); 170 | } 171 | 172 | Future bufIsValid(Buffer buffer) { 173 | return call('nvim_buf_is_valid', args: [ 174 | buffer, 175 | ]).then((v) => v as bool); 176 | } 177 | 178 | Future> bufGetMark(Buffer buffer, String name) { 179 | return call('nvim_buf_get_mark', args: [ 180 | buffer, 181 | name, 182 | ]).then>((v) => (v as List).cast()); 183 | } 184 | 185 | Future> bufGetExtmarkById( 186 | Buffer buffer, int ns_id, int id, Map opts) { 187 | return call('nvim_buf_get_extmark_by_id', args: [ 188 | buffer, 189 | ns_id, 190 | id, 191 | opts, 192 | ]).then>((v) => (v as List).cast()); 193 | } 194 | 195 | Future> bufGetExtmarks(Buffer buffer, int ns_id, dynamic start, 196 | dynamic end, Map opts) { 197 | return call('nvim_buf_get_extmarks', args: [ 198 | buffer, 199 | ns_id, 200 | start, 201 | end, 202 | opts, 203 | ]).then>((v) => (v as List).cast()); 204 | } 205 | 206 | Future bufSetExtmark( 207 | Buffer buffer, int ns_id, int line, int col, Map opts) { 208 | return call('nvim_buf_set_extmark', args: [ 209 | buffer, 210 | ns_id, 211 | line, 212 | col, 213 | opts, 214 | ]).then((v) => v as int); 215 | } 216 | 217 | Future bufDelExtmark(Buffer buffer, int ns_id, int id) { 218 | return call('nvim_buf_del_extmark', args: [ 219 | buffer, 220 | ns_id, 221 | id, 222 | ]).then((v) => v as bool); 223 | } 224 | 225 | Future bufAddHighlight(Buffer buffer, int ns_id, String hl_group, 226 | int line, int col_start, int col_end) { 227 | return call('nvim_buf_add_highlight', args: [ 228 | buffer, 229 | ns_id, 230 | hl_group, 231 | line, 232 | col_start, 233 | col_end, 234 | ]).then((v) => v as int); 235 | } 236 | 237 | Future bufClearNamespace( 238 | Buffer buffer, int ns_id, int line_start, int line_end) { 239 | return call('nvim_buf_clear_namespace', args: [ 240 | buffer, 241 | ns_id, 242 | line_start, 243 | line_end, 244 | ]); 245 | } 246 | 247 | Future bufSetVirtualText(Buffer buffer, int src_id, int line, 248 | List chunks, Map opts) { 249 | return call('nvim_buf_set_virtual_text', args: [ 250 | buffer, 251 | src_id, 252 | line, 253 | chunks, 254 | opts, 255 | ]).then((v) => v as int); 256 | } 257 | 258 | Future bufCall(Buffer buffer, LuaRef fun) { 259 | return call('nvim_buf_call', args: [ 260 | buffer, 261 | fun, 262 | ]); 263 | } 264 | 265 | Future> listBufs() { 266 | return call('nvim_list_bufs', args: []) 267 | .then>((v) => (v as List).cast()); 268 | } 269 | 270 | Future getCurrentBuf() { 271 | return call('nvim_get_current_buf', args: []) 272 | .then((v) => v as Buffer); 273 | } 274 | 275 | Future setCurrentBuf(Buffer buffer) { 276 | return call('nvim_set_current_buf', args: [ 277 | buffer, 278 | ]); 279 | } 280 | 281 | Future createBuf(bool listed, bool scratch) { 282 | return call('nvim_create_buf', args: [ 283 | listed, 284 | scratch, 285 | ]).then((v) => v as Buffer); 286 | } 287 | 288 | Future winGetBuf(Window window) { 289 | return call('nvim_win_get_buf', args: [ 290 | window, 291 | ]).then((v) => v as Buffer); 292 | } 293 | 294 | Future winSetBuf(Window window, Buffer buffer) { 295 | return call('nvim_win_set_buf', args: [ 296 | window, 297 | buffer, 298 | ]); 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /lib/src/gen/nvim.g.dart: -------------------------------------------------------------------------------- 1 | import '../neovim.dart'; 2 | import '../ext_types.dart'; 3 | 4 | extension NvimApi on Nvim { 5 | Future uiAttach(int width, int height, Map options) { 6 | return call('nvim_ui_attach', args: [ 7 | width, 8 | height, 9 | options, 10 | ]); 11 | } 12 | 13 | Future uiDetach() { 14 | return call('nvim_ui_detach', args: []); 15 | } 16 | 17 | Future uiTryResize(int width, int height) { 18 | return call('nvim_ui_try_resize', args: [ 19 | width, 20 | height, 21 | ]); 22 | } 23 | 24 | Future uiSetOption(String name, dynamic value) { 25 | return call('nvim_ui_set_option', args: [ 26 | name, 27 | value, 28 | ]); 29 | } 30 | 31 | Future uiTryResizeGrid(int grid, int width, int height) { 32 | return call('nvim_ui_try_resize_grid', args: [ 33 | grid, 34 | width, 35 | height, 36 | ]); 37 | } 38 | 39 | Future uiPumSetHeight(int height) { 40 | return call('nvim_ui_pum_set_height', args: [ 41 | height, 42 | ]); 43 | } 44 | 45 | Future uiPumSetBounds( 46 | double width, double height, double row, double col) { 47 | return call('nvim_ui_pum_set_bounds', args: [ 48 | width, 49 | height, 50 | row, 51 | col, 52 | ]); 53 | } 54 | 55 | Future exec(String src, bool output) { 56 | return call('nvim_exec', args: [ 57 | src, 58 | output, 59 | ]).then((v) => v as String); 60 | } 61 | 62 | Future command(String command) { 63 | return call('nvim_command', args: [ 64 | command, 65 | ]); 66 | } 67 | 68 | Future> getHlByName(String name, bool rgb) { 69 | return call('nvim_get_hl_by_name', args: [ 70 | name, 71 | rgb, 72 | ]).then>((v) => v as Map); 73 | } 74 | 75 | Future> getHlById(int hl_id, bool rgb) { 76 | return call('nvim_get_hl_by_id', args: [ 77 | hl_id, 78 | rgb, 79 | ]).then>((v) => v as Map); 80 | } 81 | 82 | Future getHlIdByName(String name) { 83 | return call('nvim_get_hl_id_by_name', args: [ 84 | name, 85 | ]).then((v) => v as int); 86 | } 87 | 88 | Future setHl(int ns_id, String name, Map val) { 89 | return call('nvim_set_hl', args: [ 90 | ns_id, 91 | name, 92 | val, 93 | ]); 94 | } 95 | 96 | Future feedkeys(String keys, String mode, bool escape_csi) { 97 | return call('nvim_feedkeys', args: [ 98 | keys, 99 | mode, 100 | escape_csi, 101 | ]); 102 | } 103 | 104 | Future input(String keys) { 105 | return call('nvim_input', args: [ 106 | keys, 107 | ]).then((v) => v as int); 108 | } 109 | 110 | Future inputMouse(String button, String action, String modifier, 111 | int grid, int row, int col) { 112 | return call('nvim_input_mouse', args: [ 113 | button, 114 | action, 115 | modifier, 116 | grid, 117 | row, 118 | col, 119 | ]); 120 | } 121 | 122 | Future replaceTermcodes( 123 | String str, bool from_part, bool do_lt, bool special) { 124 | return call('nvim_replace_termcodes', args: [ 125 | str, 126 | from_part, 127 | do_lt, 128 | special, 129 | ]).then((v) => v as String); 130 | } 131 | 132 | Future eval(String expr) { 133 | return call('nvim_eval', args: [ 134 | expr, 135 | ]); 136 | } 137 | 138 | Future execLua(String code, List args) { 139 | return call('nvim_exec_lua', args: [ 140 | code, 141 | args, 142 | ]); 143 | } 144 | 145 | Future notify( 146 | String msg, int log_level, Map opts) { 147 | return call('nvim_notify', args: [ 148 | msg, 149 | log_level, 150 | opts, 151 | ]); 152 | } 153 | 154 | Future callFunction(String fn, List args) { 155 | return call('nvim_call_function', args: [ 156 | fn, 157 | args, 158 | ]); 159 | } 160 | 161 | Future callDictFunction( 162 | dynamic dict, String fn, List args) { 163 | return call('nvim_call_dict_function', args: [ 164 | dict, 165 | fn, 166 | args, 167 | ]); 168 | } 169 | 170 | Future strwidth(String text) { 171 | return call('nvim_strwidth', args: [ 172 | text, 173 | ]).then((v) => v as int); 174 | } 175 | 176 | Future> listRuntimePaths() { 177 | return call('nvim_list_runtime_paths', args: []) 178 | .then>((v) => (v as List).cast()); 179 | } 180 | 181 | Future> getRuntimeFile(String name, bool all) { 182 | return call('nvim_get_runtime_file', args: [ 183 | name, 184 | all, 185 | ]).then>((v) => (v as List).cast()); 186 | } 187 | 188 | Future setCurrentDir(String dir) { 189 | return call('nvim_set_current_dir', args: [ 190 | dir, 191 | ]); 192 | } 193 | 194 | Future getCurrentLine() { 195 | return call('nvim_get_current_line', args: []) 196 | .then((v) => v as String); 197 | } 198 | 199 | Future setCurrentLine(String line) { 200 | return call('nvim_set_current_line', args: [ 201 | line, 202 | ]); 203 | } 204 | 205 | Future delCurrentLine() { 206 | return call('nvim_del_current_line', args: []); 207 | } 208 | 209 | Future getVar(String name) { 210 | return call('nvim_get_var', args: [ 211 | name, 212 | ]); 213 | } 214 | 215 | Future setVar(String name, dynamic value) { 216 | return call('nvim_set_var', args: [ 217 | name, 218 | value, 219 | ]); 220 | } 221 | 222 | Future delVar(String name) { 223 | return call('nvim_del_var', args: [ 224 | name, 225 | ]); 226 | } 227 | 228 | Future getVvar(String name) { 229 | return call('nvim_get_vvar', args: [ 230 | name, 231 | ]); 232 | } 233 | 234 | Future setVvar(String name, dynamic value) { 235 | return call('nvim_set_vvar', args: [ 236 | name, 237 | value, 238 | ]); 239 | } 240 | 241 | Future getOption(String name) { 242 | return call('nvim_get_option', args: [ 243 | name, 244 | ]); 245 | } 246 | 247 | Future> getAllOptionsInfo() { 248 | return call('nvim_get_all_options_info', args: []) 249 | .then>((v) => v as Map); 250 | } 251 | 252 | Future> getOptionInfo(String name) { 253 | return call('nvim_get_option_info', args: [ 254 | name, 255 | ]).then>((v) => v as Map); 256 | } 257 | 258 | Future setOption(String name, dynamic value) { 259 | return call('nvim_set_option', args: [ 260 | name, 261 | value, 262 | ]); 263 | } 264 | 265 | Future echo( 266 | List chunks, bool history, Map opts) { 267 | return call('nvim_echo', args: [ 268 | chunks, 269 | history, 270 | opts, 271 | ]); 272 | } 273 | 274 | Future outWrite(String str) { 275 | return call('nvim_out_write', args: [ 276 | str, 277 | ]); 278 | } 279 | 280 | Future errWrite(String str) { 281 | return call('nvim_err_write', args: [ 282 | str, 283 | ]); 284 | } 285 | 286 | Future errWriteln(String str) { 287 | return call('nvim_err_writeln', args: [ 288 | str, 289 | ]); 290 | } 291 | 292 | Future openTerm(Buffer buffer, Map opts) { 293 | return call('nvim_open_term', args: [ 294 | buffer, 295 | opts, 296 | ]).then((v) => v as int); 297 | } 298 | 299 | Future chanSend(int chan, String data) { 300 | return call('nvim_chan_send', args: [ 301 | chan, 302 | data, 303 | ]); 304 | } 305 | 306 | Future createNamespace(String name) { 307 | return call('nvim_create_namespace', args: [ 308 | name, 309 | ]).then((v) => v as int); 310 | } 311 | 312 | Future> getNamespaces() { 313 | return call('nvim_get_namespaces', args: []) 314 | .then>((v) => v as Map); 315 | } 316 | 317 | Future paste(String data, bool crlf, int phase) { 318 | return call('nvim_paste', args: [ 319 | data, 320 | crlf, 321 | phase, 322 | ]).then((v) => v as bool); 323 | } 324 | 325 | Future put(List lines, String type, bool after, bool follow) { 326 | return call('nvim_put', args: [ 327 | lines, 328 | type, 329 | after, 330 | follow, 331 | ]); 332 | } 333 | 334 | Future subscribe(String event) { 335 | return call('nvim_subscribe', args: [ 336 | event, 337 | ]); 338 | } 339 | 340 | Future unsubscribe(String event) { 341 | return call('nvim_unsubscribe', args: [ 342 | event, 343 | ]); 344 | } 345 | 346 | Future getColorByName(String name) { 347 | return call('nvim_get_color_by_name', args: [ 348 | name, 349 | ]).then((v) => v as int); 350 | } 351 | 352 | Future> getColorMap() { 353 | return call('nvim_get_color_map', args: []) 354 | .then>((v) => v as Map); 355 | } 356 | 357 | Future> getContext(Map opts) { 358 | return call('nvim_get_context', args: [ 359 | opts, 360 | ]).then>((v) => v as Map); 361 | } 362 | 363 | Future loadContext(Map dict) { 364 | return call('nvim_load_context', args: [ 365 | dict, 366 | ]); 367 | } 368 | 369 | Future> getMode() { 370 | return call('nvim_get_mode', args: []) 371 | .then>((v) => v as Map); 372 | } 373 | 374 | Future>> getKeymap(String mode) { 375 | return call('nvim_get_keymap', args: [ 376 | mode, 377 | ]).then>>( 378 | (v) => (v as List).cast>()); 379 | } 380 | 381 | Future setKeymap( 382 | String mode, String lhs, String rhs, Map opts) { 383 | return call('nvim_set_keymap', args: [ 384 | mode, 385 | lhs, 386 | rhs, 387 | opts, 388 | ]); 389 | } 390 | 391 | Future delKeymap(String mode, String lhs) { 392 | return call('nvim_del_keymap', args: [ 393 | mode, 394 | lhs, 395 | ]); 396 | } 397 | 398 | Future> getCommands(Map opts) { 399 | return call('nvim_get_commands', args: [ 400 | opts, 401 | ]).then>((v) => v as Map); 402 | } 403 | 404 | Future> getApiInfo() { 405 | return call('nvim_get_api_info', args: []) 406 | .then>((v) => (v as List).cast()); 407 | } 408 | 409 | Future setClientInfo( 410 | String name, 411 | Map version, 412 | String type, 413 | Map methods, 414 | Map attributes) { 415 | return call('nvim_set_client_info', args: [ 416 | name, 417 | version, 418 | type, 419 | methods, 420 | attributes, 421 | ]); 422 | } 423 | 424 | Future> getChanInfo(int chan) { 425 | return call('nvim_get_chan_info', args: [ 426 | chan, 427 | ]).then>((v) => v as Map); 428 | } 429 | 430 | Future> listChans() { 431 | return call('nvim_list_chans', args: []) 432 | .then>((v) => (v as List).cast()); 433 | } 434 | 435 | Future> callAtomic(List calls) { 436 | return call('nvim_call_atomic', args: [ 437 | calls, 438 | ]).then>((v) => (v as List).cast()); 439 | } 440 | 441 | Future> parseExpression( 442 | String expr, String flags, bool highlight) { 443 | return call('nvim_parse_expression', args: [ 444 | expr, 445 | flags, 446 | highlight, 447 | ]).then>((v) => v as Map); 448 | } 449 | 450 | Future> listUis() { 451 | return call('nvim_list_uis', args: []) 452 | .then>((v) => (v as List).cast()); 453 | } 454 | 455 | Future> getProcChildren(int pid) { 456 | return call('nvim_get_proc_children', args: [ 457 | pid, 458 | ]).then>((v) => (v as List).cast()); 459 | } 460 | 461 | Future getProc(int pid) { 462 | return call('nvim_get_proc', args: [ 463 | pid, 464 | ]); 465 | } 466 | 467 | Future selectPopupmenuItem( 468 | int item, bool insert, bool finish, Map opts) { 469 | return call('nvim_select_popupmenu_item', args: [ 470 | item, 471 | insert, 472 | finish, 473 | opts, 474 | ]); 475 | } 476 | 477 | Future setDecorationProvider(int ns_id, Map opts) { 478 | return call('nvim_set_decoration_provider', args: [ 479 | ns_id, 480 | opts, 481 | ]); 482 | } 483 | } 484 | -------------------------------------------------------------------------------- /lib/src/gen/tabpage.g.dart: -------------------------------------------------------------------------------- 1 | import '../neovim.dart'; 2 | import '../ext_types.dart'; 3 | 4 | import '../ext_types.dart'; 5 | 6 | extension NvimTabpageApi on Nvim { 7 | Future tabpageGetVar(Tabpage tabpage, String name) { 8 | return call('nvim_tabpage_get_var', args: [ 9 | tabpage, 10 | name, 11 | ]); 12 | } 13 | 14 | Future tabpageSetVar(Tabpage tabpage, String name, dynamic value) { 15 | return call('nvim_tabpage_set_var', args: [ 16 | tabpage, 17 | name, 18 | value, 19 | ]); 20 | } 21 | 22 | Future tabpageDelVar(Tabpage tabpage, String name) { 23 | return call('nvim_tabpage_del_var', args: [ 24 | tabpage, 25 | name, 26 | ]); 27 | } 28 | 29 | Future tabpageGetNumber(Tabpage tabpage) { 30 | return call('nvim_tabpage_get_number', args: [ 31 | tabpage, 32 | ]).then((v) => v as int); 33 | } 34 | 35 | Future tabpageIsValid(Tabpage tabpage) { 36 | return call('nvim_tabpage_is_valid', args: [ 37 | tabpage, 38 | ]).then((v) => v as bool); 39 | } 40 | 41 | Future> listTabpages() { 42 | return call('nvim_list_tabpages', args: []) 43 | .then>((v) => (v as List).cast()); 44 | } 45 | 46 | Future getCurrentTabpage() { 47 | return call('nvim_get_current_tabpage', args: []) 48 | .then((v) => v as Tabpage); 49 | } 50 | 51 | Future setCurrentTabpage(Tabpage tabpage) { 52 | return call('nvim_set_current_tabpage', args: [ 53 | tabpage, 54 | ]); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/src/gen/window.g.dart: -------------------------------------------------------------------------------- 1 | import '../neovim.dart'; 2 | import '../ext_types.dart'; 3 | 4 | import '../ext_types.dart'; 5 | 6 | extension NvimWindowApi on Nvim { 7 | Future> tabpageListWins(Tabpage tabpage) { 8 | return call('nvim_tabpage_list_wins', args: [ 9 | tabpage, 10 | ]).then>((v) => (v as List).cast()); 11 | } 12 | 13 | Future tabpageGetWin(Tabpage tabpage) { 14 | return call('nvim_tabpage_get_win', args: [ 15 | tabpage, 16 | ]).then((v) => v as Window); 17 | } 18 | 19 | Future> listWins() { 20 | return call('nvim_list_wins', args: []) 21 | .then>((v) => (v as List).cast()); 22 | } 23 | 24 | Future getCurrentWin() { 25 | return call('nvim_get_current_win', args: []) 26 | .then((v) => v as Window); 27 | } 28 | 29 | Future setCurrentWin(Window window) { 30 | return call('nvim_set_current_win', args: [ 31 | window, 32 | ]); 33 | } 34 | 35 | Future openWin( 36 | Buffer buffer, bool enter, Map config) { 37 | return call('nvim_open_win', args: [ 38 | buffer, 39 | enter, 40 | config, 41 | ]).then((v) => v as Window); 42 | } 43 | 44 | Future> winGetCursor(Window window) { 45 | return call('nvim_win_get_cursor', args: [ 46 | window, 47 | ]).then>((v) => (v as List).cast()); 48 | } 49 | 50 | Future winSetCursor(Window window, List pos) { 51 | return call('nvim_win_set_cursor', args: [ 52 | window, 53 | pos, 54 | ]); 55 | } 56 | 57 | Future winGetHeight(Window window) { 58 | return call('nvim_win_get_height', args: [ 59 | window, 60 | ]).then((v) => v as int); 61 | } 62 | 63 | Future winSetHeight(Window window, int height) { 64 | return call('nvim_win_set_height', args: [ 65 | window, 66 | height, 67 | ]); 68 | } 69 | 70 | Future winGetWidth(Window window) { 71 | return call('nvim_win_get_width', args: [ 72 | window, 73 | ]).then((v) => v as int); 74 | } 75 | 76 | Future winSetWidth(Window window, int width) { 77 | return call('nvim_win_set_width', args: [ 78 | window, 79 | width, 80 | ]); 81 | } 82 | 83 | Future winGetVar(Window window, String name) { 84 | return call('nvim_win_get_var', args: [ 85 | window, 86 | name, 87 | ]); 88 | } 89 | 90 | Future winSetVar(Window window, String name, dynamic value) { 91 | return call('nvim_win_set_var', args: [ 92 | window, 93 | name, 94 | value, 95 | ]); 96 | } 97 | 98 | Future winDelVar(Window window, String name) { 99 | return call('nvim_win_del_var', args: [ 100 | window, 101 | name, 102 | ]); 103 | } 104 | 105 | Future winGetOption(Window window, String name) { 106 | return call('nvim_win_get_option', args: [ 107 | window, 108 | name, 109 | ]); 110 | } 111 | 112 | Future winSetOption(Window window, String name, dynamic value) { 113 | return call('nvim_win_set_option', args: [ 114 | window, 115 | name, 116 | value, 117 | ]); 118 | } 119 | 120 | Future> winGetPosition(Window window) { 121 | return call('nvim_win_get_position', args: [ 122 | window, 123 | ]).then>((v) => (v as List).cast()); 124 | } 125 | 126 | Future winGetTabpage(Window window) { 127 | return call('nvim_win_get_tabpage', args: [ 128 | window, 129 | ]).then((v) => v as Tabpage); 130 | } 131 | 132 | Future winGetNumber(Window window) { 133 | return call('nvim_win_get_number', args: [ 134 | window, 135 | ]).then((v) => v as int); 136 | } 137 | 138 | Future winIsValid(Window window) { 139 | return call('nvim_win_is_valid', args: [ 140 | window, 141 | ]).then((v) => v as bool); 142 | } 143 | 144 | Future winSetConfig(Window window, Map config) { 145 | return call('nvim_win_set_config', args: [ 146 | window, 147 | config, 148 | ]); 149 | } 150 | 151 | Future> winGetConfig(Window window) { 152 | return call('nvim_win_get_config', args: [ 153 | window, 154 | ]).then>((v) => v as Map); 155 | } 156 | 157 | Future winHide(Window window) { 158 | return call('nvim_win_hide', args: [ 159 | window, 160 | ]); 161 | } 162 | 163 | Future winClose(Window window, bool force) { 164 | return call('nvim_win_close', args: [ 165 | window, 166 | force, 167 | ]); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /lib/src/neovim.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:async'; 3 | import 'dart:isolate'; 4 | import 'dart:typed_data'; 5 | 6 | import 'package:msgpack_dart/msgpack_dart.dart' as mpack; 7 | import './ext_types.dart'; 8 | 9 | const REQUEST = 0; 10 | const RESPONSE = 1; 11 | const NOTIFICATION = 2; 12 | 13 | /// Parameters to function are Neovim instance, method, args 14 | typedef NvimHandler = void Function(Nvim, String, List); 15 | 16 | enum _NvimIsolateMsgType { 17 | Request, 18 | Response, 19 | Notification, 20 | } 21 | 22 | class _NvimIsolateMsg { 23 | final _NvimIsolateMsgType msgType; 24 | final dynamic data; 25 | final int? maybeResponseId; 26 | final String? maybeMethod; 27 | 28 | _NvimIsolateMsg( 29 | {required this.msgType, required this.data, this.maybeResponseId, this.maybeMethod}); 30 | } 31 | 32 | class Nvim { 33 | final Map> _waiting = {}; 34 | int _nextReqId = 0; 35 | 36 | final bool isChild; 37 | Isolate? _nvimIsolate; 38 | Stream? _nvimRxStream; 39 | SendPort? _nvimTxPort; 40 | 41 | Nvim._spawn(String nvimBinary, List commandArgs) : isChild = false; 42 | 43 | Nvim._child() : isChild = true; 44 | 45 | late NvimHandler _onNotify; 46 | late NvimHandler _onRequest; 47 | 48 | set onNotify(NvimHandler newHandler) => _onNotify = newHandler; 49 | set onRequest(NvimHandler newHandler) => _onRequest = newHandler; 50 | 51 | static void _listener(Nvim nvim, dynamic data) { 52 | final List deserialized = 53 | mpack.deserialize(data, extDecoder: ExtTypeDecoder()); 54 | switch (deserialized[0]) { 55 | case RESPONSE: 56 | if (deserialized[2] != null) { 57 | // Throw any errors from Neovim. 58 | throw deserialized[2][1]; 59 | } 60 | // TODO(smolck): Verify `deserialized[1]` is the id. 61 | nvim._waiting[deserialized[1]]!.complete(deserialized[3]); 62 | break; 63 | case REQUEST: 64 | nvim._onRequest(nvim, deserialized[2], deserialized[3]); 65 | break; 66 | case NOTIFICATION: 67 | nvim._onNotify(nvim, deserialized[1], deserialized[2]); 68 | break; 69 | } 70 | } 71 | 72 | static Future child( 73 | {NvimHandler? onNotify, NvimHandler? onRequest}) async { 74 | var nvim = Nvim._child(); 75 | if (onRequest != null) { 76 | nvim.onRequest = onRequest; 77 | } 78 | if (onNotify != null) { 79 | nvim.onNotify = onNotify; 80 | } 81 | 82 | // TODO(smolck): Use isolates for this too like with `Nvim.spawn`? 83 | stdin.listen((data) => _listener(nvim, data)); 84 | 85 | return nvim; 86 | } 87 | 88 | static void eventLoopIsolate(SendPort sendPort) async { 89 | final receivePort = ReceivePort(); 90 | final nvimProc = await Process.start('nvim', ['--embed']); 91 | 92 | // Pass any data sent from main thread to neovim process. 93 | receivePort.listen((data) { 94 | nvimProc.stdin.add(data); 95 | }); 96 | 97 | // First message gives a way for main isolate to communicate with this one. 98 | sendPort.send(receivePort.sendPort); 99 | 100 | // Event loop. 101 | await for (final data in nvimProc.stdout) { 102 | final List deserialized = mpack 103 | .deserialize(Uint8List.fromList(data), extDecoder: ExtTypeDecoder()); 104 | switch (deserialized[0]) { 105 | case RESPONSE: 106 | if (deserialized[2] != null) { 107 | // TODO(smolck) 108 | // Throw any errors from Neovim. 109 | throw deserialized[2][1]; 110 | } 111 | sendPort.send( 112 | _NvimIsolateMsg( 113 | msgType: _NvimIsolateMsgType.Response, 114 | data: deserialized[3], 115 | maybeResponseId: deserialized[1], 116 | ), 117 | ); 118 | break; 119 | case REQUEST: 120 | sendPort.send( 121 | _NvimIsolateMsg( 122 | msgType: _NvimIsolateMsgType.Request, 123 | maybeMethod: deserialized[2], 124 | data: deserialized[3], 125 | ), 126 | ); 127 | break; 128 | case NOTIFICATION: 129 | sendPort.send( 130 | _NvimIsolateMsg( 131 | msgType: _NvimIsolateMsgType.Notification, 132 | maybeMethod: deserialized[1], 133 | data: deserialized[2], 134 | ), 135 | ); 136 | break; 137 | } 138 | } 139 | } 140 | 141 | static Future spawn( 142 | {String nvimBinary = 'nvim', 143 | List commandArgs = const ['--embed'], 144 | NvimHandler? onNotify, 145 | NvimHandler? onRequest}) async { 146 | var nvim = Nvim._spawn(nvimBinary, commandArgs); 147 | if (onRequest != null) { 148 | nvim.onRequest = onRequest; 149 | } 150 | 151 | if (onNotify != null) { 152 | nvim.onNotify = onNotify; 153 | } 154 | 155 | final receivePort = ReceivePort(); 156 | nvim._nvimIsolate = 157 | await Isolate.spawn(eventLoopIsolate, receivePort.sendPort); 158 | nvim._nvimRxStream = receivePort.asBroadcastStream(); 159 | nvim._nvimTxPort = await nvim._nvimRxStream!.first; 160 | 161 | nvim._nvimRxStream!.listen((msg) { 162 | if (msg is SendPort) { 163 | nvim._nvimTxPort = msg; 164 | } else if (!(msg is _NvimIsolateMsg)) { 165 | throw 'This should not happen, maybe open an issue at https://github.com/smolck/dart-nvim-api/issues'; 166 | } else if (msg is _NvimIsolateMsg) { 167 | switch (msg.msgType) { 168 | case _NvimIsolateMsgType.Response: 169 | nvim._waiting[msg.maybeResponseId]?.complete(msg.data); 170 | break; 171 | case _NvimIsolateMsgType.Notification: 172 | nvim._onNotify(nvim, msg.maybeMethod!, msg.data); 173 | break; 174 | case _NvimIsolateMsgType.Request: 175 | nvim._onRequest(nvim, msg.maybeMethod!, msg.data); 176 | break; 177 | } 178 | } 179 | }); 180 | 181 | return nvim; 182 | } 183 | 184 | Future call(String method, {List? args}) { 185 | final reqId = _nextReqId; 186 | _nextReqId++; 187 | 188 | final cmd = [ 189 | 0, 190 | reqId, 191 | method, 192 | if (args != null) args else [], 193 | ]; 194 | 195 | if (isChild) { 196 | stdout.add(mpack.serialize(cmd, extEncoder: ExtTypeEncoder())); 197 | } else { 198 | _nvimTxPort!.send(mpack.serialize(cmd, extEncoder: ExtTypeEncoder())); 199 | } 200 | 201 | _waiting[reqId] = Completer(); 202 | return _waiting[reqId]!.future; 203 | } 204 | 205 | void kill() => _nvimIsolate?.kill(); 206 | } 207 | -------------------------------------------------------------------------------- /lib/src/ui_attach_options.dart: -------------------------------------------------------------------------------- 1 | class UiAttachOptions { 2 | final Map _opts; 3 | 4 | bool get rgb => _opts['rgb'] ?? false; 5 | set rgb(bool val) => _opts['rgb'] = val; 6 | 7 | bool get extPopupmenu => _opts['ext_popupmenu'] ?? false; 8 | set extPopupmenu(bool val) => _opts['ext_popupmenu'] = val; 9 | 10 | bool get extTabline => _opts['ext_tabline'] ?? false; 11 | set extTabline(bool val) => _opts['ext_tabline'] = val; 12 | 13 | bool get extCmdline => _opts['ext_cmdline'] ?? false; 14 | set extCmdline(bool val) => _opts['ext_cmdline'] = val; 15 | 16 | bool get extWildmenu => _opts['ext_wildmenu'] ?? false; 17 | set extWildmenu(bool val) => _opts['ext_wildmenu'] = val; 18 | 19 | bool get extLinegrid => _opts['ext_linegrid'] ?? false; 20 | set extLinegrid(bool val) => _opts['ext_linegrid'] = val; 21 | 22 | bool get extMultigrid => _opts['ext_multigrid'] ?? false; 23 | set extMultigrid(bool val) => _opts['ext_multigrid'] = val; 24 | 25 | bool get extHlstate => _opts['ext_hlstate'] ?? false; 26 | set extHlstate(bool val) => _opts['ext_hlstate'] = val; 27 | 28 | bool get extTermColors => _opts['ext_termcolors'] ?? false; 29 | set extTermColors(bool val) => _opts['ext_termcolors'] = val; 30 | 31 | bool get extMessages => _opts['ext_messages'] ?? false; 32 | set extMessages(bool val) => _opts['ext_messages'] = val; 33 | 34 | UiAttachOptions() : _opts = {}; 35 | 36 | Map asMap() => _opts; 37 | } 38 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_nvim_api 2 | description: A Neovim API for Dart allowing for communication between a Neovim instance and a Dart program. Can be used for creating Neovim plugins, Neovim frontend GUIs, etc. 3 | version: 0.3.0 4 | homepage: https://github.com/smolck/dart-nvim-api 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | 9 | dependencies: 10 | msgpack_dart: ^1.0.0 11 | meta: ^1.1.7 12 | 13 | dev_dependencies: 14 | dart_style: 15 | code_builder: 16 | test: 17 | -------------------------------------------------------------------------------- /test/neovim_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dart_nvim_api/dart_nvim_api.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() async { 5 | var nvim = await Nvim.spawn(); 6 | 7 | test('evaluating 1 + 1 should equal 2', () async { 8 | assert(await nvim.eval('1 + 1') == 2); 9 | }); 10 | 11 | test('buffers work', () async { 12 | var buf = await nvim.createBuf(true, false); 13 | 14 | assert((await nvim.bufGetLines(buf, 0, -1, false)).length == 1); 15 | assert((await nvim.bufGetName(buf)).isEmpty); 16 | 17 | var nameWithoutPath = 'this is a name'; 18 | await nvim.bufSetName(buf, nameWithoutPath); 19 | assert((await nvim.bufGetName(buf)).contains(nameWithoutPath)); 20 | }); 21 | 22 | test('windows work', () async { 23 | var winBuf = await nvim.createBuf(true, false); 24 | var win = await nvim.openWin(winBuf, true, { 25 | 'relative': 'editor', 26 | 'width': 12, 27 | 'height': 10, 28 | 'row': 10, 29 | 'col': 10 30 | }); 31 | 32 | assert(await nvim.winGetWidth(win) == 12); 33 | assert(await nvim.winGetHeight(win) == 10); 34 | }); 35 | 36 | // TODO(smolck): Test tabs? 37 | 38 | // TODO(smolck): Should maybe kill Neovim but not quite sure how to do 39 | // that with the async main function. 40 | // nvim.kill(); 41 | } 42 | -------------------------------------------------------------------------------- /tool/src/api_gen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:code_builder/code_builder.dart'; 5 | import 'package:dart_style/dart_style.dart'; 6 | 7 | void main() { 8 | Map apiInfo = 9 | json.decode(File('tool/src/api_info.json').readAsStringSync()); 10 | 11 | var methods = 12 | apiInfo['functions'].where((x) => x['deprecated_since'] == null); 13 | var bufMethods = []; 14 | var winMethods = []; 15 | var tabpageMethods = []; 16 | var otherMethods = []; 17 | 18 | for (var method in methods) { 19 | if (method['name'].contains('buf')) { 20 | bufMethods.add(method); 21 | } else if (method['name'].contains('win')) { 22 | winMethods.add(method); 23 | } else if (method['name'].contains('tabpage')) { 24 | tabpageMethods.add(method); 25 | } else if (method['name'].contains('nvim_')) { 26 | otherMethods.add(method); 27 | } 28 | } 29 | 30 | Library library(dynamic methods) => Library( 31 | (b) => b.body.addAll(methods.map(infoToMethod).toList().cast())); 32 | 33 | final emitter = DartEmitter(); 34 | final formatter = DartFormatter(); 35 | 36 | final buf = formatter.format(wrapGeneratedCode( 37 | 'NvimBufferApi', '${library(bufMethods).accept(emitter)}')); 38 | final win = formatter.format(wrapGeneratedCode( 39 | 'NvimWindowApi', '${library(winMethods).accept(emitter)}')); 40 | final tabpage = formatter.format(wrapGeneratedCode( 41 | 'NvimTabpageApi', '${library(tabpageMethods).accept(emitter)}')); 42 | final nvim = formatter.format( 43 | wrapGeneratedCode('NvimApi', '${library(otherMethods).accept(emitter)}')); 44 | 45 | Directory('lib/src/gen') 46 | ..deleteSync(recursive: true) 47 | ..createSync(); 48 | 49 | // TODO(smolck): Make these files contain extensions on each specific class. 50 | File('lib/src/gen/nvim.g.dart') 51 | ..createSync() 52 | ..writeAsStringSync(nvim); 53 | File('lib/src/gen/buffer.g.dart') 54 | ..createSync() 55 | ..writeAsStringSync(buf); 56 | File('lib/src/gen/window.g.dart') 57 | ..createSync() 58 | ..writeAsStringSync(win); 59 | File('lib/src/gen/tabpage.g.dart') 60 | ..createSync() 61 | ..writeAsStringSync(tabpage); 62 | } 63 | 64 | String wrapGeneratedCode(String extensionName, String code) { 65 | return ''' 66 | import '../neovim.dart'; 67 | import '../ext_types.dart'; 68 | 69 | ${/* TODO(smolck): This is just . . . bad */ 70 | extensionName == 'NvimApi' ? '' : 'import \'../ext_types.dart\';'} 71 | 72 | extension ${extensionName} on Nvim { 73 | ${code} 74 | } 75 | '''; 76 | } 77 | 78 | String convertInfoName(String name) { 79 | var parts = name.split('_'); 80 | if (parts[0] == 'nvim' || parts[0] == 'vim') { 81 | parts = parts.sublist(1); 82 | } 83 | 84 | parts = [ 85 | parts[0], 86 | ...parts 87 | .sublist(1) 88 | .map((String x) => '${x[0].toUpperCase()}${x.substring(1)}') 89 | ]; 90 | 91 | return parts.join(); 92 | } 93 | 94 | Method infoToMethod(dynamic info) { 95 | final typeStr = toDartType(info['return_type']); 96 | final returnType = TypeReference((b) => b.symbol = 'Future<$typeStr>'); 97 | 98 | var typeForCastIfList = typeStr.replaceFirst('List<', ''); 99 | // Remove extra trailing '>' 100 | typeForCastIfList = typeForCastIfList.replaceRange( 101 | typeForCastIfList.length - 1, typeForCastIfList.length, ''); 102 | final cast = typeStr.contains('List') 103 | ? '(v as List).cast<$typeForCastIfList>()' 104 | : 'v as $typeStr'; 105 | 106 | return Method((b) => b 107 | ..body = Block.of([ 108 | Code("return call('${info['name']}', args: ["), 109 | ...info['parameters'].map((x) => Code('${x[1]}, ')), 110 | Code( 111 | '])${typeStr == 'void' || typeStr == 'dynamic' ? ';' : '.then<$typeStr>((v) => $cast);'}') 112 | ]) 113 | ..name = convertInfoName(info['name']) 114 | ..requiredParameters.addAll(info['parameters'] 115 | .map((x) => Parameter((b) => b 116 | ..name = x[1] 117 | ..type = TypeReference((b) => b..symbol = toDartType(x[0])))) 118 | .toList() 119 | .cast()) 120 | ..returns = returnType); 121 | } 122 | 123 | String toDartType(dynamic x) { 124 | var typeIndex = { 125 | 'Array': 'List', 126 | 'ArrayOf(Integer, 2)': 'List', 127 | 'void': 'void', 128 | 'Integer': 'int', 129 | 'Boolean': 'bool', 130 | 'Float': 'double', 131 | 'String': 'String', 132 | 'Object': 'dynamic', 133 | 'Dictionary': 'Map', 134 | 'Window': 'Window', 135 | 'Tabpage': 'Tabpage', 136 | 'Buffer': 'Buffer', 137 | 'LuaRef': 'LuaRef' 138 | }; 139 | 140 | var typeRef = typeIndex[x]; 141 | if (typeRef != null) { 142 | return typeRef; 143 | } 144 | 145 | var regex = RegExp('ArrayOf\\(\\s*(\\w+)\\s*\\)'); 146 | if (regex.hasMatch(x)) { 147 | var match = regex.firstMatch(x)!.group(1); 148 | return 'List<${typeIndex[match]}>'; 149 | } 150 | 151 | throw 'Bad things happened: $x'; 152 | } 153 | -------------------------------------------------------------------------------- /tool/src/api_info.json: -------------------------------------------------------------------------------- 1 | {"types":{"Window":{"id":1,"prefix":"nvim_win_"},"Buffer":{"id":0,"prefix":"nvim_buf_"},"Tabpage":{"id":2,"prefix":"nvim_tabpage_"}},"ui_options":["rgb","ext_cmdline","ext_popupmenu","ext_tabline","ext_wildmenu","ext_messages","ext_linegrid","ext_multigrid","ext_hlstate","ext_termcolors"],"error_types":{"Exception":{"id":0},"Validation":{"id":1}},"functions":[{"method":true,"since":1,"parameters":[["Buffer","buffer"]],"return_type":"Integer","name":"nvim_buf_line_count"},{"method":true,"since":4,"parameters":[["Buffer","buffer"],["Boolean","send_buffer"],["Dictionary","opts"]],"return_type":"Boolean","name":"nvim_buf_attach"},{"method":true,"since":4,"parameters":[["Buffer","buffer"]],"return_type":"Boolean","name":"nvim_buf_detach"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","strict_indexing"]],"return_type":"ArrayOf(String)","name":"nvim_buf_get_lines"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","strict_indexing"],["ArrayOf(String)","replacement"]],"return_type":"void","name":"nvim_buf_set_lines"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Integer","start_row"],["Integer","start_col"],["Integer","end_row"],["Integer","end_col"],["ArrayOf(String)","replacement"]],"return_type":"void","name":"nvim_buf_set_text"},{"method":true,"since":5,"parameters":[["Buffer","buffer"],["Integer","index"]],"return_type":"Integer","name":"nvim_buf_get_offset"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"Object","name":"nvim_buf_get_var"},{"method":true,"since":2,"parameters":[["Buffer","buffer"]],"return_type":"Integer","name":"nvim_buf_get_changedtick"},{"method":true,"since":3,"parameters":[["Buffer","buffer"],["String","mode"]],"return_type":"ArrayOf(Dictionary)","name":"nvim_buf_get_keymap"},{"method":true,"since":6,"parameters":[["Buffer","buffer"],["String","mode"],["String","lhs"],["String","rhs"],["Dictionary","opts"]],"return_type":"void","name":"nvim_buf_set_keymap"},{"method":true,"since":6,"parameters":[["Buffer","buffer"],["String","mode"],["String","lhs"]],"return_type":"void","name":"nvim_buf_del_keymap"},{"method":true,"since":4,"parameters":[["Buffer","buffer"],["Dictionary","opts"]],"return_type":"Dictionary","name":"nvim_buf_get_commands"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"],["Object","value"]],"return_type":"void","name":"nvim_buf_set_var"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"void","name":"nvim_buf_del_var"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"Object","name":"nvim_buf_get_option"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"],["Object","value"]],"return_type":"void","name":"nvim_buf_set_option"},{"method":true,"since":1,"parameters":[["Buffer","buffer"]],"return_type":"String","name":"nvim_buf_get_name"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"void","name":"nvim_buf_set_name"},{"method":true,"since":5,"parameters":[["Buffer","buffer"]],"return_type":"Boolean","name":"nvim_buf_is_loaded"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Dictionary","opts"]],"return_type":"void","name":"nvim_buf_delete"},{"method":true,"since":1,"parameters":[["Buffer","buffer"]],"return_type":"Boolean","name":"nvim_buf_is_valid"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"ArrayOf(Integer, 2)","name":"nvim_buf_get_mark"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","id"],["Dictionary","opts"]],"return_type":"ArrayOf(Integer)","name":"nvim_buf_get_extmark_by_id"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Object","start"],["Object","end"],["Dictionary","opts"]],"return_type":"Array","name":"nvim_buf_get_extmarks"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","line"],["Integer","col"],["Dictionary","opts"]],"return_type":"Integer","name":"nvim_buf_set_extmark"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","id"]],"return_type":"Boolean","name":"nvim_buf_del_extmark"},{"method":true,"since":1,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["String","hl_group"],["Integer","line"],["Integer","col_start"],["Integer","col_end"]],"return_type":"Integer","name":"nvim_buf_add_highlight"},{"method":true,"since":5,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","line_start"],["Integer","line_end"]],"return_type":"void","name":"nvim_buf_clear_namespace"},{"method":true,"since":5,"parameters":[["Buffer","buffer"],["Integer","src_id"],["Integer","line"],["Array","chunks"],["Dictionary","opts"]],"return_type":"Integer","name":"nvim_buf_set_virtual_text"},{"method":true,"since":7,"parameters":[["Buffer","buffer"],["LuaRef","fun"]],"return_type":"Object","name":"nvim_buf_call"},{"method":false,"deprecated_since":7,"parameters":[["String","command"]],"return_type":"String","name":"nvim_command_output","since":1},{"method":false,"deprecated_since":7,"parameters":[["String","code"],["Array","args"]],"return_type":"Object","name":"nvim_execute_lua","since":3},{"method":true,"deprecated_since":2,"parameters":[["Buffer","buffer"]],"return_type":"Integer","name":"nvim_buf_get_number","since":1},{"method":true,"deprecated_since":7,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","line_start"],["Integer","line_end"]],"return_type":"void","name":"nvim_buf_clear_highlight","since":1},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","lnum"],["ArrayOf(String)","lines"]],"return_type":"void","name":"buffer_insert","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","index"]],"return_type":"String","name":"buffer_get_line","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","index"],["String","line"]],"return_type":"void","name":"buffer_set_line","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","index"]],"return_type":"void","name":"buffer_del_line","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","include_start"],["Boolean","include_end"]],"return_type":"ArrayOf(String)","name":"buffer_get_line_slice","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","include_start"],["Boolean","include_end"],["ArrayOf(String)","replacement"]],"return_type":"void","name":"buffer_set_line_slice","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"],["Object","value"]],"return_type":"Object","name":"buffer_set_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"Object","name":"buffer_del_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["Window","window"],["String","name"],["Object","value"]],"return_type":"Object","name":"window_set_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"Object","name":"window_del_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["Tabpage","tabpage"],["String","name"],["Object","value"]],"return_type":"Object","name":"tabpage_set_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["Tabpage","tabpage"],["String","name"]],"return_type":"Object","name":"tabpage_del_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"],["Object","value"]],"return_type":"Object","name":"vim_set_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"]],"return_type":"Object","name":"vim_del_var","since":0},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"ArrayOf(Window)","name":"nvim_tabpage_list_wins"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"],["String","name"]],"return_type":"Object","name":"nvim_tabpage_get_var"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"],["String","name"],["Object","value"]],"return_type":"void","name":"nvim_tabpage_set_var"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"],["String","name"]],"return_type":"void","name":"nvim_tabpage_del_var"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"Window","name":"nvim_tabpage_get_win"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"Integer","name":"nvim_tabpage_get_number"},{"method":true,"since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"Boolean","name":"nvim_tabpage_is_valid"},{"method":false,"since":1,"parameters":[["Integer","width"],["Integer","height"],["Dictionary","options"]],"return_type":"void","name":"nvim_ui_attach"},{"method":false,"deprecated_since":1,"parameters":[["Integer","width"],["Integer","height"],["Boolean","enable_rgb"]],"return_type":"void","name":"ui_attach","since":0},{"method":false,"since":1,"parameters":[],"return_type":"void","name":"nvim_ui_detach"},{"method":false,"since":1,"parameters":[["Integer","width"],["Integer","height"]],"return_type":"void","name":"nvim_ui_try_resize"},{"method":false,"since":1,"parameters":[["String","name"],["Object","value"]],"return_type":"void","name":"nvim_ui_set_option"},{"method":false,"since":6,"parameters":[["Integer","grid"],["Integer","width"],["Integer","height"]],"return_type":"void","name":"nvim_ui_try_resize_grid"},{"method":false,"since":6,"parameters":[["Integer","height"]],"return_type":"void","name":"nvim_ui_pum_set_height"},{"method":false,"since":7,"parameters":[["Float","width"],["Float","height"],["Float","row"],["Float","col"]],"return_type":"void","name":"nvim_ui_pum_set_bounds"},{"method":false,"since":7,"parameters":[["String","src"],["Boolean","output"]],"return_type":"String","name":"nvim_exec"},{"method":false,"since":1,"parameters":[["String","command"]],"return_type":"void","name":"nvim_command"},{"method":false,"since":3,"parameters":[["String","name"],["Boolean","rgb"]],"return_type":"Dictionary","name":"nvim_get_hl_by_name"},{"method":false,"since":3,"parameters":[["Integer","hl_id"],["Boolean","rgb"]],"return_type":"Dictionary","name":"nvim_get_hl_by_id"},{"method":false,"since":7,"parameters":[["String","name"]],"return_type":"Integer","name":"nvim_get_hl_id_by_name"},{"method":false,"since":7,"parameters":[["Integer","ns_id"],["String","name"],["Dictionary","val"]],"return_type":"void","name":"nvim_set_hl"},{"method":false,"since":1,"parameters":[["String","keys"],["String","mode"],["Boolean","escape_csi"]],"return_type":"void","name":"nvim_feedkeys"},{"method":false,"since":1,"parameters":[["String","keys"]],"return_type":"Integer","name":"nvim_input"},{"method":false,"since":6,"parameters":[["String","button"],["String","action"],["String","modifier"],["Integer","grid"],["Integer","row"],["Integer","col"]],"return_type":"void","name":"nvim_input_mouse"},{"method":false,"since":1,"parameters":[["String","str"],["Boolean","from_part"],["Boolean","do_lt"],["Boolean","special"]],"return_type":"String","name":"nvim_replace_termcodes"},{"method":false,"since":1,"parameters":[["String","expr"]],"return_type":"Object","name":"nvim_eval"},{"method":false,"since":7,"parameters":[["String","code"],["Array","args"]],"return_type":"Object","name":"nvim_exec_lua"},{"method":false,"since":7,"parameters":[["String","msg"],["Integer","log_level"],["Dictionary","opts"]],"return_type":"Object","name":"nvim_notify"},{"method":false,"since":1,"parameters":[["String","fn"],["Array","args"]],"return_type":"Object","name":"nvim_call_function"},{"method":false,"since":4,"parameters":[["Object","dict"],["String","fn"],["Array","args"]],"return_type":"Object","name":"nvim_call_dict_function"},{"method":false,"since":1,"parameters":[["String","text"]],"return_type":"Integer","name":"nvim_strwidth"},{"method":false,"since":1,"parameters":[],"return_type":"ArrayOf(String)","name":"nvim_list_runtime_paths"},{"method":false,"since":7,"parameters":[["String","name"],["Boolean","all"]],"return_type":"ArrayOf(String)","name":"nvim_get_runtime_file"},{"method":false,"since":1,"parameters":[["String","dir"]],"return_type":"void","name":"nvim_set_current_dir"},{"method":false,"since":1,"parameters":[],"return_type":"String","name":"nvim_get_current_line"},{"method":false,"since":1,"parameters":[["String","line"]],"return_type":"void","name":"nvim_set_current_line"},{"method":false,"since":1,"parameters":[],"return_type":"void","name":"nvim_del_current_line"},{"method":false,"since":1,"parameters":[["String","name"]],"return_type":"Object","name":"nvim_get_var"},{"method":false,"since":1,"parameters":[["String","name"],["Object","value"]],"return_type":"void","name":"nvim_set_var"},{"method":false,"since":1,"parameters":[["String","name"]],"return_type":"void","name":"nvim_del_var"},{"method":false,"since":1,"parameters":[["String","name"]],"return_type":"Object","name":"nvim_get_vvar"},{"method":false,"since":6,"parameters":[["String","name"],["Object","value"]],"return_type":"void","name":"nvim_set_vvar"},{"method":false,"since":1,"parameters":[["String","name"]],"return_type":"Object","name":"nvim_get_option"},{"method":false,"since":7,"parameters":[],"return_type":"Dictionary","name":"nvim_get_all_options_info"},{"method":false,"since":7,"parameters":[["String","name"]],"return_type":"Dictionary","name":"nvim_get_option_info"},{"method":false,"since":1,"parameters":[["String","name"],["Object","value"]],"return_type":"void","name":"nvim_set_option"},{"method":false,"since":7,"parameters":[["Array","chunks"],["Boolean","history"],["Dictionary","opts"]],"return_type":"void","name":"nvim_echo"},{"method":false,"since":1,"parameters":[["String","str"]],"return_type":"void","name":"nvim_out_write"},{"method":false,"since":1,"parameters":[["String","str"]],"return_type":"void","name":"nvim_err_write"},{"method":false,"since":1,"parameters":[["String","str"]],"return_type":"void","name":"nvim_err_writeln"},{"method":false,"since":1,"parameters":[],"return_type":"ArrayOf(Buffer)","name":"nvim_list_bufs"},{"method":false,"since":1,"parameters":[],"return_type":"Buffer","name":"nvim_get_current_buf"},{"method":false,"since":1,"parameters":[["Buffer","buffer"]],"return_type":"void","name":"nvim_set_current_buf"},{"method":false,"since":1,"parameters":[],"return_type":"ArrayOf(Window)","name":"nvim_list_wins"},{"method":false,"since":1,"parameters":[],"return_type":"Window","name":"nvim_get_current_win"},{"method":false,"since":1,"parameters":[["Window","window"]],"return_type":"void","name":"nvim_set_current_win"},{"method":false,"since":6,"parameters":[["Boolean","listed"],["Boolean","scratch"]],"return_type":"Buffer","name":"nvim_create_buf"},{"method":false,"since":7,"parameters":[["Buffer","buffer"],["Dictionary","opts"]],"return_type":"Integer","name":"nvim_open_term"},{"method":false,"since":7,"parameters":[["Integer","chan"],["String","data"]],"return_type":"void","name":"nvim_chan_send"},{"method":false,"since":6,"parameters":[["Buffer","buffer"],["Boolean","enter"],["Dictionary","config"]],"return_type":"Window","name":"nvim_open_win"},{"method":false,"since":1,"parameters":[],"return_type":"ArrayOf(Tabpage)","name":"nvim_list_tabpages"},{"method":false,"since":1,"parameters":[],"return_type":"Tabpage","name":"nvim_get_current_tabpage"},{"method":false,"since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"void","name":"nvim_set_current_tabpage"},{"method":false,"since":5,"parameters":[["String","name"]],"return_type":"Integer","name":"nvim_create_namespace"},{"method":false,"since":5,"parameters":[],"return_type":"Dictionary","name":"nvim_get_namespaces"},{"method":false,"since":6,"parameters":[["String","data"],["Boolean","crlf"],["Integer","phase"]],"return_type":"Boolean","name":"nvim_paste"},{"method":false,"since":6,"parameters":[["ArrayOf(String)","lines"],["String","type"],["Boolean","after"],["Boolean","follow"]],"return_type":"void","name":"nvim_put"},{"method":false,"since":1,"parameters":[["String","event"]],"return_type":"void","name":"nvim_subscribe"},{"method":false,"since":1,"parameters":[["String","event"]],"return_type":"void","name":"nvim_unsubscribe"},{"method":false,"since":1,"parameters":[["String","name"]],"return_type":"Integer","name":"nvim_get_color_by_name"},{"method":false,"since":1,"parameters":[],"return_type":"Dictionary","name":"nvim_get_color_map"},{"method":false,"since":6,"parameters":[["Dictionary","opts"]],"return_type":"Dictionary","name":"nvim_get_context"},{"method":false,"since":6,"parameters":[["Dictionary","dict"]],"return_type":"Object","name":"nvim_load_context"},{"method":false,"since":2,"parameters":[],"return_type":"Dictionary","name":"nvim_get_mode"},{"method":false,"since":3,"parameters":[["String","mode"]],"return_type":"ArrayOf(Dictionary)","name":"nvim_get_keymap"},{"method":false,"since":6,"parameters":[["String","mode"],["String","lhs"],["String","rhs"],["Dictionary","opts"]],"return_type":"void","name":"nvim_set_keymap"},{"method":false,"since":6,"parameters":[["String","mode"],["String","lhs"]],"return_type":"void","name":"nvim_del_keymap"},{"method":false,"since":4,"parameters":[["Dictionary","opts"]],"return_type":"Dictionary","name":"nvim_get_commands"},{"method":false,"since":1,"parameters":[],"return_type":"Array","name":"nvim_get_api_info"},{"method":false,"since":4,"parameters":[["String","name"],["Dictionary","version"],["String","type"],["Dictionary","methods"],["Dictionary","attributes"]],"return_type":"void","name":"nvim_set_client_info"},{"method":false,"since":4,"parameters":[["Integer","chan"]],"return_type":"Dictionary","name":"nvim_get_chan_info"},{"method":false,"since":4,"parameters":[],"return_type":"Array","name":"nvim_list_chans"},{"method":false,"since":1,"parameters":[["Array","calls"]],"return_type":"Array","name":"nvim_call_atomic"},{"method":false,"since":4,"parameters":[["String","expr"],["String","flags"],["Boolean","highlight"]],"return_type":"Dictionary","name":"nvim_parse_expression"},{"method":false,"since":4,"parameters":[],"return_type":"Array","name":"nvim_list_uis"},{"method":false,"since":4,"parameters":[["Integer","pid"]],"return_type":"Array","name":"nvim_get_proc_children"},{"method":false,"since":4,"parameters":[["Integer","pid"]],"return_type":"Object","name":"nvim_get_proc"},{"method":false,"since":6,"parameters":[["Integer","item"],["Boolean","insert"],["Boolean","finish"],["Dictionary","opts"]],"return_type":"void","name":"nvim_select_popupmenu_item"},{"method":false,"since":7,"parameters":[["Integer","ns_id"],["Dictionary","opts"]],"return_type":"void","name":"nvim_set_decoration_provider"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Buffer","name":"nvim_win_get_buf"},{"method":true,"since":5,"parameters":[["Window","window"],["Buffer","buffer"]],"return_type":"void","name":"nvim_win_set_buf"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"ArrayOf(Integer, 2)","name":"nvim_win_get_cursor"},{"method":true,"since":1,"parameters":[["Window","window"],["ArrayOf(Integer, 2)","pos"]],"return_type":"void","name":"nvim_win_set_cursor"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Integer","name":"nvim_win_get_height"},{"method":true,"since":1,"parameters":[["Window","window"],["Integer","height"]],"return_type":"void","name":"nvim_win_set_height"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Integer","name":"nvim_win_get_width"},{"method":true,"since":1,"parameters":[["Window","window"],["Integer","width"]],"return_type":"void","name":"nvim_win_set_width"},{"method":true,"since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"Object","name":"nvim_win_get_var"},{"method":true,"since":1,"parameters":[["Window","window"],["String","name"],["Object","value"]],"return_type":"void","name":"nvim_win_set_var"},{"method":true,"since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"void","name":"nvim_win_del_var"},{"method":true,"since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"Object","name":"nvim_win_get_option"},{"method":true,"since":1,"parameters":[["Window","window"],["String","name"],["Object","value"]],"return_type":"void","name":"nvim_win_set_option"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"ArrayOf(Integer, 2)","name":"nvim_win_get_position"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Tabpage","name":"nvim_win_get_tabpage"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Integer","name":"nvim_win_get_number"},{"method":true,"since":1,"parameters":[["Window","window"]],"return_type":"Boolean","name":"nvim_win_is_valid"},{"method":true,"since":6,"parameters":[["Window","window"],["Dictionary","config"]],"return_type":"void","name":"nvim_win_set_config"},{"method":true,"since":6,"parameters":[["Window","window"]],"return_type":"Dictionary","name":"nvim_win_get_config"},{"method":true,"since":7,"parameters":[["Window","window"]],"return_type":"void","name":"nvim_win_hide"},{"method":true,"since":6,"parameters":[["Window","window"],["Boolean","force"]],"return_type":"void","name":"nvim_win_close"},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"]],"return_type":"Integer","name":"buffer_line_count","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","strict_indexing"]],"return_type":"ArrayOf(String)","name":"buffer_get_lines","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","start"],["Integer","end"],["Boolean","strict_indexing"],["ArrayOf(String)","replacement"]],"return_type":"void","name":"buffer_set_lines","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"Object","name":"buffer_get_var","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"Object","name":"buffer_get_option","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"],["Object","value"]],"return_type":"void","name":"buffer_set_option","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"]],"return_type":"String","name":"buffer_get_name","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"void","name":"buffer_set_name","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"]],"return_type":"Boolean","name":"buffer_is_valid","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["String","name"]],"return_type":"ArrayOf(Integer, 2)","name":"buffer_get_mark","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["String","hl_group"],["Integer","line"],["Integer","col_start"],["Integer","col_end"]],"return_type":"Integer","name":"buffer_add_highlight","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","command"]],"return_type":"String","name":"vim_command_output","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"]],"return_type":"Integer","name":"buffer_get_number","since":0},{"method":true,"deprecated_since":1,"parameters":[["Buffer","buffer"],["Integer","ns_id"],["Integer","line_start"],["Integer","line_end"]],"return_type":"void","name":"buffer_clear_highlight","since":0},{"method":true,"deprecated_since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"ArrayOf(Window)","name":"tabpage_get_windows","since":0},{"method":true,"deprecated_since":1,"parameters":[["Tabpage","tabpage"],["String","name"]],"return_type":"Object","name":"tabpage_get_var","since":0},{"method":true,"deprecated_since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"Window","name":"tabpage_get_window","since":0},{"method":true,"deprecated_since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"Boolean","name":"tabpage_is_valid","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"void","name":"ui_detach","since":0},{"method":false,"deprecated_since":1,"parameters":[["Integer","width"],["Integer","height"]],"return_type":"Object","name":"ui_try_resize","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","command"]],"return_type":"void","name":"vim_command","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","keys"],["String","mode"],["Boolean","escape_csi"]],"return_type":"void","name":"vim_feedkeys","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","keys"]],"return_type":"Integer","name":"vim_input","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","str"],["Boolean","from_part"],["Boolean","do_lt"],["Boolean","special"]],"return_type":"String","name":"vim_replace_termcodes","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","expr"]],"return_type":"Object","name":"vim_eval","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","fn"],["Array","args"]],"return_type":"Object","name":"vim_call_function","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","text"]],"return_type":"Integer","name":"vim_strwidth","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"ArrayOf(String)","name":"vim_list_runtime_paths","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","dir"]],"return_type":"void","name":"vim_change_directory","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"String","name":"vim_get_current_line","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","line"]],"return_type":"void","name":"vim_set_current_line","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"void","name":"vim_del_current_line","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"]],"return_type":"Object","name":"vim_get_var","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"]],"return_type":"Object","name":"vim_get_vvar","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"]],"return_type":"Object","name":"vim_get_option","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"],["Object","value"]],"return_type":"void","name":"vim_set_option","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","str"]],"return_type":"void","name":"vim_out_write","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","str"]],"return_type":"void","name":"vim_err_write","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","str"]],"return_type":"void","name":"vim_report_error","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"ArrayOf(Buffer)","name":"vim_get_buffers","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"Buffer","name":"vim_get_current_buffer","since":0},{"method":false,"deprecated_since":1,"parameters":[["Buffer","buffer"]],"return_type":"void","name":"vim_set_current_buffer","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"ArrayOf(Window)","name":"vim_get_windows","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"Window","name":"vim_get_current_window","since":0},{"method":false,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"void","name":"vim_set_current_window","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"ArrayOf(Tabpage)","name":"vim_get_tabpages","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"Tabpage","name":"vim_get_current_tabpage","since":0},{"method":false,"deprecated_since":1,"parameters":[["Tabpage","tabpage"]],"return_type":"void","name":"vim_set_current_tabpage","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","event"]],"return_type":"void","name":"vim_subscribe","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","event"]],"return_type":"void","name":"vim_unsubscribe","since":0},{"method":false,"deprecated_since":1,"parameters":[["String","name"]],"return_type":"Integer","name":"vim_name_to_color","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"Dictionary","name":"vim_get_color_map","since":0},{"method":false,"deprecated_since":1,"parameters":[],"return_type":"Array","name":"vim_get_api_info","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"Buffer","name":"window_get_buffer","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"ArrayOf(Integer, 2)","name":"window_get_cursor","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["ArrayOf(Integer, 2)","pos"]],"return_type":"void","name":"window_set_cursor","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"Integer","name":"window_get_height","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["Integer","height"]],"return_type":"void","name":"window_set_height","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"Integer","name":"window_get_width","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["Integer","width"]],"return_type":"void","name":"window_set_width","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"Object","name":"window_get_var","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["String","name"]],"return_type":"Object","name":"window_get_option","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"],["String","name"],["Object","value"]],"return_type":"void","name":"window_set_option","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"ArrayOf(Integer, 2)","name":"window_get_position","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"Tabpage","name":"window_get_tabpage","since":0},{"method":true,"deprecated_since":1,"parameters":[["Window","window"]],"return_type":"Boolean","name":"window_is_valid","since":0}],"ui_events":[{"since":3,"name":"mode_info_set","parameters":[["Boolean","enabled"],["Array","cursor_styles"]]},{"since":3,"name":"update_menu","parameters":[]},{"since":3,"name":"busy_start","parameters":[]},{"since":3,"name":"busy_stop","parameters":[]},{"since":3,"name":"mouse_on","parameters":[]},{"since":3,"name":"mouse_off","parameters":[]},{"since":3,"name":"mode_change","parameters":[["String","mode"],["Integer","mode_idx"]]},{"since":3,"name":"bell","parameters":[]},{"since":3,"name":"visual_bell","parameters":[]},{"since":3,"name":"flush","parameters":[]},{"since":3,"name":"suspend","parameters":[]},{"since":3,"name":"set_title","parameters":[["String","title"]]},{"since":3,"name":"set_icon","parameters":[["String","icon"]]},{"since":7,"name":"screenshot","parameters":[["String","path"]]},{"since":4,"name":"option_set","parameters":[["String","name"],["Object","value"]]},{"since":3,"name":"update_fg","parameters":[["Integer","fg"]]},{"since":3,"name":"update_bg","parameters":[["Integer","bg"]]},{"since":3,"name":"update_sp","parameters":[["Integer","sp"]]},{"since":3,"name":"resize","parameters":[["Integer","width"],["Integer","height"]]},{"since":3,"name":"clear","parameters":[]},{"since":3,"name":"eol_clear","parameters":[]},{"since":3,"name":"cursor_goto","parameters":[["Integer","row"],["Integer","col"]]},{"since":3,"name":"highlight_set","parameters":[["Dictionary","attrs"]]},{"since":3,"name":"put","parameters":[["String","str"]]},{"since":3,"name":"set_scroll_region","parameters":[["Integer","top"],["Integer","bot"],["Integer","left"],["Integer","right"]]},{"since":3,"name":"scroll","parameters":[["Integer","count"]]},{"since":4,"name":"default_colors_set","parameters":[["Integer","rgb_fg"],["Integer","rgb_bg"],["Integer","rgb_sp"],["Integer","cterm_fg"],["Integer","cterm_bg"]]},{"since":5,"name":"hl_attr_define","parameters":[["Integer","id"],["Dictionary","rgb_attrs"],["Dictionary","cterm_attrs"],["Array","info"]]},{"since":6,"name":"hl_group_set","parameters":[["String","name"],["Integer","id"]]},{"since":5,"name":"grid_resize","parameters":[["Integer","grid"],["Integer","width"],["Integer","height"]]},{"since":5,"name":"grid_clear","parameters":[["Integer","grid"]]},{"since":5,"name":"grid_cursor_goto","parameters":[["Integer","grid"],["Integer","row"],["Integer","col"]]},{"since":5,"name":"grid_line","parameters":[["Integer","grid"],["Integer","row"],["Integer","col_start"],["Array","data"]]},{"since":5,"name":"grid_scroll","parameters":[["Integer","grid"],["Integer","top"],["Integer","bot"],["Integer","left"],["Integer","right"],["Integer","rows"],["Integer","cols"]]},{"since":6,"name":"grid_destroy","parameters":[["Integer","grid"]]},{"since":6,"name":"win_pos","parameters":[["Integer","grid"],["Window","win"],["Integer","startrow"],["Integer","startcol"],["Integer","width"],["Integer","height"]]},{"since":6,"name":"win_float_pos","parameters":[["Integer","grid"],["Window","win"],["String","anchor"],["Integer","anchor_grid"],["Float","anchor_row"],["Float","anchor_col"],["Boolean","focusable"]]},{"since":6,"name":"win_external_pos","parameters":[["Integer","grid"],["Window","win"]]},{"since":6,"name":"win_hide","parameters":[["Integer","grid"]]},{"since":6,"name":"win_close","parameters":[["Integer","grid"]]},{"since":6,"name":"msg_set_pos","parameters":[["Integer","grid"],["Integer","row"],["Boolean","scrolled"],["String","sep_char"]]},{"since":7,"name":"win_viewport","parameters":[["Integer","grid"],["Window","win"],["Integer","topline"],["Integer","botline"],["Integer","curline"],["Integer","curcol"]]},{"since":3,"name":"popupmenu_show","parameters":[["Array","items"],["Integer","selected"],["Integer","row"],["Integer","col"],["Integer","grid"]]},{"since":3,"name":"popupmenu_hide","parameters":[]},{"since":3,"name":"popupmenu_select","parameters":[["Integer","selected"]]},{"since":3,"name":"tabline_update","parameters":[["Tabpage","current"],["Array","tabs"]]},{"since":3,"name":"cmdline_show","parameters":[["Array","content"],["Integer","pos"],["String","firstc"],["String","prompt"],["Integer","indent"],["Integer","level"]]},{"since":3,"name":"cmdline_pos","parameters":[["Integer","pos"],["Integer","level"]]},{"since":3,"name":"cmdline_special_char","parameters":[["String","c"],["Boolean","shift"],["Integer","level"]]},{"since":3,"name":"cmdline_hide","parameters":[["Integer","level"]]},{"since":3,"name":"cmdline_block_show","parameters":[["Array","lines"]]},{"since":3,"name":"cmdline_block_append","parameters":[["Array","lines"]]},{"since":3,"name":"cmdline_block_hide","parameters":[]},{"since":3,"name":"wildmenu_show","parameters":[["Array","items"]]},{"since":3,"name":"wildmenu_select","parameters":[["Integer","selected"]]},{"since":3,"name":"wildmenu_hide","parameters":[]},{"since":6,"name":"msg_show","parameters":[["String","kind"],["Array","content"],["Boolean","replace_last"]]},{"since":6,"name":"msg_clear","parameters":[]},{"since":6,"name":"msg_showcmd","parameters":[["Array","content"]]},{"since":6,"name":"msg_showmode","parameters":[["Array","content"]]},{"since":6,"name":"msg_ruler","parameters":[["Array","content"]]},{"since":6,"name":"msg_history_show","parameters":[["Array","entries"]]}],"version":{"api_level":7,"api_prerelease":true,"api_compatible":0,"patch":0,"major":0,"minor":5}} 2 | -------------------------------------------------------------------------------- /tool/src/api_to_json.lua: -------------------------------------------------------------------------------- 1 | local functions = vim.fn.api_info() 2 | local f = io.open('api_info.json', 'w') 3 | f:write(vim.fn.json_encode(functions)) 4 | f:close() 5 | --------------------------------------------------------------------------------