Example #1
0
		public TemplateResult FillVariables (TemplateContext context)
		{
			var expansion = CodeTemplateService.GetExpansionObject (this);
			var result = new TemplateResult ();
			var sb = new StringBuilder ();
			int lastOffset = 0;
			string code = context.Editor.FormatString (context.InsertPosition, context.TemplateCode);
			result.TextLinks = new List<TextLink> ();
			foreach (System.Text.RegularExpressions.Match match in variableRegEx.Matches (code)) {
				string name = match.Groups [1].Value;
				sb.Append (code.Substring (lastOffset, match.Index - lastOffset));
				lastOffset = match.Index + match.Length;
				if (string.IsNullOrEmpty (name)) { // $$ is interpreted as $
					sb.Append ("$");
				} else if (name == "end") {
					result.CaretEndOffset = sb.Length;
				} else if (name == "selected") {
					if (!string.IsNullOrEmpty (context.SelectedText)) {
						string indent = GetIndent (sb);
						string selection = Reindent (context.SelectedText, indent);
						sb.Append (selection);
					}
				}
				if (!variableDecarations.ContainsKey (name))
					continue;
				var link = result.TextLinks.Find (l => l.Name == name);
				bool isNew = link == null;
				if (isNew) {
					link = new TextLink (name);
					if (!string.IsNullOrEmpty (variableDecarations [name].ToolTip))
						link.Tooltip = GettextCatalog.GetString (variableDecarations [name].ToolTip);
					link.Values = new CodeTemplateListDataProvider (variableDecarations [name].Values);
					if (!string.IsNullOrEmpty (variableDecarations [name].Function)) {
						link.Values = expansion.RunFunction (context, null, variableDecarations [name].Function);
					}
					result.TextLinks.Add (link);
				}
				link.IsEditable = variableDecarations [name].IsEditable;
				link.IsIdentifier = variableDecarations [name].IsIdentifier;
				if (!string.IsNullOrEmpty (variableDecarations [name].Function)) {
					IListDataProvider<string > functionResult = expansion.RunFunction (context, null, variableDecarations [name].Function);
					if (functionResult != null && functionResult.Count > 0) {
						string s = (string)functionResult [functionResult.Count - 1];
						if (s == null) {
							if (variableDecarations.ContainsKey (name)) 
								s = variableDecarations [name].Default;
						}
						if (s != null) {
							link.AddLink (new TextSegment (sb.Length, s.Length));
							if (isNew) {
								link.GetStringFunc = delegate (Func<string, string> callback) {
									return expansion.RunFunction (context, callback, variableDecarations [name].Function);
								};
							}
							sb.Append (s);
						}
					} else {
						AddDefaultValue (sb, link, name);
					}
				} else {
					AddDefaultValue (sb, link, name);
				}
			}
			sb.Append (code.Substring (lastOffset, code.Length - lastOffset));
			
			// format & indent template code
			var data = TextEditorFactory.CreateNewDocument ();
			data.Text = sb.ToString ();
			data.TextChanged += delegate(object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) {
				int delta = e.InsertionLength - e.RemovalLength;

				foreach (var link in result.TextLinks) {
					link.Links = link.Links.AdjustSegments (e).ToList ();
				}
				if (result.CaretEndOffset > e.Offset)
					result.CaretEndOffset += delta;
			};

			IndentCode (data, context.LineIndent);
			result.Code = data.Text;
			return result;
		}
