mirror of https://github.com/jetkvm/kvm.git
Improve normalization
This commit is contained in:
parent
7b9410c36d
commit
2ce5623712
|
|
@ -326,7 +326,9 @@ type SerialSettings struct {
|
||||||
EnableEcho bool `json:"enableEcho"` // Whether to echo received characters back to the sender
|
EnableEcho bool `json:"enableEcho"` // Whether to echo received characters back to the sender
|
||||||
NormalizeMode string `json:"normalizeMode"` // Normalization mode: "carret", "names", "hex"
|
NormalizeMode string `json:"normalizeMode"` // Normalization mode: "carret", "names", "hex"
|
||||||
NormalizeLineEnd string `json:"normalizeLineEnd"` // Line ending normalization: "keep", "lf", "cr", "crlf"
|
NormalizeLineEnd string `json:"normalizeLineEnd"` // Line ending normalization: "keep", "lf", "cr", "crlf"
|
||||||
|
TabRender string `json:"tabRender"` // How to render tabs: "spaces", "arrow", "pipe"
|
||||||
PreserveANSI bool `json:"preserveANSI"` // Whether to preserve ANSI escape codes
|
PreserveANSI bool `json:"preserveANSI"` // Whether to preserve ANSI escape codes
|
||||||
|
ShowNLTag bool `json:"showNLTag"` // Whether to show a special tag for new lines
|
||||||
Buttons []QuickButton `json:"buttons"` // Custom quick buttons
|
Buttons []QuickButton `json:"buttons"` // Custom quick buttons
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,7 +440,7 @@ func getSerialSettings() (SerialSettings, error) {
|
||||||
|
|
||||||
if consoleBroker != nil {
|
if consoleBroker != nil {
|
||||||
norm := NormOptions{
|
norm := NormOptions{
|
||||||
Mode: normalizeMode, CRLF: crlfMode, TabRender: "", PreserveANSI: serialConfig.PreserveANSI,
|
Mode: normalizeMode, CRLF: crlfMode, TabRender: serialConfig.TabRender, PreserveANSI: serialConfig.PreserveANSI, ShowNLTag: serialConfig.ShowNLTag,
|
||||||
}
|
}
|
||||||
consoleBroker.SetNormOptions(norm)
|
consoleBroker.SetNormOptions(norm)
|
||||||
}
|
}
|
||||||
|
|
@ -533,7 +535,7 @@ func setSerialSettings(newSettings SerialSettings) error {
|
||||||
|
|
||||||
if consoleBroker != nil {
|
if consoleBroker != nil {
|
||||||
norm := NormOptions{
|
norm := NormOptions{
|
||||||
Mode: normalizeMode, CRLF: crlfMode, TabRender: "", PreserveANSI: serialConfig.PreserveANSI,
|
Mode: normalizeMode, CRLF: crlfMode, TabRender: serialConfig.TabRender, PreserveANSI: serialConfig.PreserveANSI, ShowNLTag: serialConfig.ShowNLTag,
|
||||||
}
|
}
|
||||||
consoleBroker.SetNormOptions(norm)
|
consoleBroker.SetNormOptions(norm)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ type NormOptions struct {
|
||||||
CRLF CRLFMode
|
CRLF CRLFMode
|
||||||
TabRender string // e.g. " " or "" to keep '\t'
|
TabRender string // e.g. " " or "" to keep '\t'
|
||||||
PreserveANSI bool
|
PreserveANSI bool
|
||||||
|
ShowNLTag bool // <- NEW: also print a visible tag for CR/LF
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalize(in []byte, opt NormOptions) string {
|
func normalize(in []byte, opt NormOptions) string {
|
||||||
|
|
@ -88,42 +89,68 @@ func normalize(in []byte, opt NormOptions) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CR/LF normalization
|
// CR/LF normalization (emit real newline(s), optionally tag them visibly)
|
||||||
if b == '\r' || b == '\n' {
|
if b == '\r' || b == '\n' {
|
||||||
|
// detect pair (CRLF or LFCR)
|
||||||
|
isPair := i+1 < len(in) &&
|
||||||
|
((b == '\r' && in[i+1] == '\n') || (b == '\n' && in[i+1] == '\r'))
|
||||||
|
|
||||||
|
// optional visible tag of what we *saw*
|
||||||
|
if opt.ShowNLTag {
|
||||||
|
if isPair {
|
||||||
|
if b == '\r' { // saw CRLF
|
||||||
|
out.WriteString("<CRLF>")
|
||||||
|
} else { // saw LFCR
|
||||||
|
out.WriteString("<LFCR>")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if b == '\r' {
|
||||||
|
out.WriteString("<CR>")
|
||||||
|
} else {
|
||||||
|
out.WriteString("<LF>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now emit the actual newline(s) per the normalization mode
|
||||||
switch opt.CRLF {
|
switch opt.CRLF {
|
||||||
case CRLFAsIs:
|
case CRLFAsIs:
|
||||||
out.WriteByte(b)
|
if isPair {
|
||||||
i++
|
out.WriteByte(b)
|
||||||
|
out.WriteByte(in[i+1])
|
||||||
|
i += 2
|
||||||
|
} else {
|
||||||
|
out.WriteByte(b)
|
||||||
|
i++
|
||||||
|
}
|
||||||
case CRLF_LF:
|
case CRLF_LF:
|
||||||
if i+1 < len(in) && ((b == '\r' && in[i+1] == '\n') || (b == '\n' && in[i+1] == '\r')) {
|
if isPair {
|
||||||
i += 2
|
i += 2
|
||||||
} else {
|
} else {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
out.WriteByte('\n')
|
out.WriteByte('\n')
|
||||||
case CRLF_CR:
|
case CRLF_CR:
|
||||||
if i+1 < len(in) && ((b == '\r' && in[i+1] == '\n') || (b == '\n' && in[i+1] == '\r')) {
|
if isPair {
|
||||||
i += 2
|
i += 2
|
||||||
} else {
|
} else {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
out.WriteByte('\r')
|
out.WriteByte('\r')
|
||||||
case CRLF_CRLF:
|
case CRLF_CRLF:
|
||||||
if i+1 < len(in) && ((b == '\r' && in[i+1] == '\n') || (b == '\n' && in[i+1] == '\r')) {
|
if isPair {
|
||||||
out.WriteString("\n")
|
|
||||||
i += 2
|
i += 2
|
||||||
} else {
|
} else {
|
||||||
out.WriteString("\n")
|
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
out.WriteString("\r\n") // (fixed to actually write CRLF)
|
||||||
case CRLF_LFCR:
|
case CRLF_LFCR:
|
||||||
if i+1 < len(in) && ((b == '\r' && in[i+1] == '\n') || (b == '\n' && in[i+1] == '\r')) {
|
if isPair {
|
||||||
out.WriteString("\r")
|
|
||||||
i += 2
|
i += 2
|
||||||
} else {
|
} else {
|
||||||
out.WriteString("\r")
|
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
out.WriteString("\n\r")
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,9 @@ interface SerialSettings {
|
||||||
enableEcho: boolean; // future use
|
enableEcho: boolean; // future use
|
||||||
normalizeMode: string; // future use
|
normalizeMode: string; // future use
|
||||||
normalizeLineEnd: string; // future use
|
normalizeLineEnd: string; // future use
|
||||||
|
tabRender: string; // future use
|
||||||
preserveANSI: boolean; // future use
|
preserveANSI: boolean; // future use
|
||||||
|
showNLTag: boolean; // future use
|
||||||
buttons: QuickButton[];
|
buttons: QuickButton[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +58,9 @@ export function SerialConsole() {
|
||||||
enableEcho: false,
|
enableEcho: false,
|
||||||
normalizeMode: "names",
|
normalizeMode: "names",
|
||||||
normalizeLineEnd: "keep",
|
normalizeLineEnd: "keep",
|
||||||
|
tabRender: "",
|
||||||
preserveANSI: true,
|
preserveANSI: true,
|
||||||
|
showNLTag: true,
|
||||||
buttons: [],
|
buttons: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -247,7 +251,7 @@ export function SerialConsole() {
|
||||||
{/* Serial settings (collapsible) */}
|
{/* Serial settings (collapsible) */}
|
||||||
{!buttonConfig.hideSerialSettings && (
|
{!buttonConfig.hideSerialSettings && (
|
||||||
<>
|
<>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4 mb-1">
|
||||||
<SelectMenuBasic
|
<SelectMenuBasic
|
||||||
label="Baud Rate"
|
label="Baud Rate"
|
||||||
options={[
|
options={[
|
||||||
|
|
@ -365,6 +369,35 @@ export function SerialConsole() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<SelectMenuBasic
|
||||||
|
className="mb-1"
|
||||||
|
label="Show newline tag"
|
||||||
|
options={[
|
||||||
|
{ label: "Hide <LF> tag", value: "hide" },
|
||||||
|
{ label: "Show <LF> tag", value: "show" },
|
||||||
|
]}
|
||||||
|
value={buttonConfig.showNLTag ? "show" : "hide"}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleSerialSettingsChange("showNLTag", e.target.value === "show")
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<InputFieldWithLabel
|
||||||
|
size="MD"
|
||||||
|
type="text"
|
||||||
|
label="Tab replacement"
|
||||||
|
placeholder="ex. spaces, →, |"
|
||||||
|
value={buttonConfig.tabRender}
|
||||||
|
onChange={e => {
|
||||||
|
handleSerialSettingsChange("tabRender", e.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="text-xs text-white opacity-70 mt-1">
|
||||||
|
Empty for no replacement
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-4 m-2">
|
<div className="space-y-4 m-2">
|
||||||
<SettingsItem
|
<SettingsItem
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue