aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@gmail.com>2012-10-09 17:09:26 +0000
committerGustavo Sverzut Barbieri <barbieri@gmail.com>2012-10-09 17:09:26 +0000
commit84d381344a2a19ac7e2cd99cf7968432c0554bef (patch)
treef80e960e4277c6a098485871577896ee03d25d39
parentsupport 'mailto:address' (diff)
downloadterminology-84d381344a2a19ac7e2cd99cf7968432c0554bef.tar.gz
big time improvement: relative paths: ~/file, ./file and ../file
The current working directory is assumed to be the cwd of our shell pid, discovered from /proc/$PID/cwd link. SVN revision: 77662
-rw-r--r--src/bin/termio.c8
-rw-r--r--src/bin/termio.h1
-rw-r--r--src/bin/termiolink.c91
-rw-r--r--src/bin/termpty.c6
-rw-r--r--src/bin/termpty.h2
5 files changed, 104 insertions, 4 deletions
diff --git a/src/bin/termio.c b/src/bin/termio.c
index d023a1b..adb794d 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -2649,3 +2649,11 @@ termio_scroll_get(Evas_Object *obj)
if (!sd) return 0;
return sd->scroll;
}
+
+pid_t
+termio_pid_get(const Evas_Object *obj)
+{
+ Termio *sd = evas_object_smart_data_get(obj);
+ if (!sd) return 0;
+ return termpty_pid_get(sd->pty);
+}
diff --git a/src/bin/termio.h b/src/bin/termio.h
index b40d6f0..20008be 100644
--- a/src/bin/termio.h
+++ b/src/bin/termio.h
@@ -18,5 +18,6 @@ void termio_size_get(Evas_Object *obj, int *w, int *h);
int termio_scroll_get(Evas_Object *obj);
void termio_font_size_set(Evas_Object *obj, int size);
void termio_grid_size_set(Evas_Object *obj, int w, int h);
+pid_t termio_pid_get(const Evas_Object *obj);
#endif
diff --git a/src/bin/termiolink.c b/src/bin/termiolink.c
index 47fcfae..f3f9c75 100644
--- a/src/bin/termiolink.c
+++ b/src/bin/termiolink.c
@@ -37,6 +37,80 @@ coord_forward(int *x, int *y, int w, int h)
return EINA_TRUE;
}
+static char *
+_cwd_path_get(const Evas_Object *obj, const char *relpath)
+{
+ char procpath[PATH_MAX], cwdpath[PATH_MAX], tmppath[PATH_MAX];
+ pid_t pid = termio_pid_get(obj);
+
+ snprintf(procpath, sizeof(procpath), "/proc/%d/cwd", pid);
+ if (readlink(procpath, cwdpath, sizeof(cwdpath)) < 1)
+ {
+ ERR("Could not load working directory %s: %s",
+ procpath, strerror(errno));
+ return NULL;
+ }
+
+ eina_str_join(tmppath, sizeof(tmppath), '/', cwdpath, relpath);
+ return strdup(tmppath);
+}
+
+static char *
+_home_path_get(const Evas_Object *obj __UNUSED__, const char *relpath)
+{
+ char tmppath[PATH_MAX];
+ const char *home = getenv("HOME");
+ if (!home)
+ {
+ uid_t uid = getuid();
+ struct passwd *pw = getpwuid(uid);
+ if (pw) home = pw->pw_dir;
+ }
+ if (!home)
+ {
+ ERR("Could not get $HOME");
+ return NULL;
+ }
+
+ eina_str_join(tmppath, sizeof(tmppath), '/', home, relpath);
+ return strdup(tmppath);
+}
+
+static char *
+_local_path_get(const Evas_Object *obj, const char *relpath)
+{
+ if (relpath[0] == '/')
+ return strdup(relpath);
+ else if (eina_str_has_prefix(relpath, "~/"))
+ return _home_path_get(obj, relpath + 2);
+ else
+ return _cwd_path_get(obj, relpath);
+}
+
+static Eina_Bool
+_is_file(const char *str)
+{
+ switch (str[0])
+ {
+ case '/':
+ case '~':
+ if (str[1] == '/')
+ return EINA_TRUE;
+ return EINA_FALSE;
+
+ case '.':
+ if (str[1] == '/')
+ return EINA_TRUE;
+ else if ((str[1] == '.') && (str[2] == '/'))
+ return EINA_TRUE;
+
+ return EINA_FALSE;
+
+ default:
+ return EINA_FALSE;
+ }
+}
+
char *
_termio_link_find(Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r)
{
@@ -85,7 +159,7 @@ _termio_link_find(Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r
else if (s[0] == '<') endmatch = '>';
if ((casestartswith((s + 1), "www.")) ||
(casestartswith((s + 1), "ftp.")) ||
- (s[1] == '/'))
+ (_is_file(s + 1)))
{
goback = EINA_FALSE;
coord_forward(&x1, &y1, w, h);
@@ -158,14 +232,23 @@ _termio_link_find(Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r
}
if ((!isspace(s[0])) && (len > 1))
{
- if (link_is_email(s) ||
- link_is_url(s) ||
- (s[0] == '/'))
+ Eina_Bool is_file = _is_file(s);
+ if (is_file ||
+ link_is_email(s) ||
+ link_is_url(s))
{
if (x1r) *x1r = x1;
if (y1r) *y1r = y1;
if (x2r) *x2r = x2;
if (y2r) *y2r = y2;
+
+ if (is_file && (s[0] != '/'))
+ {
+ char *ret = _local_path_get(obj, s);
+ free(s);
+ return ret;
+ }
+
return s;
}
}
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 6954c90..6a39e75 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -532,3 +532,9 @@ termpty_backscroll_set(Termpty *ty, int size)
ty->backpos = 0;
ty->backmax = size;
}
+
+pid_t
+termpty_pid_get(const Termpty *ty)
+{
+ return ty->pid;
+}
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index 325e823..93d87a9 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -134,4 +134,6 @@ void termpty_write(Termpty *ty, const char *input, int len);
void termpty_resize(Termpty *ty, int w, int h);
void termpty_backscroll_set(Termpty *ty, int size);
+pid_t termpty_pid_get(const Termpty *ty);
+
extern int _termpty_log_dom;