Пример #1
1
		public static int RemoveTabInLine (TextEditorData data, DocumentLine line)
		{
			if (line.LengthIncludingDelimiter == 0)
				return 0;
			char ch = data.Document.GetCharAt (line.Offset); 
			if (ch == '\t') {
				data.Remove (line.Offset, 1);
				data.Document.CommitLineUpdate (line);
				return 1;
			} else if (ch == ' ') {
				int removeCount = 0;
				for (int i = 0; i < data.Options.IndentationSize;) {
					ch = data.Document.GetCharAt (line.Offset + i);
					if (ch == ' ') {
						removeCount ++;
						i++;
					} else if (ch == '\t') {
						removeCount ++;
						i += data.Options.TabSize;
					} else {
						break;
					}
				}
				data.Remove (line.Offset, removeCount);
				data.Document.CommitLineUpdate (line);
				return removeCount;
			}
			return 0;
		}
Пример #2
0
		public bool RemoveLine (DocumentLine line)
		{
			if (!lineWidthDictionary.ContainsKey (line))
				return false;
			lineWidthDictionary.Remove (line);
			return true;
		}
Пример #3
0
		static void DrawIcon (MonoTextEditor editor, Cairo.Context cr, DocumentLine lineSegment, double x, double y, double width, double height)
		{
			if (lineSegment.IsBookmarked) {
				var color1 = editor.ColorStyle.Bookmarks.Color;
				var color2 = editor.ColorStyle.Bookmarks.SecondColor;
				
				DrawRoundRectangle (cr, x + 1, y + 1, 8, width - 4, height - 4);

				// FIXME: VV: Remove gradient features
				using (var pat = new Cairo.LinearGradient (x + width / 4, y, x + width / 2, y + height - 4)) {
					pat.AddColorStop (0, color1);
					pat.AddColorStop (1, color2);
					cr.SetSource (pat);
					cr.FillPreserve ();
				}

				// FIXME: VV: Remove gradient features
				using (var pat = new Cairo.LinearGradient (x, y + height, x + width, y)) {
					pat.AddColorStop (0, color2);
					//pat.AddColorStop (1, color1);
					cr.SetSource (pat);
					cr.Stroke ();
				}
			}
		}
		internal protected override void Draw (Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
		{
			cr.MoveTo (x + 0.5, y);
			cr.LineTo (x + 0.5, y + lineHeight);
			cr.SetSourceColor (color);
			cr.Stroke ();
		}
		bool IFoldMarginMarker.DrawBackground (TextEditor e, double marginWidth, Cairo.Context cr, Cairo.Rectangle area, DocumentLine documentLine, int line, double x, double y, double lineHeight)
		{
			if (cache.CurrentSelectedTextMarker != null && cache.CurrentSelectedTextMarker != this)
				return false;
			cr.Rectangle (x, y, marginWidth, lineHeight);
			cr.Color = LineColor.Color;
			cr.Fill ();
			return true;
		}
Пример #6
0
        protected internal override void Draw(Context cr, Xwt.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double height)
        {
            if (line != null)
            {
                TextLayout layout;
                if (!layoutDict.TryGetValue(line, out layout))
                {
                    var mode = editor.Document.SyntaxMode;
                    var style = SyntaxModeService.DefaultColorStyle;
                    var chunks = GetCachedChunks(mode, editor.Document, style, line, line.Offset, line.Length);

                    layout = new TextLayout();
                    layout.Font = editor.Options.EditorFont;
                    string lineText = editor.Document.GetLineText(lineNumber);
                    var stringBuilder = new StringBuilder(lineText.Length);

                    int currentVisualColumn = 1;
                    for (int i = 0; i < lineText.Length; ++i)
                    {
                        char chr = lineText[i];
                        if (chr == '\t')
                        {
                            int length = GetNextTabstop(editor, currentVisualColumn) - currentVisualColumn;
                            stringBuilder.Append(' ', length);
                            currentVisualColumn += length;
                        }
                        else
                        {
                            stringBuilder.Append(chr);
                            if (!char.IsLowSurrogate(chr))
                            {
                                ++currentVisualColumn;
                            }
                        }
                    }
                    layout.Text = stringBuilder.ToString();

                    int visualOffset = 1;
                    foreach (var chunk in chunks)
                    {
                        var chunkStyle = style.GetChunkStyle(chunk);
                        visualOffset = DrawLinePortion(cr, chunkStyle, layout, line, visualOffset, chunk.Length);
                    }

                    //layoutDict[line] = layout;
                }

                cr.DrawTextLayout(layout, x, y);

                if (editor.CaretVisible && editor.Caret.Line == lineNumber)
                {
                    cr.SetColor(Colors.Black);
                    cr.Rectangle(x + ColumnToX(line, editor.Caret.Column), y, caretWidth, LineHeight);
                    cr.Fill();
                }
            }
        }
Пример #7
0
		public UrlMarker (TextDocument doc, DocumentLine line, string url, UrlType urlType, string style, int startColumn, int endColumn)
		{
			this.doc = doc;
			this.line = line;
			this.url = url;
			this.urlType = urlType;
			this.style = style;
			this.startColumn = startColumn;
			this.endColumn = endColumn;
			doc.LineChanged += HandleDocLineChanged;
		}
Пример #8
0
		internal protected override void Draw (Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
		{
			var marker = lineSegment != null ? (MarginMarker)lineSegment.Markers.FirstOrDefault (m => m is MarginMarker && ((MarginMarker)m).CanDraw (this)) : null;
			bool drawBackground = true;
			if (marker != null && marker.CanDrawBackground (this))
				drawBackground = !marker.DrawBackground (editor, cr, new MarginDrawMetrics (this, area, lineSegment, line, x, y, lineHeight));

			if (drawBackground) 
				DrawMarginBackground (cr, line, x, y, lineHeight);

			if (marker != null && marker.CanDrawForeground (this))
				marker.DrawForeground (editor, cr, new MarginDrawMetrics (this, area, lineSegment, line, x, y, lineHeight));
		}
Пример #9
0
		public void DrawIcon (Mono.TextEditor.TextEditor editor, Cairo.Context cr, DocumentLine line, int lineNumber, double x, double y, double width, double height)
		{
			double size;
			if (width > height) {
				x += (width - height) / 2;
				size = height;
			} else {
				y += (height - width) / 2;
				size = width;
			}
			
			DrawIcon (cr, x, y, size);
		}
Пример #10
0
//		TextDocument baseDocument;

		public Mono.TextEditor.TextDocument.LineState GetLineState (DocumentLine line)
		{
			if (line != null && lineStates != null) {
				try {
					var info = lineStates [line.LineNumber];
					if (info != null) {
						return info.state;
					}
				} catch (Exception) {

				}
			}
			return Mono.TextEditor.TextDocument.LineState.Unchanged;
		}
		void IIconBarMarker.DrawIcon (TextEditor ed, Cairo.Context cr, DocumentLine line, int lineNumber, double x, double y, double width, double height)
		{
			cr.Save ();
			cr.Translate (
				x + 0.5  + (width - cache.errorPixbuf.Width) / 2,
				y + 0.5 + (height - cache.errorPixbuf.Height) / 2
			);
			Gdk.CairoHelper.SetSourcePixbuf (
				cr,
				errors.Any (e => e.IsError) ? cache.errorPixbuf : cache.warningPixbuf, 0, 0);
			cr.Paint ();
			cr.Restore ();

		}
Пример #12
0
		public void DrawIcon (Mono.TextEditor.TextEditor editor, Cairo.Context cr, DocumentLine line, int lineNumber, double x, double y, double width, double height)
		{
			double size;
			if (width > height) {
				size = height;
			} else {
				size = width;
			}
			double borderLineWidth = cr.LineWidth;
			x = Math.Floor (x + (width - borderLineWidth - size) / 2);
			y = Math.Floor (y + (height - size) / 2);

			DrawIcon (cr, x, y, size);
		}
Пример #13
0
        int DrawLinePortion(Context cr, ChunkStyle style, TextLayout layout, DocumentLine line, int visualOffset, int logicalLength)
        {
            int logicalColumn = line.GetLogicalColumn(editor, visualOffset);
            int logicalEndColumn = logicalColumn + logicalLength;
            int visualEndOffset = line.GetVisualColumn(editor, logicalEndColumn);

            int visualLength = visualEndOffset - visualOffset;

            int indexOffset = visualOffset - 1;

            layout.SetFontStyle(style.FontStyle, indexOffset, visualLength);
            layout.SetFontWeight(style.FontWeight, indexOffset, visualLength);
            if (style.Underline)
                layout.SetUnderline(indexOffset, visualLength);
            layout.SetForeground(style.Foreground, indexOffset, visualLength);

            return visualEndOffset;
        }
        public static void removeTrailingWhitespace( TextEditorData data, DocumentLine line )
        {
            if( line != null )
            {
                int num = 0;
                for( int i = line.Length - 1; i >= 0; i-- )
                {
                    if( !char.IsWhiteSpace( data.Document.GetCharAt( line.Offset + i ) ) )
                        break;
                    num++;
                }

                if( num > 0 )
                {
                    int offset = line.Offset + line.Length - num;
                    data.Remove( offset, num );
                }
            }
        }
Пример #15
0
		public override void Analyze (TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset)
		{
			if (endOffset <= startOffset || startOffset >= doc.TextLength || inUpdate)
				return;
			inUpdate = true;
			try {
				string text = doc.GetTextAt (startOffset, endOffset - startOffset);
				int startColumn = startOffset - line.Offset;
				var markers = new List <UrlMarker> (line.Markers.Where (m => m is UrlMarker).Cast<UrlMarker> ());
				markers.ForEach (m => doc.RemoveMarker (m, false));
				foreach (System.Text.RegularExpressions.Match m in UrlRegex.Matches (text)) {
					doc.AddMarker (line, new UrlMarker (doc, line, m.Value, UrlType.Url, syntax, startColumn + m.Index, startColumn + m.Index + m.Length), false);
				}
				foreach (System.Text.RegularExpressions.Match m in MailRegex.Matches (text)) {
					doc.AddMarker (line, new UrlMarker (doc, line, m.Value, UrlType.Email, syntax, startColumn + m.Index, startColumn + m.Index + m.Length), false);
				}
			} finally {
				inUpdate = false;
			}
		}
Пример #16
0
			public override void Analyze(TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset)
			{
				// Check line start
				int o = line.Offset;
				char c = '\0';
				for (; o < line.EndOffset && char.IsWhiteSpace(c = doc.GetCharAt(o)); o++) ;

				if (c != '-' && c != '#')
					return;

				DSyntax.Document = doc;
				var spanParser = new SpanParser(DSyntax, new CloneableStack<Span>());
				var chunkP = new ChunkParser(DSyntax, spanParser, Ide.IdeApp.Workbench.ActiveDocument.Editor.ColorStyle, line);

				var n = chunkP.GetChunks(startOffset, endOffset - startOffset);
				if (n == null)
					return;
				startChunk.Next = n;
				startChunk.Length = n.Offset - startChunk.Offset;
			}
		void IIconBarMarker.DrawBackground (TextEditor ed, Cairo.Context cr, DocumentLine line, int lineNumber, double x, double y, double width, double height)
		{
			cr.Rectangle (x, y, width, height);
			cr.Color = LineColor.SecondColor;
			cr.Fill ();

			cr.MoveTo (x + width - 0.5, y);
			cr.LineTo (x + width - 0.5, y + height);
			cr.Color = LineColor.BorderColor;
			cr.Stroke ();

			if (cache.CurrentSelectedTextMarker != null && cache.CurrentSelectedTextMarker != this) {
				cr.Rectangle (x, y, width, height);
				cr.Color = new Cairo.Color (ed.ColorStyle.IndicatorMargin.Color.R,
				                            ed.ColorStyle.IndicatorMargin.Color.G,
				                            ed.ColorStyle.IndicatorMargin.Color.B, 0.5);
				cr.Fill ();

			}

		}
Пример #18
0
		public override void Analyze (TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset)
		{
			if (endOffset <= startOffset || startOffset >= doc.TextLength || inUpdate)
				return;
			if (startChunk.Style != Highlighting.ColorScheme.CommentsSingleLineKey && startChunk.Style != Highlighting.ColorScheme.CommentsBlockKey)
				return;
			inUpdate = true;
			try {
				string text = doc.GetTextAt (startOffset, System.Math.Min (endOffset, doc.TextLength) - startOffset);
				int startColumn = startOffset - line.Offset;
				var markers = new List <UrlMarker> (line.Markers.OfType<UrlMarker> ());
				markers.ForEach (m => doc.RemoveMarker (m, false));
				foreach (System.Text.RegularExpressions.Match m in UrlRegex.Matches (text)) {
					doc.AddMarker (line, new UrlMarker (doc, line, m.Value, UrlType.Url, syntax, startColumn + m.Index, startColumn + m.Index + m.Length), false);
				}
				foreach (System.Text.RegularExpressions.Match m in MailRegex.Matches (text)) {
					doc.AddMarker (line, new UrlMarker (doc, line, m.Value, UrlType.Email, syntax, startColumn + m.Index, startColumn + m.Index + m.Length), false);
				}
			} finally {
				inUpdate = false;
			}
		}
Пример #19
0
		public void Initalize (string text, out DocumentLine longestLine)
		{
			delimiters = new List<LineSplitter.Delimiter> ();

			int offset = 0, maxLength = 0, maxLine = 0;
			while (true) {
				var delimiter = LineSplitter.NextDelimiter (text, offset);
				if (delimiter.IsInvalid)
					break;

				var length = delimiter.EndOffset - offset;
				if (length > maxLength) {
					maxLength = length;
					maxLine = delimiters.Count;
				}
				delimiters.Add (delimiter);
				offset = delimiter.EndOffset;
			}
			longestLine = Get (maxLine);

			textLength = text.Length;
		}
Пример #20
0
		public void DrawIcon (TextEditor editor, Cairo.Context cr, DocumentLine lineSegment, int lineNumber, double x, double y, double width, double height)
		{
			if (lineSegment.IsBookmarked) {
				var color1 = editor.ColorStyle.Bookmarks.Color;
				var color2 = editor.ColorStyle.Bookmarks.SecondColor;
				
				DrawRoundRectangle (cr, x + 1, y + 1, 8, width - 4, height - 4);
				using (var pat = new Cairo.LinearGradient (x + width / 4, y, x + width / 2, y + height - 4)) {
					pat.AddColorStop (0, color1);
					pat.AddColorStop (1, color2);
					cr.Pattern = pat;
					cr.FillPreserve ();
				}
				
				using (var pat = new Cairo.LinearGradient (x, y + height, x + width, y)) {
					pat.AddColorStop (0, color2);
					//pat.AddColorStop (1, color1);
					cr.Pattern = pat;
					cr.Stroke ();
				}
			}
		}
        public void CorrectLinePadding(DocumentLine currentLine, int currentIndex, Dictionary<DocumentLine, List<int>> lineOffsets)
        {
            int i = 0;

            var lines = lineOffsets.Where (e => i < e.Value.Count).ToList();

            var currentLineOffset = lineOffsets [currentLine];

            var caret = Editor.Caret.Column;

            while (lines.Count > 0)
            {
                int minOffset = lines.Max (e => LastWhitespaceCharacterOffset (Editor.GetLineText (e.Key.LineNumber), e.Value [i], i - 1 >= 0 ? e.Value [i - 1] : 0) + (i > 0 ? 1 : 0));

                minOffset = Math.Max(minOffset, currentLineOffset [i]);

                foreach (var line in lines) {
                    int offset = line.Value [i];

                    int numOfSpaces = minOffset - offset;

                    if (numOfSpaces > 0) {
                        Editor.Insert (line.Key.Offset + offset, new string (' ', numOfSpaces));
                    } else {
                        Editor.Remove (line.Key.Offset + offset + numOfSpaces, -numOfSpaces);
                    }

                    Editor.Document.CommitLineUpdate (line.Key);
                }

                i++;

                lines = lineOffsets.Where (e => i < e.Value.Count).ToList();
            }

            Editor.Caret.Column = caret;
        }
		public override IEnumerable<Chunk> GetChunks (ColorScheme style, DocumentLine line, int offset, int length)
		{
			// Multiline comment
			if (line.StartSpan.Count != 0 && line.StartSpan.Peek ().Begin.Pattern == "@*")
				return base.GetChunks (style, line, offset, length);

			var tokenizer = new CSharpTokenizer (new SeekableTextReader (doc.GetTextAt (offset, length)));
			chunks = new List<Chunk> ();
			CSharpSymbol symbol;
			CSharpSymbol prevSymbol = null;
			int off = line.Offset;
			currentState = State.None;

			while ((symbol = tokenizer.NextSymbol ()) != null) {
				// Apostrophes in text
				bool inApostrophes = false;
				if (symbol.Type == CSharpSymbolType.CharacterLiteral && prevSymbol != null && Char.IsLetterOrDigit (prevSymbol.Content.Last ())) {
					if (symbol.Content.Last () == '\'')
						inApostrophes = true;
					else {
						chunks.Add (new Chunk (off, 1, "Plain Text"));
						off++;
						tokenizer = new CSharpTokenizer (new SeekableTextReader (symbol.Content.Substring (1)));
						symbol = tokenizer.NextSymbol ();
						prevSymbol = null;
					}
				}

				string chunkStyle = inApostrophes ? "Plain Text" : GetStyleForChunk (symbol, prevSymbol, off);
				chunks.Add (new Chunk (off, symbol.Content.Length, chunkStyle));
				prevSymbol = symbol;
				off += symbol.Content.Length;
			}

			return chunks;
		}
 public override SpanParser CreateSpanParser(Mono.TextEditor.DocumentLine line, CloneableStack <Span> spanStack)
 {
     return(syntaxMode.CreateSpanParser(line, spanStack));
 }
Пример #24
0
 public override SpanParser CreateSpanParser(Mono.TextEditor.DocumentLine line, CloneableStack <Span> spanStack)
 {
     return(new GherkinSpanParser(this, spanStack ?? line.StartSpan.Clone()));
 }
Пример #25
0
 internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
 {
     cr.MoveTo(x + 0.5, y);
     cr.LineTo(x + 0.5, y + lineHeight);
     cr.SetSourceColor(color);
     cr.Stroke();
 }
Пример #26
0
        internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            var gutterMarker = lineSegment != null ? (MarginMarker)lineSegment.Markers.FirstOrDefault(marker => marker is MarginMarker && ((MarginMarker)marker).CanDraw(this)) : null;

            if (gutterMarker != null && gutterMarker.CanDrawBackground(this))
            {
                bool hasDrawn = gutterMarker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                if (!hasDrawn)
                {
                    DrawGutterBackground(cr, line, x, y, lineHeight);
                }
            }
            else
            {
                DrawGutterBackground(cr, line, x, y, lineHeight);
            }

            if (gutterMarker != null && gutterMarker.CanDrawForeground(this))
            {
                gutterMarker.DrawForeground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                return;
            }

            if (line <= editor.Document.LineCount)
            {
                // Due to a mac? gtk bug I need to re-create the layout here
                // otherwise I get pango exceptions.
                using (var layout = editor.LayoutCache.RequestLayout()) {
                    layout.FontDescription = gutterFont;
                    layout.Width           = (int)Width;
                    layout.Alignment       = Pango.Alignment.Right;
                    layout.SetText(line.ToString());
                    cr.Save();
                    cr.Translate(x + (int)Width + (editor.Options.ShowFoldMargin ? 0 : -2), y);
                    cr.SetSourceColor(lineNumberGC);
                    cr.ShowLayout(layout);
                    cr.Restore();
                }
            }
        }
Пример #27
0
        public static void Backspace(TextEditorData data, Action <TextEditorData> removeCharBeforeCaret)
        {
            if (!data.CanEditSelection)
            {
                return;
            }
            using (var undo = data.OpenUndoGroup()) {
                if (data.IsSomethingSelected)
                {
                    var visualAnchorLocation = data.LogicalToVisualLocation(data.MainSelection.Anchor);
                    var visualLeadLocation   = data.LogicalToVisualLocation(data.MainSelection.Lead);
                    // case: zero width block selection
                    if (data.MainSelection.SelectionMode == SelectionMode.Block && visualAnchorLocation.Column == visualLeadLocation.Column)
                    {
                        var col = data.MainSelection.Lead.Column;
                        if (col <= DocumentLocation.MinColumn)
                        {
                            data.ClearSelection();
                            return;
                        }
                        bool preserve = data.Caret.PreserveSelection;
                        data.Caret.PreserveSelection = true;
                        for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++)
                        {
                            var lineSegment  = data.Document.GetLine(lineNumber);
                            int insertOffset = lineSegment.GetLogicalColumn(data, visualAnchorLocation.Column - 1) - 1;
                            data.Remove(lineSegment.Offset + insertOffset, 1);
                        }

                        var visualColumn = data.GetLine(data.Caret.Location.Line).GetVisualColumn(data, col - 1);
                        data.MainSelection = new Selection(
                            new DocumentLocation(data.MainSelection.Anchor.Line, data.GetLine(data.MainSelection.Anchor.Line).GetLogicalColumn(data, visualColumn)),
                            new DocumentLocation(data.MainSelection.Lead.Line, data.GetLine(data.MainSelection.Lead.Line).GetLogicalColumn(data, visualColumn)),
                            SelectionMode.Block
                            );

                        data.Caret.PreserveSelection = preserve;
                        data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine);
                        return;
                    }
                    data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block);
                    return;
                }

                if (data.Caret.Line == DocumentLocation.MinLine && data.Caret.Column == DocumentLocation.MinColumn)
                {
                    return;
                }

                // Virtual indentation needs to be fixed before to have the same behavior
                // if it's there or not (otherwise user has to press multiple backspaces in some cases)
                data.EnsureCaretIsNotVirtual();
                DocumentLine line = data.Document.GetLine(data.Caret.Line);
                if (data.Caret.Column > line.Length + 1)
                {
                    data.Caret.Column = line.Length + 1;
                }
                else if (data.Caret.Offset == line.Offset)
                {
                    DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1);
                    if (lineAbove.Length == 0 && data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual)
                    {
                        data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, data.IndentationTracker.GetVirtualIndentationColumn(data.Caret.Line - 1, 1));
                        data.Replace(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.IndentationTracker.GetIndentationString(data.Caret.Line - 1, 1));
                    }
                    else
                    {
                        data.Remove(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength);
                    }
                }
                else
                {
                    removeCharBeforeCaret(data);
                }

                // Needs to be fixed after, the line may just contain the indentation
                data.FixVirtualIndentation();
            }
        }
