package vcaml

  1. Overview
  2. Docs
OCaml bindings for the Neovim API

Install

Dune Dependency

Authors

Maintainers

Sources

vcaml-v0.16.0.tar.gz
sha256=dd123302c46af7ca6eda8a7806c78236fd217a8c73a2e1cd7da85f1d69ed1ae4

doc/src/vcaml/command.ml.html

Source file command.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
open Core

type nargs =
  [ `Exactly of int
  | `List
  | `At_most_one
  | `At_least_one
  ]

let nargs_of_msgpack = function
  | Msgpack.Nil -> Ok (`Exactly 0)
  | Integer i -> Ok (`Exactly i)
  | String "*" -> Ok `List
  | String "?" -> Ok `At_most_one
  | String "+" -> Ok `At_least_one
  | _ -> Or_error.error_string "malformed nargs"
;;

type addr_type =
  [ `Lines
  | `Args
  | `Buffers
  | `Loaded_bufs
  | `Windows
  | `Tabs
  ]

let addr_of_msgpack = function
  | Msgpack.Nil | String "lines" -> Ok `Lines
  | String "arguments" -> Ok `Args
  | String "buffers" -> Ok `Buffers
  | String "loaded_buffers" -> Ok `Loaded_bufs
  | String "windows" -> Ok `Windows
  | String "tabs" -> Ok `Tabs
  | _ -> Or_error.error_string "malformed addr"
;;

type range_type =
  | Range of
      [ `Defaults_to_current_line
      | `Defaults_to_whole_file
      | `Defaults_to_line_nr of int
      ]
  | Count of int

let convert_range range count =
  let open Or_error.Let_syntax in
  (* This way, we can handle [range] and [combine] with one joined error. *)
  let%bind both = Or_error.combine_errors [ range; count ] in
  let range, count =
    match both with
    | [ range; count ] -> range, count
    | _ -> assert false
  in
  (* These combinations were determined experimentally and may be subject to change with
     future versions of neovim.

     Observed combinations:

     -range   gives range = "." and count = Nil
     -range=% gives range = "%" and count = Nil
     -range=N gives range = "N" and count = Nil
     -count=N gives range = "N" and count = "N" *)
  match range, count with
  | Msgpack.Nil, Msgpack.Nil -> return None
  | String ".", Nil -> return (Some (Range `Defaults_to_current_line))
  | String "%", Nil -> return (Some (Range `Defaults_to_whole_file))
  | String s, Nil ->
    let%map n = Or_error.try_with (fun () -> Int.of_string s) in
    Some (Range (`Defaults_to_line_nr n))
  | String _, String s ->
    let%map n = Or_error.try_with (fun () -> Int.of_string s) in
    Some (Count n)
  | _, _ -> Or_error.error_string "invalid or unknown [range]/[count] combination."
;;

let string_or_nil = function
  | Msgpack.Nil -> Ok None
  | Msgpack.String s -> Ok (Some s)
  | _ -> Or_error.error_string "called [string_or_nil] on wrong type"
;;

type t =
  { name : string
  ; definition : string
  ; script_id : int
  ; bang : bool
  ; bar : bool
  ; register : bool
  ; nargs : nargs
  ; complete : string option
  ; complete_arg : string option
  ; range : range_type option
  ; addr : addr_type
  }

let of_msgpack msg =
  let result =
    let open Or_error.Let_syntax in
    let find_key m s extract = Map.find_or_error m s >>= extract in
    let%bind map = Extract.map_of_msgpack_map msg in
    let%bind name = find_key map "name" Extract.string in
    let%bind definition = find_key map "definition" Extract.string in
    let%bind script_id = find_key map "script_id" Extract.int in
    let%bind bang = find_key map "bang" Extract.bool in
    let%bind bar = find_key map "bar" Extract.bool in
    let%bind register = find_key map "register" Extract.bool in
    let%bind nargs = find_key map "nargs" nargs_of_msgpack in
    let%bind complete = find_key map "complete" string_or_nil in
    let%bind complete_arg = find_key map "complete" string_or_nil in
    let range_input = Map.find_or_error map "range" in
    let count_input = Map.find_or_error map "count" in
    let%bind range = convert_range range_input count_input in
    let%bind addr = find_key map "addr" addr_of_msgpack in
    return
      { name
      ; definition
      ; script_id
      ; bang
      ; bar
      ; register
      ; nargs
      ; complete
      ; complete_arg
      ; range
      ; addr
      }
  in
  Or_error.tag ~tag:"malformed command map" result
;;
OCaml

Innovation. Community. Security.