Changeset 4812
- Timestamp:
- Dec 10, 2021, 7:59:36 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/netlabs/macros/epmshell.e ¶
r4811 r4812 24 24 25 25 define 26 INCLUDING_FILE = ' FINDDEF.E'26 INCLUDING_FILE = 'EPMSHELL.E' 27 27 28 28 include 'stdconst.e' … … 48 48 ; --------------------------------------------------------------------------- 49 49 ; Called from ShellStart 50 defproc Sue_New( var shell_handle, shellnum)50 defproc Sue_New( var shell_handle, ShellNum) 51 51 thandle = '????' 52 52 result = dynalink32( ERES_DLL, … … 54 54 address( thandle) || 55 55 GethWndC( EPMINFO_EDITCLIENT) || 56 atol( shellnum))56 atol( ShellNum)) 57 57 shell_handle = thandle 58 58 return result … … 70 70 ; --------------------------------------------------------------------------- 71 71 ; Called from ShellOutputLines 72 defproc Sue_ReadLn( shell_handle, var buffe, var bytesmoved)72 defproc Sue_ReadLn( shell_handle, var buffe, var BytesMoved) 73 73 bufstring = buffe -- just to insure the same amount of space is available 74 74 bm = "??" … … 79 79 atol( length( bufstring)) || 80 80 address( bm)) 81 bytesmoved = itoa( bm, 10)81 BytesMoved = itoa( bm, 10) 82 82 buffe = bufstring 83 83 return result … … 85 85 ; --------------------------------------------------------------------------- 86 86 ; Called from ShellWrite 87 defproc Sue_Write( shell_handle, buffe, var bytesmoved)87 defproc Sue_Write( shell_handle, buffe, var BytesMoved) 88 88 bm = "??" 89 89 result = dynalink32( ERES_DLL, … … 93 93 atol( length( buffe)) || 94 94 address( bm)) 95 bytesmoved = itoa( bm, 10)95 BytesMoved = itoa( bm, 10) 96 96 return result 97 97 … … 122 122 compile endif 123 123 124 ; --------------------------------------------------------------------------- 125 defproc ShellGetPromptValue 126 KeyPath = '\NEPMD\User\Shell\PromptValue' 127 PromptVal = QueryConfigKey( KeyPath) 128 if PromptVal = '' then 129 PromptVal = EPM_SHELL_PROMPT 130 endif 131 -- Strip leading 'prompt' or '@prompt' 132 UpPromptVal = upcase( PromptVal) 133 if wordpos( word( UpPromptVal, 1), 'PROMPT @PROMPT') then 134 PromptVal = subword( PromptVal, 2) 135 endif 136 return PromptVal 137 124 138 ; =========================================================================== 125 139 ; Find and parse prompt … … 127 141 128 142 ; --------------------------------------------------------------------------- 129 ; Returns 1 if prompt not supported, 0 if prompt supported, but not on a 130 ; prompt line, otherwise the col for the end of the prompt (> or ]). 131 defproc ShellPromptPos 132 if not IsAShell() then 133 return 0 134 endif 135 LineStr = arg( 1) 136 if LineStr = '' then 143 ; Converts a prompt value to an egrep search string. 144 defproc ShellPromptToSearchStr( PromptVal) 145 SearchStr = '' 146 147 call ShellPromptToSearchStrCommon( PromptVal, 0, SearchStr, junk) 148 --dprintf( 'PromptVal = 'PromptVal) 149 --dprintf( 'SearchStr = 'SearchStr) 150 151 return SearchStr 152 153 ; --------------------------------------------------------------------------- 154 ; Converts a prompt value to 2 egrep search strings. 2 search strings are 155 ; used to place the cursor aroound the path output $p. That allows for to 156 ; determine the current path from a shell output and is used in emergancy 157 ; cases, when the shell is not able to save its environment. 158 defproc ShellPromptToSearchStr2( PromptVal, var SearchStr1, var SearchStr2) 159 SearchStr1 = '' 160 SearchStr2 = '' 161 162 call ShellPromptToSearchStrCommon( PromptVal, 1, SearchStr1, SearchStr2) 163 --dprintf( 'PromptVal = 'PromptVal) 164 --dprintf( 'SearchStr1 = 'SearchStr1) 165 --dprintf( 'SearchStr2 = 'SearchStr2) 166 167 return 168 169 ; --------------------------------------------------------------------------- 170 defproc ShellPromptToSearchStrCommon( PromptVal, fPlaceCursor, 171 var SearchStr1, var SearchStr2) 172 fPlaceCursor = (fPlaceCursor = 1) 173 SearchStr1 = '' 174 SearchStr2 = '' 175 Rest = PromptVal 176 177 -- Filter out ANSI Esc sequences 178 pStart = 1 179 do forever 180 pEscStart = pos( '$E[', upcase( Rest), pStart) 181 if pEscStart = 0 then 182 leave 183 else 184 pEscEnd = verify( Rest, 'ABCDHJKnfRhlmpsu', 'M', pEscStart + 3) 185 if pEscEnd = 0 then 186 leave 187 endif 188 Rest = delstr( Rest, pEscStart, pEscEnd - pEscStart + 1) 189 pStart = pEscStart 190 endif 191 enddo 192 193 -- Escape egrep search chars, allowed for a prompt macro 194 -- '$|&' as normal chars cannot be used in a prompt. They are 195 -- removed here compared to EGREP_METACHARACTERS. 196 AddEscapeChars = '\[]()?*+^.:~#@' 197 pStart = 1 198 do forever 199 if Rest == '' then 200 leave 201 endif 202 pFound = verify( Rest, AddEscapeChars, 'M', pStart) 203 if not pFound then 204 leave 205 else 206 Rest = leftstr( Rest, pFound - 1)'\'substr( Rest, pFound) 207 pStart = pFound + 2 208 endif 209 enddo 210 211 -- Convert prompt macros ('$' + single char) 212 PathConvertStr = ':a\:.#' 213 pStart = 1 214 do forever 215 pMacroStart = pos( '$', Rest, pStart) 216 if pMacroStart = 0 then 217 leave 218 else 219 MacroChar = substr( Rest, pMacroStart + 1, 1) 220 UpMacroChar = upcase( MacroChar) 221 ConvertStr = '???' 222 if MacroChar = '$' then 223 ConvertStr = '\$' 224 elseif UpMacroChar = 'A' then 225 ConvertStr = '\&' 226 elseif UpMacroChar = 'B' then 227 ConvertStr = '\|' 228 elseif UpMacroChar = 'C' then 229 ConvertStr = '\(' 230 elseif UpMacroChar = 'D' then 231 ConvertStr = '.#' 232 elseif UpMacroChar = 'E' then 233 ConvertStr = \27 234 elseif UpMacroChar = 'F' then 235 ConvertStr = '\)' 236 elseif UpMacroChar = 'G' then 237 ConvertStr = '\>' 238 elseif UpMacroChar = 'H' then 239 -- Processed below: Backspace 240 -- /Backspace not supported, just print char 241 --/ConvertStr = \8 242 elseif UpMacroChar = 'I' then 243 ConvertStr = '' 244 elseif UpMacroChar = 'L' then 245 ConvertStr = '\<' 246 elseif UpMacroChar = 'N' then 247 ConvertStr = ':a\:' 248 elseif UpMacroChar = 'P' then 249 if fPlaceCursor then 250 ConvertStr = '\c'PathConvertStr 251 else 252 ConvertStr = PathConvertStr 253 endif 254 elseif UpMacroChar = 'Q' then 255 ConvertStr = '=' 256 elseif UpMacroChar = 'R' then 257 ConvertStr = '(-|):i' 258 elseif UpMacroChar = 'S' then 259 ConvertStr = ' ' 260 elseif UpMacroChar = 'T' then 261 ConvertStr = '.#' 262 elseif UpMacroChar = 'V' then 263 ConvertStr = '.#' 264 elseif MacroChar = '_' then 265 -- Processed below: Linebreak 266 endif 267 if ConvertStr <> '???' then 268 -- Insert ConvertStr 269 pDelta = length( ConvertStr) - 2 -- 2 = length( SearchStr) 270 Rest = leftstr( Rest, pMacroStart - 1)''ConvertStr''substr( Rest, pMacroStart + 2) 271 pStart = pMacroStart + pDelta 272 elseif UpMacroChar = 'H' then 273 -- Backspace 274 pDelta = 1 - 2 -- 2 = length( SearchStr) 275 Rest = leftstr( Rest, pMacroStart - 2)''substr( Rest, pMacroStart + 2) 276 pStart = pMacroStart + pDelta 277 elseif MacroChar = '_' then 278 -- Linebreak: skip everything before 279 Rest = substr( Rest, pMacroStart + 2) 280 pStart = pMacroStart 281 endif 282 endif 283 enddo 284 285 SearchStr1 = '^'Rest 286 if fPlaceCursor then 287 -- Place the cursor after the path in a second search if '$p' specified 288 pCursor = pos( '\c'PathConvertStr, SearchStr1) 289 if pCursor then 290 SearchStr2 = leftstr( SearchStr1, pCursor - 1) || 291 PathConvertStr'\c' || 292 substr( SearchStr1, pCursor + 2 + length( PathConvertStr)) 293 endif 294 endif 295 296 return 297 298 ; --------------------------------------------------------------------------- 299 defproc ShellParsePromptLine( LineNum, var Prompt, var Cmd) 300 Prompt = '' 301 Cmd = '' 302 303 getline LineStr, LineNum 304 PromptVal = ShellGetPromptValue() 305 SearchStr = ShellPromptToSearchStr( PromptVal) 306 307 do n = 1 to 2 308 -- If not found, repeat search with stripped SearchStr 309 if n = 2 then 310 SearchStr = strip( SearchStr, 'T') 311 endif 312 pFound = pos( SearchStr, LineStr, 1, 'x') 313 if pFound then 314 PromptLen = getpminfo( EPMINFO_LSLENGTH) 315 Prompt = leftstr( LineStr, PromptLen) 316 Cmd = substr( LineStr, PromptLen + 1) 317 leave 318 endif 319 enddo 320 321 return 322 323 ; --------------------------------------------------------------------------- 324 defproc ShellGetPrevDir 325 do once = 1 to 1 326 Dir = '' 327 SavedRc = rc 328 pSave_Pos( SavedPos) 329 getsearch SavedSearch 330 331 LineNum = arg( 1) 332 if LineNum = '' then 333 LineNum = .line 334 elseif not IsNum( LineNum) then 335 LineNum = .line 336 else 337 .lineg = LineNum 338 endif 339 340 PromptVal = ShellGetPromptValue() 341 call ShellPromptToSearchStr2( PromptVal, SearchStr1, SearchStr2) 342 343 display -15 -- disables all messsage output and screen updates 344 do n = 1 to 2 345 .lineg = LineNum 346 endline 347 dprintf( '.line = '.line', .col = '.col) 348 -- If not found, repeat search with stripped SearchStr 349 if n = 2 then 350 SearchStr1 = strip( SearchStr1, 'T') 351 SearchStr2 = strip( SearchStr2, 'T') 352 endif 353 'xcom l '\1''SearchStr1''\1'x-R' 354 if not rc & .line = LineNum then 355 -- Found 356 leave 357 endif 358 enddo 359 display 15 360 dprintf( 'SearchStr1 = 'SearchStr1', rc = 'rc) 361 if rc | .line <> LineNum then 362 -- Not found 363 leave 364 endif 365 pFound1 = .col 366 dprintf( 'pFound1 = 'pFound1) 367 368 display -15 -- disables all messsage output and screen updates 369 endline 370 dprintf( '.line = '.line', .col = '.col) 371 'xcom l '\1''SearchStr2''\1'x-R' 372 display 15 373 dprintf( 'SearchStr2 = 'SearchStr2', rc = 'rc) 374 if rc | .line <> LineNum then 375 -- Not found 376 leave 377 endif 378 pFound2 = .col 379 dprintf( 'pFound2 = 'pFound2) 380 137 381 getline LineStr 138 endif 139 140 compile if not (EPM_SHELL_PROMPT = '@prompt epm: $p $g' | EPM_SHELL_PROMPT = '@prompt [epm: $p ]') 141 return 1 142 compile endif 143 144 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g' 145 p = pos( '>', LineStr) 146 if leftstr( LineStr, 5) = 'epm: ' & p then 147 compile else 148 p = pos( ']', LineStr) 149 if leftstr( LineStr, 6) = '[epm: ' & p then 150 compile endif 151 return p 152 else 153 return 0 154 endif 382 Dir = substr( LineStr, pFound1, pFound2 - pFound1) 383 enddo 384 setsearch SavedSearch 385 pRestore_Pos( SavedPos) 386 rc = SavedRc 387 388 return Dir 155 389 156 390 ; --------------------------------------------------------------------------- … … 160 394 ; Sets rc from 'xcom l'. 161 395 defproc ShellGotoNextPrompt 396 --dprintf( 'ShellGotoNextPrompt 'arg( 1)) 162 397 pSave_Pos( SavedPos) 163 398 getsearch SavedSearch 164 399 if upcase( arg( 1)) = 'P' then 165 400 Direction = '-r' 401 --dprintf( 'ShellGotoNextPrompt: .col = 1 on .line = '.line) 166 402 .col = 1 167 403 else 168 404 Direction = '' 169 .col = length( textline( .line)) + 1 170 endif 405 endif 406 407 PromptVal = ShellGetPromptValue() 408 SearchStr = ShellPromptToSearchStr( PromptVal) 409 171 410 display -2 172 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g' 173 'xcom l /^epm\: .*>:o\c/x'Direction 174 compile else -- else EPM_SHELL_PROMPT = '@prompt [epm: $p ]' 175 'xcom l /^\[epm\: .*\]:o\c/x'Direction 176 compile endif -- EPM_SHELL_PROMPT 411 'xcom l '\1''SearchStr\1'x'Direction 177 412 display 2 178 413 if rc then 179 414 pRestore_Pos( SavedPos) 180 endif 415 else 416 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 417 .col = length( CurPrompt) + 1 418 endif 419 181 420 setsearch SavedSearch 182 421 return … … 200 439 201 440 ; --------------------------------------------------------------------------- 202 ; Parses current line and set Dir and Cmd via call by reference. 203 defproc ShellParsePromptLine( var Dir, var Cmd) 204 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g' 205 parse value textline( .line) with 'epm:' Dir '>' Cmd 206 compile else 207 parse value textline( .line) with 'epm:' Dir ']' Cmd 208 compile endif -- EPM_SHELL_PROMPT 209 Dir = strip( Dir) 210 Cmd = strip( Cmd) 211 return 212 213 ; --------------------------------------------------------------------------- 214 ; Called by IsADirList. 441 ; Called by IsADirList and here. 215 442 defproc ShellGetLastCmd 216 LastCmd = '' 443 --dprintf( 'ShellGetLastCmd') 217 444 call pSave_Pos( SavedPos) 218 445 SavedRc = rc 219 call ShellGotoNextPrompt( 'P') 220 if not rc then 221 call ShellParsePromptLine( Dir, Cmd) 222 LastCmd = Cmd 223 endif 446 447 -- Use current Cmd if Cmd is about to process 448 CurCmd = GetAVar( 'shellcurrentcmd') 449 if not CurCmd then 450 -- Check previous prompt line 451 call ShellGotoNextPrompt( 'P') 452 if not rc then 453 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 454 if CurCmd <> '' then 455 -- Store shellcurrentcmd 456 call SetAVar( 'shellcurrentcmd', CurCmd) 457 endif 458 endif 459 endif 460 224 461 rc = SavedRc 225 462 call pRestore_Pos( SavedPos) 226 return LastCmd463 return CurCmd 227 464 228 465 ; =========================================================================== … … 429 666 endif 430 667 431 ShellAppWaiting = GetAVar( ShellFid'.shellappwaiting')432 if words( ShellAppWaiting) < 2then668 call ShellParsePromptLine( .last, LastPrompt, LastCmd) 669 if LastPrompt | .last = 1 then 433 670 -- Execute Cmd 434 671 if Cmd then 435 'ShellWrite' ShellNum Cmd 672 --'ShellWriteQuiet' ShellNum Cmd 673 'ShellWriteCmd' ShellNum Cmd 436 674 endif 437 675 -- Use real case of current dir, even when XWP has uppercased it. … … 489 727 490 728 -- This is required for restored shell files to delete the initial lines 491 call SetAVar( ShellFid'.s tartlinenum', .last)729 call SetAVar( ShellFid'.shellstartlinenum', .last) 492 730 493 731 -- Alias file … … 499 737 500 738 -- Change prompt 501 if EPM_SHELL_PROMPT <> '' then 502 'ShellWrite' shell_index EPM_SHELL_PROMPT 503 endif 739 PromptValue = ShellGetPromptValue() 740 CurCmd = '@prompt 'PromptValue 741 call SetAVar( 'shellcurrentcmd', CurCmd) 742 --'ShellWriteCmdQuiet' ShellNum CurCmd 743 'ShellWriteCmdQuiet' ShellNum CurCmd 504 744 505 745 -- Execute InitCmd … … 507 747 InitCmd = QueryConfigKey( KeyPath) 508 748 if InitCmd <> '' then 509 'ShellWrite' ShellNum InitCmd 510 endif 511 512 ShellAppWaiting = GetAVar( ShellFid'.shellappwaiting') 513 if words( ShellAppWaiting) < 2 then 749 CurCmd = InitCmd 750 call SetAVar( 'shellcurrentcmd', CurCmd) 751 --'ShellWriteCmdQuiet' ShellNum CurCmd 752 'ShellWriteCmdQuiet' ShellNum CurCmd 753 endif 754 755 call ShellParsePromptLine( .last, LastPrompt, LastCmd) 756 if LastPrompt | .last = 1 then 514 757 -- Execute Cmd 515 758 if Cmd then 516 'ShellWrite' ShellNum Cmd 759 --'ShellWriteCmdQuiet' ShellNum Cmd 760 'ShellWriteCmd' ShellNum Cmd 517 761 endif 518 762 -- Use real case of current dir, even when XWP has uppercased it. … … 538 782 ; SHELL. Can be used to "reactivate" a shell, whose .command_shell_ output 539 783 ; was saved before and then gets reloaded. 784 ; This is executed by defc Mode. 540 785 defc ShellRestore 541 786 universal shell_index … … 574 819 575 820 -- Determine previous work dir 576 call pSave_Pos( save_pos)577 SavedRc = rc578 821 display -3 579 822 .lineg = .last 580 823 endline 581 call ShellGotoNextPrompt( 'P') 582 Dir = '' 583 Cmd = '' 584 if not rc then 585 call ShellParsePromptLine( Dir, Cmd) 586 else 587 call pRestore_Pos( save_pos) 588 endif 589 rc = SavedRc 824 Dir = ShellGetPrevDir() 590 825 display 3 591 826 … … 593 828 if directory() <> Dir then 594 829 CdCmd = 'cdd' EnquoteFilespec( Dir) 595 'ShellWrite' shell_index CdCmd 830 --'ShellWrite' shell_index CdCmd 831 'ShellWriteCmdQuiet' shell_index CdCmd 596 832 endif 597 833 endif … … 678 914 call SetAVar( 'shell_f'ShellNum, '') 679 915 call SetAVar( 'shell_h'ShellNum, '') 680 call SetAVar( S ellFid'.shellnum', '')916 call SetAVar( ShellFid'.shellnum', '') 681 917 if fClose then 682 918 if curfid <> ShellFid then … … 688 924 ; --------------------------------------------------------------------------- 689 925 defc ShellClose 690 .modify = 0926 'ShellResetModify' 691 927 'ShellKill' 928 929 ; --------------------------------------------------------------------------- 930 defmodify 931 -- 'ShellResetModify' 932 933 ; --------------------------------------------------------------------------- 934 defc ShellResetModify 935 if IsAShell() then 936 if .modify then 937 -- This ensures that special files can be closed without 938 -- popping up a message box that asks "Are you sure?" 939 if FileShouldBeDiscarded() then 940 .modify = 0 941 endif 942 943 -- This doesn't work: 944 'RefreshInfoLine DATETIMEMODIFIED' 945 -- This works: 946 --'SetStatusLine' 947 --'RefreshInfoLine FILE' -- as well 948 endif 949 endif 692 950 693 951 ; =========================================================================== … … 699 957 ; If first word is not a number, then last opened shell is used as 700 958 ; <shellnum>. 701 ; If <input> is missing, the 'Write to shell' EntryBox opens.702 959 defc ShellWrite, Shell_Write 703 universal shelllastwrite 960 961 call ShellWriteParseCommon( arg( 1), ShellNum, Input, fCallAgain, 962 'ShellWrite') 963 if fCallAgain then 964 return 965 endif 966 967 -- Write to shell 968 fAppendLineEnd = 1 969 dprintf( 'ShellWrite: -------- Input = 'Input' --------') 970 call ShellWriteCommon( ShellNum, fAppendLineEnd, Input) 971 972 ; --------------------------------------------------------------------------- 973 ; Syntax: ShellWriteCmd [<shellnum>] [<input>] 974 ; If first word is not a number, then last opened shell is used as 975 ; <shellnum>. 976 defc ShellWriteCmd 977 978 call ShellWriteParseCommon( arg( 1), ShellNum, Input, fCallAgain, 979 'ShellWriteCmd') 980 if fCallAgain then 981 return 982 endif 983 984 -- Store shellcurrentcmd 985 call SetAVar( 'shellcurrentcmd', Input) 986 987 -- Write to shell 988 fAppendLineEnd = 1 989 dprintf( 'ShellWriteCmd: -------- Input = 'Input' --------') 990 call ShellWriteCommon( ShellNum, fAppendLineEnd, Input) 991 992 ; --------------------------------------------------------------------------- 993 ; Syntax: ShellWriteCmdQuiet [<shellnum>] [<input>] 994 ; If first word is not a number, then last opened shell is used as 995 ; <shellnum>. 996 ; The output of <input> is not displayed. The previous last line (the empty 997 ; prompt) is replaced with a new one. 998 defc ShellWriteCmdQuiet 999 1000 call ShellWriteParseCommon( arg( 1), ShellNum, Input, fCallAgain, 1001 'ShellWriteCmdQuiet') 1002 if fCallAgain then 1003 return 1004 endif 1005 1006 -- Store shellcurrentcmd 1007 call SetAVar( 'shellcurrentcmd', Input) 1008 1009 -- Ignore output for Cmd 1010 imax = GetFileAVar( 'shellignorecmd.0') 1011 if imax = '' then 1012 imax = 0 1013 endif 1014 i = imax + 1 1015 SetFileAVar( 'shellignorecmd.'i, Input) 1016 SetFileAVar( 'shellignorecmd.0', i) 1017 1018 fAppendLineEnd = 1 1019 dprintf( 'ShellWriteCmdQuiet: -------- Input = 'Input' --------') 1020 call ShellWriteCommon( ShellNum, fAppendLineEnd, Input) 1021 1022 ; --------------------------------------------------------------------------- 1023 ; Syntax: ShellWriteChars [<shellnum>] [<input>] 1024 ; If first word is not a number, then last opened shell is used as 1025 ; <shellnum>. 1026 defc ShellWriteChars 1027 1028 call ShellWriteParseCommon( arg( 1), ShellNum, Input, fCallAgain, 1029 'ShellWriteChars') 1030 if fCallAgain then 1031 return 1032 endif 1033 1034 -- Split at line end and strip it 1035 pLF = pos( \10, Input) 1036 if pLF then 1037 Input = leftstr( Input, pLF) 1038 endif 1039 if rightstr( Input, 1) = \13 then 1040 Input = leftstr( Input, length( Input) - 1) 1041 endif 1042 --dprintf( 'ShellWriteChars: Input = 'Input', pLF = 'pLF) 1043 1044 -- Type Input 1045 fAppendLineEnd = 0 1046 dprintf( 'ShellWriteChars: -------- Input = 'Input', pLF = 'pLF' --------') 1047 call ShellWriteCommon( ShellNum, fAppendLineEnd, Input) 1048 1049 if pLF then 1050 -- Write cmd or line 1051 'ShellEnterLine' 1052 endif 1053 1054 ; --------------------------------------------------------------------------- 1055 ; This returns fCallAgain and ensures that ShellNum is set. 1056 ; - If ShellNum is specified, it is verified. If it's of current file, 1057 ; fCallAgain is set to 0. 1058 ; - If ShellNum is not in ring or not specified, a new shell is opened and 1059 ; fCallAgain is set to 1. 1060 ; - If ShellNum is not specified, the last opened shell is used and 1061 ; fCallAgain is set to 1. 1062 defproc ShellVerifyShellNum( var fCallAgain, var ShellNum) 704 1063 universal shell_index 705 1064 706 1065 do once = 1 to 1 1066 fCallAgain = 0 707 1067 fShellFound = 0 708 1068 709 parse arg ShellNum Input 710 --dprintf( 'ShellWrite: ShellNum Input = 'ShellNum Input) 1069 -- Keep topmost shell 1070 if IsAShell() then 1071 ShellNum = GetFileAVar( 'shellnum') 1072 getfileid ShellFid 1073 fShellFound = 1 1074 --dprintf( ' ShellVerifyShellNum 1: ShellNum = 'ShellNum) 1075 leave 1076 endif 1077 1078 -- Switch to specified ShellNum if in ring 711 1079 if IsNum( ShellNum) then 712 1080 ShellFid = GetAVar( 'shell_f'ShellNum) … … 714 1082 pActivateFile( ShellFid) 715 1083 fShellFound = 1 1084 --dprintf( ' ShellVerifyShellNum 2: ShellNum = 'ShellNum) 1085 fCallAgain = 1 716 1086 leave 717 1087 endif 718 1088 endif 719 1089 720 if IsAShell() then 721 ShellNum = GetFileAVar( 'shellnum') 722 getfileid ShellFid 723 fShellFound = 1 724 parse arg Input 725 leave 726 endif 727 1090 -- Switch to last created shell if in ring 728 1091 do s = shell_index to 1 by -1 729 1092 ShellFid = GetAVar( 'shell_f'shell_index) … … 732 1095 pActivateFile( ShellFid) 733 1096 fShellFound = 1 734 parse arg Input 735 -- After switching to the shell, Input must be posted. 736 -- Otherwise it won't be written to the shell. 737 'PostMe ShellWrite 'ShellNum Input 738 return 1097 --dprintf( ' ShellVerifyShellNum 3: ShellNum = 'ShellNum) 1098 fCallAgain = 1 1099 leave 739 1100 endif 740 1101 enddo 741 1102 742 1103 -- Open a new shell if none in ring 743 'Shell' 1104 if not fShellFound then 1105 'Shell' 1106 --dprintf( ' ShellVerifyShellNum 4: ShellNum = 'ShellNum) 1107 fCallAgain = 1 1108 leave 1109 endif 1110 1111 enddo -- once 1112 1113 return 1114 1115 ; --------------------------------------------------------------------------- 1116 defproc ShellWriteParseCommon( Args, var ShellNum, var Input, var fCallAgain, 1117 CallingCmd) 1118 parse value Args with ShellNum Input 1119 1120 ShellNum = strip( ShellNum) 1121 Input = strip( Input, 'L') 1122 if ShellNum = '' then 1123 -- nop 1124 elseif not IsNum( ShellNum) then 1125 ShellNum = '' 744 1126 parse arg Input 745 'PostMe ShellWrite 'Input 746 return 747 enddo -- once 748 749 ShellAppWaiting = GetFileAVar( 'shellappwaiting') 1127 Input = strip( Input, 'L') 1128 endif 1129 --dprintf( 'ShellWriteCmd after parse : ShellNum = 'ShellNum', Input = 'Input) 1130 1131 -- Ensure that ShellNum is set 1132 call ShellVerifyShellNum( fCallAgain, ShellNum) 1133 --dprintf( 'ShellWriteCmd after verify: ShellNum = 'ShellNum', Input = 'Input) 1134 if fCallAgain then 1135 -- After switching to the shell, Input must be posted. 1136 -- Otherwise it won't be written to the shell. 1137 'PostMe 'CallingCmd ShellNum Input 1138 endif 1139 1140 return 1141 1142 ; --------------------------------------------------------------------------- 1143 defproc ShellWriteCommon( ShellNum, fAppendLineEnd, Input) 750 1144 ShellHandle = GetAVar( 'Shell_h'ShellNum) 751 1145 752 if Input = '' & words( ShellAppWaiting) < 2 then -- disable this silly box for Return in a waiting shell 753 'ShellHistory 'ShellNum 754 endif 755 756 if Input <> '' then 757 -- Set universal 758 shelllastwrite = Input 759 -- Append line end 760 WriteBuf = Input\13\10 1146 -- Determine if cmd output should be ignored 1147 fIgnored = 0 1148 imax = GetFileAVar( 'shellignorecmd.0') 1149 if imax then 1150 do i = 1 to imax 1151 IgnoreCmd = GetFileAVar( 'shellignorecmd.'i) 1152 if Input = IgnoreCmd then 1153 fIgnored = 1 1154 leave 1155 endif 1156 enddo 1157 endif 1158 1159 -- Determine if app is waiting (LastPrompt = '') and read CurCmd 1160 call ShellParsePromptLine( .last, LastPrompt, LastCmd) 1161 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 1162 --dprintf( 'ShellWriteCommon: Input = 'Input', .line = '.line', CurCmd = 'CurCmd', CurPrompt = 'CurPrompt) 1163 1164 if not fIgnored then 1165 1166 if LastPrompt & fAppendLineEnd then 1167 1168 ---- Prompt on last line: write cmd ---- 1169 -- Change bookmark name from 'Last' to cmd 1170 -- Get bmidx for last bookmark 1171 bmidxmax = GetFileAVar( 'bmname.0') 1172 --Input = CurCmd 1173 --dprintf( 'ShellWriteCommon: fAppendLineEnd = 'fAppendLineEnd', no app is waiting, set bookmark to 'Input) 1174 --dprintf( 'Change bookmark name for bmidx 'bmidxmax' to "'Input'".') 1175 dprintf( "# ShellWriteCommon: Bookmark name with index "bmidxmax" changed from 'Last' to >"Input"<") 1176 call SetFileAVar( 'bmname.'bmidxmax, Input) 1177 1178 if .line = .last then 1179 --dprintf( 'ShellWriteCommon: Delete CurCmd = 'CurCmd', .line = '.line) 1180 .col = length( CurPrompt) + 1 1181 eraseendline 1182 elseif IsADirectoryOfLine() then 1183 -- Restore the previous 'Directory of' line from bookmark 1184 getfileid ShellFid 1185 bmidx = GetBookmarkIdx( ShellFid, .line, 1) 1186 bmname = GetBmName( ShellFid, bmidx) 1187 bmline = .line 1188 bmcol = 1 1189 -- Replaceline deletes the bookmark 1190 dprintf( '# ShellWriteCommon: Restore bmname = 'bmname', .line = '.line) 1191 replaceline bmname 1192 -- Set the bookmark back to col 1 1193 SetBookmark( 3, bmline, bmcol, bmname) 1194 dprintf( '# Bookmark set on line 'bmline' to >'bmname'<') 1195 elseif CurPrompt then 1196 -- Restore the previous Cmd from bookmark 1197 getfileid ShellFid 1198 bmidx = GetBookmarkIdx( ShellFid, .line, 1) 1199 bmname = GetBmName( ShellFid, bmidx) 1200 dprintf( '# ShellWriteCommon: Restore bmname = 'bmname', .line = '.line) 1201 .col = length( CurPrompt) + 1 1202 -- Eraseendline preserves the bookmark in col 1 1203 eraseendline 1204 keyin bmname 1205 -- Ensure that text after prompt in last line is deleted 1206 .line = .last 1207 .col = length( CurPrompt) + 1 1208 eraseendline 1209 endif 1210 1211 endif -- LastPrompt & fAppendLineEnd 1212 1213 endif -- not fIgnored 1214 1215 WriteBuff = Input 1216 if fAppendLineEnd then 1217 WriteBuff = WriteBuff\13\10 1218 endif 1219 1220 --dprintf( 'ShellWriteCommon: fAppendLineEnd = 'fAppendLineEnd', LastPrompt = 'LastPrompt) 1221 if (LastPrompt & fAppendLineEnd) | not LastPrompt then 761 1222 -- Write to shell 762 rc = Sue_Write( ShellHandle, WriteBuf, BytesMoved) 1223 --dprintf( 'ShellWriteCommon: Write Input = 'Input) 1224 rc = Sue_Write( ShellHandle, WriteBuff, BytesMoved) 763 1225 -- Check rc 764 if rc | (BytesMoved <> length( WriteBuf )) then765 'SayError ShellWrite : rc =' rc', byteswritten =' BytesMoved 'of' length( WriteBuf)1226 if rc | (BytesMoved <> length( WriteBuff)) then 1227 'SayError ShellWriteCommon: rc =' rc', byteswritten =' BytesMoved 'of' length( WriteBuff) 766 1228 'ShellBreak' 767 1229 endif 768 1230 endif 1231 1232 return 769 1233 770 1234 -- The above code is not really complete. It should also deal with … … 774 1238 775 1239 ; --------------------------------------------------------------------------- 776 ; Opens a list box with last commands. The selected one can be submitted and777 ; optionally be edited in an entry box before. This was previously a part of778 ; ShellWrite, except that the order of both boxes was changed. It starts779 ; with the list box, not with the entry box. Main idea by Joerg Tiemann.780 defc ShellHistory, Shell_History781 universal shelllastwrite782 783 do once = 1 to 1784 parse arg ShellNum Input785 if ShellNum = '' & IsAShell() then786 ShellNum = GetFileAVar( 'shellnum')787 endif788 if ShellNum = '' then789 'SayError 'NOT_IN_SHELL__MSG790 return791 endif792 793 ShellHandle = GetAVar( 'shell_h'ShellNum)794 795 if ShellHandle = '' then796 leave797 endif798 799 BoxTitle = strip( WRITE_SHELL_MENU__MSG, 'T', '.') -- '~Write to shell...'800 pTilde = pos( '~', BoxTitle)801 if pTilde then802 BoxTitle = delstr( BoxTitle, pTilde, 1)803 endif804 805 do forever806 807 getfileid ShellFid808 call pSave_Pos( SavedPos)809 'xcom e /c cmdslist'810 if rc <> -282 then -- -282 = sayerror( "New file")811 'SayError 'ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)812 return813 endif814 browse_mode = browse() -- Query current state815 if browse_mode then816 call browse( 0)817 endif818 .autosave = 0819 getfileid lb_fid820 activatefile ShellFid821 display -2822 getsearch SavedSearch823 0824 825 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g'826 'xcom l /^epm\: .*>:o./x'827 compile else -- else EPM_SHELL_PROMPT = '@prompt [epm: $p ]'828 'xcom l /^\[epm\: .*\]:o./x'829 compile endif -- EPM_SHELL_PROMPT830 831 do while rc = 0832 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g'833 parse value textline( .line) with '>' Cmd834 compile else835 parse value textline( .line) with ']' Cmd836 compile endif -- EPM_SHELL_PROMPT837 insertline strip( Cmd, 'L'), lb_fid.last + 1, lb_fid838 repeatfind839 enddo840 841 setsearch SavedSearch842 call pRestore_Pos( SavedPos)843 if browse_mode then844 call browse( 1) -- Restore browse state845 endif846 activatefile lb_fid847 display 2848 if not .modify then -- Nothing added?849 'xcom quit'850 activatefile ShellFid851 'SayError -273' -- String not found852 return853 endif854 855 if ListBox_Buffer_From_File( ShellFid, bufhndl, noflines, usedsize) then856 return857 endif858 Text = ''859 ListBoxButtons = '/'OK__MSG'/'EDIT__MSG'.../'Cancel__MSG860 DefaultItem = noflines - 1 -- Last item, first line of lb_fid is empty861 DefaultButton = 1862 HelpId = 0863 parse value ListBox( BoxTitle,864 \0 || atol( usedsize) || atoi( 32) || atoi( bufhndl),865 ListBoxButtons,866 0, 0, -- top, left867 12, 0, -- height, width,868 GethWndC( APP_HANDLE) ||869 atoi( DefaultItem) ||870 atoi( DefaultButton) ||871 atoi( HelpId) ||872 Text\0) with LbButton 2 Input \0873 call buffer( FREEBUF, bufhndl)874 875 if LbButton = \1 then876 leave877 elseif LbButton = \2 then -- 'Edit' selected878 -- Set universal879 shelllastwrite = Input880 881 Text = SHELL_PROMPT__MSG ShellNum882 Text = Text''copies( ' ', Max( 0, 100 - length( Text)))883 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g' | EPM_SHELL_PROMPT = '@prompt [epm: $p ]'884 EntryBoxButtons = '/'OK__MSG'/'LIST__MSG'/'Cancel__MSG'/'885 NumEntryBoxButtons = 3886 compile else887 EntryBoxButtons = '/'OK__MSG'/'Cancel__MSG'/'888 NumEntryBoxButtons = 2889 compile endif890 DefaultButton = 1891 --HelpId = 0892 parse value EntryBox( BoxTitle,893 EntryBoxButtons,894 shelllastwrite, -- entrytext895 0, 254, -- cols, maxchars896 atoi( DefaultButton) ||897 atoi( HelpId) ||898 GethWndC( APP_HANDLE) ||899 Text) with EbButton 2 Input \0900 if EbButton = \1 then901 leave902 elseif EbButton = \2 & NumEntryBoxButtons = 3 then -- 'List' selected903 iterate904 else905 return906 endif907 908 else909 return910 endif911 912 enddo -- forever913 914 'ShellWrite 'Input915 enddo916 917 ; ---------------------------------------------------------------------------918 1240 ; Shell object sends this command to inform the editor that there is 919 1241 ; room for additional data to be written. 920 1242 defc NowCanWriteShell 921 'SayError 'SHELL_OBJECT__MSG arg( 1) SHELL_READY__MSG -- Use ShellWrite with argumentstring 1243 -- Use ShellWrite with argumentstring 1244 'SayError 'SHELL_OBJECT__MSG arg( 1) SHELL_READY__MSG 1245 1246 ; =========================================================================== 1247 ; Current dir and E cmd 1248 ; =========================================================================== 1249 1250 ; --------------------------------------------------------------------------- 1251 ; Instead of writing to a tmp file, put it out to shell, read line 1252 ; and disable output. 1253 defproc ShellGetCmdOutput 1254 Cmd = arg( 1) 1255 LineNum = arg( 2) -- Which line of LogFile should be read 1256 if LineNum = '' then 1257 LineNum = 1 1258 endif 1259 OutputLine = '' 1260 display -1 1261 do once = 1 to 1 1262 if Cmd = '' then 1263 leave 1264 endif 1265 if not IsAShell() then 1266 leave 1267 endif 1268 LogFile = GetTmpPath()'nepmd\shellcmd.log' 1269 if Exist( LogFile) then 1270 DeleteFile( LogFile) 1271 endif 1272 1273 'ShellWriteCmdQuiet 'Cmd'>'LogFile 1274 getfileid ShellFid 1275 1276 -- Delay loop until file exists 1277 fLogFileFound = 0 1278 TimeOutMs = 1000 1279 NumIterations = 1000 -- 1000 means: a check every 1 ms 1280 do i = 1 to NumIterations 1281 if Exist( LogFile) then 1282 --dprintf( 'LogFile found after '(i - 1) * TimeOutMs / NumIterations' ms') 1283 fLogFileFound = 1 1284 leave 1285 else 1286 Sleep( TimeOutMs / NumIterations) 1287 endif 1288 enddo 1289 if not fLogFileFound then 1290 rc = 2 1291 leave 1292 endif 1293 1294 -- xcom e /d always loads a file. If it doesn't exist, it's created. 1295 'xcom e /d /q 'LogFile 1296 if rc then 1297 dprintf( sayerrortext( rc)) 1298 activatefile ShellFid 1299 leave 1300 endif 1301 1302 getfileid LogFid 1303 getline OutputLine, LineNum, LogFid 1304 activatefile LogFid 1305 .modify = 0 1306 'xcom q' 1307 DeleteFile( LogFile) 1308 activatefile ShellFid 1309 enddo 1310 display 1 1311 return OutputLine 1312 1313 ; --------------------------------------------------------------------------- 1314 ; Instead of writing to a tmp file, put it out to shell, read line 1315 ; and disable output. 1316 defproc ShellGetCurDir 1317 CurDir = '' 1318 display -1 1319 do once = 1 to 1 1320 if not IsAShell() then 1321 leave 1322 endif 1323 LogFile = GetTmpPath()'nepmd\curdir.log' 1324 Cmd = 'cd>'LogFile 1325 if Exist( LogFile) then 1326 DeleteFile( LogFile) 1327 endif 1328 1329 'ShellWriteCmdQuiet 'Cmd 1330 getfileid ShellFid 1331 1332 -- Delay loop until file exists 1333 fLogFileFound = 0 1334 TimeOutMs = 1000 1335 NumIterations = 1000 -- 1000 means: a check every 1 ms 1336 do i = 1 to NumIterations 1337 if Exist( LogFile) then 1338 --dprintf( 'LogFile found after '(i - 1) * TimeOutMs / NumIterations' ms') 1339 fLogFileFound = 1 1340 leave 1341 else 1342 Sleep( TimeOutMs / NumIterations) -- usually 1 iteration required 1343 endif 1344 enddo 1345 if not fLogFileFound then 1346 rc = 2 1347 leave 1348 endif 1349 1350 -- xcom e /d always loads a file. If it doesn't exist, it's created. 1351 'xcom e /d /q 'LogFile 1352 if rc then 1353 --dprintf( sayerrortext( rc)) 1354 activatefile ShellFid 1355 leave 1356 endif 1357 1358 getfileid LogFid 1359 LogFid.visible = 0 1360 getline CurDir, 1, LogFid 1361 activatefile LogFid 1362 .modify = 0 1363 'xcom q' 1364 DeleteFile( LogFile) 1365 --'PostMe 'ShellGetCurDirFromLog LogFile 1366 activatefile ShellFid 1367 enddo 1368 display 1 1369 return CurDir 1370 1371 defc ShellGetCurDir 1372 CurDir = ShellGetCurDir() 1373 dprintf( 'CurDir = 'CurDir', rc = 'rc) 1374 'SayError CurDir = 'CurDir', rc = 'rc 1375 1376 ; --------------------------------------------------------------------------- 1377 defc ShellGetCurDirFromLog 1378 do once = 1 to 1 1379 LogFile = strip( arg( 1)) 1380 LineStr = '' 1381 /* 1382 'xcom e /c 'LogFile 1383 getfileid 1384 --Read first line 1385 LineStr = '...' 1386 .modify = 0 1387 'xcom q' 1388 DeleteFile( LogFile) 1389 call ShellGetCurDir( LineStr) 1390 */ 1391 enddo 1392 1393 ; --------------------------------------------------------------------------- 1394 defproc ShellECmd( ECmd, Line, Col) 1395 .line = Line 1396 .col = Col 1397 1398 if .line = .last then 1399 eraseendline 1400 else 1401 -- Restore the previous Cmd from bookmark 1402 getfileid ShellFid 1403 bmidx = GetBookmarkIdx( ShellFid, .line, 1) 1404 bmname = GetBmName( ShellFid, bmidx) 1405 eraseendline 1406 keyin bmname 1407 endif 1408 1409 -- Execute ECmd 1410 ECmd 1411 1412 return 922 1413 923 1414 ; =========================================================================== … … 940 1431 ; - Recognize if an app is waiting for user input (then last line is not the 941 1432 ; EPM prompt). 942 ; - S et ShellAppWaiting to 0 or to line and col.1433 ; - Stores line and col after output to shelloutputpos. 943 1434 ; - Right margin setting of current shell is not respected. 944 1435 ; - The prompt after executing a start command (maybe "start epm config.sys") … … 960 1451 pActivateFile( ShellFid) 961 1452 962 -- Enable i titial line deletion963 StartLineNum = GetAVar( ShellFid'.s tartlinenum')1453 -- Enable initial line deletion 1454 StartLineNum = GetAVar( ShellFid'.shellstartlinenum') 964 1455 fFilterInitLines = 0 1456 /* 965 1457 if IsNum( StartLineNum) then 966 1458 if StartLineNum = .last then … … 969 1461 endif 970 1462 endif 1463 */ 971 1464 --dprintf( 'ShellOutputLines: StartLineNum = 'StartLineNum', .last = '.last', fFilterInitLines = 'fFilterInitLines) 972 1465 973 TotalBytesMoved = 0 1466 CurCmd = GetAVar( 'shellcurrentcmd') 1467 1468 TotalBytesMoved = 0 1469 fIgnoreCurrentCmd = 0 1470 fReplaceLastPrompt = 0 974 1471 do forever -- (until (BytesMoved = 0) = (RestLineStr == '')) 975 1472 … … 982 1479 retval = Sue_ReadLn( ShellHandle, ReadBuff, BytesMoved) 983 1480 ReadBuff = leftstr( ReadBuff, BytesMoved) 1481 if fIgnoreCurrentCmd then 1482 --dprintf( 'ReadBuff = 'translate( ReadBuff, \1\2'~', \10\13\20)) 1483 endif 984 1484 if not BytesMoved then 985 1485 leave … … 987 1487 988 1488 TotalBytesMoved = TotalBytesMoved + BytesMoved 989 RestLineStr = ReadBuff990 1489 --dprintf( 'ShellOutputLines: ReadBuff = 'translate( RestLineStr, \1\2'~', \10\13\20)) 991 1490 992 -- Write ReadBuff line-wise to current file. Split at LF, ignore CR.993 1491 -- Both CR and LF end a line (read by Sue_ReadLn) and start a new one. 1492 if ReadBuff = \13 then 1493 iterate -- ignore CR 1494 endif 1495 1496 -- Ignore ANSI Esc sequences. Determine if current line should be 1497 -- ignored because of quiet output set by ShellWriteCmdQuiet. 1498 call ShellFilterReadLineBuff( ReadBuff, fIgnoreCurrentCmd, fReplaceLastPrompt) 1499 dprintf( 'ShellOutputLines after filter: fIgnoreCurrentCmd = 'fIgnoreCurrentCmd', fReplaceLastPrompt = 'fReplaceLastPrompt) 1500 1501 -- Write ReadBuff line-wise to current file. 994 1502 -- ReadBuff may contain additional LF chars. That is handled here. 995 if RestLineStr = \13 then 996 iterate -- ignore CR 997 endif 998 999 -- Filter out ANSI Esc sequences. 1000 do forever 1001 pEscStart = pos( \27'[', RestLineStr) 1002 if pEscStart = 0 then 1003 leave 1004 else 1005 pEscEnd = verify( RestLineStr, 'ABCDHJKnfRhlmpsu', 'M', pEscStart + 2) 1006 if pEscEnd = 0 then 1007 leave 1008 endif 1009 RestLineStr = delstr( RestLineStr, pEscStart, pEscEnd - pEscStart + 1) 1010 endif 1011 enddo 1012 1013 -- Write output lines to the shell file 1014 -- Slow output and missing spaces in the prompt with 1015 -- "do while RestLineStr <> ''". See the description at the proc begin. 1016 do forever -- (until RestLineStr == '') 1017 -- Split at further LF chars from col 2 on 1018 pLF = pos( \10, RestLineStr, 2) 1019 if pLF > 0 then 1020 --dprintf( '* LF found in RestLineStr = 'leftstr( translate( RestLineStr, \1\2'~', \10\13\20), Min( 40, length( RestLineStr)))) 1021 NextLineStr = leftstr( RestLineStr, pLF - 1) 1022 RestLineStr = substr( RestLineStr, pLF) 1023 else 1024 NextLineStr = RestLineStr 1025 RestLineStr = '' 1026 endif 1027 1028 -- Handle LF char at col 1 1029 if leftstr( NextLineStr, 1) = \10 then -- LF is lineend 1030 insertline substr( NextLineStr, 2), .last + 1 1031 else 1032 getline PrevLineStr, .last 1033 AppendedLen = length( PrevLineStr) + length( NextLineStr) 1034 if AppendedLen <= MAXCOL then 1035 -- Append NextLineStr to PrevLineStr. 1036 -- Instead of replaceline, keyin preserves bookmarks 1037 -- in PrevLineStr. 1038 .line = .last 1039 .col = length( PrevLineStr) + 1 1040 keyin NextLineStr 1041 else 1042 insertline NextLineStr, .last + 1 1043 endif 1044 endif 1045 1046 if RestLineStr == '' then 1047 -- Get next ReadBuf from output stream 1048 leave 1049 endif 1050 enddo -- forever (until RestLineStr == '') 1503 call ShellProcessReadLineBuff( ReadBuff, fIgnoreCurrentCmd, fReplaceLastPrompt) 1504 --dprintf( 'ShellOutputLines after write : fIgnoreCurrentCmd = 'fIgnoreCurrentCmd', fReplaceLastPrompt = 'fReplaceLastPrompt) 1051 1505 1052 1506 enddo -- forever (until (BytesMoved = 0) = (RestLineStr == '')) … … 1058 1512 .line = .last 1059 1513 .col = Min( MAXCOL, length( LastLineStr) + 1) 1060 1061 -- This searches the prompt in LastLineStr 1062 -- Check if last written line was the EPM prompt 1063 -- in order to accept input by a waiting application directly 1064 -- in the shell buffer, not only in the Write to shell dialog. 1065 compile if EPM_SHELL_PROMPT = '@prompt epm: $p $g' 1066 p1 = leftstr( LastLineStr, 5) = 'epm: ' 1067 p2 = rightstr( strip( LastLineStr, 't'), 1) = '>' 1068 compile else -- else EPM_SHELL_PROMPT = '@prompt [epm: $p ]' 1069 p1 = leftstr( LastLineStr, 6) = '[epm: ' 1070 p2 = rightstr( strip( LastLineStr, 't'), 1) = ']' 1071 compile endif -- EPM_SHELL_PROMPT 1072 -- Set array var 1073 if p1 > 0 & p2 > 0 then 1074 -- Set to 0 1075 ShellAppWaiting = 0 1076 --dprintf( 'App terminated') 1077 -- Set bookmark 1514 call ShellParsePromptLine( .last, LastPrompt, LastCmd) 1515 do once = 1 to 1 1516 if not LastPrompt then 1517 leave 1518 endif 1519 -- Reset shellcurrentcmd 1520 SetAVar( 'shellcurrentcmd', '') 1521 dprintf( '# Reset shellcurrentcmd') 1522 1523 -- Prepare to set bookmark 'Last' 1078 1524 bmline = .last 1079 1525 bmcol = 1 1080 SetBookmark( 3, bmline, bmcol, 'Last') 1081 NextCmdAltersText() 1082 --bmidxmax = GetAVar( ShellFid'.bmname.0') 1083 --dprintf( 'Set bookmark for last line '.last' and bmidx 'bmidxmax' to "Last"') 1084 else 1085 -- Set to '.line .col' if app is waiting for user input 1086 ShellAppWaiting = .line .col 1087 --dprintf( 'app waiting for input or further output will follow') 1088 endif 1089 call SetAVar( ShellFid'.shellappwaiting', ShellAppWaiting) -- save 1526 bmval = 'Last' 1527 -- In case of slow output, each char of the prompt arrives separately. 1528 -- If the prompt has a trailing space, LastPrompt parsing is in both 1529 -- cases true and the same bookmark is added two times. 1530 SavedRc = rc 1531 Checkidx = GetBookmarkIdx( ShellFid, bmline, bmcol) 1532 if not rc then 1533 CheckName = GetBmName( ShellFid, Checkidx) 1534 if CheckName = bmval then 1535 -- Already set 1536 leave 1537 endif 1538 endif 1539 rc = SavedRc 1540 -- Set bookmark 1541 SetBookmark( 3, bmline, bmcol, bmval) 1542 dprintf( '# Bookmark set on line 'bmline' to >'bmval'< ShellGetLastCmd() = 'ShellGetLastCmd()) 1543 --NextCmdAltersText() 1544 enddo 1545 1546 /* 1547 -- Store pos. after output 1548 call SetAVar( ShellFid'.shelloutputpos', .line .col) 1549 */ 1090 1550 endif 1091 1551 … … 1096 1556 -- For a restored shell file, the previous last line is deleted. 1097 1557 do l = LastDeleteLineNum to StartLineNum by -1 1098 --dprintf( 'l = 'l', deleteline 'l':'textline( l)) 1099 deleteline l 1558 dprintf( 'l = 'l', deleteline 'l':'textline( l)) 1559 -- This deletes bookmarks, too: 1560 pSave_Pos( SavedPos) 1561 .lineg = l 1562 call DelAttrInLine() 1563 deleteline 1564 pRestore_Pos( SavedPos) 1100 1565 enddo 1101 --.last -- This causes sometimes the compiler to stop with: 1102 -- -- Invalid field name? 1103 -- -- Strange: It depends on the code before. 1104 .line = .last -- This compiles always. 1105 -- Disable future line deletion 1106 SetAVar( ShellFid'.startlinenum', '') 1107 endif 1566 .modify = 0 1567 endif 1568 1569 .line = .last 1570 endline 1571 -- Store pos. after output 1572 PrevOutputPos = GetAVar( ShellFid'.shelloutputpos') 1573 fInitEnded = 0 1574 if PrevOutputPos = '' then 1575 fInitEnded = 1 1576 endif 1577 call SetAVar( ShellFid'.shelloutputpos', .line .col) 1578 1579 -- Disable future line deletion 1580 SetAVar( ShellFid'.shellstartlinenum', '') 1581 dprintf( 'ShellOutputLines: -------- End of init at '.line .col' -------- PrevOutputPos = 'PrevOutputPos', fInitEnded = 'fInitEnded) 1108 1582 1109 1583 return 1110 1584 1111 ; =========================================================================== 1112 ; ShellInput 1113 ; =========================================================================== 1114 1115 ; --------------------------------------------------------------------------- 1116 ; Writes user input to the shell if EPM prompt is in current line. 1117 ; Enhanced for filename completion. Prepend 'cd ' to input if a directory. 1118 ; Remove trailing \ from directories for 'cd'. 1119 ; Works with spaces in filenames and surrounding "...". 1120 ; This is the defproc called by the Enter key def. 1121 ; Sets rc = 0 on success; 1 when not on a EPM prompt line. 1122 ; If rc = 1 is set, then ShellEnterWriteToApp() should be called by the 1123 ; Enter key def. 1124 ; 1125 ; ECHO must be ON. That is the default setting in CMD.EXE, but not in 4OS2.EXE. 1126 ; Otherwise no prompt is inserted after the command execution and further commands 1127 ; won't work (CMD.EXE) or the command is deleted (4OS2.EXE). 1128 ; Therefore ECHO ON must be executed _after_ every call of 4OS2.EXE. 1129 defproc ShellEnterWrite 1130 do once = 1 to 1 1131 rcx = 1 1132 ShellNum = GetFileAVar( 'shellnum') 1133 p = ShellPromptPos() 1134 if not p then 1135 leave 1136 endif 1137 1138 getfileid ShellFid 1139 1140 -- Parse Input 1141 getline LineStr 1142 Input = substr( LineStr, p + 1) 1143 Input = strip( Input, 'L') 1144 1145 -- Process alias in Input 1146 KeyPath = '\NEPMD\User\Shell\Alias' 1147 on = (QueryConfigKey( KeyPath) <> 0) 1148 if on then 1149 Input = ShellAliasResolve( Input) 1150 endif 1151 1152 -- Parse Input into CmdWord, CmdArgs and CmdName 1153 fCmdWordEnquoted = 0 1154 if leftstr( Input, 1) = '"' then 1155 fCmdWordEnquoted = 1 1156 parse value Input with '"'CmdWord'"' CmdArgs 1585 ; --------------------------------------------------------------------------- 1586 ; Ignores ANSI Esc sequences. Determines if current line should be 1587 ; ignored because of quiet output set by ShellWriteCmdQuiet. 1588 defproc ShellFilterReadLineBuff( var RestLineStr, var fIgnoreCurrentCmd, 1589 var fReplaceLastPrompt) 1590 -- Filter out ANSI Esc sequences 1591 do forever 1592 pEscStart = pos( \27'[', RestLineStr) 1593 if pEscStart = 0 then 1594 leave 1595 endif 1596 pEscEnd = verify( RestLineStr, 'ABCDHJKnfRhlmpsu', 'M', pEscStart + 2) 1597 if pEscEnd = 0 then 1598 leave 1599 endif 1600 RestLineStr = delstr( RestLineStr, pEscStart, pEscEnd - pEscStart + 1) 1601 enddo 1602 --dprintf( 'RestLineStr = 'translate( RestLineStr, \1\2'~', \10\13\20)) 1603 1604 -- Flag: reset fIgnoreCurrentCmd on the next prompt 1605 if fIgnoreCurrentCmd then 1606 PromptVal = ShellGetPromptValue() 1607 SearchStr = ShellPromptToSearchStr( PromptVal) 1608 if leftstr( RestLineStr, 1) = \10 then 1609 CheckLineStr = substr( RestLineStr, 2) 1157 1610 else 1158 parse value Input with CmdWord CmdArgs 1159 endif 1160 CmdName = upcase( StripExt( StripPath( CmdWord))) 1161 1162 -- Handle the silly M$ syntax extension for CD like "cd\", "cd.." etc. 1163 -- Not required for CMD.EXE, just for to determine CmdName. 1164 if wordpos( leftstr( upcase( CmdWord), 3), 'CD\ CD.') then 1165 CmdArgs = substr( CmdWord, 3) 1166 CmdWord = 'cd' 1167 CmdName = 'CD' 1168 endif 1169 1170 -- Prepend "cd" if no CmdName given (true for a trailing '\') 1171 if CmdName = '' & CmdWord <> '' & CmdArgs = '' then 1172 CmdArgs = CmdWord 1173 CmdWord = 'cd' 1174 CmdName = 'CD' 1175 fCmdWordEnquoted = 0 1176 1177 -- Strip trailing \ from CmdArgs 1178 if rightstr( CmdArgs, 1) = '\' & 1179 CmdArgs <> '\' & 1180 rightstr( CmdArgs, 2) <> ':\' then 1181 CmdArgs = strip( CmdArgs, 'T', '\') 1182 endif 1183 CmdArgs = EnquoteFileSpec( CmdArgs) 1184 endif 1185 1186 if CmdName = '4OS2' then 1187 -- Insert "echo on" when 4os2 is called 1188 if CmdArgs = '' then 1189 CmdArgs = 'echo on' 1611 CheckLineStr = RestLineStr 1612 endif 1613 if CheckLineStr <> '' then 1614 pPromptFound = pos( SearchStr, CheckLineStr, 1, 'x') 1615 if pPromptFound then 1616 -- Reset shellignorecmd 1617 fIgnoreCurrentCmd = 0 1618 imax = GetFileAVar( 'shellignorecmd.0') 1619 do i = 1 to imax 1620 DropFileAVar( 'shellignorecmd.'i) 1621 SetFileAVar( 'shellignorecmd.0', 0) 1622 enddo 1623 dprintf( 'ShellFilterReadLineBuff: Reset shellignorecmd') 1624 endif 1625 --dprintf( 'fIgnoreCurrentCmd = 'fIgnoreCurrentCmd', pPromptFound = 'pPromptFound) 1626 endif 1627 else 1628 --dprintf( 'fIgnoreCurrentCmd = 'fIgnoreCurrentCmd) 1629 endif 1630 1631 -- Flag: determine if current Cmd should be ignored 1632 --CurCmd = GetAVar( 'shellcurrentcmd') 1633 CurCmd = ShellGetLastCmd() 1634 if not fIgnoreCurrentCmd then 1635 imax = GetFileAVar( 'shellignorecmd.0') 1636 dprintf( 'ShellFilterReadLineBuff: imax = 'imax', CurCmd = 'CurCmd) 1637 if imax then 1638 do i = 1 to imax 1639 IgnoreCmd = GetFileAVar( 'shellignorecmd.'i) 1640 dprintf( 'ShellFilterReadLineBuff: IgnoreCmd = 'IgnoreCmd', i = 'i) 1641 if CurCmd = IgnoreCmd & IgnoreCmd then 1642 fIgnoreCurrentCmd = 1 1643 fReplaceLastPrompt = 1 1644 leave 1645 endif 1646 enddo 1647 endif 1648 endif 1649 1650 return 1651 1652 ; --------------------------------------------------------------------------- 1653 ; Writes RestLineStr line-wise to current file. 1654 ; RestLineStr may contain additional LF chars. That is handled here. 1655 defproc ShellProcessReadLineBuff( var RestLineStr, var fIgnoreCurrentCmd, 1656 var fReplaceLastPrompt) 1657 -- Write output lines to the shell file 1658 -- Slow output and missing spaces in the prompt with 1659 -- "do while RestLineStr <> ''" 1660 -- See the description at the begin of ShellOutputLines. 1661 do forever -- (until RestLineStr == '') 1662 1663 -- Split RestLineStr at further LF chars into NextLineStr and 1664 -- RestLineStr. A read line usually starts with LF. (CR is already 1665 -- filtered out at this point.) 1666 pLF = pos( \10, RestLineStr, 2) 1667 if pLF > 0 then 1668 --dprintf( '* LF found in RestLineStr = 'leftstr( translate( RestLineStr, \1\2'~', \10\13\20), Min( 40, length( RestLineStr)))) 1669 NextLineStr = leftstr( RestLineStr, pLF - 1) 1670 RestLineStr = substr( RestLineStr, pLF) 1671 else 1672 NextLineStr = RestLineStr 1673 RestLineStr = '' 1674 endif 1675 1676 -- TODO: Improve fIgnoreCurrentCmd handling, fix fReplaceLastPrompt 1677 if not fIgnoreCurrentCmd then 1678 1679 -- Replace last prompt 1680 if fReplaceLastPrompt then 1681 deleteline .last 1682 fReplaceLastPrompt = 0 1683 endif 1684 1685 -- Put out NextLineStr 1686 -- Handle LF char at col 1 1687 if leftstr( NextLineStr, 1) = \10 then -- LF is lineend 1688 TextStr = substr( NextLineStr, 2) 1689 insertline TextStr, .last + 1 1190 1690 else 1191 CmdArgs = 'echo on&'CmdArgs 1192 endif 1193 endif 1194 1195 -- Reconcatenate Input args 1196 if fCmdWordEnquoted = 0 then 1197 Input = CmdWord 1198 else 1199 Input = '"'CmdWord'"' 1200 endif 1201 if CmdArgs <> '' then 1202 Input = Input CmdArgs 1203 endif 1204 1205 if .line = .last then 1206 .col = p + 1 -- After prompt 1207 if rightstr( EPM_SHELL_PROMPT, 1) == ' ' | 1208 rightstr( EPM_SHELL_PROMPT, 2) == '$s' then 1209 keyin ' ' -- For the trailing space of the prompt 1210 endif 1211 --dprintf( 'Cursor on last line '.last' and col '.col) 1212 eraseendline -- Delete the rest, because echo is on to avoid 1213 -- doubled Cmd. 1214 -- Echo off, executed in CMD.EXE, would suppress the 1215 -- prompt as well. 1216 else 1217 -- The Undo statement doesn't restore the prompt line well (only 1218 -- last change, depending on .modify). Therefore the line is 1219 -- restored by an array var, set by the defproc for the Enter key. 1220 'PostMe ShellRestoreOrgCmd' .line 1221 endif 1222 1223 -- Change bookmark name from 'Last' to Input 1224 -- Get bmidx for last bookmark 1225 bmidxmax = GetAVar( ShellFid'.bmname.0') 1226 --dprintf( 'Change bookmark name for bmidx 'bmidxmax' to "'Input'".') 1227 call SetAVar( ShellFid'.bmname.'bmidxmax, Input) 1228 1229 'ShellWrite' ShellNum Input 1230 1231 rcx = 0 1232 1233 enddo 1234 rc = rcx 1235 1236 return 1237 1238 ; --------------------------------------------------------------------------- 1239 ; Restore previously saved Cmd from bmname 1240 defc ShellRestoreOrgCmd 1241 -- Get bmname from bmline and bmcol 1242 getfileid ShellFid 1243 bmline = .line 1244 bmcol = 1 1245 bmidx = GetBookmarkIdx( ShellFid, bmline, bmcol) 1246 bmname = GetAVar( ShellFid'.bmname.'bmidx) 1247 1248 -- Find prompt 1249 p = ShellPromptPos() 1250 --dprintf( 'ShellPromptPos = 'p', bmline = 'bmline', bmname = 'bmname) 1251 if p then 1252 -- Reinsert cmd, saved as bmname 1253 .col = p + 1 1254 eraseendline 1255 if rightstr( EPM_SHELL_PROMPT, 1) == ' ' | 1256 rightstr( EPM_SHELL_PROMPT, 2) == '$s' then 1257 keyin ' ' -- For the trailing space of the prompt 1258 endif 1259 keyin bmname 1260 endif 1261 1262 ; --------------------------------------------------------------------------- 1263 ; Write user input to a prompting (waiting) app. 1264 ; For differing the output that comes from the app from the user input, the 1265 ; array var "ShellAppWaiting" is used. It holds line and col from the last 1266 ; write of the shell object to the EPM window, set in defc NowCanReadShell. 1267 ; In case of a terminated app, the EPM prompt was the last output and 1268 ; ShellAppWaiting holds the value 0. 1269 ; Sets rc = 0 on success; 1 when no app is waiting. 1270 defproc ShellEnterWriteToApp 1271 rcx = 1 1272 ShellNum = GetFileAVar( 'shellnum') 1273 ShellAppWaiting = GetFileAVar( 'shellappwaiting') 1274 if words( ShellAppWaiting) = 2 then 1275 parse value ShellAppWaiting with lastl lastc 1276 Input = '' 1277 l = lastl 1278 do while l <= .line 1279 getline line, l 1280 if l = lastl then 1281 startc = lastc 1282 else 1283 startc = 1 1284 endif 1285 Input = Input''substr( line, startc) 1286 if l = .last then 1287 insertline '', .last + 1 1288 leave 1289 else 1290 l = l + 1 1291 endif 1292 enddo 1293 'ShellWrite' ShellNum Input 1294 rcx = 0 1295 endif 1296 rc = rcx 1691 getline LastLineStr, .last 1692 LastLen = length( LastLineStr) 1693 NextLen = length( NextLineStr) 1694 if LastLen + NextLen <= MAXCOL then 1695 -- Append NextLineStr to LastLineStr 1696 -- Instead of replaceline, keyin preserves bookmarks 1697 -- in LastLineStr. 1698 dprintf( 'ShellProcessReadLineBuff: Appending: 'NextLineStr) 1699 dprintf( 'ShellProcessReadLineBuff: to: 'LastLineStr) 1700 .line = .last 1701 .col = LastLen + 1 1702 keyin NextLineStr 1703 TextStr = LastLineStr''NextLineStr 1704 else 1705 -- Insert TextStr 1706 TextStr = NextLineStr 1707 insertline TextStr, .last + 1 1708 endif 1709 endif 1710 dprintf( 'TextStr = 'TextStr', ShellGetLastCmd() = 'ShellGetLastCmd()) 1711 1712 -- For a 'Directory of' line, add bookmark 1713 -- for later restore after editing 1714 if IsADirectoryOfLine( TextStr) then 1715 -- Set bookmark 1716 bmline = .last 1717 bmcol = 1 1718 bmval = TextStr 1719 SetBookmark( 3, bmline, bmcol, bmval) 1720 dprintf( '# Bookmark set on line 'bmline' to >'bmval'<') 1721 endif 1722 1723 endif -- fIgnoreCurrentCmd else 1724 1725 if RestLineStr == '' then 1726 -- Get next ReadBuf from output stream 1727 leave 1728 endif 1729 1730 enddo -- forever (until RestLineStr == '') 1297 1731 1298 1732 return … … 1319 1753 1320 1754 -- Confirm on a prompt line 1321 if ShellPromptPos() then 1755 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 1756 if CurPrompt then 1322 1757 refresh 1323 1758 if MBID_OK <> WinMessageBox( 'Sending a Break signal not required', -- title … … 1379 1814 call SetAVar( 'shell_h'ShellNum, ShellHandle) 1380 1815 InitCmd = '' 1381 compile if EPM_SHELL_PROMPT <> '' 1382 InitCmd = EPM_SHELL_PROMPT 1383 compile endif 1384 if InitCmd <> '' then 1385 'ShellWrite' ShellNum InitCmd 1386 endif 1816 ShellValue = ShellGetPromptValue() 1817 InitCmd = '@prompt 'ShellValue 1818 'ShellWriteCmdQuiet' ShellNum InitCmd 1387 1819 1388 1820 -- Determine previous work dir 1389 call pSave_Pos( save_pos)1390 SavedRc = rc1391 1821 display -3 1392 1822 .lineg = .last 1393 1823 endline 1394 call ShellGotoNextPrompt( 'P') 1395 if rc then 1396 fFound = 0 1397 else 1398 fFound = 1 1399 endif 1400 Dir = '' 1401 Cmd = '' 1402 if fFound then 1403 call ShellParsePromptLine( Dir, Cmd) 1404 else 1405 call pRestore_Pos( save_pos) 1406 endif 1407 rc = SavedRc 1824 Dir = ShellGetPrevDir() 1408 1825 display 3 1826 1409 1827 if Dir <> '' then 1410 1828 CdCmd = 'cdd' Dir 1411 'ShellWrite ' ShellNum CdCmd1829 'ShellWriteCmdQuiet' ShellNum CdCmd 1412 1830 endif 1413 1831 endif … … 1420 1838 1421 1839 ; --------------------------------------------------------------------------- 1422 defc ShellNewLine 1840 ; Enhanced for filename completion. Prepends 'cd ' to input if a directory. 1841 ; Removes trailing \ from directories for 'cd'. 1842 ; Works with spaces in filenames and surrounding "...". 1843 ; ECHO must be ON. That is the default setting in CMD.EXE, but not in 1844 ; 4OS2.EXE. Otherwise no prompt is inserted after the command execution and 1845 ; further commands won't work (CMD.EXE) or the command is deleted (4OS2.EXE). 1846 ; Therefore ECHO ON must be executed _after_ every call of 4OS2.EXE. 1847 defproc ShellFilterCmd( Input) 1848 1849 -- Process alias in Input 1850 KeyPath = '\NEPMD\User\Shell\Alias' 1851 on = (QueryConfigKey( KeyPath) <> 0) 1852 if on then 1853 Input = ShellAliasResolve( Input) 1854 endif 1855 1856 -- Parse Input into CmdWord, CmdArgs and CmdName 1857 fCmdWordEnquoted = 0 1858 if leftstr( Input, 1) = '"' then 1859 fCmdWordEnquoted = 1 1860 parse value Input with '"'CmdWord'"' CmdArgs 1861 else 1862 parse value Input with CmdWord CmdArgs 1863 endif 1864 CmdName = upcase( StripExt( StripPath( CmdWord))) 1865 1866 -- Handle the silly M$ syntax extension for CD like "cd\", "cd.." etc. 1867 -- Not required for CMD.EXE, just for to determine CmdName. 1868 if wordpos( leftstr( upcase( CmdWord), 3), 'CD\ CD.') then 1869 CmdArgs = substr( CmdWord, 3) 1870 CmdWord = 'cd' 1871 CmdName = 'CD' 1872 endif 1873 1874 -- Prepend "cd" if no CmdName given (true for a trailing '\') 1875 if CmdName = '' & CmdWord <> '' & CmdArgs = '' then 1876 CmdArgs = CmdWord 1877 CmdWord = 'cd' 1878 CmdName = 'CD' 1879 fCmdWordEnquoted = 0 1880 1881 -- Strip trailing \ from CmdArgs 1882 if rightstr( CmdArgs, 1) = '\' & 1883 CmdArgs <> '\' & 1884 rightstr( CmdArgs, 2) <> ':\' then 1885 CmdArgs = strip( CmdArgs, 'T', '\') 1886 endif 1887 CmdArgs = EnquoteFileSpec( CmdArgs) 1888 endif 1889 1890 if CmdName = '4OS2' then 1891 -- Insert "echo on" when 4os2 is called 1892 if CmdArgs = '' then 1893 CmdArgs = 'echo on' 1894 else 1895 CmdArgs = 'echo on&'CmdArgs 1896 endif 1897 endif 1898 1899 -- Reconcatenate Input args 1900 if fCmdWordEnquoted = 0 then 1901 Input = CmdWord 1902 else 1903 Input = '"'CmdWord'"' 1904 endif 1905 if CmdArgs <> '' then 1906 Input = Input CmdArgs 1907 endif 1908 1909 return Input 1910 1911 ; --------------------------------------------------------------------------- 1912 defc ShellEnterLine 1913 NormalCmd = strip( arg( 1)) 1914 fExecNormalCmd = 1 1915 SavedRc = rc 1916 1423 1917 do once = 1 to 1 1424 StdNewLine = arg( 1) 1425 SavedRc = rc 1426 1918 1919 --dprintf( 'ShellEnterLine: IsADirList() = 'IsADirList()) 1920 ---- Dir list ---- 1427 1921 if IsADirList() then 1428 call DirProcessDirectoryOfLine ()1922 call DirProcessDirectoryOfLine2() 1429 1923 if not rc then 1924 -- Processed 1925 fExecNormalCmd = 0 1430 1926 leave 1431 1927 endif 1432 1928 endif 1433 1929 1434 if IsAShell() then 1435 call ShellEnterWrite() 1436 --dprintf( 'ShellNewLine: ShellEnterWrite: rc = 'rc) 1437 if not rc then 1930 if not IsAShell() then 1931 leave 1932 endif 1933 1934 ---- Shell ---- 1935 -- Determine prompt and cmd at last line and current line 1936 CurPrompt = '' 1937 CurCmd = '' 1938 PromptVal = ShellGetPromptValue() 1939 SearchStr = ShellPromptToSearchStr( PromptVal) 1940 call ShellParsePromptLine( .last, LastPrompt, LastCmd) 1941 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 1942 1943 -- Determine fWriteToApp 1944 if CurPrompt = '' then 1945 fWriteToApp = 1 1946 else 1947 fWriteToApp = 0 1948 endif 1949 1950 -- Determine Input from current line 1951 if fWriteToApp then 1952 dprintf( 'ShellEnterLine: App is waiting for user input') 1953 parse value GetFileAVar( 'shelloutputpos') with lastl lastc 1954 if lastc = '' then 1438 1955 leave 1439 1956 endif 1440 1441 call ShellEnterWriteToApp() 1442 --dprintf( 'ShellNewLine: ShellEnterWriteToApp: rc = 'rc) 1443 if not rc then 1444 leave 1445 endif 1446 endif 1447 1448 StdNewLine 1957 Input = '' 1958 l = lastl 1959 do while l <= .line 1960 getline line, l 1961 if l = lastl then 1962 startc = lastc 1963 else 1964 startc = 1 1965 endif 1966 Input = Input''substr( line, startc) 1967 if l = .last then 1968 insertline '', .last + 1 1969 leave 1970 else 1971 l = l + 1 1972 endif 1973 enddo 1974 else 1975 --dprintf( 'ShellEnterLine: CurCmd before ShellFilterCmd = 'CurCmd) 1976 CurCmd = ShellFilterCmd( CurCmd) 1977 --dprintf( 'ShellEnterLine: CurCmd after ShellFilterCmd = 'CurCmd) 1978 Input = CurCmd 1979 endif 1980 1981 if Input == '' then 1982 -- Ask for Input 1983 if fWriteToApp then 1984 -- If Input empty, open EntryBox 9) ################################ 1985 'ShellWrite' Input 1986 else 1987 'ShellHistory' 1988 endif 1989 else 1990 /* 1991 NextCmdAltersText() 1992 */ 1993 -- Write Input to shell 1994 if fWriteToApp then 1995 'ShellWrite' Input 1996 else 1997 'ShellWriteCmd 'Input 1998 endif 1999 endif 2000 2001 -- Processed 2002 fExecNormalCmd = 0 1449 2003 enddo 2004 1450 2005 rc = SavedRc 1451 1452 ; --------------------------------------------------------------------------- 1453 defc ShellTab 2006 if fExecNormalCmd then 2007 ---- Normal NewLine (specified as arg) ---- 2008 NormalCmd 2009 endif 2010 2011 ; --------------------------------------------------------------------------- 2012 defc ShellFnc 1454 2013 universal prevkey 2014 2015 NormalCmd = strip( arg( 1)) 2016 fExecNormalCmd = 1 2017 1455 2018 parse value prevkey with PrevKeyName \1 . 1456 2019 KeyPath = '\NEPMD\User\Shell\FilenameCompletion' … … 1461 2024 endif 1462 2025 'ShellFncProcess' 1463 else 1464 'Tab' -- standard definition, keep in sync with STDKEYS.E or 1465 endif -- additional keyset definitions 1466 1467 ; --------------------------------------------------------------------------- 1468 defc ShellBackTab 2026 fExecNormalCmd = 0 2027 endif 2028 2029 if fExecNormalCmd then 2030 NormalCmd 2031 endif 2032 2033 ; --------------------------------------------------------------------------- 2034 defc ShellFncBack 1469 2035 universal prevkey 2036 2037 NormalCmd = strip( arg( 1)) 2038 fExecNormalCmd = 1 2039 1470 2040 parse value prevkey with PrevKeyName \1 . 1471 2041 KeyPath = '\NEPMD\User\Shell\FilenameCompletion' … … 1476 2046 endif 1477 2047 'ShellFncProcess -' 1478 else 1479 'BackTab' -- standard definition, keep in sync with STDKEYS.E or 1480 endif -- additional keyset definitions 2048 fExecNormalCmd = 0 2049 endif 2050 2051 if fExecNormalCmd then 2052 NormalCmd 2053 endif 2054 2055 ; --------------------------------------------------------------------------- 2056 defc ShellDeleteCmd 2057 NormalCmd = strip( arg( 1)) 2058 fExecNormalCmd = 1 2059 2060 do once = 1 to 1 2061 if not IsAShell() then 2062 leave 2063 endif 2064 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 2065 if not CurPrompt then 2066 leave 2067 endif 2068 -- Process only if cursor is at the end or after 2069 if .col < length( CurPrompt''CurCmd) + 1 then 2070 leave 2071 endif 2072 -- Delete CurCmd 2073 .col = length( CurPrompt) + 1 2074 eraseendline 2075 fExecNormalCmd = 0 2076 enddo 2077 2078 if fExecNormalCmd then 2079 NormalCmd 2080 endif 2081 2082 ; =========================================================================== 2083 ; History 2084 ; =========================================================================== 2085 2086 ; --------------------------------------------------------------------------- 2087 ; Opens a list box with last commands. The selected one can be submitted and 2088 ; optionally be edited in an entry box before. This was previously a part of 2089 ; ShellWrite, except that the order of both boxes was changed. It starts 2090 ; with the list box, not with the entry box. Main idea by Joerg Tiemann. 2091 defc ShellHistory, Shell_History 2092 do once = 1 to 1 2093 parse arg ShellNum . 2094 if ShellNum = '' & IsAShell() then 2095 ShellNum = GetFileAVar( 'shellnum') 2096 endif 2097 if ShellNum = '' then 2098 'SayError 'NOT_IN_SHELL__MSG 2099 return 2100 endif 2101 NewCmd = '' 2102 2103 ShellHandle = GetAVar( 'shell_h'ShellNum) 2104 if ShellHandle = '' then 2105 leave 2106 endif 2107 2108 BoxTitle = strip( WRITE_SHELL_MENU__MSG, 'T', '.') -- '~Write to shell...' 2109 pTilde = pos( '~', BoxTitle) 2110 if pTilde then 2111 BoxTitle = delstr( BoxTitle, pTilde, 1) 2112 endif 2113 2114 -- Get NewCmd 2115 do forever 2116 2117 -- Open ListBox 2118 getfileid ShellFid 2119 call pSave_Pos( SavedPos) 2120 2121 'xcom e /c cmdslist' 2122 if rc <> -282 then -- -282 = sayerror( "New file") 2123 'SayError 'ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc) 2124 return 2125 endif 2126 .autosave = 0 2127 getfileid lb_fid 2128 2129 activatefile ShellFid 2130 0 2131 do forever 2132 PrevPos = .line .col 2133 call ShellGoToNextPrompt() 2134 if rc then 2135 leave 2136 elseif .line .col = PrevPos then 2137 leave 2138 endif 2139 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 2140 if CurCmd = '' then 2141 iterate 2142 endif 2143 insertline strip( CurCmd, 'L'), lb_fid.last + 1, lb_fid 2144 enddo 2145 2146 call pRestore_Pos( SavedPos) 2147 2148 activatefile lb_fid 2149 if not .modify then -- Nothing added? 2150 -- ListBox needs at least one empty entry 2151 insertline '', lb_fid.last + 1, lb_fid -- empty line 2152 endif 2153 2154 if ListBox_Buffer_From_File( ShellFid, bufhndl, noflines, usedsize) then 2155 return 2156 endif 2157 Text = '' 2158 ListBoxButtons = '/'OK__MSG'/'EDIT__MSG'.../'Cancel__MSG 2159 DefaultItem = noflines - 1 -- Last item, first line of lb_fid is empty 2160 DefaultButton = 1 2161 HelpId = 0 2162 parse value ListBox( BoxTitle, 2163 \0 || atol( usedsize) || atoi( 32) || atoi( bufhndl), 2164 ListBoxButtons, 2165 0, 0, -- top, left 2166 12, 0, -- height, width, 2167 GethWndC( APP_HANDLE) || 2168 atoi( DefaultItem) || 2169 atoi( DefaultButton) || 2170 atoi( HelpId) || 2171 Text\0) with LbButton 2 NewCmd \0 2172 call buffer( FREEBUF, bufhndl) 2173 2174 if LbButton = \1 then -- OK 2175 leave 2176 elseif LbButton = \2 then -- Edit... 2177 2178 -- Open EntryBox 2179 -- Use same BoxTitle as ListBox 2180 -- Use selected entry from ListBox 2181 EntryText = NewCmd 2182 Text = SHELL_PROMPT__MSG ShellNum 2183 Text = Text''copies( ' ', Max( 0, 100 - length( Text))) 2184 EntryBoxButtons = '/'OK__MSG'/'LIST__MSG'/'Cancel__MSG'/' 2185 DefaultButton = 1 2186 --HelpId = 0 2187 parse value EntryBox( BoxTitle, 2188 EntryBoxButtons, 2189 EntryText, 2190 0, 254, -- cols, maxchars 2191 atoi( DefaultButton) || 2192 atoi( HelpId) || 2193 GethWndC( APP_HANDLE) || 2194 Text) with EbButton 2 NewCmd \0 2195 if EbButton = \1 then -- OK 2196 leave 2197 elseif EbButton = \2 then -- List... 2198 iterate 2199 else -- Cancel 2200 return 2201 endif 2202 2203 else -- Cancel 2204 return 2205 endif 2206 2207 enddo -- forever -- Get NewCmd 2208 2209 -- Write NewCmd 2210 'ShellWriteCmd 'NewCmd 2211 enddo 1481 2212 1482 2213 ; =========================================================================== … … 1506 2237 return 1507 2238 endif 1508 p = ShellPromptPos() 1509 if not p then 1510 return 1511 endif 1512 getline Line 1513 Prompt = leftstr( Line, p) 1514 PromptChar = substr( Prompt, p, 1) 1515 parse value Prompt with 'epm:' ShellDir (PromptChar) 1516 ShellDir = strip( ShellDir) 1517 1518 -- Get the part of the line between prompt and cursor 1519 Input = substr( Line, p + 1, .col - 1 - p) 1520 -- Strip leading spaces only, because a trailing space identifies the word before 1521 -- to have ended: 1522 -- > dir | -> dir * 1523 -- > dir| -> dir* (this will search for names starting with dir) 1524 Input = strip( Input, 'L') 2239 2240 call ShellParsePromptLine( .line, CurPrompt, CurCmd) 2241 Input = CurCmd 2242 ShellDir = ShellGetPrevDir() 1525 2243 1526 2244 -- Todo: … … 1708 2426 endif 1709 2427 call SetAVar( 'fncshellnum', ShellNum) 1710 call SetAVar( 'fncprompt', Prompt)1711 call SetAVar( 'fnccmdpart', CmdPart)2428 call SetAVar( 'fncprompt', CurPrompt) 2429 call SetAVar( 'fnccmdpart', CmdPart) 1712 2430 1713 2431 ; --------------------------------------------------------------------------- … … 1763 2481 ; Make -dName possible 1764 2482 if CmdPart <> '' then 1765 NewLine = Prompt 2483 NewLine = Prompt''strip( CmdPart) Name 1766 2484 else 1767 NewLine = Prompt 2485 NewLine = Prompt''Name 1768 2486 endif 1769 2487 replaceline NewLine … … 1781 2499 compile endif 1782 2500 compile if not defined( ALIAS_SEP_CHARS) 1783 ALIAS_SEP_CHARS = ' |<> '2501 ALIAS_SEP_CHARS = ' |<>&' 1784 2502 compile endif 1785 2503 … … 1814 2532 if abbrev( UpRest, UpKey) = 1 then 1815 2533 -- Get surrounding chars to check for separators 2534 -- ################################################################################ 1816 2535 PrevChar = rightstr( ResolvedString, 1) 1817 2536 NextChar = substr( Rest, length( Key) + 1, 1) … … 1837 2556 pDelta = length( Key) 1838 2557 else 2558 -- ################################################################################ 1839 2559 -- Not found, advance search pos by 1 1840 2560 pDelta = 1 … … 1842 2562 endif 1843 2563 2564 -- ################################################################################ 1844 2565 ResolvedString = ResolvedString''Val 1845 2566 Rest = substr( Rest, pDelta + 1) … … 1985 2706 call ShellAliasFileRead() 1986 2707 1987 ; =========================================================================== 1988 ; Remaining cmds from ShellKram 1989 ; =========================================================================== 1990 1991 ; --------------------------------------------------------------------------- 1992 ; Following definitions are mainly copied from Joerg Tiemann's SHELLKRAM.E 1993 ; package: 1994 1995 /********************************************************************************/ 1996 /* Shell_Input */ 1997 /* This is a cut off ShellWrite. Initially the idea was to use it to be able */ 1998 /* to use 4OS2 as the command line interpreter. But that did not work. In the */ 1999 /* meantime I've come to the conclusion that it is a nice command for use in */ 2000 /* the toolbar "* Shell_Input somecommand parameters". */ 2001 /********************************************************************************/ 2002 2003 defc ShellInput, Shell_Input 2004 universal shelllastwrite 2005 2006 parse arg Input 2007 ShellNum = '' 2008 if IsAShell() then 2009 ShellNum = GetFileAVar( 'shellnum') 2010 endif 2011 if ShellNum = '' then 2012 'SayError 'NOT_IN_SHELL__MSG 2013 return 2014 endif 2015 2016 ShellHandle = GetAVar( 'shell_h'ShellNum) 2017 2018 if ShellHandle <> '' then 2019 if Input <> '' then 2020 -- Set universal 2021 shelllastwrite = Input 2022 endif 2023 writebuf = Input\13\10 -- input text + CRLF 2024 retval = Sue_Write( ShellHandle, writebuf, bytesmoved) 2025 if retval | (bytesmoved <> length( writebuf)) then 2026 'SayError Shell_Input: write.retval = 'retval', byteswritten = 'bytesmoved' of 'length( writebuf) 2027 endif 2028 endif 2029 2030 /******************************************************************/ 2031 /* Shell_SendKey */ 2032 /* Now yet another variation. This time to send single keystrokes */ 2033 /* to the command line interpreter, for example the often needed */ 2034 /* 'y' and 'n'. */ 2035 /******************************************************************/ 2036 2037 defc ShellSendKey, Shell_SendKey 2038 parse arg Input 2039 ShellNum = '' 2040 if IsAShell() then 2041 ShellNum = GetFileAVar( 'shellnum') 2042 endif 2043 if ShellNum = '' then 2044 'SayError 'NOT_IN_SHELL__MSG 2045 return 2046 endif 2047 if Input = '' then 2048 'SayError Shell_SendKey: no key to send to shell specified' 2049 return 2050 endif 2051 2052 ShellHandle = GetAVar( 'shell_h'ShellNum) 2053 2054 if ShellHandle <> '' then 2055 writebuf = Input -- just the pure input w/o CRLF 2056 retval = Sue_Write( ShellHandle, writebuf, bytesmoved) 2057 if retval | (bytesmoved <> length( writebuf)) then 2058 'SayError Shell_SendKey: write.retval = 'retval', byteswritten = 'bytesmoved 'of' length( writebuf) 2059 endif 2060 endif 2061 2062 /* 2063 defc esk_About 2064 rcx = WinMessageBox( 'About EPM Shellkram', 2065 'EPM Shellkram v.0.88 beta'\10 || 2066 'Wed, 3 Oct 2001'\10 || 2067 'Copyright (c) 1998-2001 by Joerg Tiemann'\10 || 2068 'Joerg Tiemann <tiemannj@gmx.de>', 16432) 2069 */ 2708
Note:
See TracChangeset
for help on using the changeset viewer.