Пример #28
0
 public MdTextViewLine(MdTextViewLineCollection collection, MonoTextEditor textEditor, DocumentLine line, int lineNumber, TextViewMargin.LayoutWrapper layoutWrapper)
 {
     this.collection      = collection;
     this.layoutWrapper   = layoutWrapper;
     this.textEditor      = textEditor;
     this.line            = line;
     this.LineNumber      = lineNumber;
     Snapshot             = textEditor.VisualSnapshot;
     this.LineBreakLength = line.DelimiterLength;
 }
Пример #29
0
        static int PasteFrom(Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState)
        {
            int result = -1;

            if (!data.CanEdit(data.Document.OffsetToLineNumber(insertionOffset)))
            {
                return(result);
            }
            if (clipboard.WaitIsTargetAvailable(CopyOperation.MD_ATOM))
            {
                clipboard.RequestContents(CopyOperation.MD_ATOM, delegate(Clipboard clp, SelectionData selectionData) {
                    if (selectionData.Length > 0)
                    {
                        byte[] selBytes = selectionData.Data;
                        byte[] copyData = new byte[selBytes[1]];
                        Array.Copy(selBytes, 2, copyData, 0, copyData.Length);
                        var rawTextOffset = 1 + 1 + copyData.Length;
                        string text       = System.Text.Encoding.UTF8.GetString(selBytes, rawTextOffset, selBytes.Length - rawTextOffset);
                        bool pasteBlock   = (selBytes [0] & 1) == 1;
                        bool pasteLine    = (selBytes [0] & 2) == 2;
                        if (pasteBlock)
                        {
                            using (var undo = data.OpenUndoGroup()) {
                                var version = data.Document.Version;
                                if (!preserveSelection)
                                {
                                    data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block);
                                }
                                data.EnsureCaretIsNotVirtual();
                                insertionOffset = version.MoveOffsetTo(data.Document.Version, insertionOffset);

                                data.Caret.PreserveSelection = true;
                                var lines  = new List <string> ();
                                int offset = 0;
                                while (true)
                                {
                                    var delimiter = LineSplitter.NextDelimiter(text, offset);
                                    if (delimiter.IsInvalid)
                                    {
                                        break;
                                    }

                                    int delimiterEndOffset = delimiter.Offset + delimiter.Length;
                                    lines.Add(text.Substring(offset, delimiter.Offset - offset));
                                    offset = delimiterEndOffset;
                                }
                                if (offset < text.Length)
                                {
                                    lines.Add(text.Substring(offset, text.Length - offset));
                                }

                                int lineNr = data.Document.OffsetToLineNumber(insertionOffset);
                                int col    = insertionOffset - data.Document.GetLine(lineNr).Offset;
                                int visCol = data.Document.GetLine(lineNr).GetVisualColumn(data, col);
                                DocumentLine curLine;
                                int lineCol = col;
                                result      = 0;
                                for (int i = 0; i < lines.Count; i++)
                                {
                                    while (data.Document.LineCount <= lineNr + i)
                                    {
                                        data.Insert(data.Document.TextLength, Environment.NewLine);
                                        result += Environment.NewLine.Length;
                                    }
                                    curLine = data.Document.GetLine(lineNr + i);
                                    if (lines [i].Length > 0)
                                    {
                                        lineCol = curLine.GetLogicalColumn(data, visCol);
                                        if (curLine.Length + 1 < lineCol)
                                        {
                                            result += lineCol - curLine.Length;
                                            data.Insert(curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length));
                                        }
                                        data.Insert(curLine.Offset + lineCol, lines [i]);
                                        result += lines [i].Length;
                                    }
                                    if (!preserveState)
                                    {
                                        data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length;
                                    }
                                }
                                if (!preserveState)
                                {
                                    data.ClearSelection();
                                }
                                data.Caret.PreserveSelection = false;
                            }
                        }
                        else if (pasteLine)
                        {
                            using (var undo = data.OpenUndoGroup()) {
                                if (!preserveSelection)
                                {
                                    data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block);
                                }
                                data.EnsureCaretIsNotVirtual();

                                data.Caret.PreserveSelection = true;
                                result = text.Length;
                                DocumentLine curLine = data.Document.GetLine(data.Caret.Line);

                                result = PastePlainText(data, curLine.Offset, text + data.EolMarker, preserveSelection, copyData);
                                if (!preserveState)
                                {
                                    data.ClearSelection();
                                }
                                data.Caret.PreserveSelection = false;
                            }
                        }
                        else
                        {
                            result = PastePlainText(data, insertionOffset, text, preserveSelection, copyData);
                        }
                    }
                });
                // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice).
                return(result);
            }

            if (result < 0 && clipboard.WaitIsTextAvailable())
            {
                clipboard.RequestText(delegate(Clipboard clp, string text) {
                    if (string.IsNullOrEmpty(text))
                    {
                        return;
                    }
                    result = PastePlainText(data, insertionOffset, text, preserveSelection);
                });
            }

            return(result);
        }
