@@ -609,8 +609,7 @@ static bool is_key(unsigned char *key, size_t len, char *key_description) {
609609 memcmp (key , key_description , len ) == 0 );
610610}
611611
612- static void term_set_title (Term * term , char * title ) {
613- size_t len = strlen (title );
612+ static void term_set_title (Term * term , const char * title , size_t len ) {
614613 if (term -> title ) {
615614 free (term -> title );
616615 }
@@ -640,7 +639,11 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) {
640639
641640 break ;
642641 case VTERM_PROP_TITLE :
643- term_set_title (term , val -> string );
642+ #ifdef VTermStringFragmentNotExists
643+ term_set_title (term , val -> string , strlen (val -> string ));
644+ #else
645+ term_set_title (term , val -> string .str , val -> string .len );
646+ #endif
644647 break ;
645648 case VTERM_PROP_ALTSCREEN :
646649 invalidate_terminal (term , 0 , term -> height );
@@ -907,6 +910,11 @@ void term_finalize(void *object) {
907910 free (term -> elisp_code );
908911 term -> elisp_code = NULL ;
909912 }
913+ if (term -> cmd_buffer ) {
914+ free (term -> cmd_buffer );
915+ term -> cmd_buffer = NULL ;
916+ }
917+
910918 for (int i = 0 ; i < term -> lines_len ; i ++ ) {
911919 if (term -> lines [i ] != NULL ) {
912920 free_lineinfo (term -> lines [i ]);
@@ -924,29 +932,16 @@ void term_finalize(void *object) {
924932 free (term );
925933}
926934
927- static int osc_callback (const char * command , size_t cmdlen , void * user ) {
928- /* osc_callback (OSC = Operating System Command) */
929-
930- /* We interpret escape codes that start with "51;" */
931- /* "51;A" sets the current directory */
932- /* "51;A" has also the role of identifying the end of the prompt */
933- /* "51;E" executes elisp code */
934- /* The elisp code is executed in term_redraw */
935-
936- Term * term = (Term * )user ;
937- char buffer [cmdlen + 1 ];
938-
939- buffer [cmdlen ] = '\0' ;
940- memcpy (buffer , command , cmdlen );
941-
942- if (cmdlen > 4 && buffer [0 ] == '5' && buffer [1 ] == '1' && buffer [2 ] == ';' &&
943- buffer [3 ] == 'A' ) {
935+ static int handle_osc_cmd_51 (Term * term , char subCmd , char * buffer ) {
936+ if (subCmd == 'A' ) {
937+ /* "51;A" sets the current directory */
938+ /* "51;A" has also the role of identifying the end of the prompt */
944939 if (term -> directory != NULL ) {
945940 free (term -> directory );
946941 term -> directory = NULL ;
947942 }
948- term -> directory = malloc (cmdlen - 4 + 1 );
949- strcpy (term -> directory , & buffer [ 4 ] );
943+ term -> directory = malloc (strlen ( buffer ) + 1 );
944+ strcpy (term -> directory , buffer );
950945 term -> directory_changed = true;
951946
952947 for (int i = term -> cursor .row ; i < term -> lines_len ; i ++ ) {
@@ -957,24 +952,52 @@ static int osc_callback(const char *command, size_t cmdlen, void *user) {
957952 if (term -> lines [i ]-> directory != NULL ) {
958953 free (term -> lines [i ]-> directory );
959954 }
960- term -> lines [i ]-> directory = malloc (cmdlen - 4 + 1 );
961- strcpy (term -> lines [i ]-> directory , & buffer [ 4 ] );
955+ term -> lines [i ]-> directory = malloc (strlen ( buffer ) + 1 );
956+ strcpy (term -> lines [i ]-> directory , buffer );
962957 if (i == term -> cursor .row ) {
963958 term -> lines [i ]-> prompt_col = term -> cursor .col ;
964959 } else {
965960 term -> lines [i ]-> prompt_col = -1 ;
966961 }
967962 }
968963 return 1 ;
969- } else if (cmdlen > 4 && buffer [0 ] == '5' && buffer [1 ] == '1' &&
970- buffer [2 ] == ';' && buffer [3 ] == 'E' ) {
971- term -> elisp_code = malloc (cmdlen - 4 + 1 );
972- strcpy (term -> elisp_code , & buffer [4 ]);
964+ } else if (subCmd == 'E' ) {
965+ /* "51;E" executes elisp code */
966+ /* The elisp code is executed in term_redraw */
967+ term -> elisp_code = malloc (strlen (buffer ) + 1 );
968+ strcpy (term -> elisp_code , buffer );
973969 term -> elisp_code_changed = true;
974970 return 1 ;
975971 }
976972 return 0 ;
977973}
974+ static int handle_osc_cmd (Term * term , int cmd , char * buffer ) {
975+ if (cmd == 51 ) {
976+ char subCmd = '0' ;
977+ if (strlen (buffer ) == 0 ) {
978+ return 0 ;
979+ }
980+ subCmd = buffer [0 ];
981+ return handle_osc_cmd_51 (term , subCmd , ++ buffer );
982+ }
983+ return 0 ;
984+ }
985+ #ifdef VTermStringFragmentNotExists
986+ static int osc_callback (const char * command , size_t cmdlen , void * user ) {
987+ Term * term = (Term * )user ;
988+ char buffer [cmdlen + 1 ];
989+ buffer [cmdlen ] = '\0' ;
990+ memcpy (buffer , command , cmdlen );
991+
992+ if (cmdlen > 4 && buffer [0 ] == '5' && buffer [1 ] == '1' && buffer [2 ] == ';' &&
993+ buffer [3 ] == 'A' ) {
994+ return handle_osc_cmd_51 (term , 'A' , & buffer [4 ]);
995+ } else if (cmdlen > 4 && buffer [0 ] == '5' && buffer [1 ] == '1' &&
996+ buffer [2 ] == ';' && buffer [3 ] == 'E' ) {
997+ return handle_osc_cmd_51 (term , 'E' , & buffer [4 ]);
998+ }
999+ return 0 ;
1000+ }
9781001
9791002static VTermParserCallbacks parser_callbacks = {
9801003 .text = NULL ,
@@ -984,6 +1007,41 @@ static VTermParserCallbacks parser_callbacks = {
9841007 .osc = & osc_callback ,
9851008 .dcs = NULL ,
9861009};
1010+ #else
1011+
1012+ static int osc_callback (int cmd , VTermStringFragment frag , void * user ) {
1013+ /* osc_callback (OSC = Operating System Command) */
1014+ Term * term = (Term * )user ;
1015+ size_t oldlen = 0 ;
1016+ if (term -> cmd_buffer ) {
1017+ oldlen = strlen (term -> cmd_buffer );
1018+ }
1019+ char * buffer = malloc (oldlen + frag .len + 1 );
1020+ buffer [oldlen + frag .len ] = '\0' ;
1021+ if (term -> cmd_buffer ) {
1022+ memcpy (buffer , term -> cmd_buffer , oldlen );
1023+ memcpy (& buffer [oldlen ], frag .str , frag .len );
1024+ free (term -> cmd_buffer );
1025+ term -> cmd_buffer = NULL ;
1026+ } else {
1027+ memcpy (buffer , frag .str , frag .len );
1028+ }
1029+ term -> cmd_buffer = buffer ;
1030+ if (frag .final ) {
1031+ handle_osc_cmd (term , cmd , buffer );
1032+ free (term -> cmd_buffer );
1033+ term -> cmd_buffer = NULL ;
1034+ }
1035+ return 0 ;
1036+ }
1037+ static VTermStateFallbacks parser_callbacks = {
1038+ .control = NULL ,
1039+ .csi = NULL ,
1040+ .osc = & osc_callback ,
1041+ .dcs = NULL ,
1042+ };
1043+
1044+ #endif
9871045
9881046emacs_value Fvterm_new (emacs_env * env , ptrdiff_t nargs , emacs_value args [],
9891047 void * data ) {
@@ -1041,6 +1099,8 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
10411099 term -> elisp_code = NULL ;
10421100 term -> elisp_code_changed = false;
10431101
1102+ term -> cmd_buffer = NULL ;
1103+
10441104 term -> lines = malloc (sizeof (LineInfo * ) * rows );
10451105 term -> lines_len = rows ;
10461106 for (int i = 0 ; i < rows ; i ++ ) {
0 commit comments