zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] feat(prompt): %p for percent encoded pwd
@ 2024-08-11  8:18 Liao Junxuan
  2024-08-11 14:28 ` Roman Perepelitsa
  0 siblings, 1 reply; 3+ messages in thread
From: Liao Junxuan @ 2024-08-11  8:18 UTC (permalink / raw)
  To: zsh-workers; +Cc: Liao Junxuan

This adds a new escape %p to allow the user to set an osc 8 sequence [1] in
their prompt. Here's an example:
$'%{\e]8;;file://%M%o\e\\%}%~%{\e]8;;\e\\%}'

I'll add relevant documentation if anyone's interested.

[1]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
---
 Src/init.c   |  1 +
 Src/prompt.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/Src/init.c b/Src/init.c
index ec21521b1..75d47e62c 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1901,6 +1901,7 @@ zsh_main(UNUSED(int argc), char **argv)
 
     SHTTY = -1;
     init_io(cmd);
+    init_prompt();
     setupvals(cmd, runscript, zsh_name);
 
     init_signals();
diff --git a/Src/prompt.c b/Src/prompt.c
index e10b05215..11d81e3ef 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -120,13 +120,16 @@ typedef struct buf_vars *Buf_vars;
 /* The currently active prompt output variables */
 static Buf_vars bv;
 
+/* Should not be percent encoded in URI */
+static int percent_encode_except[256];
+
 /*
  * Expand path p; maximum is npath segments where 0 means the whole path.
  * If tilde is 1, try and find a named directory to use.
  */
 
 static void
-promptpath(char *p, int npath, int tilde)
+promptpath(char *p, int npath, int tilde, int percent_encode)
 {
     char *modp = p;
     Nameddir nd;
@@ -156,13 +159,36 @@ promptpath(char *p, int npath, int tilde)
 	    stradd(modp);
 	    *sptr = cbu;
 	}
-    } else
+    } else if (percent_encode) {
+	char *path = strdup(p);
+	unmetafy(path, NULL);
+	modp = zalloc(3 * strlen(path) + 1);
+	char *ptr_modp = modp;
+	char *ptr_p = path;
+	while (*ptr_p) {
+		if (percent_encode_except[(unsigned char)*ptr_p])
+			*ptr_modp++ = *ptr_p++;
+		else
+			ptr_modp += sprintf(ptr_modp, "%%%02x", (unsigned char) *ptr_p++);
+	}
+	*ptr_modp = 0;
+	metafy(modp, -1, META_REALLOC);
+	stradd(modp);
+    } else {
 	stradd(modp);
+    }
 
     if (p != modp)
 	zsfree(modp);
 }
 
+/**/
+mod_export void
+init_prompt(void) {
+    for (int i = 0; i < 256; i++)
+	percent_encode_except[i] = isalnum(i) || i == '~' || i == '-' || i == '.' || i == '_' || i == '/';
+}
+
 /*
  * Perform prompt expansion on a string, putting the result in a
  * permanently-allocated string.  If ns is non-zero, this string
@@ -528,21 +554,24 @@ putpromptchar(int doprint, int endchar)
 		}
 	    switch (*bv->fm) {
 	    case '~':
-		promptpath(pwd, arg, 1);
+		promptpath(pwd, arg, 1, 0);
 		break;
 	    case 'd':
 	    case '/':
-		promptpath(pwd, arg, 0);
+		promptpath(pwd, arg, 0, 0);
+		break;
+	    case 'p':
+		promptpath(pwd, 0, 0, 1);
 		break;
 	    case 'c':
 	    case '.':
-		promptpath(pwd, arg ? arg : 1, 1);
+		promptpath(pwd, arg ? arg : 1, 1, 0);
 		break;
 	    case 'C':
-		promptpath(pwd, arg ? arg : 1, 0);
+		promptpath(pwd, arg ? arg : 1, 0, 0);
 		break;
 	    case 'N':
-		promptpath(scriptname ? scriptname : argzero, arg, 0);
+		promptpath(scriptname ? scriptname : argzero, arg, 0, 0);
 		break;
 	    case 'h':
 	    case '!':
@@ -926,10 +955,10 @@ putpromptchar(int doprint, int endchar)
 		if (funcstack && funcstack->tp != FS_SOURCE &&
 		    !IN_EVAL_TRAP())
 		    promptpath(funcstack->filename ? funcstack->filename : "",
-			       arg, 0);
+			       arg, 0, 0);
 		else
 		    promptpath(scriptfilename ? scriptfilename : argzero,
-			       arg, 0);
+			       arg, 0, 0);
 		break;
 	    case '\0':
 		return 0;
-- 
2.46.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] feat(prompt): %p for percent encoded pwd
  2024-08-11  8:18 [PATCH] feat(prompt): %p for percent encoded pwd Liao Junxuan
@ 2024-08-11 14:28 ` Roman Perepelitsa
  2024-08-11 17:38   ` 廖骏轩
  0 siblings, 1 reply; 3+ messages in thread
From: Roman Perepelitsa @ 2024-08-11 14:28 UTC (permalink / raw)
  To: Liao Junxuan; +Cc: zsh-workers

On Sun, Aug 11, 2024 at 10:20 AM Liao Junxuan <mikeljx@126.com> wrote:
>
> This adds a new escape %p to allow the user to set an osc 8 sequence [1] in
> their prompt.

I use this function to URL-encode things in zsh:

    function url-encode() {
      emulate -L zsh -o extended_glob
      local MATCH MBEGIN MEND
      typeset -g
REPLY=${1//(#m)[^a-zA-Z0-9"\/:_.-!'()~"]/%${(l:2::0:)$(([##16]#MATCH))}}
    }

(Please forgive a forced line break before "REPLY".)

Example:

    % pwd
    /home/romka/hello world

    % url-encode $PWD && print -r -- $REPLY
    /home/romka/hello%20world

It's suitable for generating OSC 8 and the like. I don't think I ever
wished zsh had a dedicated escape for URL-encoded $PWD.

Roman


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] feat(prompt): %p for percent encoded pwd
  2024-08-11 14:28 ` Roman Perepelitsa
@ 2024-08-11 17:38   ` 廖骏轩
  0 siblings, 0 replies; 3+ messages in thread
From: 廖骏轩 @ 2024-08-11 17:38 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: zsh-workers


> It's suitable for generating OSC 8 and the like. I don't think I ever
> wished zsh had a dedicated escape for URL-encoded $PWD.

Yeah, that makes sense. PROMPT_SUBST is probably more suitable for the job. A new escape is maybe an overkill.

Junxuan


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-08-11 17:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-11  8:18 [PATCH] feat(prompt): %p for percent encoded pwd Liao Junxuan
2024-08-11 14:28 ` Roman Perepelitsa
2024-08-11 17:38   ` 廖骏轩

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).