Пример #30
0
        internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            var marker = lineSegment != null ? (MarginMarker)lineSegment.Markers.FirstOrDefault(m => m is MarginMarker && ((MarginMarker)m).CanDraw(this)) : null;

            if (marker != null)
            {
                bool hasDrawn = marker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                if (!hasDrawn)
                {
                    marker = null;
                }
            }

            foldSegmentSize  = marginWidth * 4 / 6;
            foldSegmentSize -= (foldSegmentSize) % 2;

            Cairo.Rectangle drawArea = new Cairo.Rectangle(x, y, marginWidth, lineHeight);
            var             state    = editor.Document.GetLineState(lineSegment);

            bool isFoldStart  = false;
            bool isContaining = false;
            bool isFoldEnd    = false;

            bool isStartSelected      = false;
            bool isContainingSelected = false;
            bool isEndSelected        = false;

            if (editor.Options.ShowFoldMargin && line <= editor.Document.LineCount)
            {
                startFoldings.Clear();
                containingFoldings.Clear();
                endFoldings.Clear();
                foreach (FoldSegment segment in editor.Document.GetFoldingContaining(lineSegment))
                {
                    if (segment.StartLine.Offset == lineSegment.Offset)
                    {
                        startFoldings.Add(segment);
                    }
                    else if (segment.EndLine.Offset == lineSegment.Offset)
                    {
                        endFoldings.Add(segment);
                    }
                    else
                    {
                        containingFoldings.Add(segment);
                    }
                }

                isFoldStart  = startFoldings.Count > 0;
                isContaining = containingFoldings.Count > 0;
                isFoldEnd    = endFoldings.Count > 0;

                isStartSelected      = this.lineHover != null && IsMouseHover(startFoldings);
                isContainingSelected = this.lineHover != null && IsMouseHover(containingFoldings);
                isEndSelected        = this.lineHover != null && IsMouseHover(endFoldings);
            }

            if (marker == null)
            {
                if (editor.Options.HighlightCaretLine && editor.Caret.Line == line)
                {
                    editor.TextViewMargin.DrawCaretLineMarker(cr, x, y, Width, lineHeight);
                }
                else
                {
                    var bgGC = foldBgGC;
                    if (editor.TextViewMargin.BackgroundRenderer != null)
                    {
                        if (isContainingSelected || isStartSelected || isEndSelected)
                        {
                            bgGC = foldBgGC;
                        }
                        else
                        {
                            bgGC = foldLineHighlightedGCBg;
                        }
                    }

                    cr.Rectangle(drawArea);
                    cr.SetSourceColor(bgGC);
                    cr.Fill();
                }
            }

            if (editor.Options.EnableQuickDiff)
            {
                if (state == TextDocument.LineState.Changed)
                {
                    cr.SetSourceColor(lineStateChangedGC);
                    cr.Rectangle(x + 1, y, marginWidth / 3, lineHeight);
                    cr.Fill();
                }
                else if (state == TextDocument.LineState.Dirty)
                {
                    cr.SetSourceColor(lineStateDirtyGC);
                    cr.Rectangle(x + 1, y, marginWidth / 3, lineHeight);
                    cr.Fill();
                }
            }

            if (editor.Options.ShowFoldMargin && line <= editor.Document.LineCount)
            {
                double foldSegmentYPos = y + System.Math.Floor(editor.LineHeight - foldSegmentSize) / 2;
                double xPos            = x + System.Math.Floor(marginWidth / 2) + 0.5;

                if (isFoldStart)
                {
                    bool isVisible         = true;
                    bool moreLinedOpenFold = false;
                    foreach (FoldSegment foldSegment in startFoldings)
                    {
                        if (foldSegment.IsFolded)
                        {
                            isVisible = false;
                        }
                        else
                        {
                            moreLinedOpenFold = foldSegment.EndLine.Offset > foldSegment.StartLine.Offset;
                        }
                    }
                    bool isFoldEndFromUpperFold = false;
                    foreach (FoldSegment foldSegment in endFoldings)
                    {
                        if (foldSegment.EndLine.Offset > foldSegment.StartLine.Offset && !foldSegment.IsFolded)
                        {
                            isFoldEndFromUpperFold = true;
                        }
                    }
                    DrawFoldSegment(cr, x, y, isVisible, isStartSelected);

                    if (isContaining || isFoldEndFromUpperFold)
                    {
                        cr.DrawLine(isContainingSelected ? foldLineHighlightedGC : foldLineGC, xPos, drawArea.Y, xPos, foldSegmentYPos - 2);
                    }
                    if (isContaining || moreLinedOpenFold)
                    {
                        cr.DrawLine(isEndSelected || (isStartSelected && isVisible) || isContainingSelected ? foldLineHighlightedGC : foldLineGC, xPos, foldSegmentYPos + foldSegmentSize + 2, xPos, drawArea.Y + drawArea.Height);
                    }
                }
                else
                {
                    if (isFoldEnd)
                    {
                        double yMid = System.Math.Floor(drawArea.Y + drawArea.Height / 2) + 0.5;
                        cr.DrawLine(isEndSelected ? foldLineHighlightedGC : foldLineGC, xPos, yMid, x + marginWidth - 2, yMid);
                        cr.DrawLine(isContainingSelected || isEndSelected ? foldLineHighlightedGC : foldLineGC, xPos, drawArea.Y, xPos, yMid);

                        if (isContaining)
                        {
                            cr.DrawLine(isContainingSelected ? foldLineHighlightedGC : foldLineGC, xPos, yMid, xPos, drawArea.Y + drawArea.Height);
                        }
                    }
                    else if (isContaining)
                    {
                        cr.DrawLine(isContainingSelected ? foldLineHighlightedGC : foldLineGC, xPos, drawArea.Y, xPos, drawArea.Y + drawArea.Height);
                    }
                }
            }
        }
