aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds_defs.h
blob: 4924e864700cd9817950b79b11a598e643fee4b1 (plain) (blame)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#pragma once

#include <stdbool.h>
#include <stdint.h>

#include "nvim/eval/typval_defs.h"
#include "nvim/ex_eval_defs.h"
#include "nvim/os/time_defs.h"
#include "nvim/regexp_defs.h"

#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds_enum.generated.h"
#endif

// When adding an Ex command:
// 1. Add an entry to the table in src/nvim/ex_cmds.lua.  Keep it sorted on the
//    shortest version of the command name that works.  If it doesn't start with
//    a lower case letter, add it at the end.
//
//    Each table entry is a table with the following keys:
//
//      Key     | Description
//      ------- | -------------------------------------------------------------
//      command | Name of the command. Required.
//      enum    | Name of the enum entry. If not set defaults to CMD_{command}.
//      flags   | A set of the flags from below list joined by bitwise or.
//      func    | Name of the function containing the implementation.
//
//    Referenced function should be either non-static one or defined in
//    ex_docmd.c and be coercible to ex_func_T type from below.
//
//    All keys not described in the above table are reserved for future use.
//
// 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c.
// 3. Add an entry in the index for Ex commands at ":help ex-cmd-index".
// 4. Add documentation in ../doc/xxx.txt.  Add a tag for both the short and
//    long name of the command.

#define EX_RANGE           0x001u  // allow a linespecs
#define EX_BANG            0x002u  // allow a ! after the command name
#define EX_EXTRA           0x004u  // allow extra args after command name
#define EX_XFILE           0x008u  // expand wildcards in extra part
#define EX_NOSPC           0x010u  // no spaces allowed in the extra part
#define EX_DFLALL          0x020u  // default file range is 1,$
#define EX_WHOLEFOLD       0x040u  // extend range to include whole fold also
                                   // when less than two numbers given
#define EX_NEEDARG         0x080u  // argument required
#define EX_TRLBAR          0x100u  // check for trailing vertical bar
#define EX_REGSTR          0x200u  // allow "x for register designation
#define EX_COUNT           0x400u  // allow count in argument, after command
#define EX_NOTRLCOM        0x800u  // no trailing comment allowed
#define EX_ZEROR          0x1000u  // zero line number allowed
#define EX_CTRLV          0x2000u  // do not remove CTRL-V from argument
#define EX_CMDARG         0x4000u  // allow "+command" argument
#define EX_BUFNAME        0x8000u  // accepts buffer name
#define EX_BUFUNL        0x10000u  // accepts unlisted buffer too
#define EX_ARGOPT        0x20000u  // allow "++opt=val" argument
#define EX_SBOXOK        0x40000u  // allowed in the sandbox
#define EX_CMDWIN        0x80000u  // allowed in cmdline window
#define EX_MODIFY       0x100000u  // forbidden in non-'modifiable' buffer
#define EX_FLAGS        0x200000u  // allow flags after count in argument
#define EX_LOCK_OK     0x1000000u  // command can be executed when textlock is
                                   // set; when missing disallows editing another
                                   // buffer when curbuf->b_ro_locked is set
#define EX_KEEPSCRIPT  0x4000000u  // keep sctx of where command was invoked
#define EX_PREVIEW     0x8000000u  // allow incremental command preview
#define EX_FILES (EX_XFILE | EX_EXTRA)  // multiple extra files allowed
#define EX_FILE1 (EX_FILES | EX_NOSPC)  // 1 file, defaults to current file
#define EX_WORD1 (EX_EXTRA | EX_NOSPC)  // one extra word allowed

/// values for cmd_addr_type
typedef enum {
  ADDR_LINES,           ///< buffer line numbers
  ADDR_WINDOWS,         ///< window number
  ADDR_ARGUMENTS,       ///< argument number
  ADDR_LOADED_BUFFERS,  ///< buffer number of loaded buffer
  ADDR_BUFFERS,         ///< buffer number
  ADDR_TABS,            ///< tab page number
  ADDR_TABS_RELATIVE,   ///< Tab page that only relative
  ADDR_QUICKFIX_VALID,  ///< quickfix list valid entry number
  ADDR_QUICKFIX,        ///< quickfix list entry number
  ADDR_UNSIGNED,        ///< positive count or zero, defaults to 1
  ADDR_OTHER,           ///< something else, use line number for '$', '%', etc.
  ADDR_NONE,            ///< no range used
} cmd_addr_T;

typedef struct exarg exarg_T;

// behavior for bad character, "++bad=" argument
#define BAD_REPLACE     '?'     // replace it with '?' (default)
#define BAD_KEEP        (-1)    // leave it
#define BAD_DROP        (-2)    // erase it

typedef void (*ex_func_T)(exarg_T *eap);
typedef int (*ex_preview_func_T)(exarg_T *eap, int cmdpreview_ns, handle_T cmdpreview_bufnr);

// NOTE: These possible could be removed and changed so that
// Callback could take a "command" style string, and simply
// execute that (instead of it being a function).
//
// But it's still a bit weird to do that.
//
// Another option would be that we just make a callback reference to
// "execute($INPUT)" or something like that, so whatever the user
// sends in via autocmds is just executed via this.
//
// However, that would probably have some performance cost (probably
// very marginal, but still some cost either way).
typedef enum {
  CALLABLE_NONE,
  CALLABLE_EX,
  CALLABLE_CB,
} AucmdExecutableType;

typedef struct aucmd_executable_t AucmdExecutable;
struct aucmd_executable_t {
  AucmdExecutableType type;
  union {
    char *cmd;
    Callback cb;
  } callable;
};

#define AUCMD_EXECUTABLE_INIT { .type = CALLABLE_NONE }

