/// <summary> /// Rearange offsets according to registered changed. Return true, if change was inside this element. /// NOTE: Removing is handled in checkChildren, here are checked only inside changes. /// </summary> /// <param name="change">The change.</param> /// <returns><c>true</c> if change was inside element, <c>false</c> otherwise.</returns> private bool rearangeOffsets(LineChange change) { // return shorting(change.Start, change.End, change.Shortening); int sh = change.Shortening; int curStart = change.Start; //cur position before/after change - is same int curEndAft = change.End; int curEndBef = curEndAft - change.Shortening; if (End < curStart) { return(false); //change start after ending } bool changed = End >= curStart && Start <= curStart; if (Start > curStart) { Start -= sh; } if (End > curStart) { End -= sh; } return(changed); }
/// <summary> /// Apply position changes and return list of changed descendants /// Element is changed, if no its children wrap whole change. /// </summary> /// <param name="change">The change.</param> /// <param name="result">The result.</param> /// <returns>List<ElementChange>.</returns> internal List <ElementChange> ApplyEdit(LineChange change, List <ElementChange> result = null) { if (result == null) { result = new List <ElementChange>(); } // if change was inside this element, try to delegate change on some child bool needFullMatch = !IsRoot && rearangeOffsets(change); foreach (var child in _children.Values) { child.ApplyEdit(change, result); if (needFullMatch) { if (child.Start <= change.Start && child.End >= change.End) { needFullMatch = false; //this child contains whole change } } } if (needFullMatch) { result.Add(new ElementChange(this, ChangeKind.Changed)); } return(result); }
/// <summary> /// Register <see cref="LineChange" /> that has been made within watched project. /// </summary> /// <param name="change">Registered change.</param> internal void RegisterChange(LineChange change) { FileItemManager fileManager; if (!_watchedItems.TryGetValue(change.Item, out fileManager)) { //requested manager is not registered yet fileManager = registerItem(change.Item, null); } if (fileManager == null) { //there is no availabe manager for requested change return; } if (change.DocumentLength >= 0) { //force checking fileManager.LineChanged(change); } //changes are fired lazily _changedFileManagers.Add(fileManager); }
/// <summary> /// Handler called whenever line of some file is changed. /// </summary> /// <param name="startPoint">Start point of change.</param> /// <param name="endPoint">End point of change.</param> /// <param name="hint">Hint determining type of change.</param> private void onLineChanged(TextPoint startPoint, TextPoint endPoint, int hint) { //reset change flushing timer _changeWait.Stop(); _changeWait.Start(); //represent opened editor window var textDocument = startPoint.Parent; if (textDocument == null) { //there is no available editor window return; } //document assigned to edited source code var changedDocument = textDocument.Parent; if (changedDocument == null) { //there is no available document return; } var changeStart = startPoint.AbsoluteCharOffset; var changeEnd = endPoint.AbsoluteCharOffset; //in debug mode is relativly slow var documentLength = textDocument.EndPoint.AbsoluteCharOffset; LogEntry entry = null; try { if (_dte.Solution.SolutionBuild.BuildState == vsBuildState.vsBuildStateInProgress) { //no changes can be done during building return; } if (changedDocument.FullName != "") { var change = new LineChange(changedDocument, documentLength, changeStart, changeEnd); _changes.Add(change); HasWaitingChanges = true; } return; } catch (COMException ex) { entry = new LogEntry(LogLevels.Error, "Line change handler throws COMException", ex.ToString(), null); } catch (ArgumentException ex) { entry = new LogEntry(LogLevels.Notification, "Line change handler throws ArgumentException", ex.ToString(), null); } Log.Entry(entry); }
/// <summary> /// modify wrapped element tree according to line change. /// </summary> /// <param name="change">The change.</param> internal void LineChanged(LineChange change) { var shortening = _docLength - change.DocumentLength; _docLength = change.DocumentLength; change.Shortening = shortening; registerChanges(Root.ApplyEdit(change)); }