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

Vimode: fix cursor position after using undo #1328

Merged
merged 1 commit into from
May 22, 2024
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
4 changes: 3 additions & 1 deletion vimode/src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ vi_srcs = \
cmds/edit.h \
cmds/edit.c \
cmds/excmds.h \
cmds/excmds.c
cmds/excmds.c \
cmds/undo.h \
cmds/undo.c

vimode_la_SOURCES = \
backends/backend-geany.c \
Expand Down
9 changes: 2 additions & 7 deletions vimode/src/cmds/edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include "cmds/edit.h"
#include "cmds/undo.h"
#include "utils.h"


Expand Down Expand Up @@ -161,13 +162,7 @@ void cmd_del_word_left(CmdContext *c, CmdParams *p)

void cmd_undo(CmdContext *c, CmdParams *p)
{
gint i;
for (i = 0; i < p->num; i++)
{
if (!SSM(p->sci, SCI_CANUNDO, 0, 0))
break;
SSM(p->sci, SCI_UNDO, 0, 0);
}
undo_apply(c, p->num);
}


Expand Down
3 changes: 2 additions & 1 deletion vimode/src/cmds/excmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "cmds/excmds.h"
#include "cmds/edit.h"
#include "cmds/undo.h"
#include "utils.h"

void excmd_save(CmdContext *c, ExCmdParams *p)
Expand Down Expand Up @@ -93,7 +94,7 @@ void excmd_put(CmdContext *c, ExCmdParams *p)

void excmd_undo(CmdContext *c, ExCmdParams *p)
{
SSM(c->sci, SCI_UNDO, 0, 0);
undo_apply(c, 1);
}


Expand Down
59 changes: 59 additions & 0 deletions vimode/src/cmds/undo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2024 Sylvain Cresto <[email protected]>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "undo.h"
#include "utils.h"

void undo_update(CmdContext *c, gint pos)
{
c->undo_pos = pos;
}


static gboolean is_start_of_line(ScintillaObject *sci, gint pos)
{
gint line = SSM(sci, SCI_LINEFROMPOSITION, pos, 0);
gint line_pos = SSM(sci, SCI_POSITIONFROMLINE, line, 0);

return pos == line_pos;
}


void undo_apply(CmdContext *c, gint num)
{
ScintillaObject *sci = c->sci;
gint i;

c->undo_pos = -1;

for (i = 0; i < num; i++)
{
if (!SSM(sci, SCI_CANUNDO, 0, 0))
break;
SSM(sci, SCI_UNDO, 0, 0);
}

/* exit when no undo has been applied */
if (c->undo_pos == -1)
return;

if (is_start_of_line(sci, c->undo_pos))
goto_nonempty(sci, SSM(sci, SCI_LINEFROMPOSITION, c->undo_pos, 0), FALSE);
else
SET_POS(sci, c->undo_pos, FALSE);
}
27 changes: 27 additions & 0 deletions vimode/src/cmds/undo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2024 Sylvain Cresto <[email protected]>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#ifndef __UNDO_H__
#define __UNDO_H__

#include "context.h"

void undo_update(CmdContext *c, gint pos);
void undo_apply(CmdContext *c, gint num);

#endif
3 changes: 3 additions & 0 deletions vimode/src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ typedef struct
* copied N times when e.g. 'i' is preceded by a number or when using '.' */
gchar insert_buf[INSERT_BUF_LEN];
gint insert_buf_len;

/* cursor position to restore after undo */
gint undo_pos;
} CmdContext;

#endif
1 change: 1 addition & 0 deletions vimode/src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ gint get_line_number_rel(ScintillaObject *sci, gint shift)
return new_line;
}


void goto_nonempty(ScintillaObject *sci, gint line, gboolean scroll)
{
gint line_end_pos = SSM(sci, SCI_GETLINEENDPOSITION, line, 0);
Expand Down
8 changes: 7 additions & 1 deletion vimode/src/vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "utils.h"
#include "keypress.h"
#include "excmd-prompt.h"
#include "cmds/undo.h"

#include <gdk/gdkkeysyms.h>

Expand Down Expand Up @@ -51,7 +52,8 @@ CmdContext ctx =
NULL, NULL, NULL,
FALSE, FALSE,
0, 1,
"", 0
"", 0,
-1
};


Expand Down Expand Up @@ -306,6 +308,10 @@ gboolean vi_notify_sci(SCNotification *nt)
}
}

/* Keep position of undo operation */
if (nt->nmhdr.code == SCN_MODIFIED && (nt->modificationType & SC_MOD_BEFOREINSERT && nt->modificationType & SC_PERFORMED_UNDO) && nt->length > 1)
undo_update(&ctx, nt->position);

/* This makes sure that when we click behind the end of line in command mode,
* the cursor is not placed BEHIND the last character but ON the last character.
* We want to ignore this when doing selection with mouse as it breaks things. */
Expand Down