wutils.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit WUtils;
  12. interface
  13. {$ifndef FPC}
  14. {$define TPUNIXLF}
  15. {$endif}
  16. uses
  17. Objects;
  18. type
  19. PByteArray = ^TByteArray;
  20. TByteArray = array[0..65520] of byte;
  21. PNoDisposeCollection = ^TNoDisposeCollection;
  22. TNoDisposeCollection = object(TCollection)
  23. procedure FreeItem(Item: Pointer); virtual;
  24. end;
  25. PUnsortedStringCollection = ^TUnsortedStringCollection;
  26. TUnsortedStringCollection = object(TCollection)
  27. constructor CreateFrom(ALines: PUnsortedStringCollection);
  28. procedure Assign(ALines: PUnsortedStringCollection);
  29. function At(Index: Integer): PString;
  30. procedure FreeItem(Item: Pointer); virtual;
  31. function GetItem(var S: TStream): Pointer; virtual;
  32. procedure PutItem(var S: TStream; Item: Pointer); virtual;
  33. end;
  34. PNulStream = ^TNulStream;
  35. TNulStream = object(TStream)
  36. constructor Init;
  37. function GetPos: Longint; virtual;
  38. function GetSize: Longint; virtual;
  39. procedure Read(var Buf; Count: Word); virtual;
  40. procedure Seek(Pos: Longint); virtual;
  41. procedure Write(var Buf; Count: Word); virtual;
  42. end;
  43. PSubStream = ^TSubStream;
  44. TSubStream = object(TStream)
  45. constructor Init(AStream: PStream; AStartPos, ASize: longint);
  46. function GetPos: Longint; virtual;
  47. function GetSize: Longint; virtual;
  48. procedure Read(var Buf; Count: Word); virtual;
  49. procedure Seek(Pos: Longint); virtual;
  50. procedure Write(var Buf; Count: Word); virtual;
  51. private
  52. StartPos: longint;
  53. S : PStream;
  54. end;
  55. PTextCollection = ^TTextCollection;
  56. TTextCollection = object(TStringCollection)
  57. function LookUp(const S: string; var Idx: sw_integer): string;
  58. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  59. end;
  60. {$ifdef TPUNIXLF}
  61. procedure readln(var t:text;var s:string);
  62. {$endif}
  63. procedure ReadlnFromStream(Stream: PStream; var s:string;var linecomplete : boolean);
  64. function eofstream(s: pstream): boolean;
  65. function Min(A,B: longint): longint;
  66. function Max(A,B: longint): longint;
  67. function CharStr(C: char; Count: byte): string;
  68. function UpcaseStr(const S: string): string;
  69. function LowCase(C: char): char;
  70. function LowcaseStr(S: string): string;
  71. function RExpand(const S: string; MinLen: byte): string;
  72. function LTrim(const S: string): string;
  73. function RTrim(const S: string): string;
  74. function Trim(const S: string): string;
  75. function IntToStr(L: longint): string;
  76. function StrToInt(const S: string): longint;
  77. function GetStr(P: PString): string;
  78. function GetPChar(P: PChar): string;
  79. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  80. function DirOf(const S: string): string;
  81. function ExtOf(const S: string): string;
  82. function NameOf(const S: string): string;
  83. function NameAndExtOf(const S: string): string;
  84. function DirAndNameOf(const S: string): string;
  85. { return Dos GetFTime value or -1 if the file does not exist }
  86. function GetFileTime(const FileName: string): longint;
  87. { copied from compiler global unit }
  88. function GetShortName(const n:string):string;
  89. function GetLongName(const n:string):string;
  90. function TrimEndSlash(const Path: string): string;
  91. function CompareText(S1, S2: string): integer;
  92. function EatIO: integer;
  93. procedure GiveUpTimeSlice;
  94. const LastStrToIntResult : integer = 0;
  95. DirSep : char = {$ifdef Linux}'/'{$else}'\'{$endif};
  96. procedure RegisterWUtils;
  97. implementation
  98. uses
  99. {$ifdef win32}
  100. windows,
  101. {$endif win32}
  102. Strings, Dos;
  103. {$ifndef NOOBJREG}
  104. const
  105. RUnsortedStringCollection: TStreamRec = (
  106. ObjType: 22500;
  107. VmtLink: Ofs(TypeOf(TUnsortedStringCollection)^);
  108. Load: @TUnsortedStringCollection.Load;
  109. Store: @TUnsortedStringCollection.Store
  110. );
  111. {$endif}
  112. {$ifdef TPUNIXLF}
  113. procedure readln(var t:text;var s:string);
  114. var
  115. c : char;
  116. i : longint;
  117. begin
  118. if TextRec(t).UserData[1]=2 then
  119. system.readln(t,s)
  120. else
  121. begin
  122. c:=#0;
  123. i:=0;
  124. while (not eof(t)) and (c<>#10) do
  125. begin
  126. read(t,c);
  127. if c<>#10 then
  128. begin
  129. inc(i);
  130. s[i]:=c;
  131. end;
  132. end;
  133. if (i>0) and (s[i]=#13) then
  134. begin
  135. dec(i);
  136. TextRec(t).UserData[1]:=2;
  137. end;
  138. s[0]:=chr(i);
  139. end;
  140. end;
  141. {$endif}
  142. function eofstream(s: pstream): boolean;
  143. begin
  144. eofstream:=(s^.getpos>=s^.getsize);
  145. end;
  146. procedure ReadlnFromStream(Stream: PStream; var S:string;var linecomplete : boolean);
  147. var
  148. c : char;
  149. i : longint;
  150. begin
  151. linecomplete:=false;
  152. c:=#0;
  153. i:=0;
  154. { this created problems for lines longer than 255 characters
  155. now those lines are cutted into pieces without warning PM }
  156. while (not eofstream(stream)) and (c<>#10) and (i<255) do
  157. begin
  158. stream^.read(c,sizeof(c));
  159. if c<>#10 then
  160. begin
  161. inc(i);
  162. s[i]:=c;
  163. end;
  164. end;
  165. if (c=#10) or eofstream(stream) then
  166. linecomplete:=true;
  167. { if there was a CR LF then remove the CR Dos newline style }
  168. if (i>0) and (s[i]=#13) then
  169. dec(i);
  170. s[0]:=chr(i);
  171. end;
  172. function Max(A,B: longint): longint;
  173. begin
  174. if A>B then Max:=A else Max:=B;
  175. end;
  176. function Min(A,B: longint): longint;
  177. begin
  178. if A<B then Min:=A else Min:=B;
  179. end;
  180. function CharStr(C: char; Count: byte): string;
  181. {$ifndef FPC}
  182. var S: string;
  183. {$endif}
  184. begin
  185. {$ifdef FPC}
  186. CharStr[0]:=chr(Count);
  187. FillChar(CharStr[1],Count,C);
  188. {$else}
  189. S[0]:=chr(Count);
  190. FillChar(S[1],Count,C);
  191. CharStr:=S;
  192. {$endif}
  193. end;
  194. function UpcaseStr(const S: string): string;
  195. var
  196. I: Longint;
  197. begin
  198. for I:=1 to length(S) do
  199. if S[I] in ['a'..'z'] then
  200. UpCaseStr[I]:=chr(ord(S[I])-32)
  201. else
  202. UpCaseStr[I]:=S[I];
  203. UpcaseStr[0]:=S[0];
  204. end;
  205. function LowerCaseStr(S: string): string;
  206. var
  207. I: Longint;
  208. begin
  209. for I:=1 to length(S) do
  210. if S[I] in ['A'..'Z'] then
  211. LowerCaseStr[I]:=chr(ord(S[I])+32)
  212. else
  213. LowerCaseStr[I]:=S[I];
  214. LowercaseStr[0]:=S[0];
  215. end;
  216. function RExpand(const S: string; MinLen: byte): string;
  217. begin
  218. if length(S)<MinLen then
  219. RExpand:=S+CharStr(' ',MinLen-length(S))
  220. else
  221. RExpand:=S;
  222. end;
  223. function LTrim(const S: string): string;
  224. var
  225. i : longint;
  226. begin
  227. i:=1;
  228. while (i<length(s)) and (s[i]=' ') do
  229. inc(i);
  230. LTrim:=Copy(s,i,255);
  231. end;
  232. function RTrim(const S: string): string;
  233. var
  234. i : longint;
  235. begin
  236. i:=length(s);
  237. while (i>0) and (s[i]=' ') do
  238. dec(i);
  239. RTrim:=Copy(s,1,i);
  240. end;
  241. function Trim(const S: string): string;
  242. begin
  243. Trim:=RTrim(LTrim(S));
  244. end;
  245. function IntToStr(L: longint): string;
  246. var S: string;
  247. begin
  248. Str(L,S);
  249. IntToStr:=S;
  250. end;
  251. function StrToInt(const S: string): longint;
  252. var L: longint;
  253. C: integer;
  254. begin
  255. Val(S,L,C); if C<>0 then L:=-1;
  256. LastStrToIntResult:=C;
  257. StrToInt:=L;
  258. end;
  259. function GetStr(P: PString): string;
  260. begin
  261. if P=nil then GetStr:='' else GetStr:=P^;
  262. end;
  263. function GetPChar(P: PChar): string;
  264. begin
  265. if P=nil then GetPChar:='' else GetPChar:=StrPas(P);
  266. end;
  267. function DirOf(const S: string): string;
  268. var D: DirStr; E: ExtStr; N: NameStr;
  269. begin
  270. FSplit(S,D,N,E);
  271. if (D<>'') and (D[Length(D)]<>DirSep) then
  272. DirOf:=D+DirSep
  273. else
  274. DirOf:=D;
  275. end;
  276. function ExtOf(const S: string): string;
  277. var D: DirStr; E: ExtStr; N: NameStr;
  278. begin
  279. FSplit(S,D,N,E);
  280. ExtOf:=E;
  281. end;
  282. function NameOf(const S: string): string;
  283. var D: DirStr; E: ExtStr; N: NameStr;
  284. begin
  285. FSplit(S,D,N,E);
  286. NameOf:=N;
  287. end;
  288. function NameAndExtOf(const S: string): string;
  289. var D: DirStr; E: ExtStr; N: NameStr;
  290. begin
  291. FSplit(S,D,N,E);
  292. NameAndExtOf:=N+E;
  293. end;
  294. function DirAndNameOf(const S: string): string;
  295. var D: DirStr; E: ExtStr; N: NameStr;
  296. begin
  297. FSplit(S,D,N,E);
  298. DirAndNameOf:=D+N;
  299. end;
  300. { return Dos GetFTime value or -1 if the file does not exist }
  301. function GetFileTime(const FileName: string): longint;
  302. var T: longint;
  303. f: file;
  304. FM: integer;
  305. begin
  306. if FileName='' then
  307. T:=-1
  308. else
  309. begin
  310. FM:=FileMode; FileMode:=0;
  311. EatIO; DosError:=0;
  312. Assign(f,FileName);
  313. {$I-}
  314. Reset(f);
  315. if InOutRes=0 then
  316. begin
  317. GetFTime(f,T);
  318. Close(f);
  319. end;
  320. {$I+}
  321. if (EatIO<>0) or (DosError<>0) then T:=-1;
  322. FileMode:=FM;
  323. end;
  324. GetFileTime:=T;
  325. end;
  326. function GetShortName(const n:string):string;
  327. {$ifdef win32}
  328. var
  329. hs,hs2 : string;
  330. i : longint;
  331. {$endif}
  332. {$ifdef go32v2}
  333. var
  334. hs : string;
  335. {$endif}
  336. begin
  337. GetShortName:=n;
  338. {$ifdef win32}
  339. hs:=n+#0;
  340. i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  341. if (i>0) and (i<=high(hs2)) then
  342. begin
  343. hs2[0]:=chr(strlen(@hs2[1]));
  344. GetShortName:=hs2;
  345. end;
  346. {$endif}
  347. {$ifdef go32v2}
  348. hs:=n;
  349. if Dos.GetShortName(hs) then
  350. GetShortName:=hs;
  351. {$endif}
  352. end;
  353. function GetLongName(const n:string):string;
  354. {$ifdef win32}
  355. var
  356. hs : string;
  357. hs2 : Array [0..255] of char;
  358. i : longint;
  359. j : pchar;
  360. {$endif}
  361. {$ifdef go32v2}
  362. var
  363. hs : string;
  364. {$endif}
  365. begin
  366. GetLongName:=n;
  367. {$ifdef win32}
  368. hs:=n+#0;
  369. i:=Windows.GetFullPathName(@hs[1],256,hs2,j);
  370. if (i>0) and (i<=255) then
  371. begin
  372. hs:=strpas(hs2);
  373. GetLongName:=hs;
  374. end;
  375. {$endif}
  376. {$ifdef go32v2}
  377. hs:=n;
  378. if Dos.GetLongName(hs) then
  379. GetLongName:=hs;
  380. {$endif}
  381. end;
  382. function EatIO: integer;
  383. begin
  384. EatIO:=IOResult;
  385. end;
  386. function LowCase(C: char): char;
  387. begin
  388. if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
  389. LowCase:=C;
  390. end;
  391. function LowcaseStr(S: string): string;
  392. var I: Longint;
  393. begin
  394. for I:=1 to length(S) do
  395. S[I]:=Lowcase(S[I]);
  396. LowcaseStr:=S;
  397. end;
  398. function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
  399. begin
  400. if B then BoolToStr:=TrueS else BoolToStr:=FalseS;
  401. end;
  402. procedure TNoDisposeCollection.FreeItem(Item: Pointer);
  403. begin
  404. { don't do anything here }
  405. end;
  406. constructor TUnsortedStringCollection.CreateFrom(ALines: PUnsortedStringCollection);
  407. begin
  408. if Assigned(ALines)=false then Fail;
  409. inherited Init(ALines^.Count,ALines^.Count div 10);
  410. Assign(ALines);
  411. end;
  412. procedure TUnsortedStringCollection.Assign(ALines: PUnsortedStringCollection);
  413. procedure AddIt(P: PString); {$ifndef FPC}far;{$endif}
  414. begin
  415. Insert(NewStr(GetStr(P)));
  416. end;
  417. begin
  418. FreeAll;
  419. if Assigned(ALines) then
  420. ALines^.ForEach(@AddIt);
  421. end;
  422. function TUnsortedStringCollection.At(Index: Integer): PString;
  423. begin
  424. At:=inherited At(Index);
  425. end;
  426. procedure TUnsortedStringCollection.FreeItem(Item: Pointer);
  427. begin
  428. if Item<>nil then DisposeStr(Item);
  429. end;
  430. function TUnsortedStringCollection.GetItem(var S: TStream): Pointer;
  431. begin
  432. GetItem:=S.ReadStr;
  433. end;
  434. procedure TUnsortedStringCollection.PutItem(var S: TStream; Item: Pointer);
  435. begin
  436. S.WriteStr(Item);
  437. end;
  438. constructor TNulStream.Init;
  439. begin
  440. inherited Init;
  441. Position:=0;
  442. end;
  443. function TNulStream.GetPos: Longint;
  444. begin
  445. GetPos:=Position;
  446. end;
  447. function TNulStream.GetSize: Longint;
  448. begin
  449. GetSize:=Position;
  450. end;
  451. procedure TNulStream.Read(var Buf; Count: Word);
  452. begin
  453. Error(stReadError,0);
  454. end;
  455. procedure TNulStream.Seek(Pos: Longint);
  456. begin
  457. if Pos<=Position then
  458. Position:=Pos;
  459. end;
  460. procedure TNulStream.Write(var Buf; Count: Word);
  461. begin
  462. Inc(Position,Count);
  463. end;
  464. constructor TSubStream.Init(AStream: PStream; AStartPos, ASize: longint);
  465. begin
  466. inherited Init;
  467. if Assigned(AStream)=false then Fail;
  468. S:=AStream; StartPos:=AStartPos; StreamSize:=ASize;
  469. Seek(0);
  470. end;
  471. function TSubStream.GetPos: Longint;
  472. var Pos: longint;
  473. begin
  474. Pos:=S^.GetPos; Dec(Pos,StartPos);
  475. GetPos:=Pos;
  476. end;
  477. function TSubStream.GetSize: Longint;
  478. begin
  479. GetSize:=StreamSize;
  480. end;
  481. procedure TSubStream.Read(var Buf; Count: Word);
  482. var Pos: longint;
  483. RCount: word;
  484. begin
  485. Pos:=GetPos;
  486. if Pos+Count>StreamSize then RCount:=StreamSize-Pos else RCount:=Count;
  487. S^.Read(Buf,RCount);
  488. if RCount<Count then
  489. Error(stReadError,0);
  490. end;
  491. procedure TSubStream.Seek(Pos: Longint);
  492. var RPos: longint;
  493. begin
  494. if (Pos<=StreamSize) then RPos:=Pos else RPos:=StreamSize;
  495. S^.Seek(StartPos+RPos);
  496. end;
  497. procedure TSubStream.Write(var Buf; Count: Word);
  498. begin
  499. S^.Write(Buf,Count);
  500. end;
  501. function TTextCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  502. var K1: PString absolute Key1;
  503. K2: PString absolute Key2;
  504. R: Sw_integer;
  505. S1,S2: string;
  506. begin
  507. S1:=UpCaseStr(K1^);
  508. S2:=UpCaseStr(K2^);
  509. if S1<S2 then R:=-1 else
  510. if S1>S2 then R:=1 else
  511. R:=0;
  512. Compare:=R;
  513. end;
  514. function TTextCollection.LookUp(const S: string; var Idx: sw_integer): string;
  515. var OLI,ORI,Left,Right,Mid: integer;
  516. LeftP,RightP,MidP: PString;
  517. LeftS,MidS,RightS: string;
  518. FoundS: string;
  519. UpS : string;
  520. begin
  521. Idx:=-1; FoundS:='';
  522. Left:=0; Right:=Count-1;
  523. UpS:=UpCaseStr(S);
  524. if Left<Right then
  525. begin
  526. while (Left<Right) do
  527. begin
  528. OLI:=Left; ORI:=Right;
  529. Mid:=Left+(Right-Left) div 2;
  530. LeftP:=At(Left); RightP:=At(Right); MidP:=At(Mid);
  531. LeftS:=UpCaseStr(LeftP^); MidS:=UpCaseStr(MidP^);
  532. RightS:=UpCaseStr(RightP^);
  533. if copy(MidS,1,length(UpS))=UpS then
  534. begin
  535. Idx:=Mid; FoundS:=GetStr(MidP);
  536. end;
  537. { else}
  538. if UpS<MidS then
  539. Right:=Mid
  540. else
  541. Left:=Mid;
  542. if (OLI=Left) and (ORI=Right) then
  543. Break;
  544. end;
  545. end;
  546. LookUp:=FoundS;
  547. end;
  548. function TrimEndSlash(const Path: string): string;
  549. var S: string;
  550. begin
  551. S:=Path;
  552. if (length(S)>0) and (S<>DirSep) and (copy(S,length(S),1)=DirSep) and
  553. (S[length(S)-1]<>':') then
  554. S:=copy(S,1,length(S)-1);
  555. TrimEndSlash:=S;
  556. end;
  557. function CompareText(S1, S2: string): integer;
  558. var R: integer;
  559. begin
  560. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  561. if S1<S2 then R:=-1 else
  562. if S1>S2 then R:= 1 else
  563. R:=0;
  564. CompareText:=R;
  565. end;
  566. procedure GiveUpTimeSlice;
  567. {$ifdef GO32V2}{$define DOS}{$endif}
  568. {$ifdef TP}{$define DOS}{$endif}
  569. {$ifdef DOS}
  570. var r: registers;
  571. begin
  572. r.ax:=$1680;
  573. intr($2f,r);
  574. end;
  575. {$endif}
  576. {$ifdef Linux}
  577. begin
  578. end;
  579. {$endif}
  580. {$ifdef Win32}
  581. begin
  582. end;
  583. {$endif}
  584. {$undef DOS}
  585. procedure RegisterWUtils;
  586. begin
  587. {$ifndef NOOBJREG}
  588. RegisterType(RUnsortedStringCollection);
  589. {$endif}
  590. end;
  591. END.
  592. {
  593. $Log$
  594. Revision 1.18 2000-03-21 23:19:13 pierre
  595. + TrimEndSlash and CompareText by Gabor
  596. Revision 1.17 2000/03/20 19:19:45 pierre
  597. * LFN support in streams
  598. Revision 1.16 2000/03/14 13:36:12 pierre
  599. * error for unexistant file in GetFileTime fixed
  600. Revision 1.15 2000/02/07 11:45:11 pierre
  601. + TUnsortedStringCollection CreateFrom/Assign/GetItem/PutItem from Gabor
  602. Revision 1.14 2000/01/20 00:30:32 pierre
  603. * Result of GetShortPathName is checked
  604. Revision 1.13 2000/01/17 12:20:03 pierre
  605. * uses windows needed for GetShortName
  606. Revision 1.12 2000/01/14 15:36:43 pierre
  607. + GetShortFileName used for tcodeeditor file opening
  608. Revision 1.11 2000/01/05 17:27:20 pierre
  609. + linecomplete arg for ReadlnFromStream
  610. Revision 1.10 2000/01/03 11:38:35 michael
  611. Changes from Gabor
  612. Revision 1.9 1999/12/01 16:19:46 pierre
  613. + GetFileTime moved here
  614. Revision 1.8 1999/10/25 16:39:03 pierre
  615. + GetPChar to avoid nil pointer problems
  616. Revision 1.7 1999/09/13 11:44:00 peter
  617. * fixes from gabor, idle event, html fix
  618. Revision 1.6 1999/08/24 22:01:48 pierre
  619. * readlnfromstream length check added
  620. Revision 1.5 1999/08/03 20:22:45 peter
  621. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  622. + Desktop saving should work now
  623. - History saved
  624. - Clipboard content saved
  625. - Desktop saved
  626. - Symbol info saved
  627. * syntax-highlight bug fixed, which compared special keywords case sensitive
  628. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  629. * with 'whole words only' set, the editor didn't found occourences of the
  630. searched text, if the text appeared previously in the same line, but didn't
  631. satisfied the 'whole-word' condition
  632. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  633. (ie. the beginning of the selection)
  634. * when started typing in a new line, but not at the start (X=0) of it,
  635. the editor inserted the text one character more to left as it should...
  636. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  637. * Shift shouldn't cause so much trouble in TCodeEditor now...
  638. * Syntax highlight had problems recognizing a special symbol if it was
  639. prefixed by another symbol character in the source text
  640. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  641. Revision 1.4 1999/04/07 21:56:06 peter
  642. + object support for browser
  643. * html help fixes
  644. * more desktop saving things
  645. * NODEBUG directive to exclude debugger
  646. Revision 1.2 1999/03/08 14:58:22 peter
  647. + prompt with dialogs for tools
  648. Revision 1.1 1999/03/01 15:51:43 peter
  649. + Log
  650. }