Пример #31
0
        internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double lineHeight)
        {
            bool backgroundIsDrawn = false;

            if (line != null)
            {
                foreach (var marker in editor.Document.GetMarkersOrderedByInsertion(line))
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawBackground(this))
                    {
                        backgroundIsDrawn = marginMarker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, line, lineNumber, x, y, lineHeight));
                    }
                }
            }

            if (!backgroundIsDrawn)
            {
                cr.Rectangle(x, y, Width, lineHeight);
                cr.SetSourceColor(backgroundColor);
                cr.Fill();

                cr.MoveTo(x + Width - 0.5, y);
                cr.LineTo(x + Width - 0.5, y + lineHeight);
                cr.SetSourceColor(separatorColor);
                cr.Stroke();
            }

            if (line != null && lineNumber <= editor.Document.LineCount)
            {
                foreach (var marker in editor.Document.GetMarkersOrderedByInsertion(line))
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawForeground(this))
                    {
                        var metrics = new MarginDrawMetrics(this, area, line, lineNumber, x, y, lineHeight);
                        marginMarker.DrawForeground(editor, cr, metrics);

                        if (markerToAccessible != null)
                        {
                            var accessible = markerToAccessible [marker];
                            if (accessible != null)
                            {
                                accessible.Metrics = metrics;
                                accessible.UpdateAccessibilityDetails();
                            }
                        }
                    }
                }
                if (DrawEvent != null)
                {
                    DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, cr, line, lineNumber, x, y));
                }
            }
        }