Example #2
0
		/// <summary>
		/// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
		/// </summary>
		public TemplateResult InsertTemplateContents (TextEditor editor, DocumentContext context)
		{
			var data = editor;
			
			int offset = data.CaretOffset;
//			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);
			
			var templateCtx = new TemplateContext {
				Template = this,
				DocumentContext = context,
				Editor = editor,
				//ParsedDocument = context.ParsedDocument != null ? context.ParsedDocument.ParsedFile : null,
				InsertPosition = data.CaretLocation,
				LineIndent = data.GetLineIndent (data.CaretLocation.Line),
				TemplateCode = Code
			};

			if (data.IsSomethingSelected) {
				int start = data.SelectionRange.Offset;
				while (Char.IsWhiteSpace (data.GetCharAt (start))) {
					start++;
				}
				int end = data.SelectionRange.EndOffset;
				while (Char.IsWhiteSpace (data.GetCharAt (end - 1))) {
					end--;
				}
				templateCtx.LineIndent = data.GetLineIndent (data.OffsetToLineNumber (start));
				templateCtx.SelectedText = RemoveIndent (data.GetTextBetween (start, end), templateCtx.LineIndent);
				data.RemoveText (start, end - start);
				offset = start;
			} else {
				string word = GetTemplateShortcutBeforeCaret (data).Trim ();
				if (word.Length > 0)
					offset = DeleteTemplateShortcutBeforeCaret (data);
			}
			
			TemplateResult template = FillVariables (templateCtx);
			template.InsertPosition = offset;
			editor.InsertText (offset, template.Code);
			
			int newoffset;
			if (template.CaretEndOffset >= 0) {
				newoffset = offset + template.CaretEndOffset; 
			} else {
				newoffset = offset + template.Code.Length; 
			}

			editor.CaretLocation = editor.OffsetToLocation (newoffset) ;

			var prettyPrinter = CodeFormatterService.GetFormatter (data.MimeType);
			if (prettyPrinter != null && prettyPrinter.SupportsOnTheFlyFormatting) {
				int endOffset = template.InsertPosition + template.Code.Length;
				var oldVersion = data.Version;
				prettyPrinter.OnTheFlyFormat (editor, context, TextSegment.FromBounds (template.InsertPosition, endOffset));
				foreach (var textLink in template.TextLinks) {
					for (int i = 0; i < textLink.Links.Count; i++) {
						var segment = textLink.Links [i];
						var translatedOffset = oldVersion.MoveOffsetTo (data.Version, template.InsertPosition + segment.Offset) - template.InsertPosition;
						textLink.Links [i] = new TextSegment (translatedOffset, segment.Length);
					}
				}
			}
			return template;
		}
		public virtual IListDataProvider<string> RunFunction (TemplateContext context, Func<string, string> callback, string function)
		{
			this.CurrentContext = context;
			Match match = functionRegEx.Match (function);
			if (!match.Success)
				return null;
			string name = match.Groups[1].Value;
			switch (name) {
			case "GetCollections":
				return GetCollections ();
			case "GetCurrentClassName":
				return new CodeTemplateListDataProvider (GetCurrentClassName ());
			case "GetConstructorModifier":
				return new CodeTemplateListDataProvider (GetConstructorModifier ());
				
			case "GetSimpleTypeName":
				return new CodeTemplateListDataProvider (GetSimpleTypeName (match.Groups[2].Value.Trim ('"')));
			case "GetLengthProperty":
				return new CodeTemplateListDataProvider (GetLengthProperty (callback, match.Groups == null || match.Groups.Count < 3 ? null : match.Groups[2].Value.Trim ('"')));
			case "GetComponentTypeOf":
				return new CodeTemplateListDataProvider (GetComponentTypeOf (callback, match.Groups[2].Value.Trim ('"')));
			}
			return null;
		}
Example #4
0
		/// <summary>
		/// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
		/// </summary>
		public TemplateResult InsertTemplateContents (MonoDevelop.Ide.Gui.Document document)
		{
			Mono.TextEditor.TextEditorData data = document.Editor;
			
			int offset = data.Caret.Offset;
//			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);
			
			var context = new TemplateContext {
				Template = this,
				Document = document,
				ParsedDocument = document.ParsedDocument.ParsedFile,
				InsertPosition = data.Caret.Location,
				LineIndent = data.Document.GetLineIndent (data.Caret.Line),
				TemplateCode = Code
			};

			if (data.IsSomethingSelected) {
				int start = data.SelectionRange.Offset;
				while (Char.IsWhiteSpace (data.Document.GetCharAt (start))) {
					start++;
				}
				int end = data.SelectionRange.EndOffset;
				while (Char.IsWhiteSpace (data.Document.GetCharAt (end - 1))) {
					end--;
				}
				context.LineIndent = data.Document.GetLineIndent (data.Document.OffsetToLineNumber (start));
				context.SelectedText = RemoveIndent (data.Document.GetTextBetween (start, end), context.LineIndent);
				data.Remove (start, end - start);
				offset = start;
			} else {
				string word = GetWordBeforeCaret (data).Trim ();
				if (word.Length > 0)
					offset = DeleteWordBeforeCaret (data);
			}
			
			TemplateResult template = FillVariables (context);
			template.InsertPosition = offset;
			document.Editor.Insert (offset, template.Code);
			
			int newoffset;
			if (template.CaretEndOffset >= 0) {
				newoffset = offset + template.CaretEndOffset; 
			} else {
				newoffset = offset + template.Code.Length; 
			}

			document.Editor.Caret.Location = document.Editor.OffsetToLocation (newoffset) ;
			
/*			if (PropertyService.Get ("OnTheFlyFormatting", false)) {
				string mt = DesktopService.GetMimeTypeForUri (document.FileName);
				var formatter = MonoDevelop.Ide.CodeFormatting.CodeFormatterService.GetFormatter (mt);
				if (formatter != null && formatter.SupportsOnTheFlyFormatting) {
					document.Editor.Document.BeginAtomicUndo ();
					formatter.OnTheFlyFormat (document.Project != null ? document.Project.Policies : null, 
						document.Editor, offset, offset + length);
					document.Editor.Document.EndAtomicUndo ();
				}
			}*/
			return template;
		}
