/// <summary>
        /// Determines whether or not the user just entered a triple slash (///) on a blank line.
        /// </summary>
        /// <returns>True if a triple slash occurred on an otherwise blank line, false if it
        /// didn't.</returns>
        /// <remarks>
        /// I tried to make this implementation as robust as possible; it actually figures out where
        /// in the current line the caret lives and adds the "/" character to the line at that location
        /// before checking to see if a triple slash occurred or not. This should get rid of any weird
        /// behavior where a triple slash gets incorrectly triggered when there isn't actually one
        /// on the line (e.g. if there's whitespace between the forward slash characters). As far as
        /// I can tell, this really does only get triggered if there are three contiguous slashes on
        /// an otherwise blank line (leading or trailing whitespace doesn't count).
        /// </remarks>
        private bool UserTypedTripleSlash()
        {
            // Convert the caret's location in screen (pixel) space to the corresponding character index in the editor text box's
            // buffer. We need this to figure out the location of the caret in the current line.
            CaretPosition caretPosition        = TextView.Caret.Position;
            SnapshotPoint?snapshotPointWrapper = caretPosition.Point.GetPoint(TextView.TextSnapshot, caretPosition.Affinity);

            if (snapshotPointWrapper == null)
            {
                return(false);
            }
            SnapshotPoint snapshotPoint = snapshotPointWrapper.Value;

            // Get the current line being edited, along with its starting position in the text snapshot
            ITextSnapshotLine currentLine = snapshotPoint.GetContainingLine();
            string            lineText    = currentLine.GetTextIncludingLineBreak();
            int lineStart = currentLine.Start;

            // Add the forward slash to the line, based on where the caret is
            int caretIndexInLine = snapshotPoint - lineStart;

            lineText = lineText.Insert(caretIndexInLine, "/");

            // Return whether or not the new line is a triple slash
            return(lineText.Trim().Equals("///"));
        }
Exemplo n.º 2
0
        public int PerformMove(IWpfTextView view, ITextSnapshotLine lineToSwap, int insertPosition)
        {
            var insertedText = lineToSwap.GetTextIncludingLineBreak();

            if(insertPosition == view.TextSnapshot.Length)
            {
                // We don't want ot move the line break if the insert position is the last character of the
                // document but also the first character of the line (i.e. an empty line at the end of the document)
                var lineUnderInsertPosition = view.TextSnapshot.GetLineFromPosition(insertPosition);
                if (lineUnderInsertPosition.Length > 0)
                {
                    // Move the line break to the start of the text to insert
                    insertedText = (Environment.NewLine + insertedText).Substring(0, insertedText.Length);
                }
            }

            using (var edit = view.TextBuffer.CreateEdit())
            {
                edit.Delete(lineToSwap.Start, lineToSwap.LengthIncludingLineBreak);
                edit.Insert(insertPosition, insertedText);
                edit.Apply();
            }

            return -lineToSwap.LengthIncludingLineBreak;
        }
Exemplo n.º 3
0
        int?ISmartIndent.GetDesiredIndentation(ITextSnapshotLine line)
        {
            line = GetPreviousNonEmpty(line);
            int whitespace = 0;

            if (line != null)
            {
                string linestr = line.GetTextIncludingLineBreak();
                int    tabs    = linestr.Count(x => { return(x == '\t'); });
                int    length  = (linestr.Length - tabs) + (tabs * 4);
                string scope   = linestr.Replace("\n", "");
                scope = scope.Replace("\r", "");
                scope = scope.Replace("\t", "");
                scope = scope.TrimStart();
                bool isscope    = scope.Length > 0;
                bool beginscope = isscope && scope.Last() == '{';
                bool endscope   = isscope && scope.Last() == '}';
                if (scope.Length == 1)
                {
                    if (beginscope)
                    {
                        // if ((length % 4) != 0)
                        //     length += 4;
                        return((int)(length / 4 * 4));
                    }
                }

                whitespace  = linestr.Length - linestr.TrimStart(' ').Length;
                whitespace += (linestr.Length - linestr.TrimStart('\t').Length) * 4;

                /*if (beginscope)
                 * {
                 *  whitespace += 4;
                 * }*/
            }
            whitespace = (whitespace / 4) * 4;
            return(whitespace);

            /*SQDeclaration d = _languageService.LanguageInstance.Dive(line.Snapshot.TextBuffer, line.LineNumber, line.Length);
             * if (d == null || d is SQDeclaration.SQFile)
             *  return 0;
             * if (d.ScopeSpan.iEndLine <= line.LineNumber)
             * {
             *  int level = d.Level;
             *  return 4 * level;
             * }
             * else
             * {
             *  int level = d.Level + 1;
             *  return 4 * level;
             * }*/
        }
