aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/os')
-rw-r--r--src/nvim/os/fs.c42
-rw-r--r--src/nvim/os/unix_defs.h2
-rw-r--r--src/nvim/os/win_defs.h1
3 files changed, 44 insertions, 1 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 21f0fc6f41..2e671653ed 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -146,6 +146,16 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
}
size_t buf_len = STRLEN(name) + STRLEN(path) + 2;
+
+#ifdef WIN32
+ const char *pathext = os_getenv("PATHEXT");
+ if (!pathext) {
+ pathext = ".com;.exe;.bat;.cmd";
+ }
+
+ buf_len += STRLEN(pathext);
+#endif
+
char_u *buf = xmalloc(buf_len);
// Walk through all entries in $PATH to check if "name" exists there and
@@ -169,6 +179,38 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
return true;
}
+#ifdef WIN32
+ // Try appending file extensions from $PATHEXT to the name.
+ char *buf_end = xstrchrnul((char *)buf, '\0');
+ for (const char *ext = pathext; *ext; ext++) {
+ // Skip the extension if there is no suffix after a '.'.
+ if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ';')) {
+ *ext++;
+
+ continue;
+ }
+
+ const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
+ STRLCPY(buf_end, ext, ext_end - ext + 1);
+
+ if (is_executable(buf)) {
+ // Check if the caller asked for a copy of the path.
+ if (abspath != NULL) {
+ *abspath = save_absolute_path(buf);
+ }
+
+ xfree(buf);
+
+ return true;
+ }
+
+ if (*ext_end != ENV_SEPCHAR) {
+ break;
+ }
+ ext = ext_end;
+ }
+#endif
+
if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
xfree(buf);
diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h
index 78fc9331d1..690a39c3cd 100644
--- a/src/nvim/os/unix_defs.h
+++ b/src/nvim/os/unix_defs.h
@@ -2,7 +2,7 @@
#define NVIM_OS_UNIX_DEFS_H
// Windows doesn't have unistd.h, so we include it here to avoid numerous
-// instances of `#ifdef HAVE_UNISTD_H'.
+// instances of `#ifdef WIN32'.
#include <unistd.h>
// POSIX.1-2008 says that NAME_MAX should be in here
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index ba96347a12..242d355f77 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -3,6 +3,7 @@
#include <windows.h>
#include <sys/stat.h>
+#include <io.h>
#include <stdio.h>
// Windows does not have S_IFLNK but libuv defines it