Esempio n. 1
0
        private void FormatLine()
        {
            //
            getEditorPreferences(TextView);
            //
            SnapshotPoint     caret = this.TextView.Caret.Position.BufferPosition;
            ITextSnapshotLine line  = caret.GetContainingLine();
            // On what line are we ?
            bool alignOnPrev = false;
            int  lineNumber  = line.LineNumber;
            int  indentation = -1;

            // we calculate the indent based on the previous line so we must be on the second line
            if (lineNumber > 0)
            {
                if (caret.Position < line.End.Position)
                {
                    alignOnPrev = true;
                }

                // wait until we can work
                while (_buffer.EditInProgress)
                {
                    System.Threading.Thread.Sleep(100);
                }
                var editSession = _buffer.CreateEdit();
                // This will calculate the desired indentation of the current line, based on the previous one
                // and may de-Indent the previous line if needed
                indentation = getDesiredIndentation(line, editSession, alignOnPrev);
                //
                try
                {
                    // but we may need to re-Format the previous line for Casing and Identifiers
                    // so, do it before indenting the current line.
                    lineNumber = lineNumber - 1;
                    ITextSnapshotLine prevLine = line.Snapshot.GetLineFromLineNumber(lineNumber);
                    this.formatLineCase(editSession, prevLine);
                    CommandFilterHelper.FormatLineIndent(this.TextView, editSession, line, indentation);
                }
                finally
                {
                    if (editSession.HasEffectiveChanges)
                    {
                        editSession.Apply();
                    }
                    else
                    {
                        editSession.Cancel();
                    }
                }
            }
        }
Esempio n. 2
0
 /// <summary>
 /// the indentation is measured in # of characters
 /// </summary>
 /// <param name="line"></param>
 /// <param name="editSession"></param>
 /// <param name="alignOnPrev"></param>
 /// <returns></returns>
 private int getDesiredIndentation(ITextSnapshotLine line, ITextEdit editSession, bool alignOnPrev)
 {
     try
     {
         //
         if (_indentStyle != vsIndentStyle.vsIndentStyleSmart)
         {
             return(-1);
         }
         // How many spaces do we need ?
         int    indentValue = 0;
         string outdentToken;
         // On what line are we ?
         int lineNumber = line.LineNumber;
         if (lineNumber > 0)
         {
             // We need to analyze the Previous line
             lineNumber = lineNumber - 1;
             ITextSnapshotLine prevLine = line.Snapshot.GetLineFromLineNumber(lineNumber);
             bool   doSkipped;
             string keyword = getFirstKeywordInLine(prevLine, out doSkipped, out indentValue);
             if (indentValue < 0)
             {
                 indentValue = 0;
             }
             _lastIndentValue = indentValue;
             if (alignOnPrev)
             {
                 return(_lastIndentValue);
             }
             // ok, now check what we have, starting the previous line
             if (!String.IsNullOrEmpty(keyword))// && !doSkipped)
             {
                 // Start of a block of code ?
                 if (_codeBlockKeywords.Contains <String>(keyword))
                 {
                     if (!_alignMethod)
                     {
                         indentValue += _indentSize;
                     }
                 }
                 else if (_specialCodeBlockKeywords.Contains <String>(keyword))
                 {
                     if (!_alignMethod)
                     {
                         indentValue += _indentSize;
                     }
                 }
                 else if (_indentKeywords.Contains <String>(keyword))
                 {
                     indentValue += _indentSize;
                 }
                 else if ((outdentToken = searchSpecialOutdentKeyword(keyword)) != null)
                 {
                     // Ok, let's try to make it smooth...
                     int specialOutdentValue = -1;
                     // The startToken is a list of possible tokens
                     specialOutdentValue = alignToSpecificTokens(line, outdentToken);
                     if (specialOutdentValue >= 0)
                     {
                         indentValue = (int)specialOutdentValue;
                     }
                     // De-Indent previous line !!!
                     try
                     {
                         CommandFilterHelper.FormatLineIndent(this.TextView, editSession, prevLine, indentValue);
                     }
                     catch (Exception ex)
                     {
                         XSharpProjectPackage.Instance.DisplayOutPutMessage("Indentation of previous line failed");
                         XSharpProjectPackage.Instance.DisplayException(ex);
                     }
                 }
                 else
                 {
                     string startToken         = searchMiddleKeyword(keyword);
                     int    specialIndentValue = -1;
                     if (startToken != null)
                     {
                         // Retrieve the Indentation for the previous line
                         specialIndentValue = alignToSpecificTokens(line, startToken);
                     }
                     else
                     {
                         if (doSkipped && keyword == "CASE")
                         {
                             if (!_alignDoCase)
                             {
                                 indentValue += _indentSize;
                             }
                         }
                         else
                         {
                             // We could have "special" middle keyword : CASE or OTHERWISE
                             startToken = searchSpecialMiddleKeyword(keyword);
                             if (startToken != null)
                             {
                                 // The startToken is a list of possible tokens
                                 specialIndentValue = alignToSpecificTokens(line, startToken);
                                 // The can be aligned to SWITCH/DO CASE or indented
                                 if (!_alignDoCase)
                                 {
                                     specialIndentValue += _indentSize;
                                 }
                             }
                         }
                     }
                     if (specialIndentValue != -1)
                     {
                         try
                         {
                             // De-Indent previous line !!!
                             CommandFilterHelper.FormatLineIndent(this.TextView, editSession, prevLine, specialIndentValue);
                             indentValue = specialIndentValue + _indentSize;
                         }
                         catch (Exception ex)
                         {
                             XSharpProjectPackage.Instance.DisplayOutPutMessage("Error indenting of current line ");
                             XSharpProjectPackage.Instance.DisplayException(ex);
                         }
                     }
                 }
                 if (indentValue < 0)
                 {
                     indentValue = 0;
                 }
                 _lastIndentValue = indentValue;
             }
             return(_lastIndentValue);
         }
     }
     catch (Exception ex)
     {
         XSharpProjectPackage.Instance.DisplayOutPutMessage("SmartIndent.GetDesiredIndentation failed: ");
         XSharpProjectPackage.Instance.DisplayException(ex);
     }
     return(_lastIndentValue);
 }