Exemplo n.º 4
0
 public LineBuffer(ITextSnapshotLine line)
 {
     this.line = line;
     if (line.LengthIncludingLineBreak <= BufferSize)
     {
         this.contents = line.GetTextIncludingLineBreak();
         this.extent   = new Span(0, line.LengthIncludingLineBreak);
     }
     else
     {
         this.extent = new Span(0, 0);
     }
 }
Exemplo n.º 5
0
        public int PerformMove(IWpfTextView view, ITextSnapshotLine lineToSwap, int insertPosition)
        {
            var insertedText = lineToSwap.GetTextIncludingLineBreak();
            var deleteStartPosition = lineToSwap.Start.Position;

            if(lineToSwap.End == lineToSwap.EndIncludingLineBreak)
            {
                insertedText = insertedText + Environment.NewLine;
                deleteStartPosition = deleteStartPosition - Environment.NewLine.Length;
            }

            using (var edit = view.TextBuffer.CreateEdit())
            {
                edit.Delete(deleteStartPosition, insertedText.Length);
                edit.Insert(insertPosition, insertedText);
                edit.Apply();
            }

            return insertedText.Length;
        }
Exemplo n.º 6
0
        private void UpdateCachedLine()
        {
            if (_explicitCache)
            {
                return;
            }

            if (_currentSnapshotLine == null ||
                Index < _currentSnapshotLineStartIndex ||
                Index >= _currentSnapshotLineStartIndex + _currentSnapshotLine.Length)
            {
                if (Index >= 0 && Index < Count)
                {
                    ITextSnapshotLine line = Snapshot.GetLineFromPosition(Index);
                    _currentSnapshotLineStartIndex = line.Start;
                    _currentSnapshotLine           = line.GetTextIncludingLineBreak();
                }
                else
                {
                    _currentSnapshotLine           = null;
                    _currentSnapshotLineStartIndex = 0;
                }
            }
        }
Exemplo n.º 7
0
        private void Jump(JumpDirection direction)
        {
            // as with the standard caret moving operations (click, arrow keys, etc.)
            // we clear our current selection when we jump
            View.Selection.Clear();

            // rules:
            // if the line we begin on contains text, or the following line contains text,
            // navigate to the next blank line
            // if the line we begin on is blank, and the next line is also blank,
            // navigate to the line preceding the next line that contains text
            // if we find no suitable lines, we navigate to the last line
            CaretPosition startingPos     = View.Caret.Position;
            ITextBuffer   buffer          = View.TextBuffer;
            ITextSnapshot currentSnapshot = buffer.CurrentSnapshot;
            SnapshotPoint start           = startingPos.BufferPosition;

            ITextSnapshotLine previousLine = start.GetContainingLine();
            ITextSnapshotLine targetLine   = null;
            bool previousLineIsBlank       = string.IsNullOrWhiteSpace(previousLine.GetTextIncludingLineBreak());
            int  startLineNo = currentSnapshot.GetLineNumberFromPosition(start.Position);
            int  lineInc     = (int)direction;
            int  firstLine   = startLineNo + lineInc;

            for (int i = firstLine; i >= 0 && i < currentSnapshot.LineCount; i += lineInc)
            {
                ITextSnapshotLine line         = currentSnapshot.GetLineFromLineNumber(i);
                string            lineContents = line.GetTextIncludingLineBreak();
                bool lineIsBlank = string.IsNullOrWhiteSpace(lineContents);
                if (lineIsBlank)
                {
                    if (!previousLineIsBlank && i != firstLine)
                    {
                        // found our next blank line beyond our text block
                        targetLine = (JumpOutsideEdge) ? line : previousLine;
                        break;
                    }
                }
                else if (!SkipClosestEdge && previousLineIsBlank && i != firstLine)
                {
                    // found our text block, go to the blank line right before it
                    targetLine = (JumpOutsideEdge) ? previousLine : line;
                    break;
                }

                previousLine        = line;
                previousLineIsBlank = lineIsBlank;
            }

            if (targetLine != null)
            {
                VirtualSnapshotPoint finalPosition;
                if (JumpOutsideEdge)
                {
                    // move the caret to the blank line indented with the appropriate number of virtual spaces
                    int?virtualSpaces = SmartIndentation.GetDesiredIndentation(View, targetLine);
                    finalPosition = new VirtualSnapshotPoint(targetLine.Start, virtualSpaces.GetValueOrDefault());
                    if (!finalPosition.IsInVirtualSpace)
                    {
                        // our line has some 'meaningful' whitespace, go to end instead
                        finalPosition = new VirtualSnapshotPoint(targetLine.End);
                    }
                }
                else
                {
                    string lineString = targetLine.GetTextIncludingLineBreak();
                    int    offset     = lineString.TakeWhile(c => char.IsWhiteSpace(c)).Count();
                    finalPosition = new VirtualSnapshotPoint(targetLine, offset);
                }
                View.Caret.MoveTo(finalPosition);
            }
            else
            {
                // we found no suitable line so just choose BOF or EOF depending on the direction we were moving
                if (direction == JumpDirection.Up)
                {
                    View.Caret.MoveTo(previousLine.Start);
                }
                else
                {
                    View.Caret.MoveTo(previousLine.End);
                }
            }

            // scroll our view to the new caret position
            View.Caret.EnsureVisible();
        }
 internal static string DefaultGetLineTextCallback(ITextSnapshotLine line)
 {
     return(line.GetTextIncludingLineBreak());
 }
