#1101087 fish: Fish outputs garble string as prompt with fbterm.

Package:
fish
Source:
fish
Description:
friendly interactive shell
Submitter:
Hideo Oshima
Date:
2025-03-23 09:18:01 UTC
Severity:
normal
#1101087#5
Date:
2025-03-23 01:46:22 UTC
From:
To:
Dear Maintainer,

*** Reporter, please consider answering these questions, where appropriate ***

   * What led up to the situation?
Fish outputs garble string as prompt with fbterm.
It's ok with gnome-console etc.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?
   * What was the outcome of this action?
Fish outputs "33;A;special_k4;1m5udeo@Mary~ $".

   * What outcome did you expect instead?
Fish outpus "hideo@mary $"
*** End of the template - remove these template lines ***

I think this issue stared from fish 4.0.

#1101087#10
Date:
2025-03-23 09:15:34 UTC
From:
To:
I think this patch to fbterm could fix it.

It's based off http://deb.debian.org/debian/pool/main/f/fbterm/fbterm_1.7.orig.tar.gz

Upstream doesn't seem active so I don't know where to send it to.

There seems to be an unrelated problem, seen on my machine with the
version of fbterm I compiled to test this patch: cursor movement in
fish does not work. But that problem does not exist in the fbterm
(1.7) installed from my package manager.  That's why I think the
patch might be enough.

diff --git a/src/lib/vterm.cpp b/src/lib/vterm.cpp
index 3a5dcc7..39d261e 100644
--- a/src/lib/vterm.cpp
+++ b/src/lib/vterm.cpp
@@ -407,7 +407,35 @@ void VTerm::input(const u8 *buf, u32 count)
 			continue;
 		}

-		do_control_char();
+		if (esc_state == VTerm::ES_CSI_Init || esc_state == VTerm::ES_CSI_Parameters || esc_state == VTerm::ES_CSI_Intermediate) {
+			if (esc_state == VTerm::ES_CSI_Init)
+			{
+				this->clear_param();
+				esc_state = VTerm::ES_CSI_Parameters;
+			}
+			if (tc >= 0x40 && tc <= 0x7e)
+				esc_state = ESnormal;
+			else if (tc >= 0x20 && tc <= 0x2f)
+				esc_state = ES_CSI_Intermediate;
+		} else if (esc_state == VTerm::ES_OSC_Init || esc_state == VTerm::ES_OSC) {
+			if (esc_state == VTerm::ES_OSC_Init) {
+				this->clear_param();
+				esc_state = VTerm::ES_OSC;
+			}
+			if (tc == 0x07)
+				esc_state = ESnormal;
+			if (esc_state == ES_OSC_Maybe_ST)
+			{
+				if (tc == '\\')
+    				    esc_state = ESnormal;
+				else
+    				    esc_state = ES_OSC;
+			}
+			if (tc == 0x1b)
+				esc_state = ES_OSC_Maybe_ST;
+		} else {
+			do_control_char();
+		}
 	}

 	update();
diff --git a/src/lib/vterm.h b/src/lib/vterm.h
index 32ffd2a..cdc4bb6 100644
--- a/src/lib/vterm.h
+++ b/src/lib/vterm.h
@@ -185,7 +185,10 @@ private:
 	static bool init_ambiguous_wide();

 	typedef enum {
-		ESnormal = 0, ESesc, ESsquare, ESnonstd, ESpercent, EScharset, EShash, ESfunckey, ESkeep
+		ESnormal = 0, ESesc, ESsquare, ESnonstd,
+		ESpercent, EScharset, EShash, ESfunckey, ESkeep,
+		ES_CSI_Init, ES_CSI_Parameters, ES_CSI_Intermediate,
+		ES_OSC_Init, ES_OSC, ES_OSC_Maybe_ST,
 	} EscapeState;

 	EscapeState esc_state;
diff --git a/src/lib/vterm_states.cpp b/src/lib/vterm_states.cpp
index 1881490..3bcfcc8 100644
--- a/src/lib/vterm_states.cpp
+++ b/src/lib/vterm_states.cpp
@@ -49,8 +49,8 @@ const VTerm::Sequence VTerm::escape_sequences[] = {
 	{ static_cast<u16>(-1) },

 	// ESesc
-	{ '[', &VTerm::clear_param,	ESsquare },
-	{ ']', &VTerm::clear_param,	ESnonstd },
+	{ '[', 0,	ES_CSI_Init },
+	{ ']', 0,	ES_OSC_Init },
 	{ '%', 0,	ESpercent },
 	{ '#', 0,	EShash },
 	{ '(', &VTerm::current_is_g0,	EScharset },