mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 16:28:17 +00:00
executor: Add :lua debug.debug mock
This commit is contained in:
187
src/nvim/eval.c
187
src/nvim/eval.c
@@ -12280,93 +12280,70 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
|
|
||||||
static int inputsecret_flag = 0;
|
static int inputsecret_flag = 0;
|
||||||
|
|
||||||
|
/// Get user input
|
||||||
/*
|
///
|
||||||
* This function is used by f_input() and f_inputdialog() functions. The third
|
/// Used for f_input and f_inputdialog functions.
|
||||||
* argument to f_input() specifies the type of completion to use at the
|
///
|
||||||
* prompt. The third argument to f_inputdialog() specifies the value to return
|
/// @param[in] prompt Input prompt.
|
||||||
* when the user cancels the prompt.
|
/// @param[in] initval Initial value, may be NULL.
|
||||||
*/
|
/// @param[in] xp_name Completion, for input().
|
||||||
static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
|
/// @param[in] cancelval Value returned when user cancelled dialog, for
|
||||||
|
/// inputdialog().
|
||||||
|
///
|
||||||
|
/// @return [allocated] User input or NULL.
|
||||||
|
char *get_user_input(const char *const prompt,
|
||||||
|
const char *const initval,
|
||||||
|
const char *const xp_name,
|
||||||
|
const char *const cancelval)
|
||||||
|
FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
|
||||||
{
|
{
|
||||||
char_u *prompt = get_tv_string_chk(&argvars[0]);
|
char *ret = NULL;
|
||||||
char_u *p = NULL;
|
const int saved_cmd_silent = cmd_silent;
|
||||||
int c;
|
cmd_silent = false; // Want to see the prompt.
|
||||||
char_u buf[NUMBUFLEN];
|
// Only the part of the message after the last NL is considered as
|
||||||
int cmd_silent_save = cmd_silent;
|
// prompt for the command line.
|
||||||
char_u *defstr = (char_u *)"";
|
const char *p = strrchr(prompt, NL);
|
||||||
int xp_type = EXPAND_NOTHING;
|
if (p == NULL) {
|
||||||
char_u *xp_arg = NULL;
|
p = prompt;
|
||||||
|
} else {
|
||||||
rettv->v_type = VAR_STRING;
|
p++;
|
||||||
rettv->vval.v_string = NULL;
|
msg_start();
|
||||||
|
msg_clr_eos();
|
||||||
cmd_silent = FALSE; /* Want to see the prompt. */
|
msg_puts_attr_len(prompt, (int)(p - prompt) + 1, echo_attr);
|
||||||
if (prompt != NULL) {
|
msg_didout = false;
|
||||||
/* Only the part of the message after the last NL is considered as
|
msg_starthere();
|
||||||
* prompt for the command line */
|
|
||||||
p = vim_strrchr(prompt, '\n');
|
|
||||||
if (p == NULL)
|
|
||||||
p = prompt;
|
|
||||||
else {
|
|
||||||
++p;
|
|
||||||
c = *p;
|
|
||||||
*p = NUL;
|
|
||||||
msg_start();
|
|
||||||
msg_clr_eos();
|
|
||||||
msg_puts_attr((const char *)prompt, echo_attr);
|
|
||||||
msg_didout = false;
|
|
||||||
msg_starthere();
|
|
||||||
*p = c;
|
|
||||||
}
|
|
||||||
cmdline_row = msg_row;
|
|
||||||
|
|
||||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
|
||||||
defstr = get_tv_string_buf_chk(&argvars[1], buf);
|
|
||||||
if (defstr != NULL)
|
|
||||||
stuffReadbuffSpec(defstr);
|
|
||||||
|
|
||||||
if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) {
|
|
||||||
char_u *xp_name;
|
|
||||||
int xp_namelen;
|
|
||||||
uint32_t argt;
|
|
||||||
|
|
||||||
/* input() with a third argument: completion */
|
|
||||||
rettv->vval.v_string = NULL;
|
|
||||||
|
|
||||||
xp_name = get_tv_string_buf_chk(&argvars[2], buf);
|
|
||||||
if (xp_name == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
xp_namelen = (int)STRLEN(xp_name);
|
|
||||||
|
|
||||||
if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
|
|
||||||
&xp_arg) == FAIL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defstr != NULL) {
|
|
||||||
int save_ex_normal_busy = ex_normal_busy;
|
|
||||||
ex_normal_busy = 0;
|
|
||||||
rettv->vval.v_string =
|
|
||||||
getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
|
|
||||||
xp_type, xp_arg);
|
|
||||||
ex_normal_busy = save_ex_normal_busy;
|
|
||||||
}
|
|
||||||
if (inputdialog && rettv->vval.v_string == NULL
|
|
||||||
&& argvars[1].v_type != VAR_UNKNOWN
|
|
||||||
&& argvars[2].v_type != VAR_UNKNOWN)
|
|
||||||
rettv->vval.v_string = vim_strsave(get_tv_string_buf(
|
|
||||||
&argvars[2], buf));
|
|
||||||
|
|
||||||
xfree(xp_arg);
|
|
||||||
|
|
||||||
/* since the user typed this, no need to wait for return */
|
|
||||||
need_wait_return = FALSE;
|
|
||||||
msg_didout = FALSE;
|
|
||||||
}
|
}
|
||||||
cmd_silent = cmd_silent_save;
|
cmdline_row = msg_row;
|
||||||
|
|
||||||
|
stuffReadbuffSpec((char_u *)initval);
|
||||||
|
|
||||||
|
char *xp_arg = NULL;
|
||||||
|
int xp_type = EXPAND_NOTHING;
|
||||||
|
if (xp_name != NULL) {
|
||||||
|
uint32_t argt;
|
||||||
|
if (parse_compl_arg((const char_u *)xp_name, (int)strlen(xp_name),
|
||||||
|
&xp_type, &argt, (char_u **)&xp_arg) == FAIL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int saved_ex_normal_busy = ex_normal_busy;
|
||||||
|
ex_normal_busy = 0;
|
||||||
|
ret = (char *)getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p,
|
||||||
|
echo_attr, xp_type, (char_u *)xp_arg);
|
||||||
|
ex_normal_busy = saved_ex_normal_busy;
|
||||||
|
|
||||||
|
if (ret == NULL && cancelval != NULL) {
|
||||||
|
ret = xstrdup(cancelval);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree(xp_arg);
|
||||||
|
|
||||||
|
// Since the user typed this, no need to wait for return.
|
||||||
|
need_wait_return = false;
|
||||||
|
msg_didout = false;
|
||||||
|
cmd_silent = saved_cmd_silent;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -12375,7 +12352,25 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
|
|||||||
*/
|
*/
|
||||||
static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
{
|
{
|
||||||
get_user_input(argvars, rettv, FALSE);
|
char initval_buf[NUMBUFLEN];
|
||||||
|
char xp_name_buf[NUMBUFLEN];
|
||||||
|
const char *const prompt = (const char *)get_tv_string_chk(&argvars[0]);
|
||||||
|
const char *const initval = (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN
|
||||||
|
? (const char *)get_tv_string_buf(&argvars[1], (char_u *)initval_buf)
|
||||||
|
: "");
|
||||||
|
const char *const xp_name = (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN
|
||||||
|
? (const char *)get_tv_string_buf(&argvars[2], (char_u *)xp_name_buf)
|
||||||
|
: NULL);
|
||||||
|
if (prompt == NULL || initval == NULL || (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN
|
||||||
|
&& xp_name == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = (char_u *)get_user_input(prompt, initval, xp_name,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -12383,7 +12378,25 @@ static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
*/
|
*/
|
||||||
static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
{
|
{
|
||||||
get_user_input(argvars, rettv, TRUE);
|
char initval_buf[NUMBUFLEN];
|
||||||
|
char cancelval_buf[NUMBUFLEN];
|
||||||
|
const char *const prompt = (const char *)get_tv_string_chk(&argvars[0]);
|
||||||
|
const char *const initval = (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN
|
||||||
|
? (const char *)get_tv_string_buf(&argvars[1], (char_u *)initval_buf)
|
||||||
|
: "");
|
||||||
|
const char *const cancelval = (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN
|
||||||
|
? (const char *)get_tv_string_buf(&argvars[2], (char_u *)cancelval_buf)
|
||||||
|
: NULL);
|
||||||
|
if (prompt == NULL || initval == NULL || (
|
||||||
|
argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN
|
||||||
|
&& cancelval == NULL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rettv->v_type = VAR_STRING;
|
||||||
|
rettv->vval.v_string = (char_u *)get_user_input(prompt, initval, NULL,
|
||||||
|
cancelval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -5757,10 +5757,10 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt,
|
|||||||
* copied to allocated memory and stored in "*compl_arg".
|
* copied to allocated memory and stored in "*compl_arg".
|
||||||
* Returns FAIL if something is wrong.
|
* Returns FAIL if something is wrong.
|
||||||
*/
|
*/
|
||||||
int parse_compl_arg(char_u *value, int vallen, int *complp,
|
int parse_compl_arg(const char_u *value, int vallen, int *complp,
|
||||||
uint32_t *argt, char_u **compl_arg)
|
uint32_t *argt, char_u **compl_arg)
|
||||||
{
|
{
|
||||||
char_u *arg = NULL;
|
const char_u *arg = NULL;
|
||||||
size_t arglen = 0;
|
size_t arglen = 0;
|
||||||
int i;
|
int i;
|
||||||
int valend = vallen;
|
int valend = vallen;
|
||||||
|
@@ -1564,7 +1564,6 @@ void msg_puts_attr(const char *const s, const int attr)
|
|||||||
|
|
||||||
/// Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes).
|
/// Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes).
|
||||||
/// When "maxlen" is -1 there is no maximum length.
|
/// When "maxlen" is -1 there is no maximum length.
|
||||||
/// When "maxlen" is >= 0 the message is not put in the history.
|
|
||||||
void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr)
|
void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr)
|
||||||
{
|
{
|
||||||
// If redirection is on, also write to the redirection file.
|
// If redirection is on, also write to the redirection file.
|
||||||
@@ -1576,7 +1575,7 @@ void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if MSG_HIST flag set, add message to history
|
// if MSG_HIST flag set, add message to history
|
||||||
if ((attr & MSG_HIST) && maxlen < 0) {
|
if (attr & MSG_HIST) {
|
||||||
add_msg_hist(str, -1, attr);
|
add_msg_hist(str, -1, attr);
|
||||||
attr &= ~MSG_HIST;
|
attr &= ~MSG_HIST;
|
||||||
}
|
}
|
||||||
|
@@ -250,15 +250,28 @@ static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
|
|||||||
/// Called by lua interpreter itself to initialize state.
|
/// Called by lua interpreter itself to initialize state.
|
||||||
static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
|
static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
|
// stricmp
|
||||||
lua_pushcfunction(lstate, &nlua_stricmp);
|
lua_pushcfunction(lstate, &nlua_stricmp);
|
||||||
lua_setglobal(lstate, "stricmp");
|
lua_setglobal(lstate, "stricmp");
|
||||||
|
|
||||||
|
// print
|
||||||
lua_pushcfunction(lstate, &nlua_print);
|
lua_pushcfunction(lstate, &nlua_print);
|
||||||
lua_setglobal(lstate, "print");
|
lua_setglobal(lstate, "print");
|
||||||
|
|
||||||
|
// debug.debug
|
||||||
|
lua_getglobal(lstate, "debug");
|
||||||
|
lua_pushcfunction(lstate, &nlua_debug);
|
||||||
|
lua_setfield(lstate, -2, "debug");
|
||||||
|
lua_pop(lstate, 1);
|
||||||
|
|
||||||
|
// vim
|
||||||
if (luaL_dostring(lstate, (char *)&vim_module[0])) {
|
if (luaL_dostring(lstate, (char *)&vim_module[0])) {
|
||||||
nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
|
nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// vim.api
|
||||||
nlua_add_api_functions(lstate);
|
nlua_add_api_functions(lstate);
|
||||||
|
// vim.types, vim.type_idx, vim.val_idx
|
||||||
nlua_init_types(lstate);
|
nlua_init_types(lstate);
|
||||||
lua_setglobal(lstate, "vim");
|
lua_setglobal(lstate, "vim");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -442,6 +455,31 @@ nlua_print_error:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// debug.debug implementation: interaction with user while debugging
|
||||||
|
///
|
||||||
|
/// @param lstate Lua interpreter state.
|
||||||
|
int nlua_debug(lua_State *lstate)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
lua_settop(lstate, 0);
|
||||||
|
char *const input = get_user_input("lua_debug> ", "", NULL, NULL);
|
||||||
|
msg_putchar('\n'); // Avoid outputting on input line.
|
||||||
|
if (input == NULL || *input == NUL || strcmp(input, "cont") == 0) {
|
||||||
|
xfree(input);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (luaL_loadbuffer(lstate, input, strlen(input), "=(debug command)")) {
|
||||||
|
nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
|
||||||
|
}
|
||||||
|
xfree(input);
|
||||||
|
if (lua_pcall(lstate, 0, 0, 0)) {
|
||||||
|
nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Evaluate lua string
|
/// Evaluate lua string
|
||||||
///
|
///
|
||||||
/// Used for luaeval().
|
/// Used for luaeval().
|
||||||
|
Reference in New Issue
Block a user