Example #5
0
		public TemplateResult FillVariables (TemplateContext context)
		{
			ExpansionObject expansion = CodeTemplateService.GetExpansionObject (this);
			TemplateResult result = new TemplateResult ();
			StringBuilder sb = new StringBuilder ();
			int lastOffset = 0;
			string code = context.Document.Editor.FormatString (context.InsertPosition, context.TemplateCode);
			
			result.TextLinks = new List<TextLink> ();
			foreach (Match match in variableRegEx.Matches (code)) {
				string name = match.Groups[1].Value;
				sb.Append (code.Substring (lastOffset, match.Index - lastOffset));
				lastOffset = match.Index + match.Length;
				if (string.IsNullOrEmpty (name)) { // $$ is interpreted as $
					sb.Append ("$");
				} else if (name == "end") {
					result.CaretEndOffset = sb.Length;
				} else if (name == "selected") {
					if (!string.IsNullOrEmpty (context.SelectedText)) {
						string indent = GetIndent (sb);
						string selection = Reindent (context.SelectedText, indent);
						sb.Append (selection);
					}
				}
				if (!variableDecarations.ContainsKey (name))
					continue;
				TextLink link = result.TextLinks.Find (l => l.Name == name);
				bool isNew = link == null;
				if (isNew) {
					link         = new TextLink (name);
					if (!string.IsNullOrEmpty (variableDecarations[name].ToolTip))
						link.Tooltip = GettextCatalog.GetString (variableDecarations[name].ToolTip);
					link.Values  = new CodeTemplateListDataProvider (variableDecarations[name].Values);
					if (!string.IsNullOrEmpty (variableDecarations[name].Function)) {
						link.Values  = expansion.RunFunction (context, null, variableDecarations[name].Function);
					}
					result.TextLinks.Add (link);
				}
				link.IsEditable = variableDecarations[name].IsEditable;
				link.IsIdentifier = variableDecarations[name].IsIdentifier;
				if (!string.IsNullOrEmpty (variableDecarations[name].Function)) {
					IListDataProvider<string> functionResult = expansion.RunFunction (context, null, variableDecarations[name].Function);
					if (functionResult != null && functionResult.Count > 0) {
						string s = (string)functionResult[functionResult.Count - 1];
						if (s == null) {
							if (variableDecarations.ContainsKey (name)) 
								s = variableDecarations[name].Default;
						}
						if (s != null) {
							link.AddLink (new Segment (sb.Length, s.Length));
							if (isNew) {
								link.GetStringFunc = delegate (Func<string, string> callback) {
									return expansion.RunFunction (context, callback, variableDecarations[name].Function);
								};
							}
							sb.Append (s);
						}
					} else {
						AddDefaultValue (sb, link, name);
					}
				} else  {
					AddDefaultValue (sb, link, name);
				}
			}
			sb.Append (code.Substring (lastOffset, code.Length - lastOffset));
			result.Code = sb.ToString ();
			return result;
		}
