fpcodcmp.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. unit FPCodCmp; { CodeComplete }
  2. interface
  3. uses Objects,Drivers,
  4. WUtils,WViews;
  5. type
  6. PCodeCompleteWordList = ^TCodeCompleteWordList;
  7. TCodeCompleteWordList = object(TTextCollection)
  8. end;
  9. PCodeCompleteDialog = ^TCodeCompleteDialog;
  10. TCodeCompleteDialog = object(TCenterDialog)
  11. constructor Init;
  12. function Execute: Word; virtual;
  13. procedure HandleEvent(var Event: TEvent); virtual;
  14. private
  15. CodeCompleteLB : PAdvancedListBox;
  16. procedure Add;
  17. procedure Edit;
  18. procedure Delete;
  19. end;
  20. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  21. procedure InitCodeComplete;
  22. function LoadCodeComplete(var S: TStream): boolean;
  23. function StoreCodeComplete(var S: TStream): boolean;
  24. procedure DoneCodeComplete;
  25. const CodeCompleteWords : PCodeCompleteWordList = nil;
  26. procedure RegisterCodeComplete;
  27. implementation
  28. uses Commands,Views,Dialogs,MsgBox,
  29. WEditor,
  30. FPConst,FPString,FPViews;
  31. {$ifndef NOOBJREG}
  32. const
  33. RCodeCompleteWordList: TStreamRec = (
  34. ObjType: 14401;
  35. VmtLink: Ofs(TypeOf(TCodeCompleteWordList)^);
  36. Load: @TCodeCompleteWordList.Load;
  37. Store: @TCodeCompleteWordList.Store
  38. );
  39. {$endif}
  40. function FPCompleteCodeWord(const WordS: string; var Text: string): boolean;
  41. var OK: boolean;
  42. Index: sw_integer;
  43. begin
  44. OK:=Assigned(CodeCompleteWords);
  45. if OK then
  46. begin
  47. Text:=CodeCompleteWords^.Lookup(WordS,Index);
  48. OK:=(Index<>-1) and (length(Text)<>length(WordS));
  49. end;
  50. if OK=false then Text:='';
  51. FPCompleteCodeWord:=OK;
  52. end;
  53. procedure InitCodeComplete;
  54. var I:integer;
  55. S: string;
  56. begin
  57. if Assigned(CodeCompleteWords) then Exit;
  58. New(CodeCompleteWords, Init(10,10));
  59. for I:=0 to GetReservedWordCount-1 do
  60. begin
  61. S:=LowCaseStr(GetReservedWord(I));
  62. if length(S)>=CodeCompleteMinLen then
  63. CodeCompleteWords^.Insert(NewStr(S));
  64. end;
  65. {
  66. there should be also a user front-end for customizing CodeComplete !
  67. any volunteers to implement? ;) - Gabor
  68. }
  69. end;
  70. function LoadCodeComplete(var S: TStream): boolean;
  71. var C: PCodeCompleteWordList;
  72. OK: boolean;
  73. begin
  74. New(C, Load(S));
  75. OK:=Assigned(C) and (S.Status=stOk);
  76. if OK then
  77. begin
  78. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  79. CodeCompleteWords:=C;
  80. end
  81. else
  82. if Assigned(C) then
  83. Dispose(C, Done);
  84. LoadCodeComplete:=OK;
  85. end;
  86. function StoreCodeComplete(var S: TStream): boolean;
  87. var OK: boolean;
  88. begin
  89. OK:=Assigned(CodeCompleteWords);
  90. if OK then
  91. begin
  92. CodeCompleteWords^.Store(S);
  93. OK:=OK and (S.Status=stOK);
  94. end;
  95. StoreCodeComplete:=OK;
  96. end;
  97. procedure DoneCodeComplete;
  98. begin
  99. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  100. CodeCompleteWords:=nil;
  101. end;
  102. constructor TCodeCompleteDialog.Init;
  103. var R,R2,R3: TRect;
  104. SB: PScrollBar;
  105. begin
  106. R.Assign(0,0,46,16);
  107. inherited Init(R,'CodeComplete');
  108. GetExtent(R); R.Grow(-3,-2); Inc(R.A.Y); R3.Copy(R); Dec(R.B.X,12);
  109. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  110. New(SB, Init(R2)); Insert(SB);
  111. New(CodeCompleteLB, Init(R,1,SB));
  112. Insert(CodeCompleteLB);
  113. R2.Copy(R); R2.Move(0,-1); R2.B.Y:=R2.A.Y+1; Dec(R2.A.X);
  114. Insert(New(PLabel, Init(R2, '~K~eywords', CodeCompleteLB)));
  115. R.Copy(R3); R.A.X:=R.B.X-10; R.B.Y:=R.A.Y+2;
  116. Insert(New(PButton, Init(R, 'O~K~', cmOK, bfNormal)));
  117. R.Move(0,2);
  118. Insert(New(PButton, Init(R, '~E~dit', cmEditItem, bfDefault)));
  119. R.Move(0,2);
  120. Insert(New(PButton, Init(R, '~N~ew', cmAddItem, bfNormal)));
  121. R.Move(0,2);
  122. Insert(New(PButton, Init(R, '~D~elete', cmDeleteItem, bfNormal)));
  123. R.Move(0,2);
  124. Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  125. SelectNext(false);
  126. end;
  127. procedure TCodeCompleteDialog.HandleEvent(var Event: TEvent);
  128. var DontClear: boolean;
  129. begin
  130. case Event.What of
  131. evKeyDown :
  132. begin
  133. DontClear:=false;
  134. case Event.KeyCode of
  135. kbIns :
  136. Message(@Self,evCommand,cmAddItem,nil);
  137. kbDel :
  138. Message(@Self,evCommand,cmDeleteItem,nil);
  139. else DontClear:=true;
  140. end;
  141. if DontClear=false then ClearEvent(Event);
  142. end;
  143. evBroadcast :
  144. case Event.Command of
  145. cmListItemSelected :
  146. if Event.InfoPtr=pointer(CodeCompleteLB) then
  147. Message(@Self,evCommand,cmEditItem,nil);
  148. end;
  149. evCommand :
  150. begin
  151. DontClear:=false;
  152. case Event.Command of
  153. cmAddItem : Add;
  154. cmDeleteItem : Delete;
  155. cmEditItem : Edit;
  156. else DontClear:=true;
  157. end;
  158. if DontClear=false then ClearEvent(Event);
  159. end;
  160. end;
  161. inherited HandleEvent(Event);
  162. end;
  163. function TCodeCompleteDialog.Execute: Word;
  164. var R: word;
  165. C: PCodeCompleteWordList;
  166. I: integer;
  167. S1,S2,S3: string;
  168. W: word;
  169. begin
  170. New(C, Init(10,20));
  171. if Assigned(CodeCompleteWords) then
  172. for I:=0 to CodeCompleteWords^.Count-1 do
  173. C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
  174. CodeCompleteLB^.NewList(C);
  175. R:=inherited Execute;
  176. if R=cmOK then
  177. begin
  178. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  179. CodeCompleteWords:=C;
  180. end
  181. else
  182. Dispose(C, Done);
  183. Execute:=R;
  184. end;
  185. procedure TCodeCompleteDialog.Add;
  186. var IC: boolean;
  187. S: string;
  188. P: PString;
  189. Cmd: word;
  190. CanExit: boolean;
  191. I: sw_integer;
  192. begin
  193. IC:=CodeCompleteLB^.Range=0;
  194. if IC=false then
  195. S:=GetStr(CodeCompleteLB^.List^.At(CodeCompleteLB^.Focused))
  196. else
  197. S:='';
  198. repeat
  199. Cmd:=InputBox(dialog_codecomplete_add,label_codecomplete_add_keyword,S,255);
  200. CanExit:=Cmd<>cmOK;
  201. if CanExit=false then
  202. begin
  203. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,I)=false;
  204. if CanExit=false then
  205. ErrorBox('"'+S+'" is already in the list',nil);
  206. end;
  207. until CanExit;
  208. if Cmd=cmOK then
  209. begin
  210. P:=NewStr(S);
  211. with CodeCompleteLB^ do
  212. begin
  213. List^.Insert(P);
  214. SetRange(List^.Count);
  215. SetFocusedItem(P);
  216. end;
  217. ReDraw;
  218. end;
  219. end;
  220. procedure TCodeCompleteDialog.Edit;
  221. var S: string;
  222. I,T: sw_integer;
  223. Cmd: word;
  224. CanExit: boolean;
  225. P: PString;
  226. begin
  227. if CodeCompleteLB^.Range=0 then Exit;
  228. I:=CodeCompleteLB^.Focused;
  229. S:=GetStr(CodeCompleteLB^.List^.At(I));
  230. repeat
  231. Cmd:=InputBox(dialog_codecomplete_edit,label_codecomplete_edit_keyword,S,255);
  232. CanExit:=Cmd<>cmOK;
  233. if CanExit=false then
  234. begin
  235. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,T)=false;
  236. CanExit:=CanExit or (T=I);
  237. if CanExit=false then
  238. ErrorBox('"'+S+'" is already in the list',nil);
  239. end;
  240. until CanExit;
  241. if Cmd=cmOK then
  242. begin
  243. P:=NewStr(S);
  244. with CodeCompleteLB^ do
  245. begin
  246. List^.AtFree(I);
  247. List^.Insert(P);
  248. SetFocusedItem(P);
  249. end;
  250. ReDraw;
  251. end;
  252. end;
  253. procedure TCodeCompleteDialog.Delete;
  254. begin
  255. if CodeCompleteLB^.Range=0 then Exit;
  256. CodeCompleteLB^.List^.AtFree(CodeCompleteLB^.Focused);
  257. CodeCompleteLB^.SetRange(CodeCompleteLB^.List^.Count);
  258. ReDraw;
  259. end;
  260. procedure RegisterCodeComplete;
  261. begin
  262. {$ifndef NOOBJREG}
  263. RegisterType(RCodeCompleteWordList);
  264. {$endif}
  265. end;
  266. END.