Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
1,032 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 2012 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "STools", "STools\STools.csproj", "{7F76394A-6480-4F47-BAC0-8B8C5D2605DA}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{7F76394A-6480-4F47-BAC0-8B8C5D2605DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{7F76394A-6480-4F47-BAC0-8B8C5D2605DA}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{7F76394A-6480-4F47-BAC0-8B8C5D2605DA}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{7F76394A-6480-4F47-BAC0-8B8C5D2605DA}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel.Composition; | ||
using System.Diagnostics; | ||
|
||
using Microsoft.VisualStudio; | ||
using Microsoft.VisualStudio.Editor; | ||
using Microsoft.VisualStudio.OLE.Interop; | ||
using Microsoft.VisualStudio.Text.Editor; | ||
using Microsoft.VisualStudio.TextManager.Interop; | ||
using Microsoft.VisualStudio.Utilities; | ||
|
||
|
||
namespace S2.STools | ||
{ | ||
[Export(typeof(IVsTextViewCreationListener))] | ||
[ContentType("code")] | ||
[TextViewRole(PredefinedTextViewRoles.Editable)] | ||
class VsTextViewCreationListener : IVsTextViewCreationListener | ||
{ | ||
[Import] | ||
IVsEditorAdaptersFactoryService AdaptersFactory = null; | ||
|
||
public void VsTextViewCreated(IVsTextView textViewAdapter) | ||
{ | ||
var wpfTextView = AdaptersFactory.GetWpfTextView(textViewAdapter); | ||
if (wpfTextView == null) | ||
{ | ||
Debug.Fail("Unable to get IWpfTextView from text view adapter"); | ||
return; | ||
} | ||
|
||
CommandFilter filter = new CommandFilter(wpfTextView); | ||
|
||
IOleCommandTarget next; | ||
if (ErrorHandler.Succeeded(textViewAdapter.AddCommandFilter(filter, out next))) | ||
filter.Next = next; | ||
} | ||
} | ||
|
||
class CommandFilter : IOleCommandTarget | ||
{ | ||
IWpfTextView _view; | ||
List<Commands.ICommand> _commandList = new List<Commands.ICommand>(); | ||
|
||
public CommandFilter(IWpfTextView view) | ||
{ | ||
_view = view; | ||
_commandList.Add(new Commands.DocumentThis(_view)); | ||
} | ||
|
||
internal IOleCommandTarget Next { get; set; } | ||
|
||
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) | ||
{ | ||
if (pguidCmdGroup != GuidList.guidSToolsCmdSet) return Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); | ||
|
||
Commands.ICommand command = _commandList.Find(c => c.IsYourId(nCmdID)); | ||
Debug.Assert(command != null); | ||
command.Execute(); | ||
return VSConstants.S_OK; | ||
} | ||
|
||
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) | ||
{ | ||
if (pguidCmdGroup != GuidList.guidSToolsCmdSet) return Next.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); | ||
prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED); | ||
Commands.ICommand command = _commandList.Find(c => c.IsYourId(prgCmds[0].cmdID)); | ||
Debug.Assert(command != null); | ||
if (command.IsEnable()) | ||
{ | ||
prgCmds[0].cmdf |= (uint)OLECMDF.OLECMDF_ENABLED; | ||
} | ||
return VSConstants.S_OK; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
using Microsoft.VisualStudio; | ||
using Microsoft.VisualStudio.Editor; | ||
using Microsoft.VisualStudio.OLE.Interop; | ||
using Microsoft.VisualStudio.Text; | ||
using Microsoft.VisualStudio.Text.Editor; | ||
using Microsoft.VisualStudio.TextManager.Interop; | ||
using Microsoft.VisualStudio.Utilities; | ||
|
||
namespace S2.STools.Commands | ||
{ | ||
class DocumentThis : ICommand | ||
{ | ||
IWpfTextView _view; | ||
|
||
public DocumentThis(IWpfTextView view) | ||
{ | ||
_view = view; | ||
} | ||
|
||
public bool IsYourId(uint commandId) | ||
{ | ||
return commandId == PkgCmdIDList.CommandIdDocumentThis; | ||
} | ||
|
||
public bool IsEnable() | ||
{ | ||
return _view.Caret.Position.BufferPosition.GetContainingLine().GetText().Contains("="); | ||
} | ||
|
||
public void Execute() | ||
{ | ||
AlignAssignments(); | ||
} | ||
|
||
private void AlignAssignments() | ||
{ | ||
// Find all lines above and below with = signs | ||
ITextSnapshot snapshot = _view.TextSnapshot; | ||
|
||
if (snapshot != snapshot.TextBuffer.CurrentSnapshot) | ||
return; | ||
|
||
int currentLineNumber = snapshot.GetLineNumberFromPosition(_view.Caret.Position.BufferPosition); | ||
|
||
Dictionary<int, ColumnAndOffset> lineNumberToEqualsColumn = new Dictionary<int, ColumnAndOffset>(); | ||
|
||
// Start with the current line | ||
ColumnAndOffset columnAndOffset = GetColumnNumberOfFirstEquals(snapshot.GetLineFromLineNumber(currentLineNumber)); | ||
if (columnAndOffset.Column == -1) | ||
return; | ||
|
||
lineNumberToEqualsColumn[currentLineNumber] = columnAndOffset; | ||
|
||
int lineNumber = currentLineNumber; | ||
int minLineNumber = 0; | ||
int maxLineNumber = snapshot.LineCount - 1; | ||
|
||
// If the selection spans multiple lines, only attempt to fix the lines in the selection | ||
if (!_view.Selection.IsEmpty) | ||
{ | ||
var selectionStartLine = _view.Selection.Start.Position.GetContainingLine(); | ||
if (_view.Selection.End.Position > selectionStartLine.End) | ||
{ | ||
minLineNumber = selectionStartLine.LineNumber; | ||
maxLineNumber = snapshot.GetLineNumberFromPosition(_view.Selection.End.Position); | ||
} | ||
} | ||
|
||
// Moving backwards | ||
for (lineNumber = currentLineNumber - 1; lineNumber >= minLineNumber; lineNumber--) | ||
{ | ||
columnAndOffset = GetColumnNumberOfFirstEquals(snapshot.GetLineFromLineNumber(lineNumber)); | ||
if (columnAndOffset.Column == -1) | ||
break; | ||
|
||
lineNumberToEqualsColumn[lineNumber] = columnAndOffset; | ||
} | ||
|
||
// Moving forwards | ||
for (lineNumber = currentLineNumber + 1; lineNumber <= maxLineNumber; lineNumber++) | ||
{ | ||
columnAndOffset = GetColumnNumberOfFirstEquals(snapshot.GetLineFromLineNumber(lineNumber)); | ||
if (columnAndOffset.Column == -1) | ||
break; | ||
|
||
lineNumberToEqualsColumn[lineNumber] = columnAndOffset; | ||
} | ||
|
||
// Perform the actual edit | ||
if (lineNumberToEqualsColumn.Count > 1) | ||
{ | ||
int columnToIndentTo = lineNumberToEqualsColumn.Values.Max(c => c.Column); | ||
|
||
using (var edit = snapshot.TextBuffer.CreateEdit()) | ||
{ | ||
foreach (var pair in lineNumberToEqualsColumn.Where(p => p.Value.Column < columnToIndentTo)) | ||
{ | ||
ITextSnapshotLine line = snapshot.GetLineFromLineNumber(pair.Key); | ||
string spaces = new string(' ', columnToIndentTo - pair.Value.Column); | ||
|
||
if (!edit.Insert(line.Start.Position + pair.Value.Offset, spaces)) | ||
return; | ||
} | ||
|
||
edit.Apply(); | ||
} | ||
} | ||
} | ||
|
||
private ColumnAndOffset GetColumnNumberOfFirstEquals(ITextSnapshotLine line) | ||
{ | ||
ITextSnapshot snapshot = line.Snapshot; | ||
int tabSize = _view.Options.GetOptionValue(DefaultOptions.TabSizeOptionId); | ||
|
||
int column = 0; | ||
int nonWhiteSpaceCount = 0; | ||
for (int i = line.Start.Position; i < line.End.Position; i++) | ||
{ | ||
char ch = snapshot[i]; | ||
if (ch == '=') | ||
return new ColumnAndOffset() | ||
{ | ||
Column = column, | ||
Offset = (i - line.Start.Position) - nonWhiteSpaceCount | ||
}; | ||
|
||
// For the sake of associating characters with the '=', include only | ||
if (!CharAssociatesWithEquals(ch)) | ||
nonWhiteSpaceCount = 0; | ||
else | ||
nonWhiteSpaceCount++; | ||
|
||
if (ch == '\t') | ||
column += tabSize - (column % tabSize); | ||
else | ||
column++; | ||
|
||
// Also, check to see if this is a surrogate pair. If so, skip the next character by incrementing | ||
// the loop counter and increment the nonWhiteSpaceCount without incrementing the column | ||
// count. | ||
if (char.IsHighSurrogate(ch) && | ||
i < line.End.Position - 1 && char.IsLowSurrogate(snapshot[i + 1])) | ||
{ | ||
nonWhiteSpaceCount++; | ||
i++; | ||
} | ||
} | ||
|
||
return new ColumnAndOffset() { Column = -1, Offset = -1 }; | ||
} | ||
|
||
struct ColumnAndOffset | ||
{ | ||
public int Column; | ||
public int Offset; | ||
} | ||
|
||
static HashSet<char> charsThatAssociateWithEquals = new HashSet<char>() { '+', '-', '.', '<', '>', '/', ':', '\\', '*', '&', '^', '%', '$', '#', '@', '!', '~' }; | ||
private bool CharAssociatesWithEquals(char ch) | ||
{ | ||
return charsThatAssociateWithEquals.Contains(ch); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
| ||
namespace S2.STools.Commands | ||
{ | ||
interface ICommand | ||
{ | ||
bool IsEnable(); | ||
void Execute(); | ||
bool IsYourId(uint commandId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// This file is used by Code Analysis to maintain SuppressMessage | ||
// attributes that are applied to this project. Project-level | ||
// suppressions either have no target or are given a specific target | ||
// and scoped to a namespace, type, member, etc. | ||
// | ||
// To add a suppression to this file, right-click the message in the | ||
// Error List, point to "Suppress Message(s)", and click "In Project | ||
// Suppression File". You do not need to add suppressions to this | ||
// file manually. | ||
|
||
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Guids.cs | ||
// MUST match guids.h | ||
using System; | ||
|
||
namespace S2.STools | ||
{ | ||
static class GuidList | ||
{ | ||
public const string guidSToolsPkgString = "df12694e-50e9-4174-b556-ff34cae42223"; | ||
public const string guidSToolsCmdSetString = "096616e7-26a9-482d-a91b-d1389e0c0bd9"; | ||
|
||
public static readonly Guid guidSToolsCmdSet = new Guid(guidSToolsCmdSetString); | ||
}; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// PkgCmdID.cs | ||
// MUST match PkgCmdID.h | ||
using System; | ||
|
||
namespace S2.STools | ||
{ | ||
static class PkgCmdIDList | ||
{ | ||
public const uint CommandIdDocumentThis = 0x100; | ||
|
||
|
||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System; | ||
using System.Reflection; | ||
using System.Resources; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: AssemblyTitle("STools")] | ||
[assembly: AssemblyDescription("")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("S2")] | ||
[assembly: AssemblyProduct("STools")] | ||
[assembly: AssemblyCopyright("")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
[assembly: ComVisible(false)] | ||
[assembly: CLSCompliant(false)] | ||
[assembly: NeutralResourcesLanguage("en-US")] | ||
|
||
// Version information for an assembly consists of the following four values: | ||
// | ||
// Major Version | ||
// Minor Version | ||
// Build Number | ||
// Revision | ||
// | ||
// You can specify all the values or you can default the Revision and Build Numbers | ||
// by using the '*' as shown below: | ||
|
||
[assembly: AssemblyVersion("1.0.0.0")] | ||
[assembly: AssemblyFileVersion("1.0.0.0")] | ||
|
||
|
||
|
Oops, something went wrong.