Example #6
0
		public TemplateResult FillVariables (TemplateContext context)
		{
			ExpansionObject expansion = CodeTemplateService.GetExpansionObject (this);
			TemplateResult result = new TemplateResult ();
			StringBuilder sb = new StringBuilder ();
			int lastOffset = 0;
			string code = context.Document.Editor.FormatString (context.InsertPosition, context.TemplateCode);
			result.TextLinks = new List<TextLink> ();
			foreach (Match match in variableRegEx.Matches (code)) {
				string name = match.Groups [1].Value;
				sb.Append (code.Substring (lastOffset, match.Index - lastOffset));
				lastOffset = match.Index + match.Length;
				if (string.IsNullOrEmpty (name)) { // $$ is interpreted as $
					sb.Append ("$");
				} else if (name == "end") {
					result.CaretEndOffset = sb.Length;
				} else if (name == "selected") {
					if (!string.IsNullOrEmpty (context.SelectedText)) {
						string indent = GetIndent (sb);
						string selection = Reindent (context.SelectedText, indent);
						sb.Append (selection);
					}
				}
				if (!variableDecarations.ContainsKey (name))
					continue;
				TextLink link = result.TextLinks.Find (l => l.Name == name);
				bool isNew = link == null;
				if (isNew) {
					link = new TextLink (name);
					if (!string.IsNullOrEmpty (variableDecarations [name].ToolTip))
						link.Tooltip = GettextCatalog.GetString (variableDecarations [name].ToolTip);
					link.Values = new CodeTemplateListDataProvider (variableDecarations [name].Values);
					if (!string.IsNullOrEmpty (variableDecarations [name].Function)) {
						link.Values = expansion.RunFunction (context, null, variableDecarations [name].Function);
					}
					result.TextLinks.Add (link);
				}
				link.IsEditable = variableDecarations [name].IsEditable;
				link.IsIdentifier = variableDecarations [name].IsIdentifier;
				if (!string.IsNullOrEmpty (variableDecarations [name].Function)) {
					IListDataProvider<string > functionResult = expansion.RunFunction (context, null, variableDecarations [name].Function);
					if (functionResult != null && functionResult.Count > 0) {
						string s = (string)functionResult [functionResult.Count - 1];
						if (s == null) {
							if (variableDecarations.ContainsKey (name)) 
								s = variableDecarations [name].Default;
						}
						if (s != null) {
							link.AddLink (new Segment (sb.Length, s.Length));
							if (isNew) {
								link.GetStringFunc = delegate (Func<string, string> callback) {
									return expansion.RunFunction (context, callback, variableDecarations [name].Function);
								};
							}
							sb.Append (s);
						}
					} else {
						AddDefaultValue (sb, link, name);
					}
				} else {
					AddDefaultValue (sb, link, name);
				}
			}
			sb.Append (code.Substring (lastOffset, code.Length - lastOffset));
			
			// format & indent template code
			TextEditorData data = new TextEditorData ();
			data.Text = sb.ToString ();
			data.Document.TextReplaced += delegate(object sender, ReplaceEventArgs e) {
				int delta = -e.Count + (e.Value != null ? e.Value.Length : 0);
				foreach (var link in result.TextLinks) {
					foreach (var segment in link.Links) {
						if (segment.Offset > e.Offset) {
							segment.Offset += delta;
						}
					}
				}
				if (result.CaretEndOffset > e.Offset)
					result.CaretEndOffset += delta;
			};
			
			var formatter = CodeFormatterService.GetFormatter (context.Document.Editor.Document.MimeType);
			if (formatter != null && context.Document.HasProject) {
				formatter.OnTheFlyFormat (context.Document.Project.Policies, data, 0, data.Length);
			}
			
			IndentCode (data, context.LineIndent);
			result.Code = data.Text;
			data.Dispose ();
			return result;
		}
		/// <summary>
		/// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
		/// </summary>
		public TemplateResult InsertTemplateContents (MonoDevelop.Ide.Gui.Document document)
		{
			ProjectDom dom = document.Dom;
			ParsedDocument doc = document.ParsedDocument ?? MonoDevelop.Projects.Dom.Parser.ProjectDomService.GetParsedDocument (dom, document.FileName);
			MonoDevelop.Ide.Gui.TextEditor editor = document.TextEditor;

			Mono.TextEditor.TextEditorData data = document.TextEditorData;

			int offset = editor.CursorPosition;
			int line, col;
			editor.GetLineColumnFromPosition (offset, out line, out col);
//			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);
			
			TemplateContext context = new TemplateContext {
				Template = this,
				Document = document,
				ProjectDom = dom,
				ParsedDocument = doc,
				InsertPosition = new DomLocation (line, col),
				LineIndent = GetIndent (editor, line, 0),
				TemplateCode = IndentCode (Code, document.TextEditorData.EolMarker, GetIndent (editor, line, 0))
			};

			if (data.IsSomethingSelected) {
				int start = data.SelectionRange.Offset;
				while (Char.IsWhiteSpace (data.Document.GetCharAt (start))) {
					start++;
				}
				int end = data.SelectionRange.EndOffset;
				while (Char.IsWhiteSpace (data.Document.GetCharAt (end - 1))) {
					end--;
				}
				context.LineIndent = GetIndent (editor, data.Document.OffsetToLineNumber (start) + 1, 0);
				context.SelectedText = RemoveIndent (data.Document.GetTextBetween (start, end), context.LineIndent);
				data.Remove (start, end - start);
				offset = start;
			} else {
				string word = GetWordBeforeCaret (editor).Trim ();
				if (word.Length > 0)
					offset = DeleteWordBeforeCaret (editor);
			}
			
			TemplateResult template = FillVariables (context);
			template.InsertPosition = offset;
			document.TextEditorData.Insert (offset, template.Code);
			
			if (template.CaretEndOffset >= 0) {
				document.TextEditorData.Caret.Offset = offset + template.CaretEndOffset; 
			} else {
				document.TextEditorData.Caret.Offset= offset + template.Code.Length; 
			}
			return template;
		}
