1/* 2 * This macro provides a simplistic, extensible mechanism for providing 3 * context-sensitive help for language instructions/functions. 4 * Simply assign a key to this macro; DEFINE F1 macro syntax F1 5 * 6 * When the macro is invoked, the current COLORING is queried. If there is 7 * a parsing engine enabled for the file, (see QUERY COLORING), then a 8 * check is made for the matching "syntax" file for the parser in MACROPATH. 9 * If found, then the word (non-blank) at the cursor position is extracted and 10 * mathed against all keywords present in the "syntax" file, and a popup menu 11 * is displayed with all matches from the file. Use the up and down arrow keys 12 * to select the item, and it will be inserted (after adjustment; see rexx.syntax 13 * for details) into the filearea where the matched text exists. 14 * To ignore the insertion, press 'q'. To see extended help (if it exists) on the 15 * highlighted match, press the key specified in the DEFINE statement (the first 16 * argument to this macro). 17 */ 18!global.!path.unix = ':' 19!global.!dir.unix = '/' 20!global.!path.windows = ';' 21!global.!dir.windows = '\' 22!global.!delim = x2c( 'FF' ) 23 24!globalv = '!global. fieldword. coloring. cursor. curline.' 25 26Parse Arg key 27If key = '' Then Call Abort 'No escape key provided' 28 29!global.!keyword_values = 'UPPER LOWER INITCAP LITERAL' 30'Extract /fieldword/coloring/cursor/curline' 31If coloring.1 = 'ON' Then 32 Do 33 !global.!func = Translate( fieldword.2 ) 34 !global.!lenfunc = Length( !global.!func ) 35 !global.!idx = 0 36 !global.!match.0 = 0 37 Call ProcessFile coloring.3'.syntax', 1 38 initial_item = 1 39 If !global.!match.0 \= 0 Then 40 Do Forever 41 cmd = 'POPUP BELOW KEYS' key 'INITIAL' initial_item !global.!delim 42 Do i = 1 To !global.!match.0 43 cmd = cmd || !global.!match.i || !global.!delim 44 End 45 cmd 46 If popup.1 \= '' Then 47 Do 48 initial_item = popup.2 49 Parse Var popup.1 keyword (!global.!argstart) args (!global.!argend) . (!global.!ignoreafter) . 50 idx = popup.2 51 If popup.4 = 1 Then 52 Do 53 /* 54 * Our alternate key ended the popup, see if we have details 55 */ 56 If !global.!details.idx \= '' Then 57 Do 58 !global.!details.idx = Changestr( !global.!delim, Substr( !global.!details.idx, 2 ), d2c(10) ) 59 cmd = 'DIALOG' || !global.!delim || !global.!details.idx || !global.!delim 'TITLE /Details for' keyword'/ OK' 60 cmd 61 End 62 End 63 Else 64 Do 65 args = Strip( args ) 66 Do i = 1 To Length( !global.!optional ) 67 args = Changestr( Substr( !global.!optional, i, 1 ), args, '' ) 68 End 69 /* 70 * We have the text to insert, we now have to work out where 71 * the text started in the current line and overlay the new 72 * text at that location. 73 * If we have a later version of THE with FIELDWORD.3 then its easy... 74 */ 75 If fieldword.0 = 3 Then 76 Do 77 res = InsertText( !global.!keyword.idx, curline.3, cursor.4, fieldword.3, !global.!func, args ) 78 End 79 Else 80 Do 81 /* 82 * We have to start at the cursor location and search backwards until we 83 * find the location in the line where the keyword starts 84 */ 85 Do i = cursor.4 To 1 By -1 86 If Translate( curline.3 ) = Translate( Overlay( !global.!func, curline.3, i ) ) Then 87 Do 88 res = InsertText( !global.!keyword.idx, curline.3, cursor.4, i, !global.!func, args ) 89 Leave 90 End 91 End 92 End 93 'r' res 94 Leave 95 End 96 End 97 Else Leave 98 End 99 Else 100 Do 101 Call Abort 'No matches for "'!global.!func'".' 102 Exit 0 103 End 104 End 105Else 106 Do 107 Call Abort 'COLORING is not on for this file' 108 End 109Exit 0 110 111ProcessFile: Procedure Expose (!globalv) 112Parse Arg fname, initial 113-- some defaults 114!global.!keyword_format.initial = 'NONE' 115sfile = GetSyntaxFile( fname ) 116If sfile \= '' Then sf = Stream( sfile, 'C', 'QUERY EXISTS' ) 117If sf = '' Then 118 Do 119-- If initial Then Call Abort 'Syntax file:' fname 'does not exist in MACROPATH.' 120-- Else Call Abort 'Included file:' fname 'does not exist.' 121 If initial Then Call Warning 'Syntax file:' fname 'does not exist in MACROPATH.' 122 Else Call Warning 'Included file:' fname 'does not exist.' 123 Return 124 End 125Call Stream sf, 'C', 'OPEN READ' 126Do While Lines( sf ) > 0 127 line = Linein( sf ) 128 Select 129 When Left( line, 1 ) = '*' Then Iterate 130 When Left( line, 1 ) = ':' Then 131 Do 132 Parse Var line ':' directive value . 133 If initial = 0 & directive \= 'KEYWORD' Then Call Abort 'Invalid directive:' directive 'invalid in included files.' 134 Select 135 When directive = 'OPTIONAL' Then !global.!optional = value 136 When directive = 'IGNOREAFTER' Then !global.!ignoreafter = value 137 When directive = 'ARGSTART' Then !global.!argstart = value 138 When directive = 'ARGEND' Then !global.!argend = value 139 When directive = 'INCLUDE' Then 140 Do 141 Call ProcessFile value, 0 142 End 143 When directive = 'KEYWORD' Then 144 Do 145 If Wordpos( value, !global.!keyword_values ) = 0 Then Call Abort 'Invalid value of "'value'" for directive :'directive'. Valid values:' !global.!keyword_values 146 !global.!keyword_format.initial = value 147 End 148 Otherwise 149 Do 150 Call Abort 'Unknown directive :'directive'.' 151 End 152 End 153 If value = '' Then Call Abort 'Must supply a value for directive :'directive'.' 154 End 155 When Left( line, 1 ) = '>' & new_keyword = 1 Then 156 Do 157 idx = !global.!idx 158 !global.!details.idx = !global.!details.idx || !global.!delim || Substr( line, 2 ) 159 End 160 When Left( Translate( line ), !global.!lenfunc ) = !global.!func Then 161 Do 162 !global.!idx = !global.!idx + 1 163 idx = !global.!idx 164 Parse Var line keyword (!global.!argstart) . 165 Select 166 When !global.!keyword_format.initial = 'UPPER' Then 167 Do 168 !global.!keyword.idx = Translate( keyword ) 169 End 170 When !global.!keyword_format.initial = 'INITCAP' Then 171 Do 172 fc = Translate( Left( keyword, 1 ) ) 173 !global.!keyword.idx = Overlay( fc, keyword , 1, 1 ) 174 End 175 Otherwise 176 Do 177 !global.!keyword.idx = keyword 178 End 179 End 180 !global.!match.idx = line 181 !global.!match.0 = !global.!idx 182 !global.!details.idx = '' 183 new_keyword = 1 184 End 185 Otherwise 186 Do 187 new_keyword = 0 188 End 189 End 190End 191Call Stream sf, 'C', 'CLOSE' 192Return 193 194GetSyntaxFile: Procedure Expose (!globalv) 195Parse Arg sf 196'extract /macropath' 197os = GetOS() 198mp = macropath.1 199Do While mp \= '' 200 Parse Var mp dir (!global.!path.os) mp 201 If Right( dir, 1 ) \= !global.!dir.os Then dir = dir||!global.!dir.os 202 fn = dir || sf 203 If Stream( fn, 'C', 'QUERY EXISTS' ) \= '' Then Return fn 204End 205Return '' 206 207InsertText: Procedure Expose (!globalv) 208Parse Arg keyword, line, curpos, fieldstart, func, args 209If coloring.3 = 'rexx' Then 210 Do 211 Parse Var line 1 call =(fieldstart) . 212 If Translate( Strip( call ) ) = 'CALL' Then args = ' 'args 213 Else args = !global.!argstart || args || !global.!argend 214 End 215Else args = !global.!argstart || args || !global.!argend 216res = Delstr( curline.3, fieldstart, Length( func ) ) 217res = Insert( keyword || args, res, fieldstart-1 ) 218Return res 219 220GetOS: Procedure 221Parse Upper Source os . 222Select 223 When os = 'WINDOWSNT' Then os = 'WINDOWS' 224 When os = 'WIN32' Then os = 'WINDOWS' 225 When os = 'WIN64' Then os = 'WINDOWS' 226 When os = 'OS/2' Then os = 'WINDOWS' 227 When os = 'LINUX' Then os = 'UNIX' 228 When os = 'QNX' Then os = 'UNIX' 229 Otherwise Nop 230End 231Return os 232 233Abort: 234Parse Arg msg 235'EMSG' msg 236Exit 0 237 238Warning: 239Parse Arg msg 240'EMSG' msg 241Return 242