void InsertWithCursorOnLayer(EditorScript currentScript, InsertionCursorLayer layer, TaskCompletionSource <Script> tcs, IList <AstNode> nodes, IDocument target)
        {
            var doc = target as TextDocument;
            var op  = new UndoOperation(layer, tcs);

            if (doc != null)
            {
                doc.UndoStack.Push(op);
            }
            layer.ScrollToInsertionPoint();
            layer.Exited += delegate(object s, InsertionCursorEventArgs args) {
                doc.UndoStack.StartContinuedUndoGroup();
                try {
                    if (args.Success)
                    {
                        if (args.InsertionPoint.LineAfter == NewLineInsertion.None &&
                            args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1)
                        {
                            args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine;
                        }

                        int offset      = currentScript.GetCurrentOffset(args.InsertionPoint.Location);
                        int indentLevel = currentScript.GetIndentLevelAt(offset);

                        foreach (var node in nodes.Reverse())
                        {
                            var output = currentScript.OutputNode(indentLevel, node);
                            int delta  = args.InsertionPoint.Insert(target, output.Text);
                            output.RegisterTrackedSegments(currentScript, delta + offset);
                        }
                        currentScript.FormatText(nodes);
                        tcs.SetResult(currentScript);
                    }
                    layer.Dispose();
                    DisposeOnClose();
                } finally {
                    doc.UndoStack.EndUndoGroup();
                }
                op.Reset();
            };
        }
Example #2
0
 public void Reset()
 {
     layer = null;
     tcs   = null;
 }
Example #3
0
 public UndoOperation(InsertionCursorLayer layer, TaskCompletionSource <Script> tcs)
 {
     this.layer = layer;
     this.tcs   = tcs;
 }
Example #4
0
        public override Task <Script> InsertWithCursor(string operation, ITypeDefinition parentType, Func <Script, RefactoringContext, IList <AstNode> > nodeCallback)
        {
            // TODO : Use undo group
            var tcs = new TaskCompletionSource <Script>();

            if (parentType == null)
            {
                return(tcs.Task);
            }
            IUnresolvedTypeDefinition part = null;

            foreach (var p in parentType.Parts)
            {
                if (part == null || EntityModelContextUtils.IsBetterPart(p, part, ".cs"))
                {
                    part = p;
                }
            }

            if (part == null)
            {
                return(tcs.Task);
            }

            var          fileName = new ICSharpCode.Core.FileName(part.Region.FileName);
            IViewContent document = SD.FileService.OpenFile(fileName);
            var          area     = document.GetService <TextArea>();

            if (area == null)
            {
                return(tcs.Task);
            }

            var          loc           = part.Region.Begin;
            var          parsedFile    = SD.ParserService.ParseFile(fileName, area.Document, cancellationToken: context.CancellationToken);
            var          declaringType = parsedFile.GetInnermostTypeDefinition(loc);
            EditorScript script;

            if (area.Document != context.Document)
            {
                script = new EditorScript(area.GetService <ITextEditor>(), SDRefactoringContext.Create(fileName, area.Document, loc, context.CancellationToken), FormattingOptions);
                startedScripts.Add(script);
            }
            else
            {
                script = this;
            }
            var nodes           = nodeCallback(script, script.context);
            var insertionPoints = InsertionPoint.GetInsertionPoints(area.Document, part);

            if (insertionPoints.Count == 0)
            {
                SD.MessageService.ShowErrorFormatted("No valid insertion point can be found in type '{0}'.", part.Name);
                return(tcs.Task);
            }

            var layer = new InsertionCursorLayer(area, operation, insertionPoints);

            area.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)area.TextView.InvalidateVisual);

            if (declaringType.Kind == TypeKind.Enum)
            {
                foreach (var node in nodes.Reverse())
                {
                    int indentLevel = GetIndentLevelAt(area.Document.GetOffset(declaringType.BodyRegion.Begin));
                    var output      = OutputNode(indentLevel, node);
                    var point       = insertionPoints[0];
                    var offset      = area.Document.GetOffset(point.Location);
                    var text        = output.Text + ",";
                    var delta       = point.Insert(area.Document, text);
                    output.RegisterTrackedSegments(script, delta + offset);
                }
                tcs.SetResult(script);
                return(tcs.Task);
            }
            InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document);
            return(tcs.Task);
        }
