fpcodcmp.pas 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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,dialog_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, label_codecomplete_keywords, 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, button_OK, cmOK, bfNormal)));
  117. R.Move(0,2);
  118. Insert(New(PButton, Init(R, button_Edit, cmEditItem, bfDefault)));
  119. R.Move(0,2);
  120. Insert(New(PButton, Init(R, button_New, cmAddItem, bfNormal)));
  121. R.Move(0,2);
  122. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  123. R.Move(0,2);
  124. Insert(New(PButton, Init(R, button_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. begin
  168. New(C, Init(10,20));
  169. if Assigned(CodeCompleteWords) then
  170. for I:=0 to CodeCompleteWords^.Count-1 do
  171. C^.Insert(NewStr(GetStr(CodeCompleteWords^.At(I))));
  172. CodeCompleteLB^.NewList(C);
  173. R:=inherited Execute;
  174. if R=cmOK then
  175. begin
  176. if Assigned(CodeCompleteWords) then Dispose(CodeCompleteWords, Done);
  177. CodeCompleteWords:=C;
  178. end
  179. else
  180. Dispose(C, Done);
  181. Execute:=R;
  182. end;
  183. procedure TCodeCompleteDialog.Add;
  184. var IC: boolean;
  185. S: string;
  186. P: PString;
  187. Cmd: word;
  188. CanExit: boolean;
  189. I: sw_integer;
  190. begin
  191. IC:=CodeCompleteLB^.Range=0;
  192. if IC=false then
  193. S:=GetStr(CodeCompleteLB^.List^.At(CodeCompleteLB^.Focused))
  194. else
  195. S:='';
  196. repeat
  197. Cmd:=InputBox(dialog_codecomplete_add,label_codecomplete_add_keyword,S,255);
  198. CanExit:=Cmd<>cmOK;
  199. if CanExit=false then
  200. begin
  201. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,I)=false;
  202. if CanExit=false then
  203. begin
  204. ClearFormatParams; AddFormatParamStr(S);
  205. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  206. end;
  207. end;
  208. until CanExit;
  209. if Cmd=cmOK then
  210. begin
  211. P:=NewStr(S);
  212. with CodeCompleteLB^ do
  213. begin
  214. List^.Insert(P);
  215. SetRange(List^.Count);
  216. SetFocusedItem(P);
  217. end;
  218. ReDraw;
  219. end;
  220. end;
  221. procedure TCodeCompleteDialog.Edit;
  222. var S: string;
  223. I,T: sw_integer;
  224. Cmd: word;
  225. CanExit: boolean;
  226. P: PString;
  227. begin
  228. if CodeCompleteLB^.Range=0 then Exit;
  229. I:=CodeCompleteLB^.Focused;
  230. S:=GetStr(CodeCompleteLB^.List^.At(I));
  231. repeat
  232. Cmd:=InputBox(dialog_codecomplete_edit,label_codecomplete_edit_keyword,S,255);
  233. CanExit:=Cmd<>cmOK;
  234. if CanExit=false then
  235. begin
  236. CanExit:=PCodeCompleteWordList(CodeCompleteLB^.List)^.Search(@S,T)=false;
  237. CanExit:=CanExit or (T=I);
  238. if CanExit=false then
  239. begin
  240. ClearFormatParams; AddFormatParamStr(S);
  241. ErrorBox(msg_codecomplete_alreadyinlist,@FormatParams);
  242. end;
  243. end;
  244. until CanExit;
  245. if Cmd=cmOK then
  246. begin
  247. P:=NewStr(S);
  248. with CodeCompleteLB^ do
  249. begin
  250. List^.AtFree(I);
  251. List^.Insert(P);
  252. SetFocusedItem(P);
  253. end;
  254. ReDraw;
  255. end;
  256. end;
  257. procedure TCodeCompleteDialog.Delete;
  258. begin
  259. if CodeCompleteLB^.Range=0 then Exit;
  260. CodeCompleteLB^.List^.AtFree(CodeCompleteLB^.Focused);
  261. CodeCompleteLB^.SetRange(CodeCompleteLB^.List^.Count);
  262. ReDraw;
  263. end;
  264. procedure RegisterCodeComplete;
  265. begin
  266. {$ifndef NOOBJREG}
  267. RegisterType(RCodeCompleteWordList);
  268. {$endif}
  269. end;
  270. END.