Пример #32
0
 public LineEventArgs(DocumentLine line)
 {
     this.line = line;
 }
Пример #33
0
        public static void Delete(TextEditorData data)
        {
            if (!data.CanEditSelection)
            {
                return;
            }

            using (var undoGroup = data.OpenUndoGroup()) {
                if (data.IsSomethingSelected)
                {
                    // case: zero width block selection
                    if (data.MainSelection.SelectionMode == SelectionMode.Block && data.MainSelection.Anchor.Column == data.MainSelection.Lead.Column)
                    {
                        var col = data.MainSelection.Lead.Column;
                        if (col <= DocumentLocation.MinColumn)
                        {
                            data.ClearSelection();
                            return;
                        }
                        bool preserve = data.Caret.PreserveSelection;
                        data.Caret.PreserveSelection = true;
                        col--;
                        for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++)
                        {
                            DocumentLine lineSegment = data.Document.GetLine(lineNumber);
                            if (col < lineSegment.Length)
                            {
                                data.Remove(lineSegment.Offset + col, 1);
                            }
                        }
                        data.Caret.PreserveSelection = preserve;
                        data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine);
                        return;
                    }
                    data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block);
                    return;
                }
                if (data.Caret.Offset >= data.Document.TextLength)
                {
                    return;
                }

                data.EnsureCaretIsNotVirtual();

                DocumentLine line = data.Document.GetLine(data.Caret.Line);
                if (data.Caret.Column == line.Length + 1)
                {
                    if (data.Caret.Line < data.Document.LineCount)
                    {
                        data.Remove(line.EndOffsetIncludingDelimiter - line.DelimiterLength, line.DelimiterLength);
                        if (line.EndOffsetIncludingDelimiter == data.Document.TextLength)
                        {
                            line.DelimiterLength = 0;
                        }
                    }
                }
                else
                {
                    data.Remove(data.Caret.Offset, 1);
                    data.Document.CommitLineUpdate(data.Caret.Line);
                }
                data.FixVirtualIndentation();
            }
        }
		internal MessageBubbleTextMarker (MessageBubbleCache cache, Task task, DocumentLine lineSegment, bool isError, string errorMessage)
		{
			if (cache == null)
				throw new ArgumentNullException ("cache");
			this.cache = cache;
			this.task = task;
			this.IsVisible = true;
			this.lineSegment = lineSegment;
			this.initialText = editor.Document.GetTextAt (lineSegment);
			this.isError = isError;
			AddError (task, isError, errorMessage);
//			cache.Changed += (sender, e) => CalculateLineFit (editor, lineSegment);
		}
Пример #35
0
			public bool Equals (DocumentLine line, int offset, int length, int selectionStart, int selectionEnd, out bool isInvalid)
			{
				int selStart = 0, selEnd = 0;
				if (selectionEnd >= 0) {
					selStart = selectionStart;
					selEnd = selectionEnd;
				}
				return base.Equals (line, offset, length, out isInvalid) && selStart == this.SelectionStart && selEnd == this.SelectionEnd;
			}
        public static void Delete(TextEditorData data)
        {
            if (!data.CanEditSelection)
            {
                return;
            }

            using (var undoGroup = data.OpenUndoGroup()) {
                if (data.IsSomethingSelected)
                {
                    // case: zero width block selection
                    if (data.MainSelection.SelectionMode == SelectionMode.Block && data.MainSelection.Anchor.Column == data.MainSelection.Lead.Column)
                    {
                        var col = data.MainSelection.Lead.Column;
                        if (col <= DocumentLocation.MinColumn)
                        {
                            data.ClearSelection();
                            return;
                        }
                        bool preserve = data.Caret.PreserveSelection;
                        data.Caret.PreserveSelection = true;
                        col--;
                        for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++)
                        {
                            DocumentLine lineSegment = data.Document.GetLine(lineNumber);
                            if (col < lineSegment.Length)
                            {
                                data.Remove(lineSegment.Offset + col, 1);
                            }
                        }
                        data.Caret.PreserveSelection = preserve;
                        data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine);
                        return;
                    }
                    data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block);
                    return;
                }
                if (data.Caret.Offset >= data.Document.TextLength)
                {
                    return;
                }

                data.EnsureCaretIsNotVirtual();

                DocumentLine line = data.Document.GetLine(data.Caret.Line);
                if (data.Caret.Column == line.Length + 1)
                {
                    if (data.Caret.Line < data.Document.LineCount)
                    {
                        var deletionLength = line.DelimiterLength;
                        // smart backspace (delete indentation)
                        if (data.Options.IndentStyle == IndentStyle.Smart || data.Options.IndentStyle == IndentStyle.Virtual)
                        {
                            var next = line.NextLine;
                            if (next != null)
                            {
                                if (data.HasIndentationTracker)
                                {
                                    var lineIndentation = next.GetIndentation(data.Document);
                                    if (lineIndentation.StartsWith(data.IndentationTracker.GetIndentationString(next.Offset)))
                                    {
                                        deletionLength += lineIndentation.Length;
                                    }
                                }
                            }
                        }

                        data.Remove(line.EndOffsetIncludingDelimiter - line.DelimiterLength, deletionLength);
                        if (line.EndOffsetIncludingDelimiter == data.Document.TextLength)
                        {
                            line.UnicodeNewline = UnicodeNewline.Unknown;
                        }
                    }
                }
                else
                {
                    data.Remove(data.Caret.Offset, 1);
                    data.Document.CommitLineUpdate(data.Caret.Line);
                }
                data.FixVirtualIndentation();
            }
        }
Пример #37
0
        internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            var  extendingMarker = lineSegment != null ? (IExtendingTextLineMarker)editor.Document.GetMarkers(lineSegment).FirstOrDefault(l => l is IExtendingTextLineMarker) : null;
            bool isSpaceAbove    = extendingMarker != null ? extendingMarker.IsSpaceAbove : false;

            var gutterMarker = lineSegment != null ? (MarginMarker)editor.Document.GetMarkers(lineSegment).FirstOrDefault(marker => marker is MarginMarker && ((MarginMarker)marker).CanDraw(this)) : null;

            if (gutterMarker != null && gutterMarker.CanDrawBackground(this))
            {
                bool hasDrawn = gutterMarker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                if (!hasDrawn)
                {
                    DrawGutterBackground(cr, line, x, y, lineHeight);
                }
            }
            else
            {
                DrawGutterBackground(cr, line, x, y, lineHeight);
            }

            if (gutterMarker != null && gutterMarker.CanDrawForeground(this))
            {
                gutterMarker.DrawForeground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                return;
            }

            if (line <= editor.Document.LineCount)
            {
                // Due to a mac? gtk bug I need to re-create the layout here
                // otherwise I get pango exceptions.
                DrawForeground(cr, line, x, y, lineHeight, isSpaceAbove);
            }
        }
Пример #38
0
		void RemoveDebugMarkers ()
		{
			if (currentLineSegment != null) {
				widget.TextEditor.Document.RemoveMarker (currentDebugLineMarker);
				currentLineSegment = null;
			}
			if (debugStackSegment != null) {
				widget.TextEditor.Document.RemoveMarker (debugStackLineMarker);
				debugStackSegment = null;
			}
		}
 public abstract void Analyze(TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset);
Пример #40
0
 internal protected abstract void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double lineHeight);
Пример #41
0
        internal protected override void Draw(Cairo.Context ctx, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            bool backgroundIsDrawn = false;

            if (lineSegment != null)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawBackground(this))
                    {
                        backgroundIsDrawn = marginMarker.DrawBackground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }

#pragma warning disable 618
                    var iconMarker = marker as IIconBarMarker;
                    if (iconMarker == null || !iconMarker.CanDrawBackground)
                    {
                        continue;
                    }
                    iconMarker.DrawBackground(editor, ctx, lineSegment, line, x, y, (int)Width, editor.LineHeight);
                    backgroundIsDrawn = true;
                    break;
#pragma warning restore 618
                }
            }

            if (!backgroundIsDrawn)
            {
                ctx.Rectangle(x, y, Width, lineHeight);
                ctx.SetSourceColor(backgroundColor);
                ctx.Fill();

                ctx.MoveTo(x + Width - 0.5, y);
                ctx.LineTo(x + Width - 0.5, y + lineHeight);
                ctx.SetSourceColor(separatorColor);
                ctx.Stroke();
            }

            if (lineSegment != null && line <= editor.Document.LineCount)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawForeground(this))
                    {
                        marginMarker.DrawForeground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }

#pragma warning disable 618
                    if (marker is IIconBarMarker)
                    {
                        ((IIconBarMarker)marker).DrawIcon(editor, ctx, lineSegment, line, x, y, (int)Width, editor.LineHeight);
                    }
#pragma warning restore 618
                }
                if (DrawEvent != null)
                {
                    DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, ctx, lineSegment, line, x, y));
                }
            }
        }
Пример #42
0
 public BookmarkMarginDrawEventArgs(MonoTextEditor editor, Cairo.Context context, DocumentLine line, int lineNumber, double xPos, double yPos)
 {
     this.Editor      = editor;
     this.Context     = context;
     this.LineSegment = line;
     this.Line        = lineNumber;
     this.X           = xPos;
     this.Y           = yPos;
 }
Пример #43
0
		public void Initalize (string text, out DocumentLine longestLine)
		{
			longestLine = null;
		}
Пример #44
0
        protected void InsertCharacter(uint unicodeKey)
        {
            if (!textEditorData.CanEdit(Data.Caret.Line))
            {
                return;
            }

            HideMouseCursor();

            using (var undo = Document.OpenUndoGroup()) {
                if (textEditorData.IsSomethingSelected && textEditorData.Options.EnableSelectionWrappingKeys && IsSpecialKeyForSelection(unicodeKey))
                {
                    textEditorData.SelectionSurroundingProvider.HandleSpecialSelectionKey(textEditorData, unicodeKey);
                    return;
                }

                textEditorData.DeleteSelectedText(
                    textEditorData.IsSomethingSelected ? textEditorData.MainSelection.SelectionMode != SelectionMode.Block : true);
                // Needs to be called after delete text, delete text handles virtual caret postitions itself,
                // but afterwards the virtual position may need to be restored.
                textEditorData.EnsureCaretIsNotVirtual();

                char ch = (char)unicodeKey;
                if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line))
                {
                    DocumentLine line = Document.GetLine(Caret.Line);
                    if (Caret.IsInInsertMode || Caret.Column >= line.Length + 1)
                    {
                        string text = ch.ToString();
                        if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
                        {
                            var visualInsertLocation = textEditorData.LogicalToVisualLocation(Caret.Location);
                            var selection            = textEditorData.MainSelection;
                            Caret.PreserveSelection = true;
                            for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++)
                            {
                                DocumentLine lineSegment  = textEditorData.GetLine(lineNumber);
                                int          insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1;
                                string       textToInsert;
                                if (lineSegment.Length < insertOffset)
                                {
                                    int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.Length + 1);
                                    int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                                    int spaceCount       = charsToInsert % editor.Options.TabSize;
                                    textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) +
                                                   new string (' ', spaceCount) + text;
                                    insertOffset = lineSegment.Length;
                                }
                                else
                                {
                                    textToInsert = text;
                                }
                                textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert);
                            }
                            var visualColumn = textEditorData.GetLine(Caret.Location.Line).GetVisualColumn(textEditorData, Caret.Column);

                            textEditorData.MainSelection = new Selection(
                                new DocumentLocation(selection.Anchor.Line, textEditorData.GetLine(selection.Anchor.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                new DocumentLocation(selection.Lead.Line, textEditorData.GetLine(selection.Lead.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                SelectionMode.Block
                                );
                            Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
                        }
                        else
                        {
                            textEditorData.Insert(Caret.Offset, text);
                        }
                    }
                    else
                    {
                        textEditorData.Replace(Caret.Offset, 1, ch.ToString());
                    }
                    // That causes unnecessary redraws:
                    //				bool autoScroll = Caret.AutoScrollToCaret;
//					Caret.Column++;
                    if (Caret.PreserveSelection)
                    {
                        Caret.PreserveSelection = false;
                    }
                    //				Caret.AutoScrollToCaret = autoScroll;
                    //				if (autoScroll)
                    //					Editor.ScrollToCaret ();
                    //				Document.RequestUpdate (new LineUpdate (Caret.Line));
                    //				Document.CommitDocumentUpdate ();
                }
            }
            Document.OptimizeTypedUndo();
        }
Пример #45
0
 public LineEventArgs(DocumentLine line, int lineNumber = -1)
 {
     this.line       = line;
     this.LineNumber = lineNumber;
 }
Пример #46
0
 public string GetLineIndent(DocumentLine segment)
 {
     return(Document.GetLineIndent(segment));
 }
Пример #47
0
            void CopyData(TextEditorData data, Selection selection)
            {
                copiedDocument = null;
                monoDocument   = null;
                if (!selection.IsEmpty && data != null && data.Document != null)
                {
                    copiedDocument      = new TextDocument();
                    monoDocument        = new TextDocument();
                    this.docStyle       = data.ColorStyle;
                    this.options        = data.Options;
                    copyData            = null;
                    copiedColoredChunks = ColoredSegment.GetChunks(data, data.SelectionRange);


                    switch (selection.SelectionMode)
                    {
                    case SelectionMode.Normal:
                        isBlockMode = false;
                        var segment      = selection.GetSelectionRange(data);
                        var pasteHandler = data.TextPasteHandler;
                        if (pasteHandler != null)
                        {
                            copyData = pasteHandler.GetCopyData(segment);
                        }
                        var text = data.GetTextAt(segment);
                        copiedDocument.Text = text;
                        monoDocument.Text   = text;
                        var line      = data.Document.GetLineByOffset(segment.Offset);
                        var spanStack = line.StartSpan.Clone();
                        this.copiedDocument.GetLine(DocumentLocation.MinLine).StartSpan = spanStack;
                        break;

                    case SelectionMode.Block:
                        isBlockMode = true;
                        DocumentLocation visStart = data.LogicalToVisualLocation(selection.Anchor);
                        DocumentLocation visEnd   = data.LogicalToVisualLocation(selection.Lead);
                        int startCol = System.Math.Min(visStart.Column, visEnd.Column);
                        int endCol   = System.Math.Max(visStart.Column, visEnd.Column);
                        for (int lineNr = selection.MinLine; lineNr <= selection.MaxLine; lineNr++)
                        {
                            DocumentLine curLine = data.Document.GetLine(lineNr);
                            int          col1    = curLine.GetLogicalColumn(data, startCol) - 1;
                            int          col2    = System.Math.Min(curLine.GetLogicalColumn(data, endCol) - 1, curLine.Length);
                            if (col1 < col2)
                            {
                                copiedDocument.Insert(copiedDocument.TextLength, data.Document.GetTextAt(curLine.Offset + col1, col2 - col1));
                                monoDocument.Insert(monoDocument.TextLength, data.Document.GetTextAt(curLine.Offset + col1, col2 - col1));
                            }
                            if (lineNr < selection.MaxLine)
                            {
                                // Clipboard line end needs to be system dependend and not the document one.
                                copiedDocument.Insert(copiedDocument.TextLength, Environment.NewLine);
                                // \r in mono document stands for block selection line end.
                                monoDocument.Insert(monoDocument.TextLength, "\r");
                            }
                        }
                        line      = data.Document.GetLine(selection.MinLine);
                        spanStack = line.StartSpan.Clone();
                        this.copiedDocument.GetLine(DocumentLocation.MinLine).StartSpan = spanStack;
                        break;
                    }
                }
                else
                {
                    copiedDocument = null;
                }
            }
Пример #48
0
 public double ColumnToX(DocumentLine line, int column)
 {
     return(TextViewMargin.ColumnToX(line, column));
 }
Пример #49
0
        public static void RemoveIndentSelection(TextEditorData data)
        {
            if (!data.IsSomethingSelected)
            {
                return;
            }
            int startLineNr, endLineNr;

            GetSelectedLines(data, out startLineNr, out endLineNr);

            using (var undo = data.OpenUndoGroup(OperationType.Format)) {
                var          anchor           = data.MainSelection.Anchor;
                var          lead             = data.MainSelection.Lead;
                bool         first            = true;
                bool         removedFromLast  = false;
                int          removeLast       = 0;
                bool         removedFromFirst = false;
                int          removeFirst      = 0;
                var          changes          = new List <Microsoft.CodeAnalysis.Text.TextChange> ();
                DocumentLine last             = null;
                foreach (var line in data.SelectedLines)
                {
                    var remove = RemoveTabInLine(data, line);
                    removedFromLast |= remove.Span.Length > 0;
                    removeLast       = remove.Span.Length;
                    if (first)
                    {
                        removedFromFirst = remove.Span.Length > 0;
                        removeFirst      = remove.Span.Length;
                        first            = false;
                    }
                    if (remove.Span.Length > 0)
                    {
                        changes.Add(remove);
                    }
                    last = line;
                }
                data.Document.ApplyTextChanges(changes);
                if (last != null)
                {
                    data.Document.CommitLineUpdate(last);
                }
                var ac = System.Math.Max(DocumentLocation.MinColumn, anchor.Column - (anchor < lead ? removeFirst : removeLast));
                var lc = System.Math.Max(DocumentLocation.MinColumn, lead.Column - (anchor < lead ? removeLast : removeFirst));

                if (anchor < lead)
                {
                    if (!removedFromFirst)
                    {
                        ac = anchor.Column;
                    }
                    if (!removedFromLast)
                    {
                        lc = lead.Column;
                    }
                }
                else
                {
                    if (!removedFromFirst)
                    {
                        lc = lead.Column;
                    }
                    if (!removedFromLast)
                    {
                        ac = anchor.Column;
                    }
                }
                data.SetSelection(anchor.Line, ac, lead.Line, lc);
            }
            data.Document.RequestUpdate(new MultipleLineUpdate(startLineNr, endLineNr));
            data.Document.CommitDocumentUpdate();
        }