Example #8
0
        /// <summary>
        /// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
        /// </summary>
        public TemplateResult InsertTemplateContents(TextEditor editor, DocumentContext context)
        {
            var data   = editor;
            int offset = data.CaretOffset;
//			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);

            var templateCtx = new TemplateContext {
                Template        = this,
                DocumentContext = context,
                Editor          = editor,
                //ParsedDocument = context.ParsedDocument != null ? context.ParsedDocument.ParsedFile : null,
                InsertPosition = data.CaretLocation,
                InsertOffset   = data.CaretOffset,
                LineIndent     = data.GetLineIndent(data.CaretLocation.Line),
                TemplateCode   = Code
            };

            if (data.IsSomethingSelected)
            {
                int start = data.SelectionRange.Offset;
                while (Char.IsWhiteSpace(data.GetCharAt(start)))
                {
                    start++;
                }
                int end = data.SelectionRange.EndOffset;
                while (start < end && Char.IsWhiteSpace(data.GetCharAt(end - 1)))
                {
                    end--;
                }
                templateCtx.LineIndent   = data.GetLineIndent(data.OffsetToLineNumber(start));
                templateCtx.SelectedText = start < end?RemoveIndent(data.GetTextBetween(start, end), templateCtx.LineIndent) : "";

                data.RemoveText(start, end - start);
                offset = start;
            }
            else
            {
                string word = GetTemplateShortcutBeforeCaret(data).Trim();
                if (word.Length > 0)
                {
                    offset = DeleteTemplateShortcutBeforeCaret(data);
                }
            }

            TemplateResult template = FillVariables(templateCtx);

            template.InsertPosition = offset;
            editor.InsertText(offset, template.Code);

            int newoffset;

            if (template.CaretEndOffset >= 0)
            {
                newoffset = offset + template.CaretEndOffset;
            }
            else
            {
                newoffset = offset + template.Code.Length;
            }

            editor.CaretLocation = editor.OffsetToLocation(newoffset);
            editor.FixVirtualIndentation();

            var prettyPrinter = CodeFormatterService.GetFormatter(data.MimeType);

            if (prettyPrinter != null && prettyPrinter.SupportsOnTheFlyFormatting)
            {
                int endOffset  = template.InsertPosition + template.Code.Length;
                var oldVersion = data.Version;

                try {
                    prettyPrinter.OnTheFlyFormat(editor, context, TextSegment.FromBounds(template.InsertPosition, editor.CaretOffset));
                    endOffset = oldVersion.MoveOffsetTo(data.Version, endOffset);
                    if (editor.CaretOffset < endOffset)
                    {
                        prettyPrinter.OnTheFlyFormat(editor, context, TextSegment.FromBounds(editor.CaretOffset, endOffset));
                    }
                } catch (Exception e) {
                    LoggingService.LogInternalError(e);
                }
                foreach (var textLink in template.TextLinks)
                {
                    for (int i = 0; i < textLink.Links.Count; i++)
                    {
                        var segment          = textLink.Links [i];
                        var translatedOffset = segment.Offset;
                        foreach (var args in oldVersion.GetChangesTo(data.Version))
                        {
                            foreach (var change in args.TextChanges)
                            {
                                if (change.Offset > template.InsertPosition + segment.Offset)
                                {
                                    break;
                                }
                                if (change.Offset + change.RemovalLength < template.InsertPosition + segment.Offset)
                                {
                                    translatedOffset += change.InsertionLength - change.RemovalLength;
                                }
                                else
                                {
                                    translatedOffset += GetDeltaInsideChange(change.InsertedText, change.RemovedText, template.InsertPosition + segment.Offset - change.Offset);
                                }
                            }
                        }
                        textLink.Links [i] = new TextSegment(translatedOffset, segment.Length);
                    }
                }
            }
            return(template);
        }