Example #5
0
        void InsertWithCursorOnLayer(EditorScript currentScript, InsertionCursorLayer layer, TaskCompletionSource <Script> tcs, IList <AstNode> nodes, IDocument target)
        {
            var doc = target as TextDocument;
            var op  = new UndoOperation(layer, tcs);

            if (doc != null)
            {
                doc.UndoStack.Push(op);
            }
            layer.ScrollToInsertionPoint();
            layer.Exited += delegate(object s, InsertionCursorEventArgs args) {
                doc.UndoStack.StartContinuedUndoGroup();
                try {
                    if (args.Success)
                    {
                        if (args.InsertionPoint.LineAfter == NewLineInsertion.None &&
                            args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1)
                        {
                            args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine;
                        }

                        var insertionPoint = args.InsertionPoint;
                        if (nodes.All(n => n is EnumMemberDeclaration))
                        {
                            insertionPoint.LineAfter  = NewLineInsertion.Eol;
                            insertionPoint.LineBefore = NewLineInsertion.None;
                        }

                        int offset      = currentScript.GetCurrentOffset(insertionPoint.Location);
                        int indentLevel = currentScript.GetIndentLevelAt(Math.Max(0, offset - 1));

                        foreach (var node in nodes.Reverse())
                        {
                            var output = currentScript.OutputNode(indentLevel, node);
                            var text   = output.Text;
                            if (node is EnumMemberDeclaration)
                            {
                                if (insertionPoint != layer.InsertionPoints.Last())
                                {
                                    text += ",";
                                }
                                else
                                {
                                    var parentEnum = currentScript.context.RootNode.GetNodeAt(insertionPoint.Location, n => (n is TypeDeclaration) && ((TypeDeclaration)n).ClassType == ClassType.Enum) as TypeDeclaration;
                                    if (parentEnum != null)
                                    {
                                        var lastMember = parentEnum.Members.LastOrDefault();
                                        if (lastMember != null)
                                        {
                                            var segment = currentScript.GetSegment(lastMember);
                                            currentScript.InsertText(segment.EndOffset, ",");
                                        }
                                    }
                                }
                            }
                            int delta = insertionPoint.Insert(target, text);
                            output.RegisterTrackedSegments(currentScript, delta + offset);
                        }
                        currentScript.FormatText(nodes);
                        tcs.SetResult(currentScript);
                    }
                    layer.Dispose();
                    DisposeOnClose();
                } finally {
                    doc.UndoStack.EndUndoGroup();
                }
                op.Reset();
            };
        }
Example #6
0
		public override Task<Script> InsertWithCursor(string operation, InsertPosition defaultPosition, IList<AstNode> nodes)
		{
			// TODO : Use undo group
			var tcs = new TaskCompletionSource<Script>();
			var loc = editor.Caret.Location;
			var currentPart = context.UnresolvedFile.GetInnermostTypeDefinition(loc);
			var insertionPoints = InsertionPoint.GetInsertionPoints(editor.Document, currentPart);
			
			if (insertionPoints.Count == 0) {
				SD.MessageService.ShowErrorFormatted("No valid insertion point can be found in type '{0}'.", currentPart.Name);
				return tcs.Task;
			}
			
			TextArea area = editor.GetService<TextArea>();
			if (area == null) return tcs.Task;
			
			var layer = new InsertionCursorLayer(area, operation, insertionPoints);
			
			switch (defaultPosition) {
				case InsertPosition.Start:
					layer.CurrentInsertionPoint = 0;
					break;
				case InsertPosition.End:
					layer.CurrentInsertionPoint = insertionPoints.Count - 1;
					break;
				case InsertPosition.Before:
					for (int i = 0; i < insertionPoints.Count; i++) {
						if (insertionPoints[i].Location < loc)
							layer.CurrentInsertionPoint = i;
					}
					break;
				case InsertPosition.After:
					for (int i = 0; i < insertionPoints.Count; i++) {
						if (insertionPoints[i].Location > loc) {
							layer.CurrentInsertionPoint = i;
							break;
						}
					}
					break;
			}
			InsertWithCursorOnLayer(this, layer, tcs, nodes, editor.Document);
			return tcs.Task;
		}
Example #7
0
			internal InputHandler(InsertionCursorLayer layer)
				: base(layer.editor)
			{
				this.layer = layer;
				AddBinding(EditingCommands.MoveDownByLine, ModifierKeys.None, Key.Down, MoveMarker(false));
				AddBinding(EditingCommands.MoveUpByLine, ModifierKeys.None, Key.Up, MoveMarker(true));
				AddBinding(EditingCommands.EnterParagraphBreak, ModifierKeys.None, Key.Enter, layer.InsertCode);
				AddBinding(ExitCommand, ModifierKeys.None, Key.Escape, layer.Cancel);
			}
Example #8
0
			public void Undo()
			{
				if (layer != null)
					layer.Dispose();
				layer = null;
				if (tcs != null)
					tcs.SetCanceled();
				tcs = null;
			}