Пример #50
0
 public double GetLineHeight(DocumentLine line)
 {
     return(TextViewMargin.GetLineHeight(line));
 }
Пример #51
0
			public LayoutDescriptor (DocumentLine line, int offset, int length, LayoutWrapper layout, int selectionStart, int selectionEnd) : base(line, offset, length)
			{
				this.Layout = layout;
				if (selectionEnd >= 0) {
					this.SelectionStart = selectionStart;
					this.SelectionEnd = selectionEnd;
				}
			}
Пример #52
0
 internal protected override void Draw(Cairo.Context cr, Cairo.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double lineHeight)
 {
     drawer.Draw(cr, area, line, lineNumber, x, y, lineHeight);
 }
Пример #53
0
		public LayoutWrapper CreateLinePartLayout (ISyntaxMode mode, DocumentLine line, int logicalRulerColumn, int offset, int length, int selectionStart, int selectionEnd)
		{
			bool containsPreedit = textEditor.ContainsPreedit (offset, length);
			LayoutDescriptor descriptor;
			if (!containsPreedit && layoutDict.TryGetValue (line, out descriptor)) {
				bool isInvalid;
				if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid) && descriptor.Layout != null) {
					return descriptor.Layout;
				}
				descriptor.Dispose ();
				layoutDict.Remove (line);
			}
			var wrapper = new LayoutWrapper (PangoUtil.CreateLayout (textEditor));
			wrapper.IsUncached = containsPreedit;
			if (logicalRulerColumn < 0)
				logicalRulerColumn = line.GetLogicalColumn (textEditor.GetTextEditorData (), textEditor.Options.RulerColumn);
			var atts = new FastPangoAttrList ();
			wrapper.Layout.Alignment = Pango.Alignment.Left;
			wrapper.Layout.FontDescription = textEditor.Options.Font;
			wrapper.Layout.Tabs = tabArray;
			if (textEditor.Options.WrapLines) {
				wrapper.Layout.Wrap = Pango.WrapMode.WordChar;
				wrapper.Layout.Width = (int)((textEditor.Allocation.Width - XOffset - TextStartPosition) * Pango.Scale.PangoScale);
			}
			StringBuilder textBuilder = new StringBuilder ();
			var chunks = GetCachedChunks (mode, Document, textEditor.ColorStyle, line, offset, length);
			wrapper.Chunks = chunks;
			foreach (var chunk in chunks) {
				try {
					textBuilder.Append (Document.GetTextAt (chunk));
				} catch {
					Console.WriteLine (chunk);
				}
			}
			int lineOffset = line.Offset;
			string lineText = textBuilder.ToString ();
			uint preeditLength = 0;
			
			if (containsPreedit) {
				if (textEditor.GetTextEditorData ().IsCaretInVirtualLocation) {
					lineText = textEditor.GetTextEditorData ().GetIndentationString (textEditor.Caret.Location) + textEditor.preeditString;
				} else {
					lineText = lineText.Insert (textEditor.preeditOffset - offset, textEditor.preeditString);
				}
				preeditLength = (uint)textEditor.preeditString.Length;
			}
			char[] lineChars = lineText.ToCharArray ();
			//int startOffset = offset, endOffset = offset + length;
			uint curIndex = 0, byteIndex = 0;
			uint curChunkIndex = 0, byteChunkIndex = 0;
			
			uint oldEndIndex = 0;
			foreach (Chunk chunk in chunks) {
				ChunkStyle chunkStyle = chunk != null ? textEditor.ColorStyle.GetChunkStyle (chunk) : null;
				foreach (TextLineMarker marker in line.Markers)
					chunkStyle = marker.GetStyle (chunkStyle);

				if (chunkStyle != null) {
					//startOffset = chunk.Offset;
					//endOffset = chunk.EndOffset;

					uint startIndex = (uint)(oldEndIndex);
					uint endIndex = (uint)(startIndex + chunk.Length);
					oldEndIndex = endIndex;
					var markers = Document.GetTextSegmentMarkersAt (line).Where (m => m.IsVisible).ToArray ();
					HandleSelection (lineOffset, logicalRulerColumn, selectionStart, selectionEnd, chunk.Offset, chunk.EndOffset, delegate(int start, int end) {
						if (containsPreedit) {
							if (textEditor.preeditOffset < start)
								start += (int)preeditLength;
							if (textEditor.preeditOffset < end)
								end += (int)preeditLength;
						}
						var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex);
						var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex);
						var color = ColorStyle.GetForeground (chunkStyle);
						foreach (var marker in markers) {
							var chunkMarker = marker as IChunkMarker;
							if (chunkMarker == null)
								continue;
							chunkMarker.ChangeForeColor (textEditor, chunk, ref color);
						}
						atts.AddForegroundAttribute ((HslColor)color, si, ei);
						
						if (!chunkStyle.TransparentBackground && GetPixel (ColorStyle.PlainText.Background) != GetPixel (chunkStyle.Background)) {
							wrapper.AddBackground (chunkStyle.Background, (int)si, (int)ei);
						} else if (chunk.SpanStack != null && ColorStyle != null) {
							foreach (var span in chunk.SpanStack) {
								if (span == null || string.IsNullOrEmpty (span.Color))
									continue;
								var spanStyle = ColorStyle.GetChunkStyle (span.Color);
								if (spanStyle != null && !spanStyle.TransparentBackground && GetPixel (ColorStyle.PlainText.Background) != GetPixel (spanStyle.Background)) {
									wrapper.AddBackground (spanStyle.Background, (int)si, (int)ei);
									break;
								}
							}
						}
					}, delegate(int start, int end) {
						if (containsPreedit) {
							if (textEditor.preeditOffset < start)
								start += (int)preeditLength;
							if (textEditor.preeditOffset < end)
								end += (int)preeditLength;
						}
						var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex);
						var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex);
						var color = !SelectionColor.TransparentForeground ? SelectionColor.Foreground : ColorStyle.GetForeground (chunkStyle);
						foreach (var marker in markers) {
							var chunkMarker = marker as IChunkMarker;
							if (chunkMarker == null)
								continue;
							chunkMarker.ChangeForeColor (textEditor, chunk, ref color);
						}
						atts.AddForegroundAttribute ((HslColor)color, si, ei);
						if (!wrapper.StartSet)
							wrapper.SelectionStartIndex = (int)si;
						wrapper.SelectionEndIndex = (int)ei;
					});

					var translatedStartIndex = TranslateToUTF8Index (lineChars, (uint)startIndex, ref curChunkIndex, ref byteChunkIndex);
					var translatedEndIndex = TranslateToUTF8Index (lineChars, (uint)endIndex, ref curChunkIndex, ref byteChunkIndex);

					if (chunkStyle.FontWeight != Xwt.Drawing.FontWeight.Normal)
						atts.AddWeightAttribute ((Pango.Weight)chunkStyle.FontWeight, translatedStartIndex, translatedEndIndex);

					if (chunkStyle.FontStyle != Xwt.Drawing.FontStyle.Normal)
						atts.AddStyleAttribute ((Pango.Style)chunkStyle.FontStyle, translatedStartIndex, translatedEndIndex);

					if (chunkStyle.Underline)
						atts.AddUnderlineAttribute (Pango.Underline.Single, translatedStartIndex, translatedEndIndex);
				}
			}
			if (containsPreedit) {
				var si = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset), ref curIndex, ref byteIndex);
				var ei = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset + preeditLength), ref curIndex, ref byteIndex);

				if (textEditor.GetTextEditorData ().IsCaretInVirtualLocation) {
					uint len = (uint)textEditor.GetTextEditorData ().GetIndentationString (textEditor.Caret.Location).Length;
					si += len;
					ei += len;
				}

				atts.AddForegroundAttribute ((HslColor)ColorStyle.PlainText.Foreground, si, ei);
				var hasBackground = wrapper.BackgroundColors.Any (bg => bg.FromIdx <= si && bg.ToIdx >= ei);
				if (hasBackground)
					atts.AddBackgroundAttribute ((HslColor)ColorStyle.PlainText.Background, si, ei);
				atts.InsertOffsetList (textEditor.preeditAttrs, si, ei);
			}
			wrapper.LineChars = lineChars;
			wrapper.Layout.SetText (lineText);
			wrapper.IndentSize = 0;
			for (int i = 0; i < lineChars.Length; i++) {
				char ch = lineChars [i];
				if (ch == ' ') {
					wrapper.IndentSize ++;
				} else if (ch == '\t') {
					wrapper.IndentSize = GetNextTabstop (textEditor.GetTextEditorData (), wrapper.IndentSize);
				} else {
					break;
				}
			}

			var nextLine = line.NextLine;
			wrapper.EolSpanStack = nextLine != null ? nextLine.StartSpan : null;
			atts.AssignTo (wrapper.Layout);
			atts.Dispose ();
			int w, h;
			wrapper.Layout.GetSize (out w, out h);
			wrapper.PangoWidth = w;

			selectionStart = System.Math.Max (line.Offset - 1, selectionStart);
			selectionEnd = System.Math.Min (line.EndOffsetIncludingDelimiter + 1, selectionEnd);
			descriptor = new LayoutDescriptor (line, offset, length, wrapper, selectionStart, selectionEnd);
			if (!containsPreedit)
				layoutDict [line] = descriptor;
			//textEditor.GetTextEditorData ().HeightTree.SetLineHeight (line.LineNumber, System.Math.Max (LineHeight, System.Math.Floor (h / Pango.Scale.PangoScale)));
			return wrapper;
		}
 public TextMarkerEvent(DocumentLine line, TextMarker textMarker) : base(line)
 {
     this.TextMarker = textMarker;
 }
		bool DrawMarginBackground (TextEditor e, Margin margin, Cairo.Context cr, Cairo.Rectangle area, DocumentLine documentLine, long line, double x, double y, double lineHeight)
		{
			if (cache.CurrentSelectedTextMarker != null && cache.CurrentSelectedTextMarker != this)
				return false;
			cr.Rectangle (x, y, margin.Width, lineHeight);
			cr.SetSourceColor (LineColor.Color);
			cr.Fill ();
			return true;
		}
