uResaltTerm.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. {Resaltador de sintaxis sencillo usado para el terminal.
  2. Se basa en el ejemplo de resaltador con plegado publicado en "La Biblia del SynEdit"
  3. Por Tito Hinostroza 27/06/2014
  4. }
  5. unit uResaltTerm;
  6. {$mode objfpc}{$H+}
  7. interface
  8. uses
  9. Classes, SysUtils, Graphics, LCLProc, SynEditHighlighter,
  10. SynEditHighlighterFoldBase;
  11. type
  12. {Clase para la creación de un resaltador}
  13. TRangeState = (rsUnknown, rsComment);
  14. //ID para categorizar a los tokens
  15. TtkTokenKind = (tkIndentif,
  16. tkComment,
  17. tkKey, //Palabra clave
  18. tkError, //Palabra ERROR.
  19. tkWarning, //Palabra WARNING.
  20. tkNull,
  21. tkSpace,
  22. tkString,
  23. tkPrompt,
  24. tkUnknown,
  25. tkDirect //Listado de directorio
  26. );
  27. TProcTableProc = procedure of object; //Tipo procedimiento para procesar el
  28. //token por el carácter inicial.
  29. { TResaltTerm }
  30. TResaltTerm = class(TSynCustomFoldHighlighter)
  31. protected
  32. posIni, posFin: Integer;
  33. fStringLen: Integer; //Tamaño del token actual
  34. fToIdent: PChar; //Puntero a identificcdor
  35. linAct : PChar;
  36. fProcTable: array[#0..#255] of TProcTableProc; //tabla de procedimientos
  37. fTokenID : TtkTokenKind; //Id del token actual
  38. fRange: TRangeState;
  39. //define las categorías de los "tokens"
  40. fAtriIdentif : TSynHighlighterAttributes;
  41. fAtriComent : TSynHighlighterAttributes;
  42. fAtriClave : TSynHighlighterAttributes;
  43. fAtriEspac : TSynHighlighterAttributes;
  44. fAtriCadena : TSynHighlighterAttributes;
  45. fAtriPrompt : TSynHighlighterAttributes;
  46. fAtriDirect : TSynHighlighterAttributes;
  47. fAtriError : TSynHighlighterAttributes;
  48. fAtriWarning : TSynHighlighterAttributes;
  49. public
  50. //detecPrompt : boolean; //Activa la detección del prompt
  51. //prIni, prFin: string; //Cadena inicial, y final del prompt { TODO : En teoría no deberían ser necesarias estas variables }
  52. curSesObj : Tobject; {Referencia a la sesión. Se requiere la sesión, porque cada sesión
  53. mantiene su propia configuración de prompt. Se define como
  54. TObject para no crear referencias circulares entre las unidades. }
  55. procedure SetLine(const NewValue: String; LineNumber: Integer); override;
  56. procedure Next; override;
  57. function GetEol: Boolean; override;
  58. procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
  59. override;
  60. function GetTokenAttribute: TSynHighlighterAttributes; override;
  61. function GetToken: String; override;
  62. function GetTokenPos: Integer; override;
  63. function GetTokenKind: integer; override;
  64. constructor Create(AOwner: TComponent); override;
  65. function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
  66. private
  67. posTok : integer; //para identificar el ordinal del token en una línea
  68. procedure CommentProc;
  69. procedure CreaTablaDeMetodos;
  70. function KeyComp(const aKey: String): Boolean;
  71. procedure ProcComent;
  72. procedure ProcIdent;
  73. procedure ProcNull;
  74. procedure ProcSpace;
  75. procedure ProcString;
  76. procedure ProcUnknown;
  77. //Funciones de procesamiento de identificadores
  78. procedure ProcA;
  79. procedure ProcB;
  80. procedure ProcC;
  81. procedure ProcD;
  82. procedure ProcE;
  83. procedure ProcF;
  84. procedure ProcG;
  85. procedure ProcH;
  86. procedure ProcI;
  87. procedure ProcK;
  88. procedure ProcJ;
  89. procedure ProcL;
  90. procedure ProcM;
  91. procedure ProcP;
  92. procedure ProcR;
  93. procedure ProcS;
  94. procedure ProcT;
  95. procedure ProcU;
  96. procedure ProcV;
  97. procedure ProcW;
  98. procedure ProcZ;
  99. public
  100. function GetRange: Pointer; override;
  101. procedure SetRange(Value: Pointer); override;
  102. procedure ResetRange; override;
  103. end;
  104. implementation
  105. uses FrameTabSession; //para la detección de prompt
  106. var
  107. Identifiers: array[#0..#255] of ByteBool;
  108. curSes: TfraTabSession;
  109. procedure CreaTablaIdentif;
  110. var i, j: Char;
  111. begin
  112. for i := #0 to #255 do
  113. begin
  114. Case i of
  115. '_', '0'..'9', 'a'..'z', 'A'..'Z': Identifiers[i] := True;
  116. else Identifiers[i] := False;
  117. end;
  118. j := UpCase(i);
  119. end;
  120. end;
  121. constructor TResaltTerm.Create(AOwner: TComponent);
  122. //Constructor de la clase. Aquí se deben crear los atributos a usar.
  123. begin
  124. inherited Create(AOwner);
  125. //atributo de identificadores
  126. fAtriIdentif := TSynHighlighterAttributes.Create('Identif');
  127. fAtriIdentif.Foreground := clWhite; //color de letra
  128. AddAttribute(fAtriIdentif);
  129. //Atributo de comentarios
  130. fAtriComent := TSynHighlighterAttributes.Create('Comment');
  131. // fAtriComent.Style := [fsItalic]; //en cursiva
  132. fAtriComent.Foreground := clLtGray; //color de letra gris
  133. AddAttribute(fAtriComent);
  134. //atribuuto de palabras claves
  135. fAtriClave := TSynHighlighterAttributes.Create('Key');
  136. fAtriClave.Style := [fsBold]; //en negrita
  137. fAtriClave.Foreground:=TColor($40D040);; //color de letra verde
  138. AddAttribute(fAtriClave);
  139. //Atributo de espacios. Sin atributos
  140. fAtriEspac := TSynHighlighterAttributes.Create('space');
  141. AddAttribute(fAtriEspac);
  142. //Atributo de cadenas
  143. fAtriCadena := TSynHighlighterAttributes.Create('String');
  144. fAtriCadena.Foreground := TColor($FFFF00); //color de letra celeste
  145. AddAttribute(fAtriCadena);
  146. //Atributo de prompt
  147. fAtriPrompt := TSynHighlighterAttributes.Create('Prompt');
  148. fAtriPrompt.Foreground := clWhite; //color de letra
  149. fAtriPrompt.Background:= clGreen;
  150. AddAttribute(fAtriPrompt);
  151. //Atributo de directorio
  152. fAtriDirect := TSynHighlighterAttributes.Create('Direct');
  153. fAtriDirect.Foreground := clYellow; //color de letra
  154. AddAttribute(fAtriDirect);
  155. //Atributo de error
  156. fAtriError := TSynHighlighterAttributes.Create('Error');
  157. fAtriError.Foreground := clRed; //color de letra
  158. AddAttribute(fAtriError);
  159. //Atributo de Advertencia
  160. fAtriWarning := TSynHighlighterAttributes.Create('Warning');
  161. fAtriWarning.Foreground := clYellow; //color de letra
  162. AddAttribute(fAtriWarning);
  163. CreaTablaDeMetodos; //Construye tabla de métodos
  164. end;
  165. procedure TResaltTerm.CreaTablaDeMetodos;
  166. var
  167. I: Char;
  168. begin
  169. for I := #0 to #255 do
  170. case I of
  171. '#' : fProcTable[I] := @ProcComent;
  172. '"' : fProcTable[I] := @ProcString;
  173. 'a': fProcTable[I] := @ProcA;
  174. 'b': fProcTable[I] := @ProcB;
  175. 'c': fProcTable[I] := @ProcC;
  176. 'd': fProcTable[I] := @ProcD;
  177. 'e','E': fProcTable[I] := @ProcE;
  178. 'f': fProcTable[I] := @ProcF;
  179. 'g': fProcTable[I] := @ProcG;
  180. 'h': fProcTable[I] := @ProcH;
  181. 'i': fProcTable[I] := @ProcI;
  182. 'j': fProcTable[I] := @ProcJ;
  183. 'k': fProcTable[I] := @ProcK;
  184. 'l': fProcTable[I] := @ProcL;
  185. 'm': fProcTable[I] := @ProcM;
  186. 'n': fProcTable[I] := @ProcIdent;
  187. 'o': fProcTable[I] := @ProcIdent;
  188. 'p': fProcTable[I] := @ProcP;
  189. 'q': fProcTable[I] := @ProcIdent;
  190. 'r': fProcTable[I] := @ProcR;
  191. 's': fProcTable[I] := @ProcS;
  192. 't': fProcTable[I] := @ProcT;
  193. 'u': fProcTable[I] := @ProcU;
  194. 'v': fProcTable[I] := @ProcV;
  195. 'w','W': fProcTable[I] := @ProcW;
  196. 'x': fProcTable[I] := @ProcIdent;
  197. 'y': fProcTable[I] := @ProcIdent;
  198. 'z': fProcTable[I] := @ProcZ;
  199. 'A'..'D','F'..'V','X'..'Z': fProcTable[I] := @ProcIdent;
  200. #0 : fProcTable[I] := @ProcNull; //Se lee el caracter de marca de fin de cadena
  201. #1..#9, #11, #12, #14..#32: fProcTable[I] := @ProcSpace;
  202. else fProcTable[I] := @ProcUnknown;
  203. end;
  204. end;
  205. function TResaltTerm.KeyComp(const aKey: String): Boolean;
  206. var
  207. I: Integer;
  208. Temp: PChar;
  209. begin
  210. Temp := fToIdent;
  211. if Length(aKey) = fStringLen then begin
  212. Result := True;
  213. for i := 1 to fStringLen do begin
  214. if Temp^ <> aKey[i] then begin
  215. Result := False;
  216. break;
  217. end;
  218. inc(Temp);
  219. end;
  220. end else Result := False;
  221. end;
  222. procedure TResaltTerm.ProcComent;
  223. //Procesa el símbolo '#'
  224. begin
  225. begin
  226. fTokenID := tkComment;
  227. inc(PosFin); //salta a siguiente token
  228. while not (linAct[PosFin] in [#0, #10, #13]) do Inc(PosFin);
  229. end;
  230. end;
  231. procedure TResaltTerm.ProcString;
  232. //Procesa el caracter comilla.
  233. begin
  234. fTokenID := tkString; //marca como cadena
  235. Inc(PosFin);
  236. while (not (linAct[PosFin] in [#0, #10, #13])) do begin
  237. if linAct[PosFin] = '"' then begin //busca fin de cadena
  238. Inc(PosFin);
  239. if (linAct[PosFin] <> '"') then break; //si no es doble comilla
  240. end;
  241. Inc(PosFin);
  242. end;
  243. end;
  244. procedure TResaltTerm.ProcIdent;
  245. begin
  246. while Identifiers[linAct[posFin]] do inc(posFin);
  247. fTokenID := tkIndentif; //identificador común
  248. end;
  249. procedure TResaltTerm.ProcA;
  250. begin
  251. while Identifiers[linAct[posFin]] do inc(posFin);
  252. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  253. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  254. if KeyComp('lias') then fTokenID := tkKey else
  255. if KeyComp('propos') then fTokenID := tkKey else
  256. if KeyComp('wk') then fTokenID := tkKey else
  257. fTokenID := tkIndentif; //identificador común
  258. end;
  259. procedure TResaltTerm.ProcB;
  260. begin
  261. while Identifiers[linAct[posFin]] do inc(posFin);
  262. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  263. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  264. if KeyComp('anner') then fTokenID := tkKey else
  265. if KeyComp('reak') then fTokenID := tkKey else
  266. fTokenID := tkIndentif; //identificador común
  267. end;
  268. procedure TResaltTerm.ProcC;
  269. begin
  270. while Identifiers[linAct[posFin]] do inc(posFin);
  271. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  272. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  273. if KeyComp('al') then fTokenID := tkKey else
  274. if KeyComp('aller') then fTokenID := tkKey else
  275. if KeyComp('ase') then fTokenID := tkKey else
  276. if KeyComp('at') then fTokenID := tkKey else
  277. if KeyComp('d') then fTokenID := tkKey else
  278. if KeyComp('hgrp') then fTokenID := tkKey else
  279. if KeyComp('hmod') then fTokenID := tkKey else
  280. if KeyComp('hown') then fTokenID := tkKey else
  281. if KeyComp('lear') then fTokenID := tkKey else
  282. if KeyComp('mp') then fTokenID := tkKey else
  283. if KeyComp('ommand') then fTokenID := tkKey else
  284. if KeyComp('ontinue') then fTokenID := tkKey else
  285. if KeyComp('p') then fTokenID := tkKey else
  286. if KeyComp('rontab') then fTokenID := tkKey else
  287. if KeyComp('ut') then fTokenID := tkKey else
  288. fTokenID := tkIndentif; //identificador común
  289. end;
  290. procedure TResaltTerm.ProcD;
  291. begin
  292. while Identifiers[linAct[posFin]] do inc(posFin);
  293. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  294. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  295. if KeyComp('ate') then fTokenID := tkKey else
  296. if KeyComp('eclare') then fTokenID := tkKey else
  297. if KeyComp('f') then fTokenID := tkKey else
  298. if KeyComp('iff') then fTokenID := tkKey else
  299. if KeyComp('ir') then fTokenID := tkKey else
  300. if KeyComp('u') then fTokenID := tkKey else
  301. fTokenID := tkIndentif; //identificador común
  302. end;
  303. procedure TResaltTerm.ProcE;
  304. var
  305. tok, utok: String;
  306. begin
  307. while Identifiers[linAct[posFin]] do inc(posFin);
  308. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  309. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  310. tok := GetToken;
  311. utok := Upcase(GetToken);
  312. if tok = 'echo' then fTokenID := tkKey else
  313. if tok = 'else' then fTokenID := tkKey else
  314. if tok = 'env' then fTokenID := tkKey else
  315. if utok = 'ERROR' then fTokenID := tkError else
  316. if tok = 'eval' then fTokenID := tkKey else
  317. if tok = 'exit' then fTokenID := tkKey else
  318. if tok = 'export' then fTokenID := tkKey else
  319. fTokenID := tkIndentif; //identificador común
  320. end;
  321. procedure TResaltTerm.ProcF;
  322. begin
  323. while Identifiers[linAct[posFin]] do inc(posFin);
  324. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  325. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  326. if KeyComp('alse') then fTokenID := tkKey else
  327. if KeyComp('c') then fTokenID := tkKey else
  328. if KeyComp('i') then fTokenID := tkKey else
  329. if KeyComp('ile') then fTokenID := tkKey else
  330. if KeyComp('ind') then fTokenID := tkKey else
  331. if KeyComp('mt') then fTokenID := tkKey else
  332. if KeyComp('or') then fTokenID := tkKey else
  333. if KeyComp('unction') then fTokenID := tkKey else
  334. fTokenID := tkIndentif; //identificador común
  335. end;
  336. procedure TResaltTerm.ProcG;
  337. begin
  338. while Identifiers[linAct[posFin]] do inc(posFin);
  339. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  340. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  341. if KeyComp('etopts') then fTokenID := tkKey else
  342. if KeyComp('rep') then fTokenID := tkKey else
  343. if KeyComp('unzip') then fTokenID := tkKey else
  344. if KeyComp('zip') then fTokenID := tkKey else
  345. fTokenID := tkIndentif; //identificador común
  346. end;
  347. procedure TResaltTerm.ProcH;
  348. begin
  349. while Identifiers[linAct[posFin]] do inc(posFin);
  350. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  351. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  352. if KeyComp('alt') then fTokenID := tkKey else
  353. if KeyComp('ash') then fTokenID := tkKey else
  354. if KeyComp('ead') then fTokenID := tkKey else
  355. if KeyComp('elp') then fTokenID := tkKey else
  356. if KeyComp('istory') then fTokenID := tkKey else
  357. if KeyComp('ostname') then fTokenID := tkKey else
  358. fTokenID := tkIndentif; //identificador común
  359. end;
  360. procedure TResaltTerm.ProcI;
  361. begin
  362. while Identifiers[linAct[posFin]] do inc(posFin);
  363. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  364. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  365. if KeyComp('d') then fTokenID := tkKey else
  366. if KeyComp('f') then fTokenID := tkKey else
  367. if KeyComp('nfo') then fTokenID := tkKey else
  368. fTokenID := tkIndentif; //identificador común
  369. end;
  370. procedure TResaltTerm.ProcJ;
  371. begin
  372. while Identifiers[linAct[posFin]] do inc(posFin);
  373. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  374. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  375. if KeyComp('obs') then fTokenID := tkKey else
  376. fTokenID := tkIndentif; //identificador común
  377. end;
  378. procedure TResaltTerm.ProcK;
  379. begin
  380. while Identifiers[linAct[posFin]] do inc(posFin);
  381. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  382. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  383. if KeyComp('ill') then fTokenID := tkKey else
  384. fTokenID := tkIndentif; //identificador común
  385. end;
  386. procedure TResaltTerm.ProcL;
  387. begin
  388. while Identifiers[linAct[posFin]] do inc(posFin);
  389. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  390. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  391. if KeyComp('dd') then fTokenID := tkKey else
  392. if KeyComp('ess') then fTokenID := tkKey else
  393. if KeyComp('n') then fTokenID := tkKey else
  394. if KeyComp('ocal') then fTokenID := tkKey else
  395. if KeyComp('ocate') then fTokenID := tkKey else
  396. if KeyComp('ogout') then fTokenID := tkKey else
  397. if KeyComp('s') then fTokenID := tkKey else
  398. fTokenID := tkIndentif; //sin atributos
  399. end;
  400. procedure TResaltTerm.ProcM;
  401. begin
  402. while Identifiers[linAct[posFin]] do inc(posFin);
  403. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  404. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  405. if KeyComp('ail') then fTokenID := tkKey else
  406. if KeyComp('an') then fTokenID := tkKey else
  407. if KeyComp('esg') then fTokenID := tkKey else
  408. if KeyComp('kdir') then fTokenID := tkKey else
  409. if KeyComp('ore') then fTokenID := tkKey else
  410. if KeyComp('v') then fTokenID := tkKey else
  411. fTokenID := tkIndentif; //identificador común
  412. end;
  413. procedure TResaltTerm.ProcP;
  414. begin
  415. while Identifiers[linAct[posFin]] do inc(posFin);
  416. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  417. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  418. if KeyComp('asswd') then fTokenID := tkKey else
  419. if KeyComp('r') then fTokenID := tkKey else
  420. if KeyComp('rintenv') then fTokenID := tkKey else
  421. if KeyComp('rintf') then fTokenID := tkKey else
  422. if KeyComp('s') then fTokenID := tkKey else
  423. if KeyComp('wd') then fTokenID := tkKey else
  424. fTokenID := tkIndentif; //identificador común
  425. end;
  426. procedure TResaltTerm.ProcR;
  427. begin
  428. while Identifiers[linAct[posFin]] do inc(posFin);
  429. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  430. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  431. if KeyComp('ead') then fTokenID := tkKey else
  432. if KeyComp('eadonly') then fTokenID := tkKey else
  433. if KeyComp('eboot') then fTokenID := tkKey else
  434. if KeyComp('eset') then fTokenID := tkKey else
  435. if KeyComp('eturn') then fTokenID := tkKey else
  436. if KeyComp('m') then fTokenID := tkKey else
  437. if KeyComp('mdir') then fTokenID := tkKey else
  438. fTokenID := tkIndentif; //identificador común
  439. end;
  440. procedure TResaltTerm.ProcS;
  441. begin
  442. while Identifiers[linAct[posFin]] do inc(posFin);
  443. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  444. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  445. if KeyComp('ed') then fTokenID := tkKey else
  446. if KeyComp('elect') then fTokenID := tkKey else
  447. if KeyComp('eq') then fTokenID := tkKey else
  448. if KeyComp('et') then fTokenID := tkKey else
  449. if KeyComp('h') then fTokenID := tkKey else
  450. if KeyComp('hift') then fTokenID := tkKey else
  451. if KeyComp('hutdown') then fTokenID := tkKey else
  452. if KeyComp('leep') then fTokenID := tkKey else
  453. if KeyComp('ort') then fTokenID := tkKey else
  454. if KeyComp('pell') then fTokenID := tkKey else
  455. if KeyComp('uspend') then fTokenID := tkKey else
  456. fTokenID := tkIndentif; //identificador común
  457. end;
  458. procedure TResaltTerm.ProcT;
  459. begin
  460. while Identifiers[linAct[posFin]] do inc(posFin);
  461. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  462. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  463. if KeyComp('ac') then fTokenID := tkKey else
  464. if KeyComp('ail') then fTokenID := tkKey else
  465. if KeyComp('alk') then fTokenID := tkKey else
  466. if KeyComp('ar') then fTokenID := tkKey else
  467. if KeyComp('est') then fTokenID := tkKey else
  468. if KeyComp('hen') then fTokenID := tkKey else
  469. if KeyComp('ime') then fTokenID := tkKey else
  470. if KeyComp('imes') then fTokenID := tkKey else
  471. if KeyComp('ouch') then fTokenID := tkKey else
  472. if KeyComp('r') then fTokenID := tkKey else
  473. if KeyComp('rap') then fTokenID := tkKey else
  474. if KeyComp('rue') then fTokenID := tkKey else
  475. if KeyComp('ype') then fTokenID := tkKey else
  476. if KeyComp('ypeset') then fTokenID := tkKey else
  477. fTokenID := tkIndentif; //identificador común
  478. end;
  479. procedure TResaltTerm.ProcU;
  480. begin
  481. while Identifiers[linAct[posFin]] do inc(posFin);
  482. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  483. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  484. if KeyComp('limit') then fTokenID := tkKey else
  485. if KeyComp('mask') then fTokenID := tkKey else
  486. if KeyComp('nalias') then fTokenID := tkKey else
  487. if KeyComp('name') then fTokenID := tkKey else
  488. if KeyComp('ncompress') then fTokenID := tkKey else
  489. if KeyComp('niq') then fTokenID := tkKey else
  490. if KeyComp('nset') then fTokenID := tkKey else
  491. if KeyComp('ntil') then fTokenID := tkKey else
  492. fTokenID := tkIndentif; //identificador común
  493. end;
  494. procedure TResaltTerm.ProcV;
  495. begin
  496. while Identifiers[linAct[posFin]] do inc(posFin);
  497. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  498. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  499. if KeyComp('dir') then fTokenID := tkKey else
  500. if KeyComp('i') then fTokenID := tkKey else
  501. if KeyComp('im') then fTokenID := tkKey else
  502. fTokenID := tkIndentif; //identificador común
  503. end;
  504. procedure TResaltTerm.ProcW;
  505. var
  506. tok, utok: String;
  507. begin
  508. while Identifiers[linAct[posFin]] do inc(posFin);
  509. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  510. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  511. tok := GetToken;
  512. utok := Upcase(GetToken);
  513. if tok = 'wait' then fTokenID := tkKey else
  514. if utok = 'WARNING' then fTokenID := tkWarning else
  515. if tok = 'wc' then fTokenID := tkKey else
  516. if tok = 'whatis' then fTokenID := tkKey else
  517. if tok = 'wwhence' then fTokenID := tkKey else
  518. if tok = 'whereis' then fTokenID := tkKey else
  519. if tok = 'which' then fTokenID := tkKey else
  520. if tok = 'while' then fTokenID := tkKey else
  521. if tok = 'who' then fTokenID := tkKey else
  522. if tok = 'whoami' then fTokenID := tkKey else
  523. fTokenID := tkIndentif; //identificador común
  524. end;
  525. procedure TResaltTerm.ProcZ;
  526. begin
  527. while Identifiers[linAct[posFin]] do inc(posFin);
  528. fStringLen := posFin - posIni - 1; //calcula tamaño - 1
  529. fToIdent := linAct + posIni + 1; //puntero al identificador + 1
  530. if KeyComp('cat') then fTokenID := tkKey else
  531. fTokenID := tkIndentif; //identificador común
  532. end;
  533. procedure TResaltTerm.ProcNull;
  534. //Procesa la ocurrencia del caracter #0
  535. begin
  536. fTokenID := tkNull; //Solo necesita esto para indicar que se llegó al final de la línae
  537. end;
  538. procedure TResaltTerm.ProcSpace;
  539. //Procesa caracter que es inicio de espacio
  540. begin
  541. fTokenID := tkSpace;
  542. repeat
  543. Inc(posFin);
  544. until (linAct[posFin] > #32) or (linAct[posFin] in [#0, #10, #13]);
  545. end;
  546. procedure TResaltTerm.ProcUnknown;
  547. begin
  548. inc(posFin);
  549. while (linAct[posFin] in [#128..#191]) OR // continued utf8 subcode
  550. ((linAct[posFin]<>#0) and (fProcTable[linAct[posFin]] = @ProcUnknown)) do inc(posFin);
  551. fTokenID := tkUnknown;
  552. end;
  553. procedure TResaltTerm.SetLine(const NewValue: String; LineNumber: Integer);
  554. begin
  555. inherited;
  556. linAct := PChar(NewValue); //copia la línea actual
  557. posFin := 0; //apunta al primer caracter
  558. posTok := 0; //inicia contador de token
  559. Next;
  560. end;
  561. procedure TResaltTerm.Next;
  562. var
  563. l: Integer;
  564. begin
  565. Inc(posTok); //lleva la cuenta del orden del token
  566. posIni := PosFin; //apunta al primer elemento
  567. //busca prompt en el inicio de la línea
  568. if (posTok=1) then begin
  569. //Estamos al inicio
  570. //verifica si hay prompt
  571. if TfraTabSession(curSesObj).detecPrompt then begin
  572. l:= TfraTabSession(curSesObj).ContainsPrompt(linAct);
  573. if l>0 then begin
  574. posFin += l; //pasa a siguiente token
  575. fTokenID := tkPrompt; //de tipo prompt
  576. EndCodeFoldBlock(); //cierra plegado
  577. StartCodeFoldBlock(nil); //abre plegado
  578. exit;
  579. end;
  580. end;
  581. //verifica si es listado detallado de arcchivos "ls -l"
  582. // tmp := copy(linAct,1,3);
  583. if length(linAct)>43 then begin //un listado común de archivos tiene al menos este tamaño
  584. if (linAct[0] = 'd') and
  585. (linAct[1] in ['r','-']) and (linAct[2] in ['w','-']) then begin
  586. //es listado detallado de un directorio
  587. posFin := length(linAct);
  588. fTokenID := tkDirect; //de tipo directorio
  589. exit;
  590. end;
  591. end;
  592. end;
  593. //caso normal
  594. // if fRange = rsComment then begin
  595. // CommentProc
  596. // end else begin
  597. fRange := rsUnknown;
  598. fProcTable[linAct[PosFin]]; //Se ejecuta la función que corresponda.
  599. // end;
  600. end;
  601. function TResaltTerm.GetEol: Boolean;
  602. {Indica cuando se ha llegado al final de la línea}
  603. begin
  604. Result := fTokenId = tkNull;
  605. end;
  606. procedure TResaltTerm.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
  607. {Devuelve información sobre el token actual}
  608. begin
  609. TokenLength := posFin - posIni;
  610. TokenStart := linAct + posIni;
  611. end;
  612. function TResaltTerm.GetTokenAttribute: TSynHighlighterAttributes;
  613. //Devuelve información sobre el token actual
  614. begin
  615. case fTokenID of
  616. tkIndentif: Result := fAtriIdentif;
  617. tkComment : Result := fAtriComent;
  618. tkKey : Result := fAtriClave;
  619. tkSpace : Result := fAtriEspac;
  620. tkString : Result := fAtriCadena;
  621. tkPrompt : Result := fAtriPrompt;
  622. tkDirect : Result := fAtriDirect;
  623. tkError : Result := fAtriError;
  624. tkWarning : Result := fAtriWarning;
  625. else
  626. Result := nil; //tkUnknown, tkNull
  627. end;
  628. end;
  629. function TResaltTerm.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
  630. {Este método es llamado por la clase "TSynCustomHighlighter", cuando se accede a alguna de
  631. sus propiedades: CommentAttribute, IdentifierAttribute, KeywordAttribute, StringAttribute,
  632. SymbolAttribute o WhitespaceAttribute.}
  633. begin
  634. case Index of
  635. SYN_ATTR_COMMENT : Result := fAtriComent;
  636. SYN_ATTR_IDENTIFIER: Result := fAtriIdentif;
  637. SYN_ATTR_KEYWORD : Result := fAtriClave;
  638. SYN_ATTR_WHITESPACE: Result := fAtriEspac;
  639. SYN_ATTR_STRING : Result := fAtriCadena;
  640. else Result := nil;
  641. end;
  642. end;
  643. {Las siguientes funciones, son usadas por SynEdit para el manejo de las
  644. llaves, corchetes, parentesis y comillas. No son cruciales para el coloreado
  645. de tokens, pero deben responder bien.}
  646. function TResaltTerm.GetToken: String;
  647. var
  648. Len: LongInt;
  649. begin
  650. Len := posFin - posIni;
  651. SetString(Result, (linAct + posIni), Len);
  652. end;
  653. function TResaltTerm.GetTokenPos: Integer;
  654. begin
  655. Result := posIni - 1;
  656. end;
  657. function TResaltTerm.GetTokenKind: integer;
  658. begin
  659. Result := 0;
  660. end;
  661. procedure TResaltTerm.CommentProc;
  662. begin
  663. fTokenID := tkComment;
  664. case linAct[PosFin] of
  665. #0:
  666. begin
  667. ProcNull;
  668. exit;
  669. end;
  670. end;
  671. while linAct[PosFin] <> #0 do
  672. case linAct[PosFin] of
  673. '*':
  674. if linAct[PosFin + 1] = '/' then
  675. begin
  676. inc(PosFin, 2);
  677. fRange := rsUnknown;
  678. break;
  679. end
  680. else inc(PosFin);
  681. #10: break;
  682. #13: break;
  683. else inc(PosFin);
  684. end;
  685. end;
  686. ///////// Implementación de las funcionalidades de rango //////////
  687. procedure TResaltTerm.ResetRange;
  688. begin
  689. inherited;
  690. fRange := rsUnknown;
  691. end;
  692. function TResaltTerm.GetRange: Pointer;
  693. begin
  694. CodeFoldRange.RangeType := Pointer(PtrInt(fRange));
  695. Result := inherited;
  696. end;
  697. procedure TResaltTerm.SetRange(Value: Pointer);
  698. begin
  699. inherited;
  700. fRange := TRangeState(PtrUInt(CodeFoldRange.RangeType));
  701. end;
  702. initialization
  703. CreaTablaIdentif; //Crea la tabla para búsqueda rápida
  704. end.