To: vim_dev@googlegroups.com Subject: Patch 8.2.3666 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3666 Problem: Libvterm is outdated. Solution: Include patches from revision 769 to revision 789. Files: Filelist, src/libvterm/Makefile, src/libvterm/doc/seqs.txt, src/libvterm/include/vterm.h, src/libvterm/src/mouse.c, src/libvterm/src/parser.c, src/libvterm/src/state.c, src/libvterm/src/vterm.c, src/libvterm/src/vterm_internal.h, src/libvterm/t/02parser.test, src/libvterm/t/17state_mouse.test, src/libvterm/t/29state_fallback.test, src/libvterm/t/40state_selection.test, src/libvterm/t/harness.c, src/libvterm/t/run-test.pl, src/libvterm/vterm.pc.in, src/terminal.c *** ../vim-8.2.3665/Filelist 2021-11-22 12:06:03.554863352 +0000 --- Filelist 2021-11-24 19:27:46.823119386 +0000 *************** *** 377,382 **** --- 377,383 ---- src/libvterm/t/30state_pen.test \ src/libvterm/t/31state_rep.test \ src/libvterm/t/32state_flow.test \ + src/libvterm/t/40state_selection.test \ src/libvterm/t/60screen_ascii.test \ src/libvterm/t/61screen_unicode.test \ src/libvterm/t/62screen_damage.test \ *** ../vim-8.2.3665/src/libvterm/Makefile 2020-12-03 20:24:04.089645975 +0000 --- src/libvterm/Makefile 2021-11-24 17:06:17.894488647 +0000 *************** *** 37,43 **** HFILES_INT=$(sort $(wildcard src/*.h)) $(HFILES) VERSION_MAJOR=0 ! VERSION_MINOR=1 VERSION_CURRENT=0 VERSION_REVISION=0 --- 37,43 ---- HFILES_INT=$(sort $(wildcard src/*.h)) $(HFILES) VERSION_MAJOR=0 ! VERSION_MINOR=2 VERSION_CURRENT=0 VERSION_REVISION=0 *************** *** 97,103 **** install -d $(DESTDIR)$(INCDIR) install -m644 $(HFILES) $(DESTDIR)$(INCDIR) install -d $(DESTDIR)$(LIBDIR)/pkgconfig ! sed -e "s,@PREFIX@,$(PREFIX)," -e "s,@LIBDIR@,$(LIBDIR)," -e "s,@VERSION@,$(VERSION)," $(DESTDIR)$(LIBDIR)/pkgconfig/vterm.pc install-lib: $(LIBRARY) install -d $(DESTDIR)$(LIBDIR) --- 97,103 ---- install -d $(DESTDIR)$(INCDIR) install -m644 $(HFILES) $(DESTDIR)$(INCDIR) install -d $(DESTDIR)$(LIBDIR)/pkgconfig ! sed -e "s,@INCDIR@,$(INCDIR)," -e "s,@LIBDIR@,$(LIBDIR)," -e "s,@VERSION@,$(VERSION)," $(DESTDIR)$(LIBDIR)/pkgconfig/vterm.pc install-lib: $(LIBRARY) install -d $(DESTDIR)$(LIBDIR) *** ../vim-8.2.3665/src/libvterm/doc/seqs.txt 2020-05-20 17:41:37.157258608 +0100 --- src/libvterm/doc/seqs.txt 2021-11-24 17:50:42.675983651 +0000 *************** *** 4,231 **** 1 = VT100 2 = VT220 3 = VT320 ! C0 controls ! 123 0x00 = NUL ! 123 0x07 = BEL ! 123 0x08 = BS ! 123 0x09 = HT ! 123 0x0A = LF ! 123 0x0B = VT ! 123 0x0C = FF ! 123 0x0D = CR ! 123 0x0E = LS1 ! 123 0x0F = LS0 ! (0x18 = CAN) ! (0x1A = SUB) ! (0x1B = ESC) ! ! 123 0x7f = DEL (ignored) ! ! C1 controls ! ! 123 0x84 = IND ! 123 0x85 = NEL ! 123 0x88 = HTS ! 123 0x8D = RI ! 23 0x8e = SS2 ! 23 0x8f = SS3 ! (0x90 = DCS) ! (0x9B = CSI) ! (0x9C = ST) ! (0x9D = OSC) ! ! Escape sequences ! - excluding sequences that are C1 aliases ! ! 123 ESC () = SCS, select character set (G0, G1) ! 23 ESC *+ = SCS, select character set (G2, G3) ! 123 ESC 7 = DECSC - save cursor ! 123 ESC 8 = DECRC - restore cursor ! 123 ESC # 3 = DECDHL, double-height line (top half) ! 123 ESC # 4 = DECDHL, double-height line (bottom half) ! 123 ESC # 5 = DECSWL, single-width single-height line ! 123 ESC # 6 = DECDWL, double-width single-height line ! 123 ESC # 8 = DECALN ! 123 ESC < = Ignored (used by VT100 to exit VT52 mode) ! 123 ESC = = DECKPAM, keypad application mode ! 123 ESC > = DECKPNM, keypad numeric mode ! 23 ESC Sp F = S7C1T ! 23 ESC Sp G = S8C1T ! (ESC P = DCS) ! (ESC [ = CSI) ! (ESC \ = ST) ! (ESC ] = OSC) ! 123 ESC c = RIS, reset initial state ! 3 ESC n = LS2 ! 3 ESC o = LS3 ! 3 ESC ~ = LS1R ! 3 ESC } = LS2R ! 3 ESC | = LS3R ! ! DCSes ! ! 3 DCS $ q ST = DECRQSS ! 3 m = Request SGR ! Sp q = Request DECSCUSR ! 3 " q = Request DECSCA ! 3 r = Request DECSTBM ! s = Request DECSLRM ! ! CSIs ! 23 CSI @ = ICH ! 123 CSI A = CUU ! 123 CSI B = CUD ! 123 CSI C = CUF ! 123 CSI D = CUB ! CSI E = CNL ! CSI F = CPL ! CSI G = CHA ! 123 CSI H = CUP ! CSI I = CHT ! 123 CSI J = ED ! 23 CSI ? J = DECSED, selective erase in display ! 123 CSI K = EL ! 23 CSI ? K = DECSEL, selective erase in line ! 23 CSI L = IL ! 23 CSI M = DL ! 23 CSI P = DCH ! CSI S = SU ! CSI T = SD ! 23 CSI X = ECH ! CSI Z = CBT ! CSI ` = HPA ! CSI a = HPR ! CSI b = REP ! 123 CSI c = DA, device attributes ! 123 0 = DA ! 23 CSI > c = DECSDA ! 23 0 = SDA ! CSI d = VPA ! CSI e = VPR ! 123 CSI f = HVP ! 123 CSI g = TBC ! 123 CSI h = SM, Set mode ! 123 CSI ? h = DECSM, DEC set mode ! CSI j = HPB ! CSI k = VPB ! 123 CSI l = RM, Reset mode ! 123 CSI ? l = DECRM, DEC reset mode ! 123 CSI m = SGR, Set Graphic Rendition ! 123 CSI n = DSR, Device Status Report ! 23 5 = operating status ! 23 6 = CPR = cursor position ! 23 CSI ? n = DECDSR; behaves as DSR but uses CSI ? instead of CSI to respond ! 23 CSI ! p = DECSTR, soft terminal reset ! 3 CSI ? $ p = DECRQM, request mode ! CSI Sp q = DECSCUSR (odd numbers blink, even numbers solid) ! 1 or 2 = block ! 3 or 4 = underline ! 5 or 6 = I-beam to left ! 23 CSI " q = DECSCA, select character attributes ! 123 CSI r = DECSTBM ! CSI s = DECSLRM ! CSI ' } = DECIC ! CSI ' ~ = DECDC ! ! OSCs ! ! OSC 0; = Set icon name and title ! OSC 1; = Set icon name ! OSC 2; = Set title ! ! Standard modes ! ! 23 SM 4 = IRM ! 123 SM 20 = NLM, linefeed/newline ! ! DEC modes ! ! 123 DECSM 1 = DECCKM, cursor keys ! 123 DECSM 5 = DECSCNM, screen ! 123 DECSM 6 = DECOM, origin ! 123 DECSM 7 = DECAWM, autowrap ! DECSM 12 = Cursor blink ! 23 DECSM 25 = DECTCEM, text cursor enable ! DECSM 69 = DECVSSM, vertical screen split ! DECSM 1000 = Mouse click/release tracking ! DECSM 1002 = Mouse click/release/drag tracking ! DECSM 1003 = Mouse all movements tracking ! DECSM 1004 = Focus in/out reporting ! DECSM 1005 = Mouse protocol extended (UTF-8) - not recommended ! DECSM 1006 = Mouse protocol SGR ! DECSM 1015 = Mouse protocol rxvt ! DECSM 1047 = Altscreen ! DECSM 1048 = Save cursor ! DECSM 1049 = 1047 + 1048 ! DECSM 2004 = Bracketed paste ! ! Graphic Renditions ! ! 123 SGR 0 = Reset ! 123 SGR 1 = Bold on ! SGR 3 = Italic on ! 123 SGR 4 = Underline single ! SGR 4:x = Underline style ! 123 SGR 5 = Blink on ! 123 SGR 7 = Reverse on ! SGR 8 = Conceal on ! SGR 9 = Strikethrough on ! SGR 10-19 = Select font ! SGR 21 = Underline double ! 23 SGR 22 = Bold off ! SGR 23 = Italic off ! 23 SGR 24 = Underline off ! 23 SGR 25 = Blink off ! 23 SGR 27 = Reverse off ! SGR 28 = Conceal off ! SGR 29 = Strikethrough off ! SGR 30-37 = Foreground ANSI ! SGR 38 = Foreground alternative palette ! SGR 39 = Foreground default ! SGR 40-47 = Background ANSI ! SGR 48 = Background alternative palette ! SGR 49 = Background default ! SGR 90-97 = Foreground ANSI high-intensity ! SGR 100-107 = Background ANSI high-intensity The state storage used by ESC 7 and DECSM 1048/1049 is shared. ! Unimplemented sequences: The following sequences are not recognised by libvterm. ! 123 0x05 = ENQ ! 3 0x11 = DC1 (XON) ! 3 0x13 = DC3 (XOFF) ! 12 ESC Z = DECID, identify terminal ! DCS $ q = [DECRQSS] ! 3 " p = Request DECSCL ! 3 $ } = Request DECSASD ! 3 $ ~ = Request DECSSDT ! 23 DCS { = DECDLD, down-line-loadable character set ! 23 DCS | = DECUDK, user-defined key ! 23 CSI i = DEC printer control ! 23 CSI " p = DECSCL, set compatibility level ! 1 CSI q = DECLL, load LEDs ! 3 CSI $ u = DECRQTSR, request terminal state report ! 3 1 = terminal state report ! 3 CSI & u = DECRQUPSS, request user-preferred supplemental set ! 3 CSI $ w = DECRQPSR, request presentation state report ! 3 1 = cursor information report ! 3 2 = tab stop report ! 1 CSI x = DECREQTPARM, request terminal parameters ! 123 CSI y = DECTST, invoke confidence test ! 3 CSI $ } = DECSASD, select active status display ! 3 CSI $ ~ = DECSSDT, select status line type ! 23 SM 2 = KAM, keyboard action ! 123 SM 12 = SRM, send/receive ! 123 DECSM 2 = DECANM, ANSI/VT52 ! 123 DECSM 3 = DECCOLM, 132 column ! 123 DECSM 4 = DECSCLM, scrolling ! 123 DECSM 8 = DECARM, auto-repeat ! 12 DECSM 9 = DECINLM, interlace ! 23 DECSM 18 = DECPFF, print form feed ! 23 DECSM 19 = DECPEX, print extent ! 23 DECSM 42 = DECNRCM, national/multinational character --- 4,278 ---- 1 = VT100 2 = VT220 3 = VT320 + x = xterm ! C0 controls ! 123 0x00 = NUL ! 123x 0x07 = BEL ! 123x 0x08 = BS ! 123x 0x09 = HT ! 123x 0x0A = LF ! 123x 0x0B = VT ! 123x 0x0C = FF ! 123x 0x0D = CR ! 123x 0x0E = LS1 ! 123x 0x0F = LS0 ! (0x18 = CAN) ! (0x1A = SUB) ! (0x1B = ESC) ! ! 123 0x7f = DEL (ignored) ! ! C1 controls ! ! 123x 0x84 = IND ! 123x 0x85 = NEL ! 123x 0x88 = HTS ! 123x 0x8D = RI ! 23x 0x8E = SS2 ! 23x 0x8F = SS3 ! (0x90 = DCS) ! (0x98 = SOS) ! (0x9B = CSI) ! (0x9C = ST) ! (0x9D = OSC) ! (0x9E = PM) ! (0x9F = APC) ! ! Escape sequences ! - excluding sequences that are C1 aliases ! ! 123x ESC ( = SCS, select character set G0 ! 123x ESC ) = SCS, select character set G1 ! 23x ESC * = SCS, select character set G2 ! 23x ESC + = SCS, select character set G3 ! 123x ESC 7 = DECSC - save cursor ! 123x ESC 8 = DECRC - restore cursor ! 123x ESC # 3 = DECDHL, double-height line (top half) ! 123x ESC # 4 = DECDHL, double-height line (bottom half) ! 123x ESC # 5 = DECSWL, single-width single-height line ! 123x ESC # 6 = DECDWL, double-width single-height line ! 123x ESC # 8 = DECALN ! 123 ESC < = Ignored (used by VT100 to exit VT52 mode) ! 123x ESC = = DECKPAM, keypad application mode ! 123x ESC > = DECKPNM, keypad numeric mode ! 23x ESC Sp F = S7C1T ! 23x ESC Sp G = S8C1T ! (ESC P = DCS) ! (ESC X = SOS) ! (ESC [ = CSI) ! (ESC \ = ST) ! (ESC ] = OSC) ! (ESC ^ = PM) ! (ESC _ = APC) ! 123x ESC c = RIS, reset initial state ! 3x ESC n = LS2 ! 3x ESC o = LS3 ! 3x ESC | = LS3R ! 3x ESC } = LS2R ! 3x ESC ~ = LS1R ! ! DCSes ! ! 3x DCS $ q ST = DECRQSS ! 3x m = Request SGR ! x Sp q = Request DECSCUSR ! 3x " q = Request DECSCA ! 3x r = Request DECSTBM ! x s = Request DECSLRM ! ! CSIs ! 23x CSI @ = ICH ! 123x CSI A = CUU ! 123x CSI B = CUD ! 123x CSI C = CUF ! 123x CSI D = CUB ! x CSI E = CNL ! x CSI F = CPL ! x CSI G = CHA ! 123x CSI H = CUP ! x CSI I = CHT ! 123x CSI J = ED ! 23x CSI ? J = DECSED, selective erase in display ! 123x CSI K = EL ! 23x CSI ? K = DECSEL, selective erase in line ! 23x CSI L = IL ! 23x CSI M = DL ! 23x CSI P = DCH ! x CSI S = SU ! x CSI T = SD ! 23x CSI X = ECH ! x CSI Z = CBT ! x CSI ` = HPA ! x CSI a = HPR ! x CSI b = REP ! 123x CSI c = DA, device attributes ! 123 0 = DA ! 23x CSI > c = DECSDA ! 23 0 = SDA ! x CSI d = VPA ! x CSI e = VPR ! 123x CSI f = HVP ! 123x CSI g = TBC ! 123x CSI h = SM, Set mode ! 123x CSI ? h = DECSM, DEC set mode ! CSI j = HPB ! CSI k = VPB ! 123x CSI l = RM, Reset mode ! 123x CSI ? l = DECRM, DEC reset mode ! 123x CSI m = SGR, Set Graphic Rendition ! 123x CSI n = DSR, Device Status Report ! 23x 5 = operating status ! 23x 6 = CPR = cursor position ! 23x CSI ? n = DECDSR; behaves as DSR but uses CSI ? instead of CSI to respond ! 23x CSI ! p = DECSTR, soft terminal reset ! 3x CSI ? $ p = DECRQM, request private mode ! x CSI Sp q = DECSCUSR (odd numbers blink, even numbers solid) ! 1 or 2 = block ! 3 or 4 = underline ! 5 or 6 = I-beam to left ! 23x CSI " q = DECSCA, select character attributes ! 123x CSI r = DECSTBM ! x CSI s = DECSLRM ! x CSI ' } = DECIC ! x CSI ' ~ = DECDC ! ! OSCs ! ! x OSC 0; = Set icon name and title ! x OSC 1; = Set icon name ! x OSC 2; = Set title ! x OSC 52; = Selection management ! ! Standard modes ! ! 23x SM 4 = IRM ! 123x SM 20 = NLM, linefeed/newline ! ! DEC modes ! ! 123x DECSM 1 = DECCKM, cursor keys ! 123x DECSM 5 = DECSCNM, screen ! 123x DECSM 6 = DECOM, origin ! 123x DECSM 7 = DECAWM, autowrap ! x DECSM 12 = Cursor blink ! 23x DECSM 25 = DECTCEM, text cursor enable ! x DECSM 69 = DECVSSM, vertical screen split ! x DECSM 1000 = Mouse click/release tracking ! x DECSM 1002 = Mouse click/release/drag tracking ! x DECSM 1003 = Mouse all movements tracking ! x DECSM 1004 = Focus in/out reporting ! x DECSM 1005 = Mouse protocol extended (UTF-8) - not recommended ! x DECSM 1006 = Mouse protocol SGR ! x DECSM 1015 = Mouse protocol rxvt ! x DECSM 1047 = Altscreen ! x DECSM 1048 = Save cursor ! x DECSM 1049 = 1047 + 1048 ! x DECSM 2004 = Bracketed paste ! ! Graphic Renditions ! ! 123x SGR 0 = Reset ! 123x SGR 1 = Bold on ! x SGR 3 = Italic on ! 123x SGR 4 = Underline single ! SGR 4:x = Underline style ! 123x SGR 5 = Blink on ! 123x SGR 7 = Reverse on ! x SGR 8 = Conceal on ! x SGR 9 = Strikethrough on ! SGR 10-19 = Select font ! x SGR 21 = Underline double ! 23x SGR 22 = Bold off ! x SGR 23 = Italic off ! 23x SGR 24 = Underline off ! 23x SGR 25 = Blink off ! 23x SGR 27 = Reverse off ! x SGR 28 = Conceal off ! x SGR 29 = Strikethrough off ! x SGR 30-37 = Foreground ANSI ! x SGR 38 = Foreground alternative palette ! x SGR 39 = Foreground default ! x SGR 40-47 = Background ANSI ! x SGR 48 = Background alternative palette ! x SGR 49 = Background default ! x SGR 90-97 = Foreground ANSI high-intensity ! x SGR 100-107 = Background ANSI high-intensity The state storage used by ESC 7 and DECSM 1048/1049 is shared. ! Unimplemented sequences: The following sequences are not recognised by libvterm. ! 123x 0x05 = ENQ ! 3 0x11 = DC1 (XON) ! 3 0x13 = DC3 (XOFF) ! x ESC % @ = Select default character set ! x ESC % G = Select UTF-8 character set ! x ESC 6 = DECBI, Back Index ! 12 ESC Z = DECID, identify terminal ! x DCS + Q = XTGETXRES, Request resource values ! DCS $ q = [DECRQSS] ! 3x " p = Request DECSCL ! x t = Request DECSLPP ! x $ | = Request DECSCPP ! x * | = Request DECSLNS ! 3 $ } = Request DECSASD ! 3 $ ~ = Request DECSSDT ! x DCS + p = XTSETTCAP, set termcap/terminfo data ! x DCS + q = XTGETTCAP, request termcap/terminfo ! 23 DCS { = DECDLD, down-line-loadable character set ! 23x DCS | = DECUDK, user-defined key ! x CSI Sp @ = Shift left columns ! x CSI Sp A = Shift right columns ! x CSI # P = XTPUSHCOLORS, push current dynamic colours to stack ! x CSI # Q = XTPOPCOLORS, pop dynamic colours from stack ! x CSI # R = XTREPORTCOLORS, report current entry on palette stack ! x CSI ? S = XTSMGRAPHICS, set/request graphics attribute ! x CSI > T = XTRMTITLE, reset title mode features ! 23x CSI i = DEC printer control ! x CSI > m = XTMODKEYS, set key modifier options ! x CSI > n = (XTMODKEYS), reset key modifier options ! x CSI $ p = DECRQM, request ANSI mode ! 23x CSI " p = DECSCL, set compatibility level ! x CSI > p = XTSMPOINTER, set resource value pointer mode ! 1 x CSI q = DECLL, load LEDs ! x CSI ? r = XTRESTORE, restore DEC private mode values ! x CSI $ r = DECCARA, change attributes in rectangular area ! x CSI > s = XTSHIFTESCAPE, set/reset shift-escape options ! x CSI ? s = XTSAVE, save DEC private mode values ! x CSI t = XTWINOPS, window operations ! x CSI > t = XTSMTITLE, set title mode features ! x CSI $ t = DECRARA, reset attributes in rectangular area ! 3 CSI $ u = DECRQTSR, request terminal state report ! 3 1 = terminal state report ! 3 CSI & u = DECRQUPSS, request user-preferred supplemental set ! x CSI $ v = DECCRA, copy rectangular area ! 3x CSI $ w = DECRQPSR, request presentation state report ! 3x 1 = cursor information report ! 3x 2 = tab stop report ! x CSI ' w = DECEFR, enable filter rectangle ! 1 x CSI x = DECREQTPARM, request terminal parameters ! x CSI * x = DECSACE, select attribute change extent ! x CSI $ x = DECFRA, fill rectangular area ! 123 CSI y = DECTST, invoke confidence test ! x CSI $ z = DECERA, erase rectangular area ! x CSI # { = XTPUSHSGR, push video attributes onto stack ! x CSI $ { = DECSERA, selective erase in rectangular area ! x CSI # | = XTREPORTSGR, report selected graphic rendition ! x CSI $ | = DECSCPP, select columns per page ! x CSI # } = XTPOPSGR, pop video attributes from stack ! 3 CSI $ } = DECSASD, select active status display ! 3 CSI $ ~ = DECSSDT, select status line type ! 23 SM 2 = KAM, keyboard action ! 123 SM 12 = SRM, send/receive ! 123 DECSM 2 = DECANM, ANSI/VT52 ! 123 DECSM 3 = DECCOLM, 132 column ! 123 DECSM 4 = DECSCLM, scrolling ! 123 DECSM 8 = DECARM, auto-repeat ! 12 DECSM 9 = DECINLM, interlace ! 23 DECSM 18 = DECPFF, print form feed ! 23 DECSM 19 = DECPEX, print extent ! 23 DECSM 42 = DECNRCM, national/multinational character *** ../vim-8.2.3665/src/libvterm/include/vterm.h 2021-11-20 13:45:37.806729612 +0000 --- src/libvterm/include/vterm.h 2021-11-24 18:52:29.588021073 +0000 *************** *** 17,26 **** // from stdint.h typedef unsigned char uint8_t; typedef unsigned int uint32_t; #define VTERM_VERSION_MAJOR 0 ! #define VTERM_VERSION_MINOR 1 #define VTERM_CHECK_VERSION \ vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR) --- 17,27 ---- // from stdint.h typedef unsigned char uint8_t; + typedef unsigned short uint16_t; typedef unsigned int uint32_t; #define VTERM_VERSION_MAJOR 0 ! #define VTERM_VERSION_MINOR 2 #define VTERM_CHECK_VERSION \ vterm_check_version(VTERM_VERSION_MAJOR, VTERM_VERSION_MINOR) *************** *** 267,272 **** --- 268,281 ---- VTERM_N_PROP_MOUSES }; + typedef enum { + VTERM_SELECTION_CLIPBOARD = (1<<0), + VTERM_SELECTION_PRIMARY = (1<<1), + VTERM_SELECTION_SECONDARY = (1<<2), + VTERM_SELECTION_SELECT = (1<<3), + VTERM_SELECTION_CUT0 = (1<<4), /* also CUT1 .. CUT7 by bitshifting */ + } VTermSelectionMask; + typedef struct { const uint32_t *chars; int width; *************** *** 375,380 **** --- 384,392 ---- int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user); int (*osc)(int command, VTermStringFragment frag, void *user); int (*dcs)(const char *command, size_t commandlen, VTermStringFragment frag, void *user); + int (*apc)(VTermStringFragment frag, void *user); + int (*pm)(VTermStringFragment frag, void *user); + int (*sos)(VTermStringFragment frag, void *user); int (*resize)(int rows, int cols, void *user); } VTermParserCallbacks; *************** *** 419,426 **** --- 431,446 ---- int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user); int (*osc)(int command, VTermStringFragment frag, void *user); int (*dcs)(const char *command, size_t commandlen, VTermStringFragment frag, void *user); + int (*apc)(VTermStringFragment frag, void *user); + int (*pm)(VTermStringFragment frag, void *user); + int (*sos)(VTermStringFragment frag, void *user); } VTermStateFallbacks; + typedef struct { + int (*set)(VTermSelectionMask mask, VTermStringFragment frag, void *user); + int (*query)(VTermSelectionMask mask, void *user); + } VTermSelectionCallbacks; + VTermState *vterm_obtain_state(VTerm *vt); void vterm_state_set_callbacks(VTermState *state, const VTermStateCallbacks *callbacks, void *user); *************** *** 457,462 **** --- 477,487 ---- */ void vterm_state_convert_color_to_rgb(const VTermState *state, VTermColor *col); + void vterm_state_set_selection_callbacks(VTermState *state, const VTermSelectionCallbacks *callbacks, void *user, + char *buffer, size_t buflen); + + void vterm_state_send_selection(VTermState *state, VTermSelectionMask mask, VTermStringFragment frag); + // ------------ // Screen layer // ------------ *** ../vim-8.2.3665/src/libvterm/src/mouse.c 2020-07-01 14:49:26.300450527 +0100 --- src/libvterm/src/mouse.c 2021-11-24 18:15:20.008818182 +0000 *************** *** 89,94 **** --- 89,97 ---- if (!(state->mouse_flags & MOUSE_WANT_CLICK)) return; + if(!state->mouse_flags) + return; + if(button < 4) { output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row); } *** ../vim-8.2.3665/src/libvterm/src/parser.c 2020-05-22 21:06:02.165271263 +0100 --- src/libvterm/src/parser.c 2021-11-24 18:06:27.100380024 +0000 *************** *** 77,86 **** break; case DCS: ! if(len && vt->parser.callbacks && vt->parser.callbacks->dcs) (*vt->parser.callbacks->dcs)(vt->parser.v.dcs.command, vt->parser.v.dcs.commandlen, frag, vt->parser.cbdata); break; case NORMAL: case CSI_LEADER: case CSI_ARGS: --- 77,101 ---- break; case DCS: ! if(vt->parser.callbacks && vt->parser.callbacks->dcs) (*vt->parser.callbacks->dcs)(vt->parser.v.dcs.command, vt->parser.v.dcs.commandlen, frag, vt->parser.cbdata); break; + case APC: + if(vt->parser.callbacks && vt->parser.callbacks->apc) + (*vt->parser.callbacks->apc)(frag, vt->parser.cbdata); + break; + + case PM: + if(vt->parser.callbacks && vt->parser.callbacks->pm) + (*vt->parser.callbacks->pm)(frag, vt->parser.cbdata); + break; + + case SOS: + if(vt->parser.callbacks && vt->parser.callbacks->sos) + (*vt->parser.callbacks->sos)(frag, vt->parser.cbdata); + break; + case NORMAL: case CSI_LEADER: case CSI_ARGS: *************** *** 112,117 **** --- 127,135 ---- break; case OSC: case DCS: + case APC: + case PM: + case SOS: string_start = bytes; break; } *************** *** 150,155 **** --- 168,176 ---- // fallthrough } else if(c < 0x20) { // other C0 + if(vt->parser.state == SOS) + continue; // All other C0s permitted in SOS + if(vterm_get_special_pty_type() == 2) { if(c == 0x08) // BS // Set the trick for BS output after a sequence, to delay backspace *************** *** 176,182 **** ((!IS_STRING_STATE() || c == 0x5c))) { c += 0x40; c1_allowed = TRUE; ! string_len -= 1; vt->parser.in_esc = FALSE; } else { --- 197,204 ---- ((!IS_STRING_STATE() || c == 0x5c))) { c += 0x40; c1_allowed = TRUE; ! if(string_len) ! string_len -= 1; vt->parser.in_esc = FALSE; } else { *************** *** 279,284 **** --- 301,309 ---- string_state: case OSC: case DCS: + case APC: + case PM: + case SOS: if(c == 0x07 || (c1_allowed && c == 0x9c)) { string_fragment(vt, string_start, string_len, TRUE); ENTER_NORMAL_STATE(); *************** *** 308,313 **** --- 333,344 ---- vt->parser.v.dcs.commandlen = 0; ENTER_STATE(DCS_COMMAND); break; + case 0x98: // SOS + vt->parser.string_initial = TRUE; + ENTER_STATE(SOS); + string_start = bytes + pos + 1; + string_len = 0; + break; case 0x9b: // CSI vt->parser.v.csi.leaderlen = 0; ENTER_STATE(CSI_LEADER); *************** *** 318,323 **** --- 349,366 ---- string_start = bytes + pos + 1; ENTER_STATE(OSC_COMMAND); break; + case 0x9e: // PM + vt->parser.string_initial = TRUE; + ENTER_STATE(PM); + string_start = bytes + pos + 1; + string_len = 0; + break; + case 0x9f: // APC + vt->parser.string_initial = TRUE; + ENTER_STATE(APC); + string_start = bytes + pos + 1; + string_len = 0; + break; default: do_control(vt, c); break; *************** *** 340,347 **** } } ! if(string_start) ! string_fragment(vt, string_start, bytes + pos - string_start, FALSE); return len; } --- 383,394 ---- } } ! if(string_start) { ! size_t string_len = bytes + pos - string_start; ! if(vt->parser.in_esc) ! string_len -= 1; ! string_fragment(vt, string_start, string_len, FALSE); ! } return len; } *** ../vim-8.2.3665/src/libvterm/src/state.c 2021-02-08 20:28:53.825440827 +0000 --- src/libvterm/src/state.c 2021-11-24 19:15:30.677245415 +0000 *************** *** 79,84 **** --- 79,88 ---- state->callbacks = NULL; state->cbdata = NULL; + state->selection.callbacks = NULL; + state->selection.user = NULL; + state->selection.buffer = NULL; + vterm_state_newpen(state); state->bold_is_highbright = 0; *************** *** 1615,1620 **** --- 1619,1792 ---- return 1; } + static char base64_one(uint8_t b) + { + if(b < 26) + return 'A' + b; + else if(b < 52) + return 'a' + b - 26; + else if(b < 62) + return '0' + b - 52; + else if(b == 62) + return '+'; + else if(b == 63) + return '/'; + return 0; + } + + static uint8_t unbase64one(char c) + { + if(c >= 'A' && c <= 'Z') + return c - 'A'; + else if(c >= 'a' && c <= 'z') + return c - 'a' + 26; + else if(c >= '0' && c <= '9') + return c - '0' + 52; + else if(c == '+') + return 62; + else if(c == '/') + return 63; + + return 0xFF; + } + + static void osc_selection(VTermState *state, VTermStringFragment frag) + { + if(frag.initial) { + state->tmp.selection.mask = 0; + state->tmp.selection.state = SELECTION_INITIAL; + } + + while(!state->tmp.selection.state && frag.len) { + /* Parse selection parameter */ + switch(frag.str[0]) { + case 'c': + state->tmp.selection.mask |= VTERM_SELECTION_CLIPBOARD; + break; + case 'p': + state->tmp.selection.mask |= VTERM_SELECTION_PRIMARY; + break; + case 'q': + state->tmp.selection.mask |= VTERM_SELECTION_SECONDARY; + break; + case 's': + state->tmp.selection.mask |= VTERM_SELECTION_SELECT; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state->tmp.selection.mask |= (VTERM_SELECTION_CUT0 << (frag.str[0] - '0')); + break; + + case ';': + state->tmp.selection.state = SELECTION_SELECTED; + if(!state->tmp.selection.mask) + state->tmp.selection.mask = VTERM_SELECTION_SELECT|VTERM_SELECTION_CUT0; + break; + } + + frag.str++; + frag.len--; + } + + if(!frag.len) + return; + + if(state->tmp.selection.state == SELECTION_SELECTED) { + if(frag.str[0] == '?') { + state->tmp.selection.state = SELECTION_QUERY; + } + else { + state->tmp.selection.state = SELECTION_SET_INITIAL; + state->tmp.selection.recvpartial = 0; + } + } + + if(state->tmp.selection.state == SELECTION_QUERY) { + if(state->selection.callbacks->query) + (*state->selection.callbacks->query)(state->tmp.selection.mask, state->selection.user); + return; + } + + if(state->selection.callbacks->set) { + size_t bufcur = 0; + char *buffer = state->selection.buffer; + + uint32_t x = 0; /* Current decoding value */ + int n = 0; /* Number of sextets consumed */ + + if(state->tmp.selection.recvpartial) { + n = state->tmp.selection.recvpartial >> 24; + x = state->tmp.selection.recvpartial & 0x03FFFF; /* could be up to 18 bits of state in here */ + + state->tmp.selection.recvpartial = 0; + } + + while((state->selection.buflen - bufcur) >= 3 && frag.len) { + if(frag.str[0] == '=') { + if(n == 2) { + buffer[0] = (x >> 4) & 0xFF; + buffer += 1, bufcur += 1; + } + if(n == 3) { + buffer[0] = (x >> 10) & 0xFF; + buffer[1] = (x >> 2) & 0xFF; + buffer += 2, bufcur += 2; + } + + while(frag.len && frag.str[0] == '=') + frag.str++, frag.len--; + + n = 0; + } + else { + uint8_t b = unbase64one(frag.str[0]); + if(b == 0xFF) { + DEBUG_LOG1("base64decode bad input %02X\n", (uint8_t)frag.str[0]); + } + else { + x = (x << 6) | b; + n++; + } + frag.str++, frag.len--; + + if(n == 4) { + buffer[0] = (x >> 16) & 0xFF; + buffer[1] = (x >> 8) & 0xFF; + buffer[2] = (x >> 0) & 0xFF; + + buffer += 3, bufcur += 3; + x = 0; + n = 0; + } + } + + if(!frag.len || (state->selection.buflen - bufcur) < 3) { + if(bufcur) { + (*state->selection.callbacks->set)(state->tmp.selection.mask, (VTermStringFragment){ + .str = state->selection.buffer, + .len = bufcur, + .initial = state->tmp.selection.state == SELECTION_SET_INITIAL, + .final = frag.final, + }, state->selection.user); + state->tmp.selection.state = SELECTION_SET; + } + + buffer = state->selection.buffer; + bufcur = 0; + } + } + + if(n) + state->tmp.selection.recvpartial = (n << 24) | x; + } + } + static int on_osc(int command, VTermStringFragment frag, void *user) { VTermState *state = user; *************** *** 1656,1661 **** --- 1828,1839 ---- settermprop_string(state, VTERM_PROP_CURSORCOLOR, frag); return 1; + case 52: + if(state->selection.callbacks) + osc_selection(state, frag); + + return 1; + default: if(state->fallbacks && state->fallbacks->osc) if((*state->fallbacks->osc)(command, frag, state->fbdata)) *************** *** 1718,1729 **** case 'r': // Query DECSTBM ! vterm_push_output_sprintf_dcs(vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state)); return; case 's': // Query DECSLRM ! vterm_push_output_sprintf_dcs(vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state)); return; case ' '|('q'<<8): { --- 1896,1909 ---- case 'r': // Query DECSTBM ! vterm_push_output_sprintf_str(vt, C1_DCS, TRUE, ! "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state)); return; case 's': // Query DECSLRM ! vterm_push_output_sprintf_str(vt, C1_DCS, TRUE, ! "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state)); return; case ' '|('q'<<8): { *************** *** 1736,1752 **** } if(state->mode.cursor_blink) reply--; ! vterm_push_output_sprintf_dcs(vt, "1$r%d q", reply); return; } case '\"'|('q'<<8): // Query DECSCA ! vterm_push_output_sprintf_dcs(vt, "1$r%d\"q", state->protected_cell ? 1 : 2); return; } ! vterm_push_output_sprintf_dcs(state->vt, "0$r%s", tmp); } static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user) --- 1916,1934 ---- } if(state->mode.cursor_blink) reply--; ! vterm_push_output_sprintf_str(vt, C1_DCS, TRUE, ! "1$r%d q", reply); return; } case '\"'|('q'<<8): // Query DECSCA ! vterm_push_output_sprintf_str(vt, C1_DCS, TRUE, ! "1$r%d\"q", state->protected_cell ? 1 : 2); return; } ! vterm_push_output_sprintf_str(state->vt, C1_DCS, TRUE, "0$r%s", tmp); } static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user) *************** *** 1765,1770 **** --- 1947,1988 ---- return 0; } + static int on_apc(VTermStringFragment frag, void *user) + { + VTermState *state = user; + + if(state->fallbacks && state->fallbacks->apc) + if((*state->fallbacks->apc)(frag, state->fbdata)) + return 1; + + /* No DEBUG_LOG because all APCs are unhandled */ + return 0; + } + + static int on_pm(VTermStringFragment frag, void *user) + { + VTermState *state = user; + + if(state->fallbacks && state->fallbacks->pm) + if((*state->fallbacks->pm)(frag, state->fbdata)) + return 1; + + /* No DEBUG_LOG because all PMs are unhandled */ + return 0; + } + + static int on_sos(VTermStringFragment frag, void *user) + { + VTermState *state = user; + + if(state->fallbacks && state->fallbacks->sos) + if((*state->fallbacks->sos)(frag, state->fbdata)) + return 1; + + /* No DEBUG_LOG because all SOSs are unhandled */ + return 0; + } + static int on_resize(int rows, int cols, void *user) { VTermState *state = user; *************** *** 1866,1871 **** --- 2084,2092 ---- on_csi, // csi on_osc, // osc on_dcs, // dcs + on_apc, // apc + on_pm, // pm + on_sos, // sos on_resize // resize }; *************** *** 1909,1914 **** --- 2130,2137 ---- state->mode.bracketpaste = 0; state->mode.report_focus = 0; + state->mouse_flags = 0; + state->vt->mode.ctrl8bit = 0; { *************** *** 2087,2089 **** --- 2310,2405 ---- { return state->lineinfo + row; } + + void vterm_state_set_selection_callbacks(VTermState *state, const VTermSelectionCallbacks *callbacks, void *user, + char *buffer, size_t buflen) + { + if(buflen && !buffer) + buffer = vterm_allocator_malloc(state->vt, buflen); + + state->selection.callbacks = callbacks; + state->selection.user = user; + state->selection.buffer = buffer; + state->selection.buflen = buflen; + } + + void vterm_state_send_selection(VTermState *state, VTermSelectionMask mask, VTermStringFragment frag) + { + VTerm *vt = state->vt; + + if(frag.initial) { + /* TODO: support sending more than one mask bit */ + static char selection_chars[] = "cpqs"; + int idx; + for(idx = 0; idx < 4; idx++) + if(mask & (1 << idx)) + break; + + vterm_push_output_sprintf_str(vt, C1_OSC, FALSE, "52;%c;", selection_chars[idx]); + + state->tmp.selection.sendpartial = 0; + } + + if(frag.len) { + size_t bufcur = 0; + char *buffer = state->selection.buffer; + + uint32_t x = 0; + int n = 0; + + if(state->tmp.selection.sendpartial) { + n = state->tmp.selection.sendpartial >> 24; + x = state->tmp.selection.sendpartial & 0xFFFFFF; + + state->tmp.selection.sendpartial = 0; + } + + while((state->selection.buflen - bufcur) >= 4 && frag.len) { + x = (x << 8) | frag.str[0]; + n++; + frag.str++, frag.len--; + + if(n == 3) { + buffer[0] = base64_one((x >> 18) & 0x3F); + buffer[1] = base64_one((x >> 12) & 0x3F); + buffer[2] = base64_one((x >> 6) & 0x3F); + buffer[3] = base64_one((x >> 0) & 0x3F); + + buffer += 4, bufcur += 4; + x = 0; + n = 0; + } + + if(!frag.len || (state->selection.buflen - bufcur) < 4) { + if(bufcur) + vterm_push_output_bytes(vt, state->selection.buffer, bufcur); + + buffer = state->selection.buffer; + bufcur = 0; + } + } + + if(n) + state->tmp.selection.sendpartial = (n << 24) | x; + } + + if(frag.final) { + if(state->tmp.selection.sendpartial) { + int n = state->tmp.selection.sendpartial >> 24; + uint32_t x = state->tmp.selection.sendpartial & 0xFFFFFF; + char *buffer = state->selection.buffer; + + /* n is either 1 or 2 now */ + x <<= (n == 1) ? 16 : 8; + + buffer[0] = base64_one((x >> 18) & 0x3F); + buffer[1] = base64_one((x >> 12) & 0x3F); + buffer[2] = (n == 1) ? '=' : base64_one((x >> 6) & 0x3F); + buffer[3] = '='; + + vterm_push_output_sprintf_str(vt, 0, TRUE, "%.*s", 4, buffer); + } + else + vterm_push_output_sprintf_str(vt, 0, TRUE, ""); + } + } *** ../vim-8.2.3665/src/libvterm/src/vterm.c 2020-05-22 21:06:02.165271263 +0100 --- src/libvterm/src/vterm.c 2021-11-24 19:05:46.423600774 +0000 *************** *** 200,226 **** va_end(args); } ! INTERNAL void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...) { size_t cur; va_list args; ! cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, ! vt->mode.ctrl8bit ? "\x90" : ESC_S "P"); // DCS ! ! if(cur >= vt->tmpbuffer_len) ! return; ! vterm_push_output_bytes(vt, vt->tmpbuffer, cur); va_start(args, fmt); vterm_push_output_vsprintf(vt, fmt, args); va_end(args); ! cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, ! vt->mode.ctrl8bit ? "\x9C" : ESC_S "\\"); // ST ! if(cur >= vt->tmpbuffer_len) ! return; ! vterm_push_output_bytes(vt, vt->tmpbuffer, cur); } size_t vterm_output_get_buffer_size(const VTerm *vt) --- 200,234 ---- va_end(args); } ! INTERNAL void vterm_push_output_sprintf_str(VTerm *vt, unsigned char ctrl, int term, const char *fmt, ...) { size_t cur; va_list args; ! if(ctrl) { ! if(ctrl >= 0x80 && !vt->mode.ctrl8bit) ! cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, ! ESC_S "%c", ctrl - 0x40); ! else ! cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, ! "%c", ctrl); ! ! if(cur >= vt->tmpbuffer_len) ! return; ! vterm_push_output_bytes(vt, vt->tmpbuffer, cur); ! } va_start(args, fmt); vterm_push_output_vsprintf(vt, fmt, args); va_end(args); ! if(term) { ! cur = SNPRINTF(vt->tmpbuffer, vt->tmpbuffer_len, ! vt->mode.ctrl8bit ? "\x9C" : ESC_S "\\"); // ST ! if(cur >= vt->tmpbuffer_len) ! return; ! vterm_push_output_bytes(vt, vt->tmpbuffer, cur); ! } } size_t vterm_output_get_buffer_size(const VTerm *vt) *** ../vim-8.2.3665/src/libvterm/src/vterm_internal.h 2020-05-22 21:06:02.165271263 +0100 --- src/libvterm/src/vterm_internal.h 2021-11-24 19:15:49.825166830 +0000 *************** *** 154,160 **** --- 154,179 ---- /* Temporary state for DECRQSS parsing */ union { char decrqss[4]; + struct { + uint16_t mask; + enum { + SELECTION_INITIAL, + SELECTION_SELECTED, + SELECTION_QUERY, + SELECTION_SET_INITIAL, + SELECTION_SET, + } state : 8; + uint32_t recvpartial; + uint32_t sendpartial; + } selection; } tmp; + + struct { + const VTermSelectionCallbacks *callbacks; + void *user; + char *buffer; + size_t buflen; + } selection; }; struct VTerm *************** *** 181,186 **** --- 200,208 ---- OSC_COMMAND, OSC, DCS, + APC, + PM, + SOS, } state; unsigned int in_esc : 1; *************** *** 248,254 **** void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args); void vterm_push_output_sprintf(VTerm *vt, const char *format, ...); void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...); ! void vterm_push_output_sprintf_dcs(VTerm *vt, const char *fmt, ...); void vterm_state_free(VTermState *state); --- 270,276 ---- void vterm_push_output_vsprintf(VTerm *vt, const char *format, va_list args); void vterm_push_output_sprintf(VTerm *vt, const char *format, ...); void vterm_push_output_sprintf_ctrl(VTerm *vt, unsigned char ctrl, const char *fmt, ...); ! void vterm_push_output_sprintf_str(VTerm *vt, unsigned char ctrl, int term, const char *fmt, ...); void vterm_state_free(VTermState *state); *** ../vim-8.2.3665/src/libvterm/t/02parser.test 2020-05-20 18:30:13.828123549 +0100 --- src/libvterm/t/02parser.test 2021-11-24 17:58:26.667491664 +0000 *************** *** 17,31 **** PUSH "\x83" control 0x83 ! PUSH "\x9f" ! control 0x9f !C1 7bit PUSH "\e\x43" control 0x83 ! PUSH "\e\x5f" ! control 0x9f !High bytes PUSH "\xa0\xcc\xfe" --- 17,31 ---- PUSH "\x83" control 0x83 ! PUSH "\x99" ! control 0x99 !C1 7bit PUSH "\e\x43" control 0x83 ! PUSH "\e\x59" ! control 0x99 !High bytes PUSH "\xa0\xcc\xfe" *************** *** 184,189 **** --- 184,195 ---- PUSH "\x{90}Hello\x9c" dcs ["Hello"] + !Split write of 7bit ST + PUSH "\ePABC\e" + dcs ["ABC" + PUSH "\\" + dcs ] + !Escape cancels DCS, starts Escape PUSH "\ePSomething\e9" escape "9" *************** *** 198,203 **** --- 204,251 ---- control 10 dcs "e"] + !APC BEL + PUSH "\e_Hello\x07" + apc ["Hello"] + + !APC ST (7bit) + PUSH "\e_Hello\e\\" + apc ["Hello"] + + !APC ST (8bit) + PUSH "\x{9f}Hello\x9c" + apc ["Hello"] + + !PM BEL + PUSH "\e^Hello\x07" + pm ["Hello"] + + !PM ST (7bit) + PUSH "\e^Hello\e\\" + pm ["Hello"] + + !PM ST (8bit) + PUSH "\x{9e}Hello\x9c" + pm ["Hello"] + + !SOS BEL + PUSH "\eXHello\x07" + sos ["Hello"] + + !SOS ST (7bit) + PUSH "\eXHello\e\\" + sos ["Hello"] + + !SOS ST (8bit) + PUSH "\x{98}Hello\x9c" + sos ["Hello"] + + !SOS can contain any C0 or C1 code + PUSH "\eXABC\x01DEF\e\\" + sos ["ABC\x01DEF"] + PUSH "\eXABC\x99DEF\e\\" + sos ["ABC\x{99}DEF"] + !NUL ignored PUSH "\x{00}" *** ../vim-8.2.3665/src/libvterm/t/17state_mouse.test 2017-06-24 15:44:02.000000000 +0100 --- src/libvterm/t/17state_mouse.test 2021-11-24 18:15:20.008818182 +0000 *************** *** 170,172 **** --- 170,181 ---- output "\e[?1006;2\$y" PUSH "\e[?1015\$p" output "\e[?1015;1\$y" + + !Mouse disabled reports nothing + RESET + settermprop 1 true + settermprop 2 true + settermprop 7 1 + MOUSEMOVE 0,0 0 + MOUSEBTN d 1 0 + MOUSEBTN u 1 0 *** ../vim-8.2.3665/src/libvterm/t/29state_fallback.test 2020-05-19 20:19:34.891367031 +0100 --- src/libvterm/t/29state_fallback.test 2021-11-24 17:28:16.817091187 +0000 *************** *** 17,19 **** --- 17,31 ---- !Unrecognised DCS PUSH "\ePz123\e\\" dcs ["z123"] + + !Unrecognised APC + PUSH "\e_z123\e\\" + apc ["z123"] + + !Unrecognised PM + PUSH "\e^z123\e\\" + pm ["z123"] + + !Unrecognised SOS + PUSH "\eXz123\e\\" + sos ["z123"] *** ../vim-8.2.3665/src/libvterm/t/40state_selection.test 2021-11-24 19:29:08.738951514 +0000 --- src/libvterm/t/40state_selection.test 2021-11-24 19:25:09.291467212 +0000 *************** *** 0 **** --- 1,55 ---- + INIT + UTF8 1 + WANTSTATE + + !Set clipboard; final chunk len 4 + PUSH "\e]52;c;SGVsbG8s\e\\" + selection-set mask=0001 ["Hello,"] + + !Set clipboard; final chunk len 3 + PUSH "\e]52;c;SGVsbG8sIHc=\e\\" + selection-set mask=0001 ["Hello, w"] + + !Set clipboard; final chunk len 2 + PUSH "\e]52;c;SGVsbG8sIHdvcmxkCg==\e\\" + selection-set mask=0001 ["Hello, world\n"] + + !Set clipboard; split between chunks + PUSH "\e]52;c;SGVs" + selection-set mask=0001 ["Hel" + PUSH "bG8s\e\\" + selection-set mask=0001 "lo,"] + + !Set clipboard; split within chunk + PUSH "\e]52;c;SGVsbG" + selection-set mask=0001 ["Hel" + PUSH "8s\e\\" + selection-set mask=0001 "lo,"] + + !Query clipboard + PUSH "\e]52;c;?\e\\" + selection-query mask=0001 + + !Send clipboard; final chunk len 4 + SELECTION 1 ["Hello,"] + output "\e]52;c;SGVsbG8s\e\\" + + !Send clipboard; final chunk len 3 + SELECTION 1 ["Hello, w"] + output "\e]52;c;SGVsbG8sIHc=\e\\" + + !Send clipboard; final chunk len 2 + SELECTION 1 ["Hello, world\n"] + output "\e]52;c;SGVsbG8sIHdvcmxkCg==\e\\" + + !Send clipboard; split between chunks + SELECTION 1 ["Hel" + output "\e]52;c;SGVs" + SELECTION 1 "lo,"] + output "bG8s\e\\" + + !Send clipboard; split within chunk + SELECTION 1 ["Hello" + output "\e]52;c;SGVs" + SELECTION 1 ","] + output "bG8s\e\\" *** ../vim-8.2.3665/src/libvterm/t/harness.c 2020-05-21 19:10:00.285336763 +0100 --- src/libvterm/t/harness.c 2021-11-24 18:55:23.855929731 +0000 *************** *** 13,19 **** while(*inpos) { unsigned int ch; ! sscanf(inpos, "%2x", &ch); *outpos = ch; outpos += 1; inpos += 2; } --- 13,20 ---- while(*inpos) { unsigned int ch; ! if(sscanf(inpos, "%2x", &ch) < 1) ! break; *outpos = ch; outpos += 1; inpos += 2; } *************** *** 98,104 **** static void printhex(const char *s, size_t len) { while(len--) ! printf("%02x", (s++)[0]); } static int parser_text(const char bytes[], size_t len, void *user UNUSED) --- 99,105 ---- static void printhex(const char *s, size_t len) { while(len--) ! printf("%02x", (uint8_t)(s++)[0]); } static int parser_text(const char bytes[], size_t len, void *user UNUSED) *************** *** 216,221 **** --- 217,273 ---- return 1; } + static int parser_apc(VTermStringFragment frag, void *user UNUSED) + { + printf("apc "); + + if(frag.initial) + printf("["); + + printhex(frag.str, frag.len); + + if(frag.final) + printf("]"); + + printf("\n"); + + return 1; + } + + static int parser_pm(VTermStringFragment frag, void *user UNUSED) + { + printf("pm "); + + if(frag.initial) + printf("["); + + printhex(frag.str, frag.len); + + if(frag.final) + printf("]"); + + printf("\n"); + + return 1; + } + + static int parser_sos(VTermStringFragment frag, void *user UNUSED) + { + printf("sos "); + + if(frag.initial) + printf("["); + + printhex(frag.str, frag.len); + + if(frag.final) + printf("]"); + + printf("\n"); + + return 1; + } + static VTermParserCallbacks parser_cbs = { parser_text, // text parser_control, // control *************** *** 223,228 **** --- 275,283 ---- parser_csi, // csi parser_osc, // osc parser_dcs, // dcs + parser_apc, // apc + parser_pm, // pm + parser_sos, // sos NULL // resize }; *************** *** 230,236 **** parser_control, // control parser_csi, // csi parser_osc, // osc ! parser_dcs // dcs }; /* These callbacks are shared by State and Screen */ --- 285,294 ---- parser_control, // control parser_csi, // csi parser_osc, // osc ! parser_dcs, // dcs ! parser_apc, // dcs ! parser_pm, // pm ! parser_sos // sos }; /* These callbacks are shared by State and Screen */ *************** *** 414,419 **** --- 472,502 ---- state_setlineinfo, // setlineinfo }; + static int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user UNUSED) + { + printf("selection-set mask=%04X ", mask); + if(frag.initial) + printf("["); + printhex(frag.str, frag.len); + if(frag.final) + printf("]"); + printf("\n"); + + return 1; + } + + static int selection_query(VTermSelectionMask mask, void *user UNUSED) + { + printf("selection-query mask=%04X\n", mask); + + return 1; + } + + VTermSelectionCallbacks selection_cbs = { + .set = selection_set, + .query = selection_query, + }; + static int want_screen_damage = 0; static int want_screen_damage_cells = 0; static int screen_damage(VTermRect rect, void *user UNUSED) *************** *** 555,560 **** --- 638,644 ---- if(!state) { state = vterm_obtain_state(vt); vterm_state_set_callbacks(state, &state_cbs, NULL); + vterm_state_set_selection_callbacks(state, &selection_cbs, NULL, NULL, 1024); vterm_state_set_bold_highbright(state, 1); vterm_state_reset(state, 1); } *************** *** 768,773 **** --- 852,883 ---- vterm_mouse_button(vt, button, (press == 'd' || press == 'D'), mod); } + else if(strstartswith(line, "SELECTION ")) { + char *linep = line + 10; + unsigned int mask; + int len; + VTermStringFragment frag = { 0 }; + sscanf(linep, "%x%n", &mask, &len); + linep += len; + while(linep[0] == ' ') + linep++; + if(linep[0] == '[') { + frag.initial = TRUE; + linep++; + while(linep[0] == ' ') + linep++; + } + frag.len = inplace_hex2bytes(linep); + frag.str = linep; + linep += frag.len * 2; + while(linep[0] == ' ') + linep++; + if(linep[0] == ']') { + frag.final = TRUE; + } + vterm_state_send_selection(state, mask, frag); + } + else if(strstartswith(line, "DAMAGEMERGE ")) { char *linep = line + 12; while(linep[0] == ' ') *** ../vim-8.2.3665/src/libvterm/t/run-test.pl 2020-12-03 20:24:04.089645975 +0000 --- src/libvterm/t/run-test.pl 2021-11-24 18:52:34.676018400 +0000 *************** *** 85,90 **** --- 85,95 ---- my $string = eval($2); $line = "$1 " . unpack "H*", $string; } + elsif( $line =~ m/^(SELECTION \d+) +(\[?)(.*?)(\]?)$/ ) { + # we're evil + my $string = eval($3); + $line = "$1 $2 " . unpack( "H*", $string ) . " $4"; + } do_onetest if defined $command; *************** *** 113,127 **** $line = "$cmd $initial" . join( "", map sprintf("%02x", $_), unpack "C*", length $data ? eval($data) : "" ) . "$final"; } ! elsif( $line =~ m/^(escape|dcs) (\[?)(.*?)(\]?)$/ ) { ! $line = "$1 $2" . join( "", map sprintf("%02x", $_), unpack "C*", eval($3) ) . "$4"; } elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) { $line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2"; } ! elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc) / ) { # no conversion } else { warn "Unrecognised test expectation '$line'\n"; } --- 118,135 ---- $line = "$cmd $initial" . join( "", map sprintf("%02x", $_), unpack "C*", length $data ? eval($data) : "" ) . "$final"; } ! elsif( $line =~ m/^(escape|dcs|apc|pm|sos) (\[?)(.*?)(\]?)$/ ) { ! $line = "$1 $2" . join( "", map sprintf("%02x", $_), unpack "C*", length $3 ? eval($3) : "" ) . "$4"; } elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) { $line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2"; } ! elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc|selection-query) / ) { # no conversion } + elsif( $line =~ m/^(selection-set) (.*?) (\[?)(.*?)(\]?)$/ ) { + $line = "$1 $2 $3" . join( "", map sprintf("%02x", $_), unpack "C*", eval($4) ) . "$5"; + } else { warn "Unrecognised test expectation '$line'\n"; } *** ../vim-8.2.3665/src/libvterm/vterm.pc.in 2017-06-24 15:44:02.000000000 +0100 --- src/libvterm/vterm.pc.in 2021-11-24 17:04:35.310582157 +0000 *************** *** 1,6 **** - prefix=@PREFIX@ libdir=@LIBDIR@ ! includedir=${prefix}/include Name: vterm Description: Abstract VT220/Xterm/ECMA-48 emulation library --- 1,5 ---- libdir=@LIBDIR@ ! includedir=@INCDIR@ Name: vterm Description: Abstract VT220/Xterm/ECMA-48 emulation library *** ../vim-8.2.3665/src/terminal.c 2021-11-23 12:07:21.105730814 +0000 --- src/terminal.c 2021-11-24 17:30:59.957020863 +0000 *************** *** 4526,4532 **** NULL, // control parse_csi, // csi parse_osc, // osc ! NULL // dcs }; /* --- 4526,4535 ---- NULL, // control parse_csi, // csi parse_osc, // osc ! NULL, // dcs ! NULL, // apc ! NULL, // pm ! NULL // sos }; /* *** ../vim-8.2.3665/src/version.c 2021-11-24 16:32:50.724422463 +0000 --- src/version.c 2021-11-24 19:28:35.395018923 +0000 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3666, /**/ -- What do you get when you cross a joke with a rehtorical question? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///