From 3f0c604111ee8d16afaa26824cae5db070c30cff Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Sun, 1 Dec 2019 23:00:06 +0530
Subject: [PATCH] Option -R to disable rollover at edges

---
 README.md                                     |  1 +
 misc/auto-completion/bash/nnn-completion.bash |  1 +
 misc/auto-completion/fish/nnn.fish            |  1 +
 misc/auto-completion/zsh/_nnn                 |  1 +
 nnn.1                                         |  4 ++++
 src/nnn.c                                     | 16 +++++++++++-----
 6 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index aefeaeca..e8f479bf 100644
--- a/README.md
+++ b/README.md
@@ -189,6 +189,7 @@ optional args:
  -o      open files on Enter
  -p file selection file [stdout if '-']
  -r      use advcpmv patched cp, mv
+ -R      disable rollover at edges
  -s      string filters [default: regex]
  -S      du mode
  -t      disable dir auto-select
diff --git a/misc/auto-completion/bash/nnn-completion.bash b/misc/auto-completion/bash/nnn-completion.bash
index 75586d22..bddf84f8 100644
--- a/misc/auto-completion/bash/nnn-completion.bash
+++ b/misc/auto-completion/bash/nnn-completion.bash
@@ -26,6 +26,7 @@ _nnn ()
         -o
         -p
         -r
+        -R
         -s
         -S
         -t
diff --git a/misc/auto-completion/fish/nnn.fish b/misc/auto-completion/fish/nnn.fish
index ac73654b..36133437 100644
--- a/misc/auto-completion/fish/nnn.fish
+++ b/misc/auto-completion/fish/nnn.fish
@@ -25,6 +25,7 @@ complete -c nnn -s n    -d 'use version compare to sort files'
 complete -c nnn -s o    -d 'open files only on Enter'
 complete -c nnn -s p -r -d 'copy selection to file' -a '-\tstdout'
 complete -c nnn -s r    -d 'show cp, mv progress (Linux-only)'
+complete -c nnn -s R    -d 'disable rollover at edges'
 complete -c nnn -s s    -d 'use substring match for filters'
 complete -c nnn -s S    -d 'start in disk usage analyzer mode'
 complete -c nnn -s t    -d 'disable dir auto-select'
diff --git a/misc/auto-completion/zsh/_nnn b/misc/auto-completion/zsh/_nnn
index 5e9cb1c7..d5d5c1dc 100644
--- a/misc/auto-completion/zsh/_nnn
+++ b/misc/auto-completion/zsh/_nnn
@@ -23,6 +23,7 @@ args=(
     '(-o)-o[open files only on Enter]'
     '(-p)-p[copy selection to file]:file name'
     '(-r)-r[show cp, mv progress (Linux-only)]'
+    '(-R)-R[disable rollover at edges]'
     '(-s)-s[use substring match for filters]'
     '(-S)-S[start in disk usage analyzer mode]'
     '(-t)-t[disable dir auto-select]'
diff --git a/nnn.1 b/nnn.1
index 04904844..6db2e9f7 100644
--- a/nnn.1
+++ b/nnn.1
@@ -19,6 +19,7 @@
 .Op Ar -n
 .Op Ar -p file
 .Op Ar -r
+.Op Ar -R
 .Op Ar -s
 .Op Ar -S
 .Op Ar -v
@@ -84,6 +85,9 @@ supports the following options:
 .Fl r
         show cp, mv progress (Linux-only, needs advcpmv; '^T' shows the progress on BSD/macOS)
 .Pp
+.Fl R
+        disable rollover at edges
+.Pp
 .Fl s
         use substring match for filters instead of regex
 .Pp
diff --git a/src/nnn.c b/src/nnn.c
index d8a240d9..3d8db0e9 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -227,7 +227,7 @@ typedef struct {
 	uint selmode    : 1;  /* Set when selecting files */
 	uint showdetail : 1;  /* Clear to show fewer file info */
 	uint ctxactive  : 1;  /* Context active or not */
-	uint reserved   : 4;
+	uint reserved   : 3;
 	/* The following settings are global */
 	uint curctx     : 2;  /* Current context number */
 	uint dircolor   : 1;  /* Current status of dir color */
@@ -245,6 +245,7 @@ typedef struct {
 	uint mtime      : 1;  /* Use modification time (else access time) */
 	uint cliopener  : 1;  /* All-CLI app opener */
 	uint waitedit   : 1;  /* For ops that can't be detached, used EDITOR */
+	uint rollover   : 1;  /* Roll over at edges */
 } settings;
 
 /* Contexts or workspaces */
@@ -296,6 +297,7 @@ static settings cfg = {
 	1, /* mtime */
 	0, /* cliopener */
 	0, /* waitedit */
+	1, /* rollover */
 };
 
 static context g_ctx[CTX_MAX] __attribute__ ((aligned));
@@ -3937,17 +3939,17 @@ static void move_cursor(int target, int ignore_scrolloff)
 	curscroll = MAX(curscroll, MAX(cur - (onscreen - 1), 0));
 }
 
-static void handle_screen_move(enum action sel)
+static inline void handle_screen_move(enum action sel)
 {
 	int onscreen;
 
 	switch (sel) {
 	case SEL_NEXT:
-		if (ndents)
+		if (ndents && (cfg.rollover || (cur != ndents - 1)))
 			move_cursor((cur + 1) % ndents, 0);
 		break;
 	case SEL_PREV:
-		if (ndents)
+		if (ndents && (cfg.rollover || cur))
 			move_cursor((cur + ndents - 1) % ndents, 0);
 		break;
 	case SEL_PGDN:
@@ -5415,6 +5417,7 @@ static void usage(void)
 		" -o      open files on Enter\n"
 		" -p file selection file [stdout if '-']\n"
 		" -r      use advcpmv patched cp, mv\n"
+		" -R      disable rollover at edges\n"
 		" -s      string filters [default: regex]\n"
 		" -S      du mode\n"
 		" -t      disable dir auto-select\n"
@@ -5561,7 +5564,7 @@ int main(int argc, char *argv[])
 	bool progress = FALSE;
 #endif
 
-	while ((opt = getopt(argc, argv, "HSKiab:cde:Efnop:rstvh")) != -1) {
+	while ((opt = getopt(argc, argv, "HSKiab:cde:Efnop:rRstvh")) != -1) {
 		switch (opt) {
 		case 'S':
 			cfg.blkorder = 1;
@@ -5623,6 +5626,9 @@ int main(int argc, char *argv[])
 			progress = TRUE;
 #endif
 			break;
+		case 'R':
+			cfg.rollover = 0;
+			break;
 		case 's':
 			cfg.filter_re = 0;
 			filterfn = &visible_str;
-- 
2.51.0