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
|
/*
* Copyright (C) 2012-2025 Robin Haberkorn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <glib.h>
#include "sciteco.h"
#include "string-utils.h"
#include "parser.h"
#include "undo.h"
typedef struct {
/**
* State machine used for interactive mode (commandline macro).
* It is initialized on-demand in main.c.
* This is a global variable instead of being passed down the call stack
* since some process_edit_cmd_cb will be for nested state machines
* but we must "step" only the toplevel state machine.
*/
teco_machine_main_t machine;
/**
* String containing the current command line
* (both effective and rubbed out).
*/
teco_string_t str;
/**
* Effective command line length.
* The length of the rubbed out part of the command line
* is (teco_cmdline.str.len - teco_cmdline.effective_len).
*/
gsize effective_len;
/** Program counter within the command-line macro */
gsize pc;
/**
* Specifies whether the immediate editing modifier
* is enabled/disabled.
* It can be toggled with the ^G immediate editing command
* and influences the undo/redo direction and function of the
* TAB key.
*/
gboolean modifier_enabled;
} teco_cmdline_t;
extern teco_cmdline_t teco_cmdline;
gboolean teco_cmdline_keypress(const gchar *data, gsize len, GError **error);
typedef enum {
TECO_KEYMACRO_ERROR = 0, /**< GError occurred */
TECO_KEYMACRO_SUCCESS, /**< key macro found and inserted */
TECO_KEYMACRO_UNDEFINED /**< no key macro found */
} teco_keymacro_status_t;
teco_keymacro_status_t teco_cmdline_keymacro(const gchar *name, gssize name_len, GError **error);
static inline gboolean
teco_cmdline_keymacro_c(gchar key, GError **error)
{
switch (teco_cmdline_keymacro(&key, sizeof(key), error)) {
case TECO_KEYMACRO_ERROR:
return FALSE;
case TECO_KEYMACRO_SUCCESS:
break;
case TECO_KEYMACRO_UNDEFINED:
return teco_cmdline_keypress(&key, sizeof(key), error);
}
return TRUE;
}
/** Check whether we are executing directly from the end of the command line. */
static inline gboolean
teco_cmdline_is_executing(teco_machine_main_t *ctx)
{
return ctx == &teco_cmdline.machine && ctx->macro_pc == teco_cmdline.effective_len;
}
extern gboolean teco_quit_requested;
/*
* Command states
*/
TECO_DECLARE_STATE(teco_state_save_cmdline);
|