Пример #56
0
        /// <summary>
        /// Transpose characters (Emacs C-t)
        /// </summary>
        public static void TransposeCharacters(TextEditorData data)
        {
            if (data.Caret.Offset == 0)
            {
                return;
            }
            DocumentLine line = data.Document.GetLine(data.Caret.Line);

            if (line == null)
            {
                return;
            }
            int  transposeOffset = data.Caret.Offset - 1;
            char ch;

            if (data.Caret.Column == 0)
            {
                DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1);
                if (lineAbove.Length == 0 && line.Length == 0)
                {
                    return;
                }

                if (line.Length != 0)
                {
                    ch = data.Document.GetCharAt(data.Caret.Offset);
                    data.Remove(data.Caret.Offset, 1);
                    data.Insert(lineAbove.Offset + lineAbove.Length, ch.ToString());
                    data.Document.CommitLineUpdate(data.Caret.Line - 1);
                    return;
                }

                int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1;
                ch = data.Document.GetCharAt(lastCharOffset);
                data.Remove(lastCharOffset, 1);
                data.InsertAtCaret(ch.ToString());
                return;
            }

            int offset = data.Caret.Offset;

            if (data.Caret.Column >= line.Length + 1)
            {
                offset          = line.Offset + line.Length - 1;
                transposeOffset = offset - 1;
                // case one char in line:
                if (transposeOffset < line.Offset)
                {
                    DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1);
                    transposeOffset = lineAbove.Offset + lineAbove.Length;
                    ch = data.Document.GetCharAt(offset);
                    data.Remove(offset, 1);
                    data.Insert(transposeOffset, ch.ToString());
                    data.Caret.Offset = line.Offset;
                    data.Document.CommitLineUpdate(data.Caret.Line - 1);
                    return;
                }
            }

            ch = data.Document.GetCharAt(offset);
            data.Replace(offset, 1, data.Document.GetCharAt(transposeOffset).ToString());
            data.Replace(transposeOffset, 1, ch.ToString());
            if (data.Caret.Column < line.Length + 1)
            {
                data.Caret.Offset = offset + 1;
            }
        }
Пример #57
0
		void UpdateExecutionLocation ()
		{
			if (DebuggingService.IsDebugging && !DebuggingService.IsRunning) {
				var frame = CheckFrameIsInFile (DebuggingService.CurrentFrame)
					?? CheckFrameIsInFile (DebuggingService.GetCurrentVisibleFrame ());
				if (frame != null) {
					if (lastDebugLine == frame.SourceLocation.Line)
						return;
					RemoveDebugMarkers ();
					lastDebugLine = frame.SourceLocation.Line;
					var segment = widget.TextEditor.Document.GetLine (lastDebugLine);
					if (segment != null) {
						if (DebuggingService.CurrentFrameIndex == 0) {
							currentLineSegment = segment;
							widget.TextEditor.Document.AddMarker (segment, currentDebugLineMarker);
						} else {
							debugStackSegment = segment;
							widget.TextEditor.Document.AddMarker (segment, debugStackLineMarker);
						}
						widget.TextEditor.QueueDraw ();
					}
					return;
				}
			}
			
			if (currentLineSegment != null || debugStackSegment != null) {
				RemoveDebugMarkers ();
				lastDebugLine = -1;
				widget.TextEditor.QueueDraw ();
			}
		}
 public MdTextViewLine(MdTextViewLineCollection collection, MonoTextEditor textEditor, DocumentLine line, int lineNumber, TextViewMargin.LayoutWrapper layoutWrapper)
 {
     this.collection      = collection;
     this.layoutWrapper   = layoutWrapper;
     this.textEditor      = textEditor;
     this.line            = line;
     this.LineNumber      = lineNumber;
     this.lineSpan        = new SnapshotSpan(textEditor.VisualSnapshot, line.Offset, line.LengthIncludingDelimiter);
     this.lineBreakLength = line.DelimiterLength;
 }
Пример #59
0
		public ErrorMarker (TextDocument doc, Error info, DocumentLine line)
		{
			Info = info;
			LineSegment = line;
			// may be null if no line is assigned to the error.
			Wave = true;
			
			StartCol = Info.Region.BeginColumn;
			if (line != null) {
				var startOffset = line.Offset;
				if (startOffset + StartCol - 1 >= 0) {
					while (StartCol < line.Length) {
						char ch = doc.GetCharAt (startOffset + StartCol - 1);
						if (!char.IsWhiteSpace (ch))
							break;
						StartCol++;
					}
				}
			}

			if (Info.Region.EndColumn > StartCol) {
				EndCol = Info.Region.EndColumn;
			} else {
				if (line == null) {
					EndCol = StartCol + 1;
					return;
				}
				var start = line.Offset + StartCol - 1;
				int o = start + 1;
				while (o < line.EndOffset) {
					char ch = doc.GetCharAt (o);
					if (!(char.IsLetterOrDigit (ch) || ch == '_'))
						break;
					o++;
				}
				EndCol = Info.Region.BeginColumn + o - start + 1;
			}
		}
Пример #60
0
        internal protected override void Draw(Cairo.Context ctx, Cairo.Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight)
        {
            bool backgroundIsDrawn = false;

            if (lineSegment != null)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawBackground(this))
                    {
                        backgroundIsDrawn = marginMarker.DrawBackground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }
                }
            }

            if (!backgroundIsDrawn)
            {
                ctx.Rectangle(x, y, Width, lineHeight);
                ctx.SetSourceColor(backgroundColor);
                ctx.Fill();

                ctx.MoveTo(x + Width - 0.5, y);
                ctx.LineTo(x + Width - 0.5, y + lineHeight);
                ctx.SetSourceColor(separatorColor);
                ctx.Stroke();
            }

            if (lineSegment != null && line <= editor.Document.LineCount)
            {
                foreach (var marker in lineSegment.Markers)
                {
                    var marginMarker = marker as MarginMarker;
                    if (marginMarker != null && marginMarker.CanDrawForeground(this))
                    {
                        marginMarker.DrawForeground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight));
                    }
                }
                if (DrawEvent != null)
                {
                    DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, ctx, lineSegment, line, x, y));
                }
            }
        }