From 08cfcfea59a8ee0759d3644b06eca597d95d9277 Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Sat, 8 Dec 2018 18:22:06 +0530
Subject: [PATCH] Support run file as executable

---
 README.md |  4 +++-
 nnn.1     |  2 ++
 src/nnn.c | 23 +++++++++++++++++++++--
 src/nnn.h |  3 +++
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 4ec87619..be68cd71 100644
--- a/README.md
+++ b/README.md
@@ -117,6 +117,7 @@ We need contributors. Please visit the ToDo list.
   - Show directories in custom color (default: blue)
   - Spawn a subshell in the current directory
   - Run custom scripts in the current directory
+  - Run current file as executable
   - Change directory at exit (*easy* shell integration)
   - Edit file in EDITOR or open in PAGER
   - Application launcher
@@ -247,7 +248,8 @@ Press <kbd>?</kbd> in `nnn` to see the list anytime.
               s  Size                  t  Modification time
  MISC
           !, ^]  Spawn SHELL in dir    o  Launch app
-              R  Run custom script     L  Lock terminal
+              R  Run custom script    ^S  Execute entry
+              L  Lock terminal
 ```
 
 Help & settings, file details, media info and archive listing are shown in the PAGER. Please use the PAGER-specific keys in these screens.
diff --git a/nnn.1 b/nnn.1
index 9dc63340..1bcf3a1f 100644
--- a/nnn.1
+++ b/nnn.1
@@ -149,6 +149,8 @@ Spawn SHELL in current directory (fallback sh)
 Launch an application (takes 2 combined arguments)
 .It Ic R
 Run a custom script
+.It Ic ^S
+Execute entry
 .It Ic L
 Lock terminal (Linux only)
 .El
diff --git a/src/nnn.c b/src/nnn.c
index 84df28b0..4b51ec7b 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -2060,7 +2060,8 @@ static bool show_help(char *path)
              "es  Size                  t  Modification time\n"
 "1MISC\n"
          "a!, ^]  Spawn SHELL in dir    o  Launch app\n"
-             "eR  Run custom script     L  Lock terminal\n"};
+             "eR  Run custom script    ^S  Execute entry\n"
+             "eL  Lock terminal\n"};
 
 	if (fd == -1)
 		return FALSE;
@@ -3371,9 +3372,27 @@ nochange:
 			close(fd);
 			xstrlcpy(lastname, tmp, NAME_MAX + 1);
 			goto begin;
+		case SEL_EXEC:
+			if (!ndents)
+				goto nochange; // fallthrough
 		case SEL_SHELL: // fallthrough
 		case SEL_SCRIPT:
-			if (sel == SEL_SCRIPT) {
+			if (sel == SEL_EXEC) {
+				/* Check if this is a directory */
+				if (S_ISDIR(dents[cur].mode)) {
+					printmsg("directory");
+					goto nochange;
+				}
+
+				/* Check if file is executable */
+				if (!(dents[cur].mode & 0100)) {
+					printmsg("Permission denied");
+					goto nochange;
+				}
+
+				mkpath(path, dents[cur].name, newpath, PATH_MAX);
+				spawn(newpath, NULL, NULL, path, F_NORMAL | F_SIGINT);
+			} else if (sel == SEL_SCRIPT) {
 				tmp = getenv("NNN_SCRIPT");
 				if (tmp) {
 					if (getenv("NNN_MULTISCRIPT")) {
diff --git a/src/nnn.h b/src/nnn.h
index 088f5a60..9e7d5f7d 100644
--- a/src/nnn.h
+++ b/src/nnn.h
@@ -80,6 +80,7 @@ enum action {
 	SEL_RENAME,
 	SEL_RENAMEALL,
 	SEL_HELP,
+	SEL_EXEC,
 	SEL_SHELL,
 	SEL_SCRIPT,
 	SEL_RUNEDIT,
@@ -209,6 +210,8 @@ static struct key bindings[] = {
 	{ 'r',            SEL_RENAMEALL },
 	/* Show help */
 	{ '?',            SEL_HELP },
+	/* Execute file */
+	{ CONTROL('S'),   SEL_EXEC },
 	/* Run command */
 	{ '!',            SEL_SHELL },
 	{ CONTROL(']'),   SEL_SHELL },
-- 
2.51.0