Example #9
0
        public TemplateResult FillVariables(TemplateContext context)
        {
            var    expansion  = CodeTemplateService.GetExpansionObject(this);
            var    result     = new TemplateResult();
            var    sb         = StringBuilderCache.Allocate();
            int    lastOffset = 0;
            string code       = context.Editor.FormatString(context.InsertPosition, context.TemplateCode);

            result.TextLinks = new List <TextLink> ();
            foreach (System.Text.RegularExpressions.Match match in variableRegEx.Matches(code))
            {
                string name = match.Groups [1].Value;
                sb.Append(code, lastOffset, match.Index - lastOffset);
                lastOffset = match.Index + match.Length;
                if (string.IsNullOrEmpty(name))                    // $$ is interpreted as $
                {
                    sb.Append("$");
                }
                else
                {
                    switch (name)
                    {
                    case "end":
                        result.CaretEndOffset = sb.Length;
                        break;

                    case "selected":
                        if (!string.IsNullOrEmpty(context.SelectedText))
                        {
                            string indent    = GetIndent(sb);
                            string selection = Reindent(context.SelectedText, indent);
                            sb.Append(selection);
                        }
                        break;

                    case "TM_CURRENT_LINE":
                        sb.Append(context.Editor.CaretLine);
                        break;

                    case "TM_CURRENT_WORD":
                        sb.Append("");
                        break;

                    case "TM_FILENAME":
                        sb.Append(context.Editor.FileName);
                        break;

                    case "TM_FILEPATH":
                        sb.Append(Path.GetDirectoryName(context.Editor.FileName));
                        break;

                    case "TM_FULLNAME":
                        sb.Append(AuthorInformation.Default.Name);
                        break;

                    case "TM_LINE_INDEX":
                        sb.Append(context.Editor.CaretColumn - 1);
                        break;

                    case "TM_LINE_NUMBER":
                        sb.Append(context.Editor.CaretLine);
                        break;

                    case "TM_SOFT_TABS":
                        sb.Append(context.Editor.Options.TabsToSpaces ? "YES" : "NO");                          // Note: these strings need no translation.
                        break;

                    case "TM_TAB_SIZE":
                        sb.Append(context.Editor.Options.TabSize);
                        break;
                    }
                }
                if (!variableDecarations.ContainsKey(name))
                {
                    continue;
                }
                var  link  = result.TextLinks.Find(l => l.Name == name);
                bool isNew = link == null;
                if (isNew)
                {
                    link = new TextLink(name);
                    if (!string.IsNullOrEmpty(variableDecarations [name].ToolTip))
                    {
                        link.Tooltip = GettextCatalog.GetString(variableDecarations [name].ToolTip);
                    }
                    link.Values = new CodeTemplateListDataProvider(variableDecarations [name].Values);
                    if (!string.IsNullOrEmpty(variableDecarations [name].Function))
                    {
                        link.Values = expansion.RunFunction(context, null, variableDecarations [name].Function);
                    }
                    result.TextLinks.Add(link);
                }
                link.IsEditable   = variableDecarations [name].IsEditable;
                link.IsIdentifier = variableDecarations [name].IsIdentifier;
                if (!string.IsNullOrEmpty(variableDecarations [name].Function))
                {
                    var functionResult = expansion.RunFunction(context, null, variableDecarations [name].Function);
                    if (functionResult != null && functionResult.Count > 0)
                    {
                        string s = (string)functionResult [functionResult.Count - 1];
                        if (s == null)
                        {
                            if (variableDecarations.ContainsKey(name))
                            {
                                s = variableDecarations [name].Default;
                            }
                        }
                        if (s != null)
                        {
                            if (!link.IsEditable)
                            {
                                result.TextLinks.Remove(link);
                            }
                            else
                            {
                                link.AddLink(new TextSegment(sb.Length, s.Length));
                                if (isNew)
                                {
                                    link.GetStringFunc = delegate(Func <string, string> callback) {
                                        return(expansion.RunFunction(context, callback, variableDecarations [name].Function));
                                    };
                                }
                            }
                            sb.Append(s);
                        }
                    }
                    else
                    {
                        AddDefaultValue(sb, link, name);
                    }
                }
                else
                {
                    AddDefaultValue(sb, link, name);
                }
            }
            sb.Append(code, lastOffset, code.Length - lastOffset);

            // format & indent template code
            var data = TextEditorFactory.CreateNewDocument();

            data.Text         = StringBuilderCache.ReturnAndFree(sb);
            data.TextChanged += delegate(object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) {
                for (int i = 0; i < e.TextChanges.Count; ++i)
                {
                    var change = e.TextChanges[i];
                    int delta  = change.InsertionLength - change.RemovalLength;

                    foreach (var link in result.TextLinks)
                    {
                        link.Links = link.Links.AdjustSegments(e).ToList();
                    }
                    if (result.CaretEndOffset > change.Offset)
                    {
                        result.CaretEndOffset += delta;
                    }
                }
            };

            IndentCode(data, context.LineIndent);
            result.Code = data.Text;
            return(result);
        }