Example #9
0
			public void Reset()
			{
				layer = null;
				tcs = null;
			}
Example #10
0
			public UndoOperation(InsertionCursorLayer layer, TaskCompletionSource<Script> tcs)
			{
				this.layer = layer;
				this.tcs = tcs;
			}
Example #11
0
		public override Task<Script> InsertWithCursor(string operation, ITypeDefinition parentType, Func<Script, RefactoringContext, IList<AstNode>> nodeCallback)
		{
			// TODO : Use undo group
			var tcs = new TaskCompletionSource<Script>();
			if (parentType == null)
				return tcs.Task;
			var part = parentType.Parts.FirstOrDefault ();
			if (part == null)
				return tcs.Task;
			
			var fileName = new ICSharpCode.Core.FileName(part.Region.FileName);
			IViewContent document = SD.FileService.OpenFile(fileName);
			var area = document.GetService<TextArea>();
			
			if (area == null) return tcs.Task;
			
			var loc = part.Region.Begin;
			var parsedFile = SD.ParserService.ParseFile(fileName, area.Document, cancellationToken: context.CancellationToken);
			var declaringType = parsedFile.GetInnermostTypeDefinition(loc);
			EditorScript script;

			if (area.Document != context.Document) {
				script = new EditorScript(area.GetService<ITextEditor>(), SDRefactoringContext.Create(fileName, area.Document, loc, context.CancellationToken), FormattingOptions);
				startedScripts.Add(script);
			} else {
				script = this;
			}
			var nodes = nodeCallback (script, script.context);
			var insertionPoints = InsertionPoint.GetInsertionPoints(area.Document, part);
			
			if (insertionPoints.Count == 0) {
				SD.MessageService.ShowErrorFormatted("No valid insertion point can be found in type '{0}'.", part.Name);
				return tcs.Task;
			}
			
			var layer = new InsertionCursorLayer(area, operation, insertionPoints);
			area.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)area.TextView.InvalidateVisual);
			
			if (declaringType.Kind == TypeKind.Enum) {
				foreach (var node in nodes.Reverse()) {
					int indentLevel = GetIndentLevelAt(area.Document.GetOffset(declaringType.BodyRegion.Begin));
					var output = OutputNode(indentLevel, node);
					var point = insertionPoints[0];
					var offset = area.Document.GetOffset(point.Location);
					var text = output.Text + ",";
					var delta = point.Insert(area.Document, text);
					output.RegisterTrackedSegments(script, delta + offset);
				}
				tcs.SetResult(script);
				return tcs.Task;
			}
			InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document);
			return tcs.Task;
		}
Example #12
0
		void InsertWithCursorOnLayer(EditorScript currentScript, InsertionCursorLayer layer, TaskCompletionSource<Script> tcs, IList<AstNode> nodes, IDocument target)
		{
			var doc = target as TextDocument;
			var op = new UndoOperation(layer, tcs);
			if (doc != null) {
				doc.UndoStack.Push(op);
			}
			layer.Exited += delegate(object s, InsertionCursorEventArgs args) {
				doc.UndoStack.StartContinuedUndoGroup();
				try {
					if (args.Success) {
						if (args.InsertionPoint.LineAfter == NewLineInsertion.None &&
						    args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1) {
							args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine;
						}
						foreach (var node in nodes.Reverse ()) {
							int indentLevel = currentScript.GetIndentLevelAt(target.GetOffset(args.InsertionPoint.Location));
							var output = currentScript.OutputNode(indentLevel, node);
							var offset = target.GetOffset(args.InsertionPoint.Location);
							var delta = args.InsertionPoint.Insert(target, output.Text);
							output.RegisterTrackedSegments(currentScript, delta + offset);
						}
						tcs.SetResult(currentScript);
					}
					layer.Dispose();
					DisposeOnClose();
				} finally {
					doc.UndoStack.EndUndoGroup();
				}
				op.Reset();
			};
		}
Example #13
0
		void InsertWithCursorOnLayer(EditorScript currentScript, InsertionCursorLayer layer, TaskCompletionSource<Script> tcs, IList<AstNode> nodes, IDocument target)
		{
			layer.Exited += delegate(object s, InsertionCursorEventArgs args) {
				if (args.Success) {
					if (args.InsertionPoint.LineAfter == NewLineInsertion.None &&
					    args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1) {
						args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine;
					}
					foreach (var node in nodes.Reverse ()) {
						int indentLevel = currentScript.GetIndentLevelAt(target.GetOffset(args.InsertionPoint.Location));
						var output = currentScript.OutputNode(indentLevel, node);
						var offset = target.GetOffset(args.InsertionPoint.Location);
						var delta = args.InsertionPoint.Insert(target, output.Text);
						output.RegisterTrackedSegments(currentScript, delta + offset);
					}
					tcs.SetResult(currentScript);
				}
				layer.Dispose();
				DisposeOnClose();
			};
		}
