lister.pas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. {
  2. $Id$
  3. This file is a Free Pascal example
  4. Copyright (C) 2005 by Marco van de Voort
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. An filebrowser inspired by Vernon D. Buerg's list.com, designed
  9. to be a shell to less under Unix, but works fine under Windows too.
  10. (using any less and file in the path)
  11. See the file COPYING.FPC, included in this distribution,
  12. for details about the copyright.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. **********************************************************************}
  17. {$mode Delphi}
  18. Uses Process,SysUtils,Video,Keyboard,FList
  19. {$IFDEF UNIX}, BaseUnix{$ENDIF};
  20. Function Do_File_cmd(path:String):String;
  21. Const BufSize = 1024;
  22. TheProgram = 'file' {$IFDEF Win32}+'.exe' {$ENDIF};
  23. Var S : TProcess;
  24. Buf : Array[1..BUFSIZE] of char;
  25. I,Count : longint;
  26. begin
  27. S:=TProcess.Create(Nil);
  28. S.Commandline:=theprogram+' '+path;
  29. S.Options:=[poUsePipes,poNoConsole];
  30. S.execute;
  31. Result:='';
  32. Count:=s.output.read(buf,BufSize);
  33. If Count>0 Then
  34. Begin
  35. SetLength(Result,Count);
  36. Move(buf[1],Result[1],Count);
  37. End;
  38. S.Free;
  39. {$ifdef win32}
  40. If Length(Result)>2 Then
  41. Begin
  42. If Result[2]=':' Then
  43. Result[2]:=' ';
  44. End;
  45. {$endif}
  46. i:=Pos(':',Result);
  47. If I>0 Then
  48. Delete(Result,1,I);
  49. Result:=Trim(Result);
  50. I:=Length(Result);
  51. While (I>0) and (Result[I]=#10) DO
  52. Dec(I);
  53. If I>ScreenWidth Then
  54. I:=ScreenWidth;
  55. SetLength(Result,I);
  56. end;
  57. Var
  58. FileSpec : String;
  59. D : TVidDirList;
  60. ExitNow : Boolean;
  61. K : TKeyEvent;
  62. OldHome,
  63. OldCursor: Integer;
  64. S,S2 : String;
  65. Forced,
  66. ForcedFull: Boolean;
  67. C : Char;
  68. Editor,
  69. Pager : AnsiString;
  70. Procedure ReDraw;
  71. Begin
  72. D.ClearArea;
  73. D.BuildDisplay;
  74. D.HiLight(D.Cursor,D.Position,1);
  75. // Probably so much changed that diffing won't help?
  76. UpdateScreen(true);
  77. End;
  78. procedure loadutil(const envvar,default : string;var symbol : string);
  79. begin
  80. Symbol:=GetEnvironmentVariable(envvar);
  81. if Symbol='' Then
  82. Symbol:=default;
  83. if Pos('/',Symbol)=0 Then
  84. Symbol:=FileSearch(Symbol,GetEnvironmentVariable('PATH'));
  85. end;
  86. Begin
  87. InitVideo;
  88. InitKeyboard;
  89. {$ifdef Unix}
  90. FileSpec:='*';
  91. {$else}
  92. FileSpec:='*.*';
  93. {$endif}
  94. ExitNow:=False;
  95. {$ifdef win32}
  96. Pager:='notepad.exe';
  97. Editor:='notepad.exe';
  98. {$else}
  99. loadutil('EDITOR','joe' ,editor);
  100. loadutil('PAGER' ,'less',pager);
  101. {$endif}
  102. If ParamCount()>0 Then
  103. FileSpec:=ParamStr(1);
  104. {$ifdef debug}
  105. assign(f,'log.txt');
  106. rewrite(F);
  107. {$endif}
  108. D:=TVidDirList.Create;
  109. D.Columns:=5; // default
  110. D.Directory:=GetCurrentDir;
  111. D.PopulateList(FileSpec);
  112. D.Attributes[NoMarkNoSelect]:=$07;
  113. D.Attributes[MarkNoSelect] :=$17;
  114. D.Attributes[NoMarkSelect] :=$0F;
  115. D.Attributes[MarkSelect] :=$1F;
  116. ReDraw;
  117. Repeat
  118. {$ifdef debug}
  119. Writeln(F,'Cursor :',D.Cursor);
  120. Writeln(F,'Position:',D.Position);
  121. Writeln(F,'Totalent:',D.TotalEnt);
  122. // Writeln(F,'wdth :',D.wdth);
  123. Writeln(F,'maxent :',D.maxent);
  124. Writeln(F,'colh :',D.colh);
  125. Writeln(F,'columns :',D.columns);
  126. Writeln(F);
  127. {$endif}
  128. K:=GetKeyEvent;
  129. K:=TranslateKeyEvent(K);
  130. OldCursor:=D.Cursor;
  131. OldHome:=D.Position;
  132. Forced:=False;
  133. ForcedFull:=False;
  134. IF IsFunctionKey(K) Then
  135. Begin
  136. K:=TKeyRecord(K).KeyCode;
  137. Case K Of
  138. kbdRight: Begin
  139. If D.Cursor<(D.TotalEnt-D.Colh) Then
  140. D.Cursor:=D.Cursor+D.colh
  141. else
  142. D.Cursor:=D.TotalEnt-1;
  143. If D.Cursor>=(D.Position+D.MaxEnt) Then
  144. D.Position:=D.Position+d.colh;
  145. End;
  146. kbdDown : Begin
  147. If D.Cursor<(D.TotalEnt-1) Then
  148. D.Cursor:=D.Cursor+1;
  149. If D.Cursor>(D.Position+D.MaxEnt-1) Then
  150. D.Position:=D.Position+D.Colh;
  151. End;
  152. kbdUp : Begin
  153. If D.Cursor>0 Then
  154. D.Cursor:=D.Cursor-1;
  155. If D.Cursor<D.Position Then
  156. Begin
  157. D.Position:=D.Position-D.Colh;
  158. If D.Position<0 Then
  159. D.Position:=0;
  160. End;
  161. End;
  162. kbdLeft : Begin
  163. If D.Cursor>=(D.Colh) Then
  164. D.Cursor:=D.Cursor-D.colh
  165. else
  166. D.Cursor:=0;
  167. If D.Cursor<D.Position Then
  168. D.Position:=D.Position-D.Colh;
  169. If D.Position<0 Then
  170. D.Position:=0;
  171. End;
  172. End;
  173. End
  174. Else
  175. Begin
  176. C:=GetKeyEventChar(K);
  177. if C<>#0 Then
  178. Case C Of
  179. #13 : Begin
  180. If D.Cursor>=D.DirCount Then
  181. Begin
  182. {$ifdef win32} // try to get "open" action ?
  183. S:=ExtractFileExt(D[D.Cursor]);
  184. Delete(S,1,1);
  185. {$endif}
  186. ExecuteProcess(Pager,[D.Directory+D[D.Cursor]]);
  187. // TextOut(10,1,' ');
  188. //TextOut(10,1,D[D.Cursor]);
  189. ForcedFull:=True;
  190. End
  191. Else
  192. Begin
  193. S:=D.Directories[D.Cursor];
  194. S2:=D.Directory+S;
  195. If S='..' Then
  196. S2:=ExpandFileName(S2);
  197. {$IFDEF UNIX}
  198. IF FPAccess(pchar(s2),X_OK)=0 Then
  199. begin
  200. {$ENDIF}
  201. D.Directory:=S2;
  202. D.PopulateList(FileSpec);
  203. ForcedFull:=True;
  204. {$IFDEF UNIX}
  205. end;
  206. {$ENDIF}
  207. End;
  208. End;
  209. 'e','E' : begin
  210. If D.Cursor>=D.DirCount Then
  211. Begin
  212. {$ifdef win32} // try to get "edit" action ?
  213. S:=ExtractFileExt(D[D.Cursor]);
  214. Delete(S,1,1);
  215. {$endif}
  216. ExecuteProcess(Editor,[D.Directory+D[D.Cursor]]);
  217. // TextOut(10,1,' ');
  218. //TextOut(10,1,D[D.Cursor]);
  219. ForcedFull:=True;
  220. End
  221. end;
  222. 'd','D' : Begin
  223. If D.Cursor>=D.DirCount Then
  224. Begin
  225. s:=ExpandFileName(D.Directory+D[D.Cursor]);
  226. DeleteFile(S);
  227. D.PopulateList(FileSpec);
  228. ForcedFull:=True;
  229. End;
  230. End;
  231. #27,'q' : exitnow:=True;
  232. ' ' : Begin
  233. D.Toggle(D.Cursor);
  234. Forced:=True;
  235. End;
  236. 'i' : Begin
  237. TextClear(1,1,ScreenWidth);
  238. If D.Cursor>=D.DirCount Then
  239. Begin
  240. TextOut(1,1,do_file_cmd(' '+D.Directory+D[D.Cursor]));
  241. End
  242. Else
  243. Begin
  244. textout(1,1,+' is a directory');
  245. End;
  246. Forced:=True;
  247. End;
  248. End;
  249. End;
  250. // Determine if, and what kind of updating necessary;
  251. If (OldHome<>D.Position) OR ForcedFull Then
  252. Redraw
  253. Else
  254. Begin
  255. If (OldCursor<>D.Cursor) Or Forced Then
  256. Begin
  257. D.Hilight(OldCursor,OldHome,0);
  258. D.HiLight(D.Cursor,D.Position,1);
  259. UpdateScreen(False);
  260. End;
  261. End;
  262. Until ExitNow;
  263. DoneKeyboard;
  264. DoneVideo;
  265. {$ifdef Debug}
  266. d.printdirs;
  267. d.printfiles;
  268. {$endif}
  269. D.Free;
  270. {$ifdef debug}
  271. Close(F);
  272. {$endif}
  273. End.
  274. {
  275. $Log$
  276. Revision 1.3 2005-04-06 20:16:48 marco
  277. * deletefile support
  278. Revision 1.2 2005/04/06 18:45:47 marco
  279. * editing added
  280. Revision 1.1 2005/04/06 08:54:16 marco
  281. * new Unix demo: lister
  282. }