@@ -171,6 +171,48 @@ let determineFsiPath () =
171171else
172172 raise( SessionError( VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath))
173173
174+ let readLinesAsync ( reader : System.IO.StreamReader ): IEvent < string > =
175+ let newLine = Event<_>()
176+ let buffer = System.Text.StringBuilder( 1024 )
177+ let byteBuffer = Array.zeroCreate128
178+ let encoding = System.Text.Encoding.UTF8
179+ let decoder = encoding.GetDecoder()
180+ let async0 = async.Return0
181+ let charBuffer =
182+ let maxCharsInBuffer = encoding.GetMaxCharCount byteBuffer.Length
183+ Array.zeroCreate maxCharsInBuffer
184+
185+ let rec findLinesInBuffer pos =
186+ if pos>= buffer.Lengththen max( buffer.Length- 1 ) 0 // exit and point to the last char
187+ else
188+ let c = buffer.[ pos]
189+ if c= '\r' || c= '\n' then
190+ let line = buffer.ToString( 0 , pos)
191+ newLine.Trigger line
192+
193+ let deletePos =
194+ if c= '\r' && ( pos+ 1 ) < buffer.Length&& buffer.[ pos+ 1 ] = '\n' then pos+ 2 else pos+ 1
195+ buffer.Remove( 0 , deletePos) |> ignore
196+ findLinesInBuffer0
197+ else
198+ findLinesInBuffer( pos+ 1 )
199+
200+ let rec read pos =
201+ async {
202+ let! bytesRead =
203+ try
204+ reader.BaseStream.AsyncRead( byteBuffer, 0 , byteBuffer.Length)
205+ with
206+ | : ? IOException -> async0
207+ if bytesRead<> 0 then
208+ let charsRead = decoder.GetChars( byteBuffer, 0 , bytesRead, charBuffer, 0 )
209+ buffer.Append( charBuffer, 0 , charsRead) |> ignore
210+ let newPos = findLinesInBuffer pos
211+ return ! read newPos
212+ }
213+ Async.StartImmediate( read0 )
214+ newLine.Publish
215+
174216let fsiStartInfo channelName =
175217let procInfo = new ProcessStartInfo()
176218let fsiPath = determineFsiPath()
@@ -208,16 +250,13 @@ let fsiProcess (procInfo:ProcessStartInfo) =
208250let outW , outE = let e = new Event<_>() in e.Trigger, e.Publish
209251let errW , errE = let e = new Event<_>() in e.Trigger, e.Publish
210252let exitE = ( cmdProcess.Exited|> Observable.map( fun x -> x)) // this gives the event the F# "standard" event type IEvent<'a> rather than IEvent<_,_>
211-
212- // wire up output (to both stdout and stderr)
213- cmdProcess.OutputDataReceived|> catchAll|> Observable.add( fun data ->
214- //System.Windows.Forms.MessageBox.Show (sprintf "OutputDataRecieved '%s'\n" data.Data) |> ignore
215- outW( data.Data));
216- cmdProcess.ErrorDataReceived|> catchAll|> Observable.add( fun data -> errW( data.Data));
217253
218254let _ = cmdProcess.Start()
219- cmdProcess.BeginOutputReadLine();
220- cmdProcess.BeginErrorReadLine();
255+ // wire up output (to both stdout and stderr)
256+ readLinesAsync cmdProcess.StandardOutput|> catchAll|> Observable.add( fun data ->
257+ //System.Windows.Forms.MessageBox.Show (sprintf "OutputDataRecieved '%s'\n" data.Data) |> ignore
258+ outW( data));
259+ readLinesAsync cmdProcess.StandardError|> catchAll|> Observable.add( fun data -> errW( data));
221260
222261// wire up input
223262// Fix 982: Force input to be written in UTF8 regardless of the apparent encoding.