Example #10
0
        public TemplateResult FillVariables(TemplateContext context)
        {
            var    expansion  = CodeTemplateService.GetExpansionObject(this);
            var    result     = new TemplateResult();
            var    sb         = new StringBuilder();
            int    lastOffset = 0;
            string code       = context.Editor.FormatString(context.InsertPosition, context.TemplateCode);

            result.TextLinks = new List <TextLink> ();
            foreach (System.Text.RegularExpressions.Match match in variableRegEx.Matches(code))
            {
                string name = match.Groups [1].Value;
                sb.Append(code.Substring(lastOffset, match.Index - lastOffset));
                lastOffset = match.Index + match.Length;
                if (string.IsNullOrEmpty(name))                    // $$ is interpreted as $
                {
                    sb.Append("$");
                }
                else if (name == "end")
                {
                    result.CaretEndOffset = sb.Length;
                }
                else if (name == "selected")
                {
                    if (!string.IsNullOrEmpty(context.SelectedText))
                    {
                        string indent    = GetIndent(sb);
                        string selection = Reindent(context.SelectedText, indent);
                        sb.Append(selection);
                    }
                }
                if (!variableDecarations.ContainsKey(name))
                {
                    continue;
                }
                var  link  = result.TextLinks.Find(l => l.Name == name);
                bool isNew = link == null;
                if (isNew)
                {
                    link = new TextLink(name);
                    if (!string.IsNullOrEmpty(variableDecarations [name].ToolTip))
                    {
                        link.Tooltip = GettextCatalog.GetString(variableDecarations [name].ToolTip);
                    }
                    link.Values = new CodeTemplateListDataProvider(variableDecarations [name].Values);
                    if (!string.IsNullOrEmpty(variableDecarations [name].Function))
                    {
                        link.Values = expansion.RunFunction(context, null, variableDecarations [name].Function);
                    }
                    result.TextLinks.Add(link);
                }
                link.IsEditable   = variableDecarations [name].IsEditable;
                link.IsIdentifier = variableDecarations [name].IsIdentifier;
                if (!string.IsNullOrEmpty(variableDecarations [name].Function))
                {
                    IListDataProvider <string> functionResult = expansion.RunFunction(context, null, variableDecarations [name].Function);
                    if (functionResult != null && functionResult.Count > 0)
                    {
                        string s = (string)functionResult [functionResult.Count - 1];
                        if (s == null)
                        {
                            if (variableDecarations.ContainsKey(name))
                            {
                                s = variableDecarations [name].Default;
                            }
                        }
                        if (s != null)
                        {
                            link.AddLink(new TextSegment(sb.Length, s.Length));
                            if (isNew)
                            {
                                link.GetStringFunc = delegate(Func <string, string> callback) {
                                    return(expansion.RunFunction(context, callback, variableDecarations [name].Function));
                                };
                            }
                            sb.Append(s);
                        }
                    }
                    else
                    {
                        AddDefaultValue(sb, link, name);
                    }
                }
                else
                {
                    AddDefaultValue(sb, link, name);
                }
            }
            sb.Append(code.Substring(lastOffset, code.Length - lastOffset));

            // format & indent template code
            var data = TextEditorFactory.CreateNewDocument();

            data.Text         = sb.ToString();
            data.TextChanged += delegate(object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) {
                int delta = e.InsertionLength - e.RemovalLength;

                foreach (var link in result.TextLinks)
                {
                    link.Links = link.Links.AdjustSegments(e).ToList();
                }
                if (result.CaretEndOffset > e.Offset)
                {
                    result.CaretEndOffset += delta;
                }
            };

            IndentCode(data, context.LineIndent);
            result.Code = data.Text;
            return(result);
        }
