public async Task EvaluateAsync( string input, CancellationToken cancellationToken = default(CancellationToken)) { if (!CanEvaluate || string.IsNullOrWhiteSpace(input)) { return; } using (InhibitEvaluate()) { if (!CodeCells.TryGetValue( WorkbookPage?.Contents?.GetLastCell <CodeCell> ()?.View?.Editor, out var codeCell) || codeCell.Cell.Buffer.Length > 0) { codeCell = StartNewCodeCell(); } codeCell.Cell.Buffer.Value = input; // TODO: Set Mac document dirty switch (await CoreEvaluateCodeCellAsync(codeCell, cancellationToken)) { case EvaluationStatus.ErrorDiagnostic: case EvaluationStatus.Disconnected: break; default: StartNewCodeCell(); break; } } }
CodeCellId GetCodeCellId(CodeCell codeCell) { if (codeCell?.View?.Editor != null && CodeCells.TryGetValue(codeCell.View.Editor, out CodeCellState codeCellState)) { return(codeCellState.CodeCellId); } return(null); }
public async Task EvaluateAllAsync(CancellationToken cancellationToken = default) { var firstCell = WorkbookPage.Contents.GetFirstCell <CodeCell> (); if (firstCell?.View?.Editor == null) { return; } if (CodeCells.TryGetValue(firstCell.View.Editor, out var codeCellState)) { await EvaluateCodeCellAsync(codeCellState, evaluateAll : true); } }
void PopulateCompilationWorkspace() { DocumentId previousDocumentId = null; foreach (var codeCell in WorkbookPage.Contents.OfType <CodeCell> ()) { var editor = codeCell?.View?.Editor; if (editor == null || !CodeCells.TryGetValue(editor, out var codeCellState)) { continue; } codeCellState.CompilationWorkspace = ClientSession.CompilationWorkspace; codeCellState.DocumentId = ClientSession.CompilationWorkspace.AddSubmission( codeCell.CodeAnalysisBuffer.CurrentText, previousDocumentId, null); previousDocumentId = codeCellState.DocumentId; } }
public Task <bool> AddTopLevelReferencesAsync( IReadOnlyList <string> references, CancellationToken cancellationToken = default) { // TODO: soo.....why are new #r's added after there are other cells not bringing in the reference right? if (references == null || references.Count == 0) { return(Task.FromResult(false)); } // TODO: Should we be saving a quick reference to the hidden cell/editor? var hiddenCellState = CodeCells .Where(p => p.Key is HiddenCodeCellEditor) .Select(p => p.Value) .FirstOrDefault(); if (hiddenCellState == null) { hiddenCellState = InsertHiddenCell(); } // TODO: Prevent dupes. Return false if no changes made var builder = new StringBuilder(hiddenCellState.Cell.Buffer.Value); foreach (var reference in references) { if (builder.Length > 0) { //builder.AppendLine (); builder.Append("\n"); } builder .Append("#r \"") .Append(reference) .Append("\""); } hiddenCellState.Cell.Buffer.Value = builder.ToString(); return(Task.FromResult(true)); }
void PopulateCompilationWorkspace() { CodeCellId previousDocumentId = null; foreach (var codeCell in WorkbookPage.Contents.OfType <CodeCell> ()) { var editor = codeCell?.View?.Editor; if (editor == null || !CodeCells.TryGetValue(editor, out var codeCellState)) { continue; } codeCellState.BindToWorkspace( ClientSession.CompilationWorkspace, ClientSession.CompilationWorkspace.InsertCell( codeCell.Buffer.Value, previousDocumentId, null)); previousDocumentId = codeCellState.CodeCellId; } }
void HandleEditorEvent(EditorEvent evnt) { CodeCells.TryGetValue(evnt.Source, out var sourceCodeCellState); switch (evnt) { case EvaluateCodeCellEvent _: EvaluateCodeCellAsync(sourceCodeCellState).Forget(); break; case InsertCellEvent <MarkdownCell> insertCellEvent: InsertOrFocusMarkdownCell(insertCellEvent.SourceCell); break; case InsertCellEvent <CodeCell> insertCellEvent: InsertCodeCell(insertCellEvent.SourceCell); break; case FocusEvent focusEvent: HandleFocusEvent(focusEvent, sourceCodeCellState); break; case FocusSiblingEditorEvent focusSiblingEditorEvent: HandleFocusSiblingEditor(focusSiblingEditorEvent); break; case NavigateReplHistoryEvent navigateReplHistoryEvent: HandleNavigateReplHistoryEvent(navigateReplHistoryEvent); break; case ChangeEvent _ when sourceCodeCellState != null && ClientSession.SessionKind == ClientSessionKind.Workbook: sourceCodeCellState.View.IsDirty = true; break; } }
// Only call this from EvaluateCodeCellAsync, for CanEvaluate handling async Task DoEvaluateCodeCellAsync(CodeCellState codeCellState, bool evaluateAll = false) { await ClientSession.EnsureAgentConnectionAsync(); var codeCellsToEvaluate = ImmutableList <CodeCellState> .Empty; var originalCodeCellState = codeCellState; if (ClientSession.ViewControllers.ReplHistory != null) { ClientSession.ViewControllers.ReplHistory.UpdateLastAppended( codeCellState.Cell.Buffer.Value.Trim()); ClientSession.ViewControllers.ReplHistory.Save(); } var codeCell = originalCodeCellState.Cell; var isLastCell = codeCell.GetNextCell <CodeCell> () == null; var isFirstCell = codeCell.GetPreviousCell <CodeCell> () == null; if (isFirstCell && ClientSession.SessionKind == ClientSessionKind.Workbook) { await ClientSession.Agent.Api.EvaluationContextManager.ResetStateAsync( TargetCompilationConfiguration.EvaluationContextId); } while (codeCell != null) { if (CodeCells.TryGetValue(codeCell.View.Editor, out codeCellState)) { var evaluateCodeCell = codeCellState == originalCodeCellState || codeCellState.EvaluationCount == 0 || codeCellState.View.IsDirty || codeCellState.View.IsOutdated; if (await ClientSession.CompilationWorkspace.IsCellOutdatedAsync(codeCellState.CodeCellId)) { evaluateCodeCell = true; } if (evaluateCodeCell) { codeCellsToEvaluate = codeCellsToEvaluate.Insert(0, codeCellState); } } codeCell = codeCell.GetPreviousCell <CodeCell> (); } codeCell = originalCodeCellState.Cell; var skipRemainingCodeCells = false; while (true) { codeCell = codeCell.GetNextCell <CodeCell> (); if (codeCell == null) { break; } if (CodeCells.TryGetValue(codeCell.View.Editor, out codeCellState)) { if (skipRemainingCodeCells || codeCellState.AgentTerminatedWhileEvaluating) { skipRemainingCodeCells = true; } else if (evaluateAll || codeCellState.EvaluationCount > 0) { codeCellsToEvaluate = codeCellsToEvaluate.Add(codeCellState); } codeCellState.View.IsOutdated = true; } } foreach (var evaluatableCodeCell in codeCellsToEvaluate) { evaluatableCodeCell.View.Reset(); evaluatableCodeCell.View.IsEvaluating = true; switch (await CoreEvaluateCodeCellAsync(evaluatableCodeCell)) { case EvaluationStatus.ErrorDiagnostic: case EvaluationStatus.Disconnected: return; } } if (isLastCell && !evaluateAll) { StartNewCodeCell(); } // NOTE: I cannot remember why this has to be run after awaiting // CoreEvaluateCodeCellAsync but it does... so don't move it? -abock if (ClientSession.ViewControllers.ReplHistory != null) { ClientSession.ViewControllers.ReplHistory.CursorToEnd(); ClientSession.ViewControllers.ReplHistory.Append(null); } }