Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api/#163): Part 1: Add an API to get pending operator information #218

Merged
merged 3 commits into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,6 @@ jobs:
parameters:
testRunner: run-tests.sh

- job: Linux
displayName: "Linux - Ubuntu 16.04"
pool:
vmImage: 'Ubuntu 16.04'
steps:
- template: .ci/esy-build-steps.yml
- template: .ci/libvim-test.yml
parameters:
testRunner: run-tests.sh

- job: MacOS14
displayName: "MacOS Mojave"
pool:
Expand Down
94 changes: 94 additions & 0 deletions src/apitest/operator_pending.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,105 @@ MU_TEST(test_delete_operator_pending)
mu_check((vimGetMode() & NORMAL) == NORMAL);
}

MU_TEST(test_pending_operator_insert)
{
vimInput("i");

mu_check((vimGetMode() & INSERT) == INSERT);

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == FALSE);
}

MU_TEST(test_pending_operator_cmdline)
{
vimInput(":");

mu_check((vimGetMode() & CMDLINE) == CMDLINE);

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == FALSE);
}

MU_TEST(test_pending_operator_visual)
{
vimInput("v");

mu_check((vimGetMode() & VISUAL) == VISUAL);

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == FALSE);
}

MU_TEST(test_pending_operator_delete)
{
vimInput("d");

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == TRUE);
mu_check(pendingOp.op_type == OP_DELETE);
mu_check(pendingOp.count == 0);
}

MU_TEST(test_pending_operator_delete_count)
{
vimInput("5");
vimInput("d");

//mu_check((vimGetMode() & VISUAL) == VISUAL);

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == TRUE);
mu_check(pendingOp.op_type == OP_DELETE);
mu_check(pendingOp.count == 5);
}

MU_TEST(test_pending_operator_change)
{
vimInput("2");
vimInput("c");

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == TRUE);
mu_check(pendingOp.op_type == OP_CHANGE);
mu_check(pendingOp.count == 2);
}

MU_TEST(test_pending_operator_comment)
{
vimInput("g");
vimInput("c");

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == TRUE);
mu_check(pendingOp.op_type == OP_COMMENT);
}

MU_TEST(test_pending_operator_register)
{
vimInput("\"");
vimInput("a");
vimInput("y");

pendingOp_T pendingOp;
mu_check(vimGetPendingOperator(&pendingOp) == TRUE);
mu_check(pendingOp.op_type == OP_YANK);
mu_check(pendingOp.regname == 'a');
}

MU_TEST_SUITE(test_suite)
{
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);

MU_RUN_TEST(test_delete_operator_pending);
MU_RUN_TEST(test_pending_operator_insert);
MU_RUN_TEST(test_pending_operator_cmdline);
MU_RUN_TEST(test_pending_operator_visual);
MU_RUN_TEST(test_pending_operator_delete);
MU_RUN_TEST(test_pending_operator_delete_count);
MU_RUN_TEST(test_pending_operator_change);
MU_RUN_TEST(test_pending_operator_comment);
MU_RUN_TEST(test_pending_operator_register);
}

int main(int argc, char **argv)
Expand Down
5 changes: 5 additions & 0 deletions src/libvim.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,11 @@ void vimSetClipboardGetCallback(ClipboardGetCallback callback)

int vimGetMode(void) { return get_real_state(); }

int vimGetPendingOperator(pendingOp_T *pendingOp)
{
return sm_get_pending_operator(pendingOp);
}

void vimSetFormatCallback(FormatCallback callback)
{
formatCallback = callback;
Expand Down
1 change: 1 addition & 0 deletions src/libvim.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ void vimSetWindowMovementCallback(WindowMovementCallback callback);
void vimSetClipboardGetCallback(ClipboardGetCallback callback);

int vimGetMode(void);
int vimGetPendingOperator(pendingOp_T *pendingOp);

void vimSetYankCallback(YankCallback callback);

Expand Down
26 changes: 26 additions & 0 deletions src/normal.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,32 @@ void *state_normal_cmd_initialize()
return context;
}

int state_normal_pending_operator(void *ctx, pendingOp_T *pendingOp)
{
if (ctx == NULL)
{
return FALSE;
}

normalCmd_T *context = (normalCmd_T *)ctx;

if (context->oap == NULL)
{
return FALSE;
}

if (context->oap->op_type == OP_NOP)
{
return FALSE;
}

pendingOp->op_type = context->oap->op_type;
pendingOp->regname = context->oap->regname;
pendingOp->count = context->ca.opcount;

return TRUE;
}

