ref: 73e115aab038880a68c9f73b5c49d8fa12d0e5e2
parent: 827fdabbf912fa94b6472cf21cbdc5c82306af01
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Dec 14 15:52:04 EST 2022
vt: add OSC 7 support for plumbing of remote files without mount/bind magic
--- a/sys/src/cmd/vt/cons.h
+++ b/sys/src/cmd/vt/cons.h
@@ -10,7 +10,10 @@
#define INSET 2
#define BUFS 256
#define HISTSIZ (64*1024) /* number of history characters */
-#define BSIZE (8*1024)
+#define BSIZE (8*1024)
+#define WDIR 1024
+
+extern char osc7cwd[];
#define SCROLL 2
#define NEWLINE 1
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -1007,13 +1007,30 @@
void
plumbsel(void)
{
- char *s, wdir[1024];
+ char *s, *e, wdir[WDIR];
+ Plumbmsg msg;
int plumb;
s = selection();
if(s == nil || *s == 0)
return;
- if(getwd(wdir, sizeof wdir) == nil){
+ memset(&msg, 0, sizeof(msg));
+ msg.src = "vt";
+ msg.type = "text";
+ msg.ndata = strlen(s);
+ msg.data = s;
+ msg.wdir = wdir;
+ if(*osc7cwd != 0){
+ strcpy(wdir, osc7cwd);
+ /* absolute path? adjust wdir and path */
+ if(*s == '/'){
+ if((e = strchr(wdir+3, '/')) != nil){
+ *e = 0;
+ msg.data++;
+ msg.ndata--;
+ }
+ }
+ }else if(getwd(wdir, sizeof wdir) == nil){
free(s);
return;
}
@@ -1021,7 +1038,7 @@
free(s);
return;
}
- plumbsendtext(plumb, "vt", nil, wdir, s);
+ plumbsend(plumb, &msg);
close(plumb);
free(s);
}
--- a/sys/src/cmd/vt/vt.c
+++ b/sys/src/cmd/vt/vt.c
@@ -32,6 +32,7 @@
int originrelative = 0;
int tabcol[200];
+char osc7cwd[WDIR];
struct funckey ansifk[] = {
{ "up key", "\033[A", },
@@ -952,6 +953,16 @@
}
}
+static int
+hexnib(char c)
+{
+ if(c >= 'a')
+ return c - 'a' + 10;
+ if(c >= 'A')
+ return c - 'A' + 10;
+ return c - '0';
+}
+
// handle ESC], Operating System Command
static void
osc(void)
@@ -958,6 +969,7 @@
{
Rune ch, buf[BUFS+1];
int fd, osc, got, i;
+ char *o, *s;
osc = number(&ch, &got);
if(got) {
@@ -964,8 +976,7 @@
switch(osc) {
case 0:
case 1:
- case 2:
- // set title
+ case 2: /* set title */
i = 0;
while((ch = get_next_char()) != '\a') {
@@ -977,6 +988,33 @@
if((fd = open("/dev/label", OWRITE)) >= 0) {
fprint(fd, "%S", buf);
close(fd);
+ }
+ break;
+
+ case 7: /* set pwd */
+ i = 0;
+
+ while((ch = get_next_char()) != '\033'){
+ if(i < sizeof(osc7cwd)-UTFmax-1)
+ i += runetochar(osc7cwd+i, &ch);
+ }
+ get_next_char();
+ osc7cwd[i] = 0;
+
+ /* file://hostname/path → /n/hostname/path */
+ if(strncmp(osc7cwd, "file://", 7) == 0){
+ osc7cwd[0] = '/';
+ osc7cwd[1] = 'n';
+ o = osc7cwd+2;
+ s = osc7cwd+6;
+ while(*s){
+ if(*s == '%' && s[1] != 0 && s[2] != 0){
+ *o++ = hexnib(s[1])<<4 | hexnib(s[2]);
+ s += 3;
+ }else
+ *o++ = *s++;
+ }
+ *o = 0;
}
break;
}