diff --git a/lazproj/coedit.lpi b/lazproj/coedit.lpi
index 66d0ec21..382f8dfe 100644
--- a/lazproj/coedit.lpi
+++ b/lazproj/coedit.lpi
@@ -52,6 +52,11 @@
+
+
+
+
+
@@ -135,7 +140,7 @@
-
+
@@ -304,6 +309,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/ce_main.lfm b/src/ce_main.lfm
index e253d632..12ecd70f 100644
--- a/src/ce_main.lfm
+++ b/src/ce_main.lfm
@@ -1829,6 +1829,42 @@ object CEMainForm: TCEMainForm
Caption = 'Windows'
object mnuLayout: TMenuItem
Caption = 'Layout'
+ Bitmap.Data = {
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00BE7D
+ 558FBD7C54B5BC7B53EEBA7953FFB67751FFB47651FFB17450FFAD724FFFAA71
+ 4FFFA86F4EFFA76E4DFFA66E4DFEA46E4DF1A66E4DC4FFFFFF00FFFFFF00C080
+ 55DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA66E4DEDFFFFFF00FFFFFF00C282
+ 58FEFFFFFFFFAF672CFFAD642BFFAD642BFFFFFFFFFF56AB5DFF51A657FF4CA1
+ 52FF479C4CFF449849FF409445FFFFFFFFFFA76F4EFEFFFFFF00FFFFFF00C486
+ 5AFFFFFFFFFFAF672CFFCD9F74FFAD642BFFFFFFFFFF4B9F50FF70C97BFF70C9
+ 7BFF6FC87AFF6EC778FF3E9343FFFFFFFFFFA8714FFFFFFFFF00FFFFFF00C586
+ 5BFFFFFFFFFFAF672CFFCDA075FFAD642BFFFFFFFFFF4EA354FF73CA7DFF72CA
+ 7DFF71C97CFF6FC87AFF419546FFFFFFFFFFAC7250FFFFFFFF00FFFFFF00C788
+ 5AFFFFFFFFFFB46E33FFD0A57EFFB26C2EFFFFFFFFFF50A556FF74CB7EFF73CB
+ 7DFF72CA7CFF70C97BFF449949FFFFFFFFFFB27651FFFFFFFF00FFFFFF00C88A
+ 5BFFFFFFFFFFB77640FFD1A683FFB67338FFFFFFFFFF52A859FF73CB7DFF73CB
+ 7DFF72CA7CFF70C97BFF479C4DFFFFFFFFFFB67853FFFFFFFF00FFFFFF00CA8C
+ 5CFFFFFFFFFFBC7F54FFBA7D4CFFBA7C4AFFFFFFFFFF469B4CFF53A859FF51A6
+ 57FF4FA455FF4DA253FF4A9F50FFFFFFFFFFB97C54FFFFFFFF00FFFFFF00CB8E
+ 5DFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC7E55FFFFFFFF00FFFFFF00CC90
+ 5EFAFFFFFFFFEDC49BFFEDC49BFFEDC49BFFEDC49BFFEDC49BFFEDC49BFFEDC4
+ 9BFFEDC49BFFEDC49BFFEDC49BFFFFFFFFFFBE8157FFFFFFFF00FFFFFF00CD91
+ 5FF0FFFFFFFFEDC49CFFF4DAC1FFF4DAC1FFF4DBC2FFF4DBC2FFF4DBC2FFF4DB
+ C2FFF4DBC2FFF4DBC2FFEDC49BFFFFFFFFFFC18458FEFFFFFF00FFFFFF00CE93
+ 5FD8FFFFFFFFEDC49CFFEDC49CFFEDC49CFFEDC49BFFEDC49BFFEDC49BFFEDC4
+ 9BFFEDC49BFFEDC49BFFEDC49BFFFFFFFFFFC68C61F8FFFFFF00FFFFFF00CE93
+ 5F9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6AA89FFFFFFFF00FFFFFF00CE93
+ 5F71CE935F90CE935FCCCE935FFFCD935FFECD925FFFCC905FFFCD9261FFCD93
+ 63FFCB9161FFCB8E5FEFCA9264CBD8AE8BFFD7AC8BFFFFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ }
ImageIndex = 31
end
end
@@ -3149,4 +3185,10 @@ object CEMainForm: TCEMainForm
OnShowHint = ApplicationProperties1ShowHint
left = 96
end
+ object OutputTimer: TIdleTimer
+ Interval = 100
+ OnTimer = OutputTimerTimer
+ left = 128
+ top = 1
+ end
end
diff --git a/src/ce_main.pas b/src/ce_main.pas
index 35667f18..d942be9a 100644
--- a/src/ce_main.pas
+++ b/src/ce_main.pas
@@ -5,13 +5,13 @@ unit ce_main;
interface
uses
- Classes, SysUtils, FileUtil, SynEditKeyCmds, SynHighlighterLFM, Forms,
+ Classes, SysUtils, FileUtil, SynEditKeyCmds, SynHighlighterLFM, Forms, asyncprocess,
AnchorDocking, AnchorDockStorage, AnchorDockOptionsDlg, Controls, Graphics,
Dialogs, Menus, ActnList, ExtCtrls, process, XMLPropStorage, ComCtrls, dynlibs,
ce_common, ce_dmdwrap, ce_project, ce_dcd, ce_plugin, ce_synmemo, ce_widget,
ce_messages, ce_interfaces, ce_editor, ce_projinspect, ce_projconf, ce_search,
ce_staticexplorer, ce_miniexplorer, ce_libman, ce_libmaneditor, ce_customtools,
- ce_observer, ce_writableComponent, ce_toolseditor;
+ ce_observer, ce_writableComponent, ce_toolseditor, ce_procinput;
type
@@ -60,6 +60,7 @@ type
actEdUnIndent: TAction;
Actions: TActionList;
ApplicationProperties1: TApplicationProperties;
+ OutputTimer: TIdleTimer;
imgList: TImageList;
mainMenu: TMainMenu;
MenuItem1: TMenuItem;
@@ -170,6 +171,7 @@ type
var CanShow: Boolean; var HintInfo: THintInfo);
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
+ procedure OutputTimerTimer(Sender: TObject);
private
fDoc: TCESynMemo;
@@ -189,8 +191,11 @@ type
fProjMru: TMruFileList;
fFileMru: TMruFileList;
fLibMan: TLibraryManager;
+ fPrInpWidg: TCEProcInputWidget;
fTools: TCETools;
+ fRunProc: TProcess;// TAsyncProcess;
+
// ICEMultiDocObserver
procedure docNew(const aDoc: TCESynMemo);
procedure docClosing(const aDoc: TCESynMemo);
@@ -224,12 +229,14 @@ type
procedure LoadDocking;
procedure SaveDocking;
procedure KillPlugs;
+ procedure FreeRunnableProc;
// widget interfaces subroutines
procedure checkWidgetActions(const aWidget: TCEWidget);
procedure widgetShowFromAction(sender: TObject);
// run & exec sub routines
+ procedure asyncprocOutput(sender: TObject);
procedure ProcessOutputToMsg(const aProcess: TProcess;aCtxt: TMessageContext = mcUnknown);
procedure compileAndRunFile(const edIndex: NativeInt; const runArgs: string = '');
procedure compileProject(const aProject: TCEProject);
@@ -457,6 +464,7 @@ begin
fExplWidg := TCEMiniExplorerWidget.create(self);
fLibMWidg := TCELibManEditorWidget.create(self);
fTlsEdWidg:= TCEToolsEditorWidget.create(self);
+ fPrInpWidg:= TCEProcInputWidget.create(self);
fWidgList.addWidget(@fMesgWidg);
fWidgList.addWidget(@fEditWidg);
@@ -467,6 +475,7 @@ begin
fWidgList.addWidget(@fExplWidg);
fWidgList.addWidget(@fLibMWidg);
fWidgList.addWidget(@fTlsEdWidg);
+ fWidgList.addWidget(@fPrInpWidg);
for widg in fWidgList do
begin
@@ -661,6 +670,21 @@ begin
fPlugList.Free;
end;
+procedure TCEMainForm.FreeRunnableProc;
+var
+ fname: string;
+begin
+ if fRunProc = nil then
+ exit;
+ //
+ fname := fRunProc.Executable;
+ fRunProc.Terminate(0);
+ fRunProc.Free;
+ fRunProc := nil;
+ if fileExists(fname) then
+ sysutils.DeleteFile(fname);
+end;
+
destructor TCEMainForm.destroy;
begin
SaveSettings;
@@ -671,6 +695,7 @@ begin
fProjMru.Free;
fFileMru.Free;
fProject.Free;
+ FreeRunnableProc;
//
EntitiesConnector.removeObserver(self);
inherited;
@@ -1177,21 +1202,25 @@ var
dt: PMessageItemData;
i: NativeInt;
msg: string;
+ hasRead: boolean;
begin
If not (poUsePipes in aProcess.Options) then exit;
//
readCnt := 0;
+ readSz := 0;
+ hasRead := false;
ioBuffSz := aProcess.PipeBufferSize;
str := TMemorystream.Create;
lns := TStringList.Create;
- readSz := 0;
try
- repeat
- str.SetSize(readSz + ioBuffSz);
+ while aProcess.Output.NumBytesAvailable <> 0 do
+ begin
+ hasRead := true;
+ str.Size := str.Size + ioBuffSz;
readCnt := aProcess.Output.Read((str.Memory + readSz)^, ioBuffSz);
- Inc(readSz, readCnt);
- until readCnt = 0;
- Str.SetSize(readSz);
+ readSz += readCnt;
+ end;
+ str.Size := readSz;
lns.LoadFromStream(Str);
for i:= 0 to lns.Count-1 do begin
msg := lns.Strings[i];
@@ -1209,19 +1238,36 @@ begin
finally
str.Free;
lns.Free;
- fMesgWidg.scrollToBack;
+ if hasRead then
+ fMesgWidg.scrollToBack;
end;
end;
+procedure TCEMainForm.OutputTimerTimer(Sender: TObject);
+begin
+ if fRunProc <> nil then
+ ProcessOutputToMsg(fRunProc, mcEditor);
+end;
+
+procedure TCEMainForm.asyncprocOutput(sender: TObject);
+begin
+ //ProcessOutputToMsg(TAsyncProcess(sender), mcEditor);
+end;
+
procedure TCEMainForm.compileAndRunFile(const edIndex: NativeInt; const runArgs: string = '');
var
editor: TCESynMemo;
dmdproc: TProcess;
- runproc: TProcess;
+ //runproc: TProcess;
fname: string;
begin
+
+ FreeRunnableProc;
+ fRunProc := TProcess.Create(nil);
+ //fRunProc := TAsyncProcess.Create(nil);
+ //fRunProc.OnReadData := @asyncprocOutput;
+
dmdproc := TProcess.Create(nil);
- runproc := TProcess.Create(nil);
editor := fEditWidg.editor[edIndex];
try
@@ -1250,13 +1296,17 @@ begin
begin
ProcessOutputToMsg(dmdproc, mcEditor);
fMesgWidg.addCeInf(editor.fileName + ' successfully compiled', mcEditor );
- runproc.Options := [poStderrToOutPut, poUsePipes];
- runproc.CurrentDirectory := extractFilePath(runProc.Executable);
- runproc.Parameters.DelimitedText := expandSymbolicString(runArgs);
- runproc.Executable := fname + exeExt;
- runproc.Execute;
- repeat ProcessOutputToMsg(runproc, mcEditor) until not runproc.Running;
- sysutils.DeleteFile(fname + exeExt);
+ fRunProc.Options := fRunProc.Options + [poStderrToOutPut, poUsePipes];
+ fRunProc.CurrentDirectory := extractFilePath(fRunProc.Executable);
+ fRunProc.Parameters.DelimitedText := expandSymbolicString(runArgs);
+ fRunProc.Executable := fname + exeExt;
+ fPrInpWidg.process := fRunProc;
+ fRunProc.Execute;
+
+ //ProcessOutputToMsg(fRunProc, mcEditor);
+
+ //repeat ProcessOutputToMsg(runproc, mcEditor) until not runproc.Running;
+ //sysutils.DeleteFile(fname + exeExt);
sysutils.DeleteFile(fname + objExt);
end
else begin
@@ -1264,9 +1314,11 @@ begin
fMesgWidg.addCeErr(editor.fileName + ' has not been compiled', mcEditor );
end;
+ //fPrInpWidg.process := nil;
+
finally
dmdproc.Free;
- runproc.Free;
+ //runproc.Free;
end;
end;
diff --git a/src/ce_procinput.lfm b/src/ce_procinput.lfm
new file mode 100644
index 00000000..69eeb5db
--- /dev/null
+++ b/src/ce_procinput.lfm
@@ -0,0 +1,59 @@
+inherited CEProcInputWidget: TCEProcInputWidget
+ Left = 1427
+ Height = 61
+ Top = 335
+ Width = 481
+ Caption = 'Process input'
+ ClientHeight = 61
+ ClientWidth = 481
+ inherited Back: TPanel
+ Height = 61
+ Width = 481
+ ClientHeight = 61
+ ClientWidth = 481
+ inherited Content: TPanel
+ Height = 61
+ Width = 481
+ ClientHeight = 61
+ ClientWidth = 481
+ object txtInp: TEdit[0]
+ Left = 4
+ Height = 27
+ Top = 30
+ Width = 394
+ Align = alClient
+ BorderSpacing.Left = 4
+ BorderSpacing.Top = 2
+ BorderSpacing.Right = 4
+ BorderSpacing.Bottom = 4
+ OnKeyPress = txtInpKeyPress
+ TabOrder = 0
+ end
+ object btnSend: TButton[1]
+ Left = 402
+ Height = 27
+ Top = 30
+ Width = 75
+ Align = alRight
+ BorderSpacing.Top = 2
+ BorderSpacing.Right = 4
+ BorderSpacing.Bottom = 4
+ Caption = 'Send'
+ OnClick = btnSendClick
+ TabOrder = 1
+ end
+ object txtExeName: TStaticText[2]
+ Left = 4
+ Height = 22
+ Top = 4
+ Width = 473
+ Align = alTop
+ BorderSpacing.Around = 4
+ BorderStyle = sbsSunken
+ Caption = 'no process'
+ TabOrder = 2
+ Transparent = False
+ end
+ end
+ end
+end
diff --git a/src/ce_procinput.pas b/src/ce_procinput.pas
new file mode 100644
index 00000000..1723dbca
--- /dev/null
+++ b/src/ce_procinput.pas
@@ -0,0 +1,71 @@
+unit ce_procinput;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+ Menus, StdCtrls, ce_widget, process, ce_common;
+
+type
+
+ { TCEProcInputWidget }
+ TCEProcInputWidget = class(TCEWidget)
+ btnSend: TButton;
+ txtInp: TEdit;
+ txtExeName: TStaticText;
+ procedure btnSendClick(Sender: TObject);
+ procedure txtInpKeyPress(Sender: TObject; var Key: char);
+ private
+ fProc: TProcess;
+ procedure sendInput;
+ procedure setProc(const aValue: TProcess);
+ public
+ property process: TProcess read fProc write setProc;
+ end;
+
+implementation
+{$R *.lfm}
+
+procedure TCEProcInputWidget.setProc(const aValue: TProcess);
+begin
+ txtExeName.Caption := 'no process';
+ fProc := nil;
+ if aValue = nil then
+ exit;
+ if not (poUsePipes in aValue.Options) then
+ exit;
+ fProc := aValue;
+ txtExeName.Caption := shortenPath(fProc.Executable);
+end;
+
+procedure TCEProcInputWidget.sendInput;
+var
+ inp: string;
+begin
+ inp := txtInp.Text + lineEnding;
+ fProc.Input.Write(inp[1], length(inp));
+ txtInp.Text := '';
+end;
+
+procedure TCEProcInputWidget.txtInpKeyPress(Sender: TObject; var Key: char);
+begin
+ if fProc = nil then
+ exit;
+ if key <> lineEnding[1] then
+ exit;
+ sendInput;
+end;
+
+procedure TCEProcInputWidget.btnSendClick(Sender: TObject);
+begin
+ if fProc = nil then
+ exit;
+ sendInput;
+end;
+
+
+
+end.
+