Esempio n. 3
0
        private void FormatDocument()
        {
            XSharpProjectPackage.Instance.DisplayOutPutMessage("CommandFilter.FormatDocument()");
            if (!_buffer.CheckEditAccess())
            {
                // can't edit !
                return;
            }
            // Read Settings
            getEditorPreferences(TextView);
            formatCaseForWholeBuffer();
            // Try to retrieve an already parsed list of Tags
            if (_classifier != null)
            {
#if TRACE
                //
                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();
#endif
                //
                ITextSnapshot snapshot        = _classifier.Snapshot;
                SnapshotSpan  Span            = new SnapshotSpan(snapshot, 0, snapshot.Length);
                var           classifications = _classifier.GetRegionTags();
                // We cannot use SortedList, because we may have several Classification that start at the same position
                List <ClassificationSpan> sortedTags = new List <ClassificationSpan>();
                foreach (var tag in classifications)
                {
                    sortedTags.Add(tag);
                }
                sortedTags.Sort((a, b) => a.Span.Start.Position.CompareTo(b.Span.Start.Position));
                // Now that Tags are sorted, we can use a stack to arrange them by pairs
                Stack <Span> regionStarts          = new Stack <Span>();
                List <Tuple <Span, Span> > regions = new List <Tuple <Span, Span> >();
                //
                foreach (var tag in sortedTags)
                {
                    if (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpRegionStartFormat))
                    {
                        regionStarts.Push(tag.Span.Span);
                    }
                    else if (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpRegionStopFormat))
                    {
                        if (regionStarts.Count > 0)
                        {
                            var start = regionStarts.Pop();
                            regions.Add(new Tuple <Span, Span>(start, tag.Span.Span));
                        }
                    }
                }
                // In order to try to speed up the formatting process, it would be good to have the regions sorted by their Start
                regions.Sort((a, b) => a.Item1.Start.CompareTo(b.Item1.Start));
                //Now, we have a list of Regions Start/Stop
                // wait until we can work
                while (_buffer.EditInProgress)
                {
                    System.Threading.Thread.Sleep(100);
                }
                var editSession = _buffer.CreateEdit();
                try
                {
                    var  lines          = _buffer.CurrentSnapshot.Lines;
                    int  indentSize     = 0;
                    bool inComment      = false;
                    bool prevContinue   = false;
                    int  prevIndentSize = 0;
                    foreach (var snapLine in lines)
                    {
                        // Ignore Empty lines
                        if (snapLine.Length > 0)
                        {
                            SnapshotSpan sSpan    = new SnapshotSpan(snapLine.Start, snapLine.End);
                            string       lineText = sSpan.GetText();
                            lineText = lineText.Trim();
                            if (lineText.Length > 0)
                            {
                                char start = lineText.Substring(0, 1)[0];
                                char end   = lineText.Substring(lineText.Length - 1, 1)[0];
                                //
                                if (prevContinue)
                                {
                                    indentSize = prevIndentSize;
                                }
                                else
                                {
                                    indentSize = getDesiredIndentationInDocument(snapLine, regions, out inComment);
                                }
                                if (!inComment && (end == ';'))
                                {
                                    // Keep the previous Indentation
                                    prevContinue   = true;
                                    prevIndentSize = indentSize;
                                }
                                else
                                {
                                    prevContinue = false;
                                }
                            }
                        }
                        formatLineCase(editSession, snapLine);
                        CommandFilterHelper.FormatLineIndent(this.TextView, editSession, snapLine, indentSize);
                    }
                }
                finally
                {
                    if (editSession.HasEffectiveChanges)
                    {
                        editSession.Apply();
                    }
                    else
                    {
                        editSession.Cancel();
                    }
                }
                //
#if TRACE
                stopWatch.Stop();
                // Get the elapsed time as a TimeSpan value.
                TimeSpan ts = stopWatch.Elapsed;

                // Format and display the TimeSpan value.
                string elapsedTime = String.Format("{0:00}h {1:00}m {2:00}.{3:00}s",
                                                   ts.Hours, ts.Minutes, ts.Seconds,
                                                   ts.Milliseconds / 10);
                //
                XSharpProjectPackage.Instance.DisplayOutPutMessage("FormatDocument : Done in " + elapsedTime);
#endif
            }
        }