Exemplo n.º 9
0
        public override void Execute()
        {
            ITextSnapshot snapshot = _view.TextSnapshot;

            if (snapshot != snapshot.TextBuffer.CurrentSnapshot)
            {
                return;
            }

            if (_view.Selection.IsEmpty)
            {
                // nothing is selected, duplicate current line
                using (var edit = snapshot.TextBuffer.CreateEdit())
                {
                    ITextSnapshotLine line = snapshot.GetLineFromPosition(_view.Selection.AnchorPoint.Position.Position);
                    edit.Insert(line.EndIncludingLineBreak.Position, line.GetTextIncludingLineBreak());
                    edit.Apply();
                }
            }
            else
            {
                // duplicate selection

                // If we have a multi-line stream slection, it is likely that the user wants to
                // duplicate all lines in the selection. Extend the selection to accomplish this
                // if necessary.
                if (_view.Selection.Mode == TextSelectionMode.Stream)
                {
                    var startLine = snapshot.GetLineFromPosition(_view.Selection.Start.Position.Position);
                    var endLine   = snapshot.GetLineFromPosition(_view.Selection.End.Position.Position);
                    if (startLine.LineNumber != endLine.LineNumber &&
                        (!_view.Selection.IsReversed || _view.Selection.End.Position != endLine.End))
                    {
                        // selection spans multiple lines
                        var newSelStart = _view.Selection.Start.Position;
                        var newSelEnd   = _view.Selection.End.Position;
                        if (startLine.Start < newSelStart)
                        {
                            newSelStart = startLine.Start;
                        }
                        if (endLine.Start != newSelEnd)
                        {
                            newSelEnd = endLine.EndIncludingLineBreak;
                        }
                        if (_view.Selection.Start.Position != newSelStart || _view.Selection.End.Position != newSelEnd)
                        {
                            _view.Selection.Select(new SnapshotSpan(newSelStart, newSelEnd), false);
                            _view.Caret.MoveTo(newSelEnd, PositionAffinity.Predecessor);
                        }
                    }
                }

                // When text is inserted into a pre-existing selection, VS extends the selection
                // to also contain the inserted text. This is not desired in this case, so save
                // the current selection so we can revert to it later.
                var initAnchor = _view.Selection.AnchorPoint;
                var initActive = _view.Selection.ActivePoint;

                using (var edit = snapshot.TextBuffer.CreateEdit())
                {
                    // Unless this is a box selection there will likely only be one span.
                    // Iterate backwards over the spans so we don't have to change the insertion point
                    // to compensate for already-inserted text.
                    foreach (var span in _view.Selection.SelectedSpans.Reverse())
                    {
                        if (!span.IsEmpty)
                        {
                            edit.Insert(span.End.Position, span.GetText());
                        }
                    }
                    edit.Apply();
                }

                var newAnchor = initAnchor.TranslateTo(_view.TextSnapshot, PointTrackingMode.Negative);
                var newActive = initActive.TranslateTo(_view.TextSnapshot, PointTrackingMode.Negative);
                _view.Selection.Select(newAnchor, newActive);
                _view.Caret.MoveTo(newActive, PositionAffinity.Predecessor);
            }
        }