void state_normal_cmd_cleanup(void *ctx)
{
normalCmd_T *context = (normalCmd_T *)ctx;
Expand Down
1 change: 1 addition & 0 deletions src/proto/normal.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
void *state_normal_cmd_initialize();
void state_normal_cmd_cleanup(void *ctx);
executionStatus_T state_normal_cmd_execute(void *ctx, int key);
int state_normal_pending_operator(void *ctx, pendingOp_T *pendingOp);

void init_normal_cmds(void);
void normal_cmd(oparg_T *oap, int toplevel);
Expand Down
2 changes: 2 additions & 0 deletions src/proto/state_machine.pro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* state_machine.c */

void sm_push(int mode, void *context, state_execute executeFn,
state_pending_operator pendingOperatorFn,
state_cleanup cleanupFn);

void sm_push_insert(int cmdchar, int startln, long count);
Expand All @@ -13,6 +14,7 @@ void sm_execute_normal(char_u *keys);
void sm_execute(char_u *key);

int sm_get_current_mode(void);
int sm_get_pending_operator(pendingOp_T *pendingOp);

sm_T *sm_get_current(void);

Expand Down
25 changes: 22 additions & 3 deletions src/state_machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ sm_T *sm_get_current() { return state_current; }

int sm_get_current_mode() { return state_current->mode; }

int no_pending_operator(void *ctx, pendingOp_T *cmdarg)
{
return FALSE;
}

void sm_push(int mode, void *context, state_execute executeFn,
state_pending_operator pendingOperatorFn,
state_cleanup cleanupFn)
{
sm_T *lastState = state_current;
Expand All @@ -23,38 +29,51 @@ void sm_push(int mode, void *context, state_execute executeFn,
newState->prev = (sm_T *)lastState;
newState->execute_fn = executeFn;
newState->cleanup_fn = cleanupFn;
newState->pending_operator_fn = pendingOperatorFn;
newState->context = context;
newState->mode = mode;

state_current = newState;
}

int sm_get_pending_operator(pendingOp_T *pendingOp)
{
if (state_current == NULL)
{
return FALSE;
}

return state_current->pending_operator_fn(state_current->context, pendingOp);
}

void sm_push_normal()
{
sm_push(NORMAL, state_normal_cmd_initialize(), state_normal_cmd_execute,
state_normal_pending_operator,
state_normal_cmd_cleanup);
}

void sm_push_insert(int cmdchar, int startln, long count)
{
sm_push(INSERT, state_edit_initialize(cmdchar, startln, count),
state_edit_execute, state_edit_cleanup);
state_edit_execute, no_pending_operator, state_edit_cleanup);
}

void sm_push_insert_literal(int *ret)
{
sm_push(INSERT, state_insert_literal_initialize(ret), state_insert_literal_execute, state_insert_literal_cleanup);
sm_push(INSERT, state_insert_literal_initialize(ret), state_insert_literal_execute, no_pending_operator, state_insert_literal_cleanup);
}

void sm_push_cmdline(int cmdchar, long count, int indent)
{
sm_push(CMDLINE, state_cmdline_initialize(cmdchar, count, indent),
state_cmdline_execute, state_cmdline_cleanup);
state_cmdline_execute, no_pending_operator, state_cmdline_cleanup);
}

void sm_push_change(oparg_T *oap)
{
sm_push(INSERT, state_change_initialize(oap), state_change_execute,
no_pending_operator,
state_change_cleanup);
}

Expand Down
39 changes: 24 additions & 15 deletions src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,6 @@ typedef enum
COMPLETED_UNHANDLED,
} executionStatus_T;

typedef executionStatus_T (*state_execute)(void *context, int key);
typedef void (*state_cleanup)(void *context);

typedef const char *sname;

/* State machine information */
typedef struct
{
void *context;
int mode;
state_execute execute_fn;
state_cleanup cleanup_fn;
void *prev;
} sm_T;

/*
* Same, but without coladd.
*/
Expand Down Expand Up @@ -2967,6 +2952,30 @@ typedef struct cmdarg_S
char_u *searchbuf; /* return: pointer to search pattern or NULL */
} cmdarg_T;

typedef struct pendingOp_S
{
int op_type;
int regname;
long count;
} pendingOp_T;

typedef executionStatus_T (*state_execute)(void *context, int key);
typedef void (*state_cleanup)(void *context);
typedef int (*state_pending_operator)(void *context, pendingOp_T *pendingOp);

typedef const char *sname;

/* State machine information */
typedef struct
{
void *context;
int mode;
state_execute execute_fn;
state_cleanup cleanup_fn;
state_pending_operator pending_operator_fn;
void *prev;
} sm_T;

/* values for retval: */
#define CA_COMMAND_BUSY 1 /* skip restarting edit() once */
#define CA_NO_ADJ_OP_END 2 /* don't adjust operator end */
Expand Down