Example #14
0
		public override Task<Script> InsertWithCursor(string operation, ITypeDefinition parentType, Func<Script, RefactoringContext, IList<AstNode>> nodeCallback)
		{
			// TODO : Use undo group
			var tcs = new TaskCompletionSource<Script>();
			if (parentType == null)
				return tcs.Task;
			IUnresolvedTypeDefinition part = null;
			
			foreach (var p in parentType.Parts) {
				if (part == null || EntityModelContextUtils.IsBetterPart(p, part, ".cs"))
					part = p;
			}
			
			if (part == null)
				return tcs.Task;
			
			var fileName = new ICSharpCode.Core.FileName(part.Region.FileName);
			IViewContent document = SD.FileService.OpenFile(fileName);
			var area = document.GetService<TextArea>();
			
			if (area == null) return tcs.Task;
			
			var loc = part.Region.Begin;
			var parsedFile = SD.ParserService.ParseFile(fileName, area.Document, cancellationToken: context.CancellationToken);
			var declaringType = parsedFile.GetInnermostTypeDefinition(loc);
			EditorScript script;

			if (area.Document != context.Document) {
				script = new EditorScript(area.GetService<ITextEditor>(), SDRefactoringContext.Create(fileName, area.Document, loc, context.CancellationToken), FormattingOptions);
				startedScripts.Add(script);
			} else {
				script = this;
			}
			var nodes = nodeCallback (script, script.context);
			var insertionPoints = InsertionPoint.GetInsertionPoints(area.Document, part);
			
			if (insertionPoints.Count == 0) {
				SD.MessageService.ShowErrorFormatted("No valid insertion point can be found in type '{0}'.", part.Name);
				return tcs.Task;
			}
			
			var layer = new InsertionCursorLayer(area, operation, insertionPoints);
			area.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)area.TextView.InvalidateVisual);
			
			InsertWithCursorOnLayer(script, layer, tcs, nodes, area.Document);
			return tcs.Task;
		}
Example #15
0
		void InsertWithCursorOnLayer(EditorScript currentScript, InsertionCursorLayer layer, TaskCompletionSource<Script> tcs, IList<AstNode> nodes, IDocument target)
		{
			var doc = target as TextDocument;
			var op = new UndoOperation(layer, tcs);
			if (doc != null) {
				doc.UndoStack.Push(op);
			}
			layer.ScrollToInsertionPoint();
			layer.Exited += delegate(object s, InsertionCursorEventArgs args) {
				doc.UndoStack.StartContinuedUndoGroup();
				try {
					if (args.Success) {
						if (args.InsertionPoint.LineAfter == NewLineInsertion.None &&
						    args.InsertionPoint.LineBefore == NewLineInsertion.None && nodes.Count > 1) {
							args.InsertionPoint.LineAfter = NewLineInsertion.BlankLine;
						}
						
						var insertionPoint = args.InsertionPoint;
						if (nodes.All(n => n is EnumMemberDeclaration)) {
							insertionPoint.LineAfter = NewLineInsertion.Eol;
							insertionPoint.LineBefore = NewLineInsertion.None;
						}

						int offset = currentScript.GetCurrentOffset(insertionPoint.Location);
						int indentLevel = currentScript.GetIndentLevelAt(Math.Max(0, offset - 1));
						
						foreach (var node in nodes.Reverse()) {
							var output = currentScript.OutputNode(indentLevel, node);
							var text = output.Text;
							if (node is EnumMemberDeclaration) {
								if (insertionPoint != layer.InsertionPoints.Last()) {
									text += ",";
								} else {
									var parentEnum = currentScript.context.RootNode.GetNodeAt(insertionPoint.Location, n => (n is TypeDeclaration) && ((TypeDeclaration)n).ClassType == ClassType.Enum) as TypeDeclaration;
									if (parentEnum != null) {
										var lastMember = parentEnum.Members.LastOrDefault();
										if (lastMember != null) {
											var segment = currentScript.GetSegment(lastMember);
											currentScript.InsertText(segment.EndOffset, ",");
										}
									}
								}
							}
							int delta = insertionPoint.Insert(target, text);
							output.RegisterTrackedSegments(currentScript, delta + offset);
						}
						currentScript.FormatText(nodes);
						tcs.SetResult(currentScript);
					}
					layer.Dispose();
					DisposeOnClose();
				} finally {
					doc.UndoStack.EndUndoGroup();
				}
				op.Reset();
			};
		}