|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Text.Shared.Extensions
{
internal static class ITextSnapshotLineExtensions
{
/// <summary>
/// Returns the first non-whitespace position on the given line, or null if
/// the line is empty or contains only whitespace.
/// </summary>
public static int? GetFirstNonWhitespacePosition(this ITextSnapshotLine line)
{
Contract.ThrowIfNull(line);
var text = line.GetText();
for (var i = 0; i < text.Length; i++)
{
if (!char.IsWhiteSpace(text[i]))
{
return line.Start + i;
}
}
return null;
}
/// <summary>
/// Returns the first non-whitespace position on the given line as an offset
/// from the start of the line, or null if the line is empty or contains only
/// whitespace.
/// </summary>
public static int? GetFirstNonWhitespaceOffset(this ITextSnapshotLine line)
{
Contract.ThrowIfNull(line);
var text = line.GetText();
for (var i = 0; i < text.Length; i++)
{
if (!char.IsWhiteSpace(text[i]))
{
return i;
}
}
return null;
}
/// <summary>
/// Returns the last non-whitespace position on the given line, or null if
/// the line is empty or contains only whitespace.
/// </summary>
public static int? GetLastNonWhitespacePosition(this ITextSnapshotLine line)
=> line.AsTextLine().GetLastNonWhitespacePosition();
/// <summary>
/// Determines whether the specified line is empty or contains whitespace only.
/// </summary>
public static bool IsEmptyOrWhitespace(this ITextSnapshotLine line, int startIndex = 0, int endIndex = -1)
{
Contract.ThrowIfNull(line, "line");
Contract.ThrowIfFalse(startIndex >= 0);
var text = line.GetText();
if (endIndex == -1)
{
endIndex = text.Length;
}
for (var i = startIndex; i < endIndex; i++)
{
if (!char.IsWhiteSpace(text[i]))
{
return false;
}
}
return true;
}
public static ITextSnapshotLine? GetPreviousMatchingLine(this ITextSnapshotLine line, Func<ITextSnapshotLine, bool> predicate)
{
Contract.ThrowIfNull(line, @"line");
Contract.ThrowIfNull(predicate, @"tree");
if (line.LineNumber <= 0)
{
return null;
}
var snapshot = line.Snapshot;
for (var lineNumber = line.LineNumber - 1; lineNumber >= 0; lineNumber--)
{
var currentLine = snapshot.GetLineFromLineNumber(lineNumber);
if (!predicate(currentLine))
{
continue;
}
return currentLine;
}
return null;
}
public static int GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(this ITextSnapshotLine line, IEditorOptions editorOptions)
=> line.GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(editorOptions.GetTabSize());
public static int GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(this ITextSnapshotLine line, int tabSize)
=> line.GetText().GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(tabSize);
public static int GetColumnFromLineOffset(this ITextSnapshotLine line, int lineOffset, IEditorOptions editorOptions)
=> line.GetText().GetColumnFromLineOffset(lineOffset, editorOptions.GetTabSize());
public static int GetLineOffsetFromColumn(this ITextSnapshotLine line, int column, IEditorOptions editorOptions)
=> line.GetText().GetLineOffsetFromColumn(column, editorOptions.GetTabSize());
/// <summary>
/// Checks if the given line at the given snapshot index starts with the provided value.
/// </summary>
public static bool StartsWith(this ITextSnapshotLine line, int index, string value, bool ignoreCase)
{
var snapshot = line.Snapshot;
if (index + value.Length > snapshot.Length)
return false;
for (var i = 0; i < value.Length; i++)
{
var snapshotIndex = index + i;
var actualCharacter = snapshot[snapshotIndex];
var expectedCharacter = value[i];
if (ignoreCase)
{
actualCharacter = char.ToLowerInvariant(actualCharacter);
expectedCharacter = char.ToLowerInvariant(expectedCharacter);
}
if (actualCharacter != expectedCharacter)
return false;
}
return true;
}
public static bool Contains(this ITextSnapshotLine line, int index, string value, bool ignoreCase)
{
var snapshot = line.Snapshot;
for (var i = index; i < line.End; i++)
{
if (i + value.Length > snapshot.Length)
return false;
if (line.StartsWith(i, value, ignoreCase))
return true;
}
return false;
}
}
}
|