typedef char *(*LineGetter)(int, void *, int, bool);

/// Structure for command definition.
typedef struct {
  char *cmd_name;                      ///< Name of the command.
  ex_func_T cmd_func;                  ///< Function with implementation of this command.
  ex_preview_func_T cmd_preview_func;  ///< Preview callback function of this command.
  uint32_t cmd_argt;                   ///< Relevant flags from the declared above.
  cmd_addr_T cmd_addr_type;            ///< Flag for address type.
} CommandDefinition;

/// Arguments used for Ex commands.
struct exarg {
  char *arg;                    ///< argument of the command
  char **args;                  ///< starting position of command arguments
  size_t *arglens;              ///< length of command arguments
  size_t argc;                  ///< number of command arguments
  char *nextcmd;                ///< next command (NULL if none)
  char *cmd;                    ///< the name of the command (except for :make)
  char **cmdlinep;              ///< pointer to pointer of allocated cmdline
  char *cmdline_tofree;         ///< free later
  cmdidx_T cmdidx;              ///< the index for the command
  uint32_t argt;                ///< flags for the command
  int skip;                     ///< don't execute the command, only parse it
  int forceit;                  ///< true if ! present
  int addr_count;               ///< the number of addresses given
  linenr_T line1;               ///< the first line number
  linenr_T line2;               ///< the second line number or count
  cmd_addr_T addr_type;         ///< type of the count/range
  int flags;                    ///< extra flags after count: EXFLAG_
  char *do_ecmd_cmd;            ///< +command arg to be used in edited file
  linenr_T do_ecmd_lnum;        ///< the line number in an edited file
  int append;                   ///< true with ":w >>file" command
  int usefilter;                ///< true with ":w !command" and ":r!command"
  int amount;                   ///< number of '>' or '<' for shift command
  int regname;                  ///< register name (NUL if none)
  int force_bin;                ///< 0, FORCE_BIN or FORCE_NOBIN
  int read_edit;                ///< ++edit argument
  int mkdir_p;                  ///< ++p argument
  int force_ff;                 ///< ++ff= argument (first char of argument)
  int force_enc;                ///< ++enc= argument (index in cmd[])
  int bad_char;                 ///< BAD_KEEP, BAD_DROP or replacement byte
  int useridx;                  ///< user command index
  char *errmsg;                 ///< returned error message
  LineGetter ea_getline;        ///< function used to get the next line
  void *cookie;                 ///< argument for ea_getline()
  cstack_T *cstack;             ///< condition stack for ":if" etc.
};

#define FORCE_BIN 1             // ":edit ++bin file"
#define FORCE_NOBIN 2           // ":edit ++nobin file"

// Values for "flags"
#define EXFLAG_LIST     0x01    // 'l': list
#define EXFLAG_NR       0x02    // '#': number
#define EXFLAG_PRINT    0x04    // 'p': print

enum {
  CMOD_SANDBOX      = 0x0001,  ///< ":sandbox"
  CMOD_SILENT       = 0x0002,  ///< ":silent"
  CMOD_ERRSILENT    = 0x0004,  ///< ":silent!"
  CMOD_UNSILENT     = 0x0008,  ///< ":unsilent"
  CMOD_NOAUTOCMD    = 0x0010,  ///< ":noautocmd"
  CMOD_HIDE         = 0x0020,  ///< ":hide"
  CMOD_BROWSE       = 0x0040,  ///< ":browse" - invoke file dialog
  CMOD_CONFIRM      = 0x0080,  ///< ":confirm" - invoke yes/no dialog
  CMOD_KEEPALT      = 0x0100,  ///< ":keepalt"
  CMOD_KEEPMARKS    = 0x0200,  ///< ":keepmarks"
  CMOD_KEEPJUMPS    = 0x0400,  ///< ":keepjumps"
  CMOD_LOCKMARKS    = 0x0800,  ///< ":lockmarks"
  CMOD_KEEPPATTERNS = 0x1000,  ///< ":keeppatterns"
  CMOD_NOSWAPFILE   = 0x2000,  ///< ":noswapfile"
};

/// Command modifiers ":vertical", ":browse", ":confirm", ":hide", etc. set a
/// flag.  This needs to be saved for recursive commands, put them in a
/// structure for easy manipulation.
typedef struct {
  int cmod_flags;  ///< CMOD_ flags

  int cmod_split;  ///< flags for win_split()
  int cmod_tab;  ///< > 0 when ":tab" was used
  char *cmod_filter_pat;
  regmatch_T cmod_filter_regmatch;  ///< set by :filter /pat/
  bool cmod_filter_force;  ///< set for :filter!

  int cmod_verbose;  ///< 0 if not set, > 0 to set 'verbose' to cmod_verbose - 1

  // values for undo_cmdmod()
  char *cmod_save_ei;  ///< saved value of 'eventignore'
  int cmod_did_sandbox;  ///< set when "sandbox" was incremented
  OptInt cmod_verbose_save;  ///< if 'verbose' was set: value of p_verbose plus one
  int cmod_save_msg_silent;  ///< if non-zero: saved value of msg_silent + 1
  int cmod_save_msg_scroll;  ///< for restoring msg_scroll
  int cmod_did_esilent;  ///< incremented when emsg_silent is
} cmdmod_T;

/// Stores command modifier info used by `nvim_parse_cmd`
typedef struct {
  cmdmod_T cmdmod;
  struct {
    bool file;
    bool bar;
  } magic;
} CmdParseInfo;

/// Previous :substitute replacement string definition
typedef struct {
  char *sub;            ///< Previous replacement string.
  Timestamp timestamp;  ///< Time when it was last set.
  AdditionalData *additional_data;  ///< Additional data left from ShaDa file.
} SubReplacementString;