Example #11
0
        /// <summary>
        /// Don't use this unless you're implementing ICodeTemplateWidget. Use Insert instead.
        /// </summary>
        public TemplateResult InsertTemplateContents(MonoDevelop.Ide.Gui.Document document)
        {
            Mono.TextEditor.TextEditorData data = document.Editor;

            int offset = data.Caret.Offset;
            //			string leadingWhiteSpace = GetLeadingWhiteSpace (editor, editor.CursorLine);

            var context = new TemplateContext {
                Template = this,
                Document = document,
                ParsedDocument = document.ParsedDocument != null ? document.ParsedDocument.ParsedFile : null,
                InsertPosition = data.Caret.Location,
                LineIndent = data.Document.GetLineIndent (data.Caret.Line),
                TemplateCode = Code
            };

            if (data.IsSomethingSelected) {
                int start = data.SelectionRange.Offset;
                while (Char.IsWhiteSpace (data.Document.GetCharAt (start))) {
                    start++;
                }
                int end = data.SelectionRange.EndOffset;
                while (Char.IsWhiteSpace (data.Document.GetCharAt (end - 1))) {
                    end--;
                }
                context.LineIndent = data.Document.GetLineIndent (data.Document.OffsetToLineNumber (start));
                context.SelectedText = RemoveIndent (data.Document.GetTextBetween (start, end), context.LineIndent);
                data.Remove (start, end - start);
                offset = start;
            } else {
                string word = GetWordBeforeCaret (data).Trim ();
                if (word.Length > 0)
                    offset = DeleteWordBeforeCaret (data);
            }

            TemplateResult template = FillVariables (context);
            template.InsertPosition = offset;
            document.Editor.Insert (offset, template.Code);

            int newoffset;
            if (template.CaretEndOffset >= 0) {
                newoffset = offset + template.CaretEndOffset;
            } else {
                newoffset = offset + template.Code.Length;
            }

            document.Editor.Caret.Location = document.Editor.OffsetToLocation (newoffset) ;

            var prettyPrinter = CodeFormatterService.GetFormatter (data.MimeType);
            if (prettyPrinter != null) {
                int endOffset = template.InsertPosition + template.Code.Length;
                var oldVersion = data.Version;
                prettyPrinter.OnTheFlyFormat (document, template.InsertPosition, endOffset);
                foreach (var textLink in template.TextLinks) {
                    for (int i = 0; i < textLink.Links.Count; i++) {
                        var segment = textLink.Links [i];
                        var translatedOffset = oldVersion.MoveOffsetTo (data.Version, template.InsertPosition + segment.Offset) - template.InsertPosition;
                        textLink.Links [i] = new TextSegment (translatedOffset, segment.Length);
                    }
                }
            }
            return template;
        }