Skip to content

Instantly share code, notes, and snippets.

@mattn
Last active August 2, 2017 01:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattn/9e087f303a94e35e26d5c666ac101084 to your computer and use it in GitHub Desktop.
Save mattn/9e087f303a94e35e26d5c666ac101084 to your computer and use it in GitHub Desktop.
diff --git a/src/evalfunc.c b/src/evalfunc.c
index fc0e05dad..9ef54bba8 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -835,6 +835,7 @@ static struct fst
{"term_getcursor", 1, 1, f_term_getcursor},
{"term_getjob", 1, 1, f_term_getjob},
{"term_getline", 1, 2, f_term_getline},
+ {"term_getruncmd", 1, 1, f_term_getruncmd},
{"term_getsize", 1, 1, f_term_getsize},
{"term_getstatus", 1, 1, f_term_getstatus},
{"term_gettitle", 1, 1, f_term_gettitle},
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index 556f9dd61..8bc413bda 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -20,6 +20,7 @@ void f_term_getattr(typval_T *argvars, typval_T *rettv);
void f_term_getcursor(typval_T *argvars, typval_T *rettv);
void f_term_getjob(typval_T *argvars, typval_T *rettv);
void f_term_getline(typval_T *argvars, typval_T *rettv);
+void f_term_getruncmd(typval_T *argvars, typval_T *rettv);
void f_term_getsize(typval_T *argvars, typval_T *rettv);
void f_term_getstatus(typval_T *argvars, typval_T *rettv);
void f_term_gettitle(typval_T *argvars, typval_T *rettv);
diff --git a/src/terminal.c b/src/terminal.c
index 738849be4..9a0ac6643 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -73,6 +73,14 @@
#include "vim.h"
+#if defined(__APPLE__)
+# include <sys/types.h>
+# include <sys/sysctl.h>
+#endif
+#if defined(_WIN32)
+# include <tlhelp32.h>
+#endif
+
#if defined(FEAT_TERMINAL) || defined(PROTO)
#ifdef WIN3264
@@ -1862,6 +1870,98 @@ f_term_getline(typval_T *argvars, typval_T *rettv)
}
/*
+ * "term_getruncmd(buf)" function
+ */
+ void
+f_term_getruncmd(typval_T *argvars, typval_T *rettv)
+{
+ buf_T *buf = term_get_buf(argvars);
+ channel_T *ch;
+#ifdef _WIN32
+ PROCESSENTRY32 pe;
+ HANDLE h;
+#else
+ pid_t pgrp;
+#endif
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ if (buf == NULL)
+ return;
+
+ if (buf->b_term->tl_job == NULL)
+ return;
+
+ ch = buf->b_term->tl_job->jv_channel;
+ if (ch == NULL || ch->CH_IN_FD == -1)
+ return;
+
+#ifdef _WIN32
+ h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ if (Process32First(h, &pe))
+ {
+ char_u fname[MAX_PATH];
+ fname[0] = NUL;
+ /* Get last process in process list. */
+ do
+ {
+ if (pe.th32ParentProcessID !=
+ buf->b_term->tl_job->jv_proc_info.dwProcessId)
+ continue;
+ STRCPY(fname, pe.szExeFile);
+ } while (Process32Next(h, &pe));
+
+ if (STRLEN(fname))
+ {
+ rettv->vval.v_string = vim_strsave(fname);
+ return;
+ }
+ }
+#else
+ pgrp = tcgetpgrp(ch->CH_IN_FD);
+ if (pgrp <= 0)
+ return;
+#endif
+
+#if defined(__linux__)
+ {
+ char fname[MAXPATHL];
+ char cmdline[64];
+ FILE *fp;
+ size_t bytes_read;
+ size_t i;
+
+ vim_snprintf(fname, MAXPATHL, "/proc/%ld/cmdline", pgrp);
+ fp = mch_fopen(fname, "r");
+ if (fp == NULL)
+ return;
+
+ bytes_read = fread(cmdline, 1, sizeof(cmdline), fp);
+ fclose(fp);
+
+ for (i = 0; i < bytes_read; ++i)
+ if (cmdline[i] == NUL)
+ cmdline[i] = ' ';
+ cmdline[bytes_read - 1] = NUL;
+
+ rettv->vval.v_string = vim_strsave(cmdline);
+ }
+#elif defined(__APPLE__)
+ {
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pgrp };
+ struct kinfo_proc kp;
+ size_t size = sizeof(kp);
+
+ if (sysctl(mib, 4, &kp, &size, NULL, 0) == -1)
+ return;
+
+ rettv->vval.v_string = vim_strsave((char_u *)kp.kp_proc.p_comm);
+ }
+#endif
+}
+
+/*
* "term_getsize(buf)" function
*/
void
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment