commit 95220bf88775deab4a037264d08b21bacc612d70 from: sean via: Russ Cox date: Sat May 30 01:42:23 2020 UTC ed: handle Unicode beyond the BMP correctly in list mode. List mode was constrained to the BMP. This change introduces the following new list mode convention, using Go string literal syntax: Non-printing ASCII characters display as \xhh. Non-ASCII characters in the BMP display as \uhhhh. Characters beyond the BMP display as \Uhhhhhhhh. commit - 3850e6e177677885074c8896ef24534894726ad5 commit + 95220bf88775deab4a037264d08b21bacc612d70 blob - 00eb095a35788a190851bdfe1d082b458146ff24 blob + 9b161b297e911b51d7e36ca944763faf1095c03f --- man/man1/ed.1 +++ man/man1/ed.1 @@ -441,10 +441,18 @@ a backspace as .LR \eb , backslashes as .LR \e\e , -and non-printing characters as +and non-printing ASCII characters as a backslash, an .LR x , -and four hexadecimal digits. +and two hexadecimal digits. +non-ASCII characters in the Basic Multilingual Plane +are printed as a backslash, a small +.LR u , +and four hexadecimal digits; and characters above the +Basic Multilingual Plane are printed as a backslash, +a big +.LR U , +and six hexadecimal digits. Long lines are folded, with the second and subsequent sub-lines indented one tab stop. If the last character in the line is a blank, blob - 8b0f36e547b8bf8e204a624715d67349221599e0 blob + a04f0d3f4b7d68090d7255d7798c5e6fef18969f --- src/cmd/ed.c +++ src/cmd/ed.c @@ -19,6 +19,12 @@ enum MAXSUB = 9, /* max number of sub reg exp */ ESCFLG = 0xFFFF, /* escape Rune - user defined code */ EOF = -1 +}; + +enum +{ + LINELEN = 70, /* max number of glyphs in a display line */ + BELL = 6 /* A char could require up to BELL glyphs to display */ }; void (*oldhup)(int); @@ -40,7 +46,7 @@ int ichanged; int io; Biobuf iobuf; int lastc; -char line[70]; +char line[LINELEN]; Rune* linebp; Rune linebuf[LBSIZE]; int listf; @@ -1543,7 +1549,7 @@ putchr(int ac) *lp++ = 'n'; } } else { - if(col > (72-6-2)) { + if(col > (LINELEN-BELL)) { col = 8; *lp++ = '\\'; *lp++ = '\n'; @@ -1558,15 +1564,32 @@ putchr(int ac) if(c == '\t') c = 't'; col++; - } else - if(c<' ' || c>='\177') { + } else if (c<' ' || c=='\177') { *lp++ = '\\'; *lp++ = 'x'; - *lp++ = hex[c>>12]; - *lp++ = hex[c>>8&0xF]; - *lp++ = hex[c>>4&0xF]; - c = hex[c&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; + col += 3; + } else if (c>'\177' && c<=0xFFFF) { + *lp++ = '\\'; + *lp++ = 'u'; + *lp++ = hex[(c>>12)&0xF]; + *lp++ = hex[(c>>8)&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; col += 5; + } else if (c>0xFFFF) { + *lp++ = '\\'; + *lp++ = 'U'; + *lp++ = hex[(c>>28)&0xF]; + *lp++ = hex[(c>>24)&0xF]; + *lp++ = hex[(c>>20)&0xF]; + *lp++ = hex[(c>>16)&0xF]; + *lp++ = hex[(c>>12)&0xF]; + *lp++ = hex[(c>>8)&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; + col += 9; } } } @@ -1574,7 +1597,7 @@ putchr(int ac) rune = c; lp += runetochar(lp, &rune); - if(c == '\n' || lp >= &line[sizeof(line)-5]) { + if(c == '\n' || lp >= &line[LINELEN-BELL]) { linp = line; write(oflag? 2: 1, line, lp-line); return;