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

avoid cursor jump when file under cursor is renamed by plugin/r #1869

Closed
wants to merge 1 commit into from
Closed
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
28 changes: 21 additions & 7 deletions src/nnn.c
Original file line number Diff line number Diff line change
Expand Up @@ -5394,7 +5394,7 @@ static char *readpipe(int fd, char *ctxnum, char **path)
return nextpath;
}

static bool run_plugin(char **path, const char *file, char *runfile, char **lastname, char **lastdir)
static bool run_plugin(char **path, const char *file, char *runfile, char **lastname, char **lastdir, bool *cd)
{
pid_t p;
char ctx = 0;
Expand Down Expand Up @@ -5477,6 +5477,8 @@ static bool run_plugin(char **path, const char *file, char *runfile, char **last
nextpath = readpipe(rfd, &ctx, path);
if (nextpath)
set_smart_ctx(ctx, nextpath, path, runfile, lastname, lastdir);
else
*cd = FALSE;
Comment on lines 5478 to +5481
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prior, there was an assumption that every plugin execution could change the directory, and so cd = TRUE for every plugin run. We now accurately set cd based on whether the plugin changed the directory or not.

I believe this is the only way for a plugin to change the directory, would like confirmation.


close(rfd);

Expand Down Expand Up @@ -5991,7 +5993,7 @@ static int dentfill(char *path, struct entry **ppdents)
return ndents;
}

static void populate(char *path, char *lastname)
static void populate(char *path, char *lastname, bool cd)
{
#ifdef DEBUG
struct timespec ts1, ts2;
Expand All @@ -6014,7 +6016,18 @@ static void populate(char *path, char *lastname)

/* Find cur from history */
/* No NULL check for lastname, always points to an array */
move_cursor(*lastname ? dentfind(lastname, ndents) : 0, 0);
int target;
if (*lastname) {
target = dentfind(lastname, ndents);
/* If we failed to find the previous filename, and we didn't change directories, */
/* default to the previous cursor position. This way, when a file is renamed by */
/* a plugin, the cursor does not jump to the top of the directory. */
if (target == 0 && !cd)
target = cur;
} else
target = 0;

move_cursor(target, 0);
Comment on lines +6019 to +6030
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if now lastname is on position 0 and we didn't cd? You set target = cur which is probably not what we want.

Also, we generally don't know if cur will be a valid position after running external actions. Any number of entries may be added or removed or renamed, in which case you might as well place the cursor on a random line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I didn't consider these cases. I will fix them in my fork.


// Force full redraw
last_curscroll = -1;
Expand Down Expand Up @@ -6887,15 +6900,16 @@ static bool browse(char *ipath, const char *session, int pkey)
} else
cfgsort[cfg.curctx] = cfgsort[CTX_MAX];
}
cd = TRUE;

populate(path, lastname);
populate(path, lastname, cd);
if (g_state.interrupt) {
g_state.interrupt = cfg.apparentsz = cfg.blkorder = 0;
blk_shift = BLK_SHIFT_512;
presel = CONTROL('L');
}

cd = TRUE;

#ifdef LINUX_INOTIFY
if (presel != FILTER && inotify_wd == -1)
inotify_wd = inotify_add_watch(inotify_fd, path, INOTIFY_MASK);
Expand Down Expand Up @@ -7122,7 +7136,7 @@ static bool browse(char *ipath, const char *session, int pkey)
clearfilter();

if (chdir(path) == -1
|| !run_plugin(&path, pent->name, runfile, &lastname, &lastdir)) {
|| !run_plugin(&path, pent->name, runfile, &lastname, &lastdir, &cd)) {
DPRINTF_S("plugin failed!");
}

Expand Down Expand Up @@ -7940,7 +7954,7 @@ static bool browse(char *ipath, const char *session, int pkey)
r = TRUE;

if (!run_plugin(&path, tmp, (ndents ? pdents[cur].name : NULL),
&lastname, &lastdir)) {
&lastname, &lastdir, &cd)) {
printwait(messages[MSG_FAILED], &presel);
goto nochange;
}
Expand Down
Loading