├── .editorconfig ├── .github └── workflows │ └── workflow.yml ├── .gitignore ├── CodeNav.Languages.CSS ├── CodeNav.Languages.CSS.projitems ├── CodeNav.Languages.CSS.shproj ├── Mappers │ ├── BaseMapper.cs │ └── SyntaxMapper.cs └── Models │ └── CodeStyleRuleItem.cs ├── CodeNav.Languages.JS ├── CodeNav.Languages.JS.projitems ├── CodeNav.Languages.JS.shproj └── Mappers │ ├── BaseMapperJS.cs │ ├── FunctionMapperJS.cs │ └── SyntaxMapperJS.cs ├── CodeNav.Shared ├── CodeNav.Shared.projitems ├── CodeNav.Shared.shproj ├── CodeNavMargin.cs ├── CodeNavMarginFactory.cs ├── CodeViewUserControl.xaml ├── CodeViewUserControl.xaml.cs ├── CodeViewUserControlTop.xaml ├── CodeViewUserControlTop.xaml.cs ├── Comparers │ └── CodeItemComparer.cs ├── Controls │ ├── ClassDataTemplate.xaml │ ├── DepthGroupDataTemplate.xaml │ ├── FilterToolbar.xaml │ ├── FilterToolbar.xaml.cs │ ├── ItemDataTemplate.xaml │ ├── MainToolbar.xaml │ ├── MainToolbar.xaml.cs │ ├── NamespaceDataTemplate.xaml │ └── RegionDataTemplate.xaml ├── Extensions │ └── CodeItemExtensions.cs ├── Helpers │ ├── BookmarkHelper.cs │ ├── ColorHelper.cs │ ├── DocumentHelper.cs │ ├── HighlightHelper.cs │ ├── HistoryHelper.cs │ ├── LanguageHelper.cs │ ├── LogHelper.cs │ ├── NavBarOverrider.cs │ ├── OutliningHelper.cs │ ├── PlaceholderHelper.cs │ ├── SettingsHelper.cs │ ├── SolutionStorageHelper.cs │ ├── SortHelper.cs │ ├── SymbolHelper.cs │ ├── SyntaxHelper.cs │ ├── VisibilityHelper.cs │ └── WpfHelper.cs ├── ICodeViewUserControl.cs ├── Mappers │ ├── BaseMapper.cs │ ├── ClassMapper.cs │ ├── DelegateEventMapper.cs │ ├── EnumMapper.cs │ ├── FieldMapper.cs │ ├── FontStyleMapper.cs │ ├── IconMapper.cs │ ├── IdMapper.cs │ ├── IndexerMapper.cs │ ├── InterfaceMapper.cs │ ├── MethodMapper.cs │ ├── NamespaceMapper.cs │ ├── ParameterMapper.cs │ ├── PropertyMapper.cs │ ├── RecordMapper.cs │ ├── RegionMapper.cs │ ├── StatementMapper.cs │ ├── StructMapper.cs │ ├── SyntaxMapper.cs │ ├── TooltipMapper.cs │ ├── TriviaSummaryMapper.cs │ └── TypeMapper.cs ├── Menus │ └── ItemContextMenu.xaml ├── Models │ ├── BookmarkStyle.cs │ ├── CodeClassItem.cs │ ├── CodeDepthGroupItem.cs │ ├── CodeFunctionItem.cs │ ├── CodeInterfaceItem.cs │ ├── CodeItem.cs │ ├── CodeItemAccessEnum.cs │ ├── CodeItemKindEnum.cs │ ├── CodeNamespaceItem.cs │ ├── CodePropertyItem.cs │ ├── CodeRegionItem.cs │ ├── FilterRule.cs │ ├── ICodeCollapsible.cs │ ├── IMembers.cs │ ├── LanguageEnum.cs │ ├── MarginSideEnum.cs │ ├── SolutionStorageModel.cs │ └── SortOrderEnum.cs ├── Options │ └── General.cs ├── Styles │ ├── BookmarkButtonStyle.xaml │ ├── ComboBoxStyle.xaml │ ├── ContextMenuStyle.xaml │ └── PlusMinusExpanderStyles.xaml ├── ToolWindow │ ├── CodeNavToolWindow.cs │ ├── CodeNavToolWindowCommand.cs │ ├── CodeNavToolWindowPackage.cs │ └── VSPackage.resx ├── VSPackage.resx ├── ViewModels │ ├── BookmarkStylesWindowViewModel.cs │ ├── CodeDocumentViewModel.cs │ ├── FilterWindowViewModel.cs │ └── OptionsWindowViewModel.cs └── Windows │ ├── BookmarkStylesWindow.xaml │ ├── BookmarkStylesWindow.xaml.cs │ ├── FilterWindow.xaml │ ├── FilterWindow.xaml.cs │ ├── OptionsWindow.xaml │ └── OptionsWindow.xaml.cs ├── CodeNav.Tests ├── CodeNav.Tests.csproj ├── Files │ ├── CodeNavTest.cs │ ├── JavaScript │ │ ├── TestFunction.js │ │ └── TestVariable.js │ ├── TestEmptyClass.cs │ ├── TestEmptyInterface.cs │ ├── TestIndexers.cs │ ├── TestInterface.cs │ ├── TestInterface2.cs │ ├── TestInterface3.cs │ ├── TestInterface4.cs │ ├── TestInterfaceRegion.cs │ ├── TestMethodsWithComments.cs │ ├── TestNamespaceRegions.cs │ ├── TestNestedNamespaces.cs │ ├── TestNestedRegions.cs │ ├── TestNoNamespace.cs │ ├── TestPartial1.cs │ ├── TestPartial2.cs │ ├── TestProperties.cs │ ├── TestRegions.cs │ ├── TestRegionsNoName.cs │ ├── TestSealed.cs │ ├── TestSorting.cs │ ├── TestSwitch.cs │ ├── TestUsingsInNamespace.cs │ ├── TestVisibility.cs │ └── VisualBasic │ │ ├── TestClasses.vb │ │ ├── TestFields.vb │ │ ├── TestInterfaces.vb │ │ ├── TestMethods.vb │ │ ├── TestMethodsWithComments.vb │ │ ├── TestModules.vb │ │ ├── TestNamespaces.vb │ │ ├── TestProperties.vb │ │ └── TestRegions.vb ├── HelperTests │ ├── HighlightHelperTests.cs │ ├── LanguageHelperTests.cs │ ├── SortHelperTests.cs │ └── VisibilityHelperTests.cs ├── MapperTests │ ├── JavaScript │ │ ├── TestFunctions.cs │ │ └── TestVariables.cs │ ├── RegionMapperTests.cs │ ├── TestClasses.cs │ ├── TestEmptyClass.cs │ ├── TestEmptyInterface.cs │ ├── TestEnums.cs │ ├── TestFields.cs │ ├── TestIndexers.cs │ ├── TestInterface.cs │ ├── TestInterface2.cs │ ├── TestInterface3.cs │ ├── TestInterface4.cs │ ├── TestMethodsWithComments.cs │ ├── TestNamespaces.cs │ ├── TestNestedRegions.cs │ ├── TestNoNamespace.cs │ ├── TestProperties.cs │ ├── TestSealed.cs │ ├── TestSwitch.cs │ ├── TestUsingsInNamespace.cs │ ├── TooltipMapperTests.cs │ ├── TypeMapperTests.cs │ └── VisualBasic │ │ ├── TestMethods.cs │ │ └── TestMethodsWithComments.cs ├── Properties │ └── AssemblyInfo.cs └── app.config ├── CodeNav.VS2019 ├── CodeNav.VS2019.csproj ├── CodeNavToolWindowCommandTable.cs ├── CodeNavToolWindowCommandTable.vsct ├── DocumentOutline_256x.ico ├── Properties │ └── AssemblyInfo.cs ├── Resources │ └── DocumentOutline_256x.png └── source.extension.vsixmanifest ├── CodeNav.VS2022 ├── CodeNav.VS2022.csproj ├── CodeNavToolWindowCommandTable.cs ├── CodeNavToolWindowCommandTable.vsct ├── DocumentOutline_256x.ico ├── Properties │ └── AssemblyInfo.cs ├── Resources │ └── DocumentOutline_256x.png └── source.extension.vsixmanifest ├── CodeNav.sln ├── LICENSE ├── README.md ├── Resources ├── Bookmark styles.png ├── CodeNavToolWindowCommandTable.vsct ├── DocumentOutline_256x.ico ├── DocumentOutline_256x.png ├── Filters.png ├── Options - Fonts.png ├── Options - General.png ├── Preview-dark.png ├── Preview-small.png ├── Preview.png └── ToolWindow.png ├── nuget.config ├── publish-manifest.VS2019.json └── publish-manifest.VS2022.json /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE0008: Use explicit type 4 | dotnet_diagnostic.IDE0008.severity = none 5 | 6 | # IDE0022: Use block body for methods 7 | dotnet_diagnostic.IDE0022.severity = none 8 | 9 | # VSTHRD200: Use "Async" suffix for async methods 10 | dotnet_diagnostic.VSTHRD200.severity = none 11 | 12 | # VSTHRD111: Use ConfigureAwait(bool) 13 | dotnet_diagnostic.VSTHRD111.severity = none 14 | 15 | # IDE0058: Expression value is never used 16 | dotnet_diagnostic.IDE0058.severity = none 17 | -------------------------------------------------------------------------------- /.github/workflows/workflow.yml: -------------------------------------------------------------------------------- 1 | name: CodeNav 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - 'feature/**' 8 | 9 | env: 10 | version: '8.9.${{ github.run_number }}' 11 | repoUrl: ${{ github.server_url }}/${{ github.repository }} 12 | 13 | jobs: 14 | build: 15 | name: Build 16 | runs-on: windows-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | 21 | - name: Update Assembly Version 22 | uses: dannevesdantas/set-version-assemblyinfo@v.1.0.0 23 | with: 24 | version: ${{ env.version }} 25 | 26 | - name: Update Vsix Version (VS2019) 27 | uses: cezarypiatek/VsixVersionAction@1.2 28 | with: 29 | version: ${{ env.version }} 30 | vsix-manifest-file: 'CodeNav.VS2019\source.extension.vsixmanifest' 31 | 32 | - name: Update Vsix Version (VS2022) 33 | uses: cezarypiatek/VsixVersionAction@1.2 34 | with: 35 | version: ${{ env.version }} 36 | vsix-manifest-file: 'CodeNav.VS2022\source.extension.vsixmanifest' 37 | 38 | - name: Setup MSBuild 39 | uses: microsoft/setup-msbuild@v2 40 | 41 | - name: NuGet restore 42 | run: nuget restore CodeNav.sln -ConfigFile nuget.config 43 | 44 | - name: Build VSIX 45 | run: msbuild CodeNav.sln /t:Rebuild /p:Configuration=Release 46 | env: 47 | DeployExtension: False 48 | 49 | - name: Publish Build Artifacts 50 | uses: actions/upload-artifact@v4 51 | with: 52 | name: CodeNav 53 | path: | 54 | **\*.vsix 55 | publish-manifest.*.json 56 | readme.md 57 | 58 | release: 59 | name: Release 60 | needs: build 61 | runs-on: windows-latest 62 | environment: Release 63 | steps: 64 | - name: Download artifact 65 | uses: actions/download-artifact@v4 66 | 67 | - name: Tag release 68 | id: tag_release 69 | uses: mathieudutour/github-tag-action@v6.1 70 | with: 71 | custom_tag: '${{ env.version }}' 72 | github_token: ${{ secrets.GITHUB_TOKEN }} 73 | 74 | - name: Create a GitHub release 75 | uses: ncipollo/release-action@v1 76 | with: 77 | tag: ${{ steps.tag_release.outputs.new_tag }} 78 | name: ${{ steps.tag_release.outputs.new_tag }} 79 | body: ${{ steps.tag_release.outputs.changelog }} 80 | artifacts: "**/*.vsix" 81 | 82 | - name: Publish to Marketplace - VS2019 83 | uses: cezarypiatek/VsixPublisherAction@1.1 84 | with: 85 | extension-file: CodeNav/CodeNav.VS2019/bin/release/CodeNav.VS2019.vsix 86 | publish-manifest-file: CodeNav/publish-manifest.VS2019.json 87 | personal-access-code: ${{ secrets.VS_PUBLISHER_ACCESS_TOKEN }} 88 | 89 | - name: Publish to Marketplace - VS2022 90 | uses: cezarypiatek/VsixPublisherAction@1.1 91 | with: 92 | extension-file: CodeNav/CodeNav.VS2022/bin/release/CodeNav.VS2022.vsix 93 | publish-manifest-file: CodeNav/publish-manifest.VS2022.json 94 | personal-access-code: ${{ secrets.VS_PUBLISHER_ACCESS_TOKEN }} 95 | 96 | - name: Publish to Open VSIX Gallery - VS2019 97 | run: | 98 | curl -L 'https://www.vsixgallery.com/api/upload?repo=${{ env.repoUrl }}&issuetracker=${{ env.repoUrl }}/issues' -F 'file=@"CodeNav/CodeNav.VS2019/bin/release/CodeNav.VS2019.vsix"' 99 | 100 | - name: Publish to Open VSIX Gallery - VS2022 101 | run: | 102 | curl -L 'https://www.vsixgallery.com/api/upload?repo=${{ env.repoUrl }}&issuetracker=${{ env.repoUrl }}/issues' -F 'file=@"CodeNav/CodeNav.VS2022/bin/release/CodeNav.VS2022.vsix"' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /CodeNav/*.user 3 | /CodeNav/bin 4 | /CodeNav/obj 5 | /packages 6 | /Backup 7 | /UpgradeLog.htm 8 | /*.user 9 | /CodeNav.Tests/bin 10 | /CodeNav.Tests/obj 11 | /CodeNav.Nunit/bin 12 | /CodeNav.Nunit/obj 13 | /CodeNav.Tests/*.user 14 | /CodeNav.Tests/Files/.vs 15 | /Visual Studio 2019 16 | /CodeNav.VS2019/obj 17 | /CodeNav.VS2019/bin 18 | /CodeNav.VS2022/obj 19 | /CodeNav.VS2022/bin 20 | /CodeNav.VS2022/*.user 21 | /CodeNav.VS2019/*.user 22 | -------------------------------------------------------------------------------- /CodeNav.Languages.CSS/CodeNav.Languages.CSS.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 55d33626-0080-407a-bcda-52dafc2eb45c 7 | 8 | 9 | CodeNav.Languages.CSS 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CodeNav.Languages.CSS/CodeNav.Languages.CSS.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 55d33626-0080-407a-bcda-52dafc2eb45c 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CodeNav.Languages.CSS/Mappers/BaseMapper.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using CodeNav.Mappers; 3 | using CodeNav.Models; 4 | using ExCSS; 5 | using Microsoft.CodeAnalysis.Text; 6 | using System; 7 | using System.Windows.Media; 8 | using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan; 9 | using Colors = System.Windows.Media.Colors; 10 | 11 | namespace CodeNav.Languages.CSS.Mappers 12 | { 13 | public static class BaseMapper 14 | { 15 | public static T MapBase(Rule member, string id, ICodeViewUserControl control) where T : CodeItem 16 | { 17 | var element = Activator.CreateInstance(); 18 | 19 | var name = string.IsNullOrEmpty(id) ? "anonymous" : id; 20 | var startPos = member.StylesheetText.Range.Start.Position; 21 | var endPos = member.StylesheetText.Range.End.Position; 22 | 23 | element.Name = name; 24 | element.FullName = name; 25 | element.Id = name; 26 | element.Tooltip = name; 27 | element.StartLine = member.StylesheetText.Range.Start.Line - 1; 28 | element.StartLinePosition = new LinePosition(member.StylesheetText.Range.Start.Line - 1, 0); 29 | element.EndLine = member.StylesheetText.Range.End.Line - 1; 30 | element.EndLinePosition = new LinePosition(member.StylesheetText.Range.End.Line - 1, 0); 31 | element.Span = new TextSpan(startPos, endPos - startPos); 32 | element.ForegroundColor = Colors.Black; 33 | element.Access = CodeItemAccessEnum.Public; 34 | element.FontSize = SettingsHelper.Font.SizeInPoints; 35 | element.ParameterFontSize = SettingsHelper.Font.SizeInPoints - 1; 36 | element.FontFamily = new FontFamily(SettingsHelper.Font.FontFamily.Name); 37 | element.FontStyle = FontStyleMapper.Map(SettingsHelper.Font.Style); 38 | element.Control = control; 39 | element.FilePath = control.CodeDocumentViewModel.FilePath; 40 | 41 | return element; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /CodeNav.Languages.CSS/Models/CodeStyleRuleItem.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Models; 2 | 3 | namespace CodeNav.Languages.CSS.Models 4 | { 5 | public class CodeStyleRuleItem : CodeItem 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /CodeNav.Languages.JS/CodeNav.Languages.JS.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | bf58ba60-38bf-4c54-bd9d-307475371cad 7 | 8 | 9 | CodeNav.Languages.JS 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CodeNav.Languages.JS/CodeNav.Languages.JS.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bf58ba60-38bf-4c54-bd9d-307475371cad 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CodeNav.Languages.JS/Mappers/BaseMapperJS.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | #nullable enable 4 | 5 | using CodeNav.Helpers; 6 | using CodeNav.Mappers; 7 | using CodeNav.Models; 8 | using Microsoft.CodeAnalysis.Text; 9 | using System; 10 | using System.Linq; 11 | using System.Windows.Media; 12 | using Zu.TypeScript.TsTypes; 13 | using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan; 14 | 15 | namespace CodeNav.Languages.JS.Mappers 16 | { 17 | public static class BaseMapperJS 18 | { 19 | public static T MapBase(Node member, string id, ICodeViewUserControl? control) where T : CodeItem 20 | { 21 | var element = Activator.CreateInstance(); 22 | 23 | var name = string.IsNullOrEmpty(id) ? "anonymous" : id; 24 | 25 | element.Name = name; 26 | element.FullName = name; 27 | element.Id = name; 28 | element.Tooltip = name; 29 | element.StartLine = GetLineNumber(member, member.NodeStart); 30 | element.StartLinePosition = new LinePosition(GetLineNumber(member, member.NodeStart) - 1, 0); 31 | element.EndLine = GetLineNumber(member, member.End); 32 | element.EndLinePosition = new LinePosition(GetLineNumber(member, member.End), 0); 33 | element.Span = new TextSpan(member.NodeStart, member.End.GetValueOrDefault() - member.NodeStart); 34 | element.ForegroundColor = Colors.Black; 35 | element.Access = CodeItemAccessEnum.Public; 36 | element.FontSize = SettingsHelper.Font.SizeInPoints; 37 | element.ParameterFontSize = SettingsHelper.Font.SizeInPoints - 1; 38 | element.FontFamily = new FontFamily(SettingsHelper.Font.FontFamily.Name); 39 | element.FontStyle = FontStyleMapper.Map(SettingsHelper.Font.Style); 40 | element.Control = control; 41 | element.FilePath = control?.CodeDocumentViewModel.FilePath ?? string.Empty; 42 | 43 | return element; 44 | } 45 | 46 | private static int GetLineNumber(Node member, int? pos) 47 | { 48 | return member.SourceStr.Take(pos.GetValueOrDefault(0)).Count(c => c == '\n') + 1; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /CodeNav.Shared/CodeNav.Shared.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fdb3d737-bcd7-42b1-a560-ca869de9bce3 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CodeNav.Shared/CodeNavMarginFactory.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System.ComponentModel.Composition; 4 | using CodeNav.Helpers; 5 | using Microsoft.VisualStudio.Text.Editor; 6 | using Microsoft.VisualStudio.Utilities; 7 | using CodeNav.Models; 8 | 9 | namespace CodeNav 10 | { 11 | [Export(typeof(IWpfTextViewMarginProvider))] 12 | [Name(CodeNavMargin.MarginName + "Left")] 13 | [Order(Before = PredefinedMarginNames.Left)] // Ensure that the margin occurs left of the editor window 14 | [MarginContainer(PredefinedMarginNames.Left)] // Set the container to the left of the editor window 15 | [ContentType("CSharp")] // Show this margin for supported code-based types 16 | [ContentType("Basic")] 17 | [ContentType("JavaScript")] 18 | [ContentType("TypeScript")] 19 | [ContentType("CSS")] 20 | [TextViewRole(PredefinedTextViewRoles.Debuggable)] // This is to prevent the margin from loading in the diff view 21 | internal sealed class CodeNavLeftFactory : IWpfTextViewMarginProvider 22 | { 23 | public IWpfTextViewMargin? CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin marginContainer) 24 | { 25 | return CodeNavFactory.CreateMargin(wpfTextViewHost, MarginSideEnum.Left); 26 | } 27 | } 28 | 29 | [Export(typeof(IWpfTextViewMarginProvider))] 30 | [Name(CodeNavMargin.MarginName + "Right")] 31 | [Order(After = PredefinedMarginNames.RightControl)] // Ensure that the margin occurs after the vertical scrollbar 32 | [MarginContainer(PredefinedMarginNames.Right)] // Set the container to the right of the editor window 33 | [ContentType("CSharp")] // Show this margin for supported code-based types 34 | [ContentType("Basic")] 35 | [ContentType("JavaScript")] 36 | [ContentType("TypeScript")] 37 | [ContentType("CSS")] 38 | [TextViewRole(PredefinedTextViewRoles.Debuggable)] // This is to prevent the margin from loading in the diff view 39 | internal sealed class CodeNavRightFactory : IWpfTextViewMarginProvider 40 | { 41 | public IWpfTextViewMargin? CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin marginContainer) 42 | { 43 | return CodeNavFactory.CreateMargin(wpfTextViewHost, MarginSideEnum.Right); 44 | } 45 | } 46 | 47 | [Export(typeof(IWpfTextViewMarginProvider))] 48 | [Name(CodeNavMargin.MarginName + "Top")] 49 | [Order(After = PredefinedMarginNames.Top)] 50 | [MarginContainer(PredefinedMarginNames.Top)] 51 | [ContentType("CSharp")] 52 | [ContentType("Basic")] 53 | [ContentType("JavaScript")] 54 | [ContentType("TypeScript")] 55 | [ContentType("CSS")] 56 | [TextViewRole(PredefinedTextViewRoles.Debuggable)] 57 | internal sealed class CodeNavTopFactory : IWpfTextViewMarginProvider 58 | { 59 | public IWpfTextViewMargin? CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTextViewMargin marginContainer) 60 | { 61 | var margin = CodeNavFactory.CreateMargin(wpfTextViewHost, MarginSideEnum.Top); 62 | new NavBarOverrider(margin as CodeNavMargin); 63 | 64 | return margin; 65 | } 66 | } 67 | 68 | internal static class CodeNavFactory 69 | { 70 | public static IWpfTextViewMargin? CreateMargin(IWpfTextViewHost wpfTextViewHost, MarginSideEnum side) 71 | { 72 | if ((MarginSideEnum)General.Instance.MarginSide != side) 73 | { 74 | return null; 75 | } 76 | 77 | var codeNav = new CodeNavMargin(wpfTextViewHost, side); 78 | 79 | return codeNav; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CodeNav.Shared/CodeViewUserControl.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CodeNav.Shared/CodeViewUserControlTop.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /CodeNav.Shared/CodeViewUserControlTop.xaml.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Windows.Controls; 6 | using System.Windows.Media; 7 | using CodeNav.Helpers; 8 | using CodeNav.Models; 9 | using CodeNav.Models.ViewModels; 10 | using Microsoft.VisualStudio.PlatformUI; 11 | using Microsoft.VisualStudio.Shell; 12 | using Microsoft.VisualStudio.Text.Editor; 13 | using Microsoft.VisualStudio.Text.Outlining; 14 | using Task = System.Threading.Tasks.Task; 15 | 16 | namespace CodeNav 17 | { 18 | public partial class CodeViewUserControlTop : ICodeViewUserControl 19 | { 20 | private readonly RowDefinition? _row; 21 | 22 | public IDisposable? CaretPositionChangedSubscription { get; set; } 23 | public IDisposable? TextContentChangedSubscription { get; set; } 24 | public IDisposable? UpdateWhileTypingSubscription { get; set; } 25 | public IDisposable? FileActionOccurredSubscription { get; set; } 26 | 27 | public CodeDocumentViewModel CodeDocumentViewModel { get; set; } 28 | 29 | public CodeViewUserControlTop(RowDefinition? row = null) 30 | { 31 | InitializeComponent(); 32 | 33 | // Setup viewmodel as datacontext 34 | CodeDocumentViewModel = new CodeDocumentViewModel(); 35 | DataContext = CodeDocumentViewModel; 36 | 37 | _row = row; 38 | 39 | VSColorTheme.ThemeChanged += VSColorTheme_ThemeChanged; 40 | } 41 | 42 | private void VSColorTheme_ThemeChanged(ThemeChangedEventArgs e) => UpdateDocument(); 43 | 44 | public void FilterBookmarks() 45 | => VisibilityHelper.SetCodeItemVisibility(CodeDocumentViewModel); 46 | 47 | public void RegionsCollapsed(RegionsCollapsedEventArgs e) => 48 | OutliningHelper.RegionsCollapsed(e, CodeDocumentViewModel.CodeDocument); 49 | 50 | public void RegionsExpanded(RegionsExpandedEventArgs e) => 51 | OutliningHelper.RegionsExpanded(e, CodeDocumentViewModel.CodeDocument); 52 | 53 | public void ToggleAll(bool isExpanded, List? root = null) 54 | { 55 | OutliningHelper.ToggleAll(root ?? CodeDocumentViewModel.CodeDocument, isExpanded); 56 | } 57 | 58 | /// 59 | public void UpdateDocument(string filePath = "", bool force = false) 60 | => ThreadHelper.JoinableTaskFactory.RunAsync(async () => await DocumentHelper.UpdateDocument(this, CodeDocumentViewModel, 61 | null, _row, filePath, force)); 62 | 63 | public void HighlightCurrentItem(CaretPositionChangedEventArgs e, Color backgroundBrushColor) 64 | { 65 | HighlightHelper.HighlightCurrentItem( 66 | CodeDocumentViewModel, 67 | backgroundBrushColor, 68 | e.NewPosition.BufferPosition.GetContainingLine().LineNumber); 69 | 70 | // Force NotifyPropertyChanged 71 | CodeDocumentViewModel.CodeDocumentTop = new List(); 72 | } 73 | 74 | public async Task RegisterDocumentEvents() 75 | { 76 | // Todo: Implement events 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CodeNav.Shared/Comparers/CodeItemComparer.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace CodeNav.Shared.Comparers 9 | { 10 | public class CodeItemComparer : IEqualityComparer 11 | { 12 | public bool Equals(CodeItem left, CodeItem right) 13 | { 14 | //Check whether the objects are the same object. 15 | if (ReferenceEquals(left, right)) 16 | { 17 | return true; 18 | } 19 | 20 | //Check whether the products' properties are equal. 21 | var membersAreEqual = true; 22 | if (left is CodeClassItem leftItem && 23 | right is CodeClassItem rightItem) 24 | { 25 | membersAreEqual = leftItem.Members.SequenceEqual(rightItem.Members, new CodeItemComparer()); 26 | } 27 | if (left is CodeNamespaceItem leftNamespaceItem && 28 | right is CodeNamespaceItem rightNamespaceItem) 29 | { 30 | membersAreEqual = leftNamespaceItem.Members.SequenceEqual(rightNamespaceItem.Members, new CodeItemComparer()); 31 | } 32 | 33 | return left != null && right != null && left.Id.Equals(right.Id) && membersAreEqual; 34 | } 35 | 36 | // Not used, but must be implemented because of interface 37 | public int GetHashCode(CodeItem obj) 38 | { 39 | return 0; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/ClassDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/DepthGroupDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/FilterToolbar.xaml.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System; 4 | using System.Windows; 5 | using System.Windows.Controls; 6 | using CodeNav.Helpers; 7 | using CodeNav.Models.ViewModels; 8 | using CodeNav.Windows; 9 | 10 | namespace CodeNav.Controls 11 | { 12 | public partial class FilterToolbar 13 | { 14 | public FilterToolbar() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) 20 | { 21 | if (!(DataContext is CodeDocumentViewModel dataContext)) 22 | { 23 | // Datacontext error while filtering items by name 24 | return; 25 | } 26 | 27 | dataContext.FilterText = FilterTextBox.Text; 28 | 29 | try 30 | { 31 | VisibilityHelper.SetCodeItemVisibility(dataContext); 32 | } 33 | catch (Exception) 34 | { 35 | // Error filtering items 36 | } 37 | } 38 | 39 | private void ButtonClear_OnClick(object sender, RoutedEventArgs e) 40 | { 41 | FilterTextBox.Text = string.Empty; 42 | } 43 | 44 | private void ButtonFilter_OnClick(object sender, RoutedEventArgs e) 45 | { 46 | new FilterWindow().ShowDialog(); 47 | 48 | var control = WpfHelper.FindParent(this); 49 | control?.UpdateDocument(); 50 | } 51 | 52 | private void ButtonFilterBookmark_OnClick(object sender, RoutedEventArgs e) 53 | { 54 | var control = WpfHelper.FindParent(this); 55 | 56 | if (control == null) 57 | { 58 | return; 59 | } 60 | 61 | control.CodeDocumentViewModel.FilterOnBookmarks = !control.CodeDocumentViewModel.FilterOnBookmarks; 62 | control.FilterBookmarks(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/ItemDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/MainToolbar.xaml.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System.Windows; 4 | using System.Windows.Controls.Primitives; 5 | using CodeNav.Helpers; 6 | using CodeNav.Models; 7 | using CodeNav.Windows; 8 | using Microsoft.VisualStudio.Shell; 9 | using Task = System.Threading.Tasks.Task; 10 | 11 | namespace CodeNav.Controls 12 | { 13 | public partial class MainToolbar 14 | { 15 | public MainToolbar() 16 | { 17 | InitializeComponent(); 18 | 19 | ButtonSortByName.IsChecked = (SortOrderEnum)General.Instance.SortOrder == SortOrderEnum.SortByName; 20 | ButtonSortByFile.IsChecked = (SortOrderEnum)General.Instance.SortOrder == SortOrderEnum.SortByFile; 21 | } 22 | 23 | private void ButtonRefresh_OnClick(object sender, RoutedEventArgs e) 24 | => WpfHelper.FindParent(this)?.UpdateDocument(force: true); 25 | 26 | private void ButtonSortByFileOrder_OnClick(object sender, RoutedEventArgs e) 27 | => Sort(SortOrderEnum.SortByFile).FireAndForget(); 28 | 29 | private void ButtonSortByName_OnClick(object sender, RoutedEventArgs e) 30 | => Sort(SortOrderEnum.SortByName).FireAndForget(); 31 | 32 | private void ButtonOptions_OnClick(object sender, RoutedEventArgs e) 33 | { 34 | new OptionsWindow().ShowDialog(); 35 | 36 | var control = WpfHelper.FindParent(this); 37 | control?.UpdateDocument(); 38 | control?.RegisterDocumentEvents().FireAndForget(); 39 | } 40 | 41 | private void ButtonRegion_OnClick(object sender, RoutedEventArgs e) 42 | { 43 | if (!(sender is ToggleButton toggleButton)) 44 | { 45 | return; 46 | } 47 | 48 | WpfHelper.FindParent(this)?.ToggleAll(toggleButton.IsChecked == false); 49 | } 50 | 51 | private async Task Sort(SortOrderEnum sortOrder) 52 | { 53 | var control = WpfHelper.FindParent(this); 54 | 55 | if (control == null) 56 | { 57 | return; 58 | } 59 | 60 | control.CodeDocumentViewModel.SortOrder = sortOrder; 61 | control.CodeDocumentViewModel.CodeDocument = SortHelper.Sort(control.CodeDocumentViewModel); 62 | 63 | var general = await General.GetLiveInstanceAsync(); 64 | general.SortOrder = (int)sortOrder; 65 | await general.SaveAsync(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CodeNav.Shared/Controls/RegionDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /CodeNav.Shared/Extensions/CodeItemExtensions.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace CodeNav.Extensions 8 | { 9 | public static class CodeItemExtensions 10 | { 11 | /// 12 | /// Transform a nested list of CodeItems to a flat list 13 | /// 14 | /// Nested list of CodeItems 15 | /// Flat list of CodeItems 16 | public static IEnumerable Flatten(this IEnumerable codeDocument) 17 | => codeDocument 18 | .SelectMany(codeItem => codeItem is IMembers codeMembersItem 19 | ? Flatten(codeMembersItem.Members) : new[] { codeItem }).Concat(codeDocument); 20 | 21 | /// 22 | /// Delete null items from a flat list of CodeItems 23 | /// 24 | /// Flat list of CodeItems 25 | /// Flat list of CodeItems 26 | public static IEnumerable FilterNull(this IEnumerable codeDocument) 27 | => codeDocument.Where(codeItem => codeItem != null); 28 | 29 | /// 30 | /// Recursively delete null items from a nested list of CodeItems 31 | /// 32 | /// Nested list of CodeItems 33 | public static List FilterNullItems(this List items) 34 | { 35 | if (items == null) 36 | { 37 | return new List(); 38 | } 39 | 40 | items.RemoveAll(item => item == null); 41 | 42 | foreach (var item in items) 43 | { 44 | if (item is IMembers memberItem) 45 | { 46 | FilterNullItems(memberItem.Members.Cast().ToList()); 47 | } 48 | } 49 | 50 | return items.Cast().ToList(); 51 | } 52 | 53 | public static void AddIfNotNull(this List items, CodeItem? item) 54 | { 55 | if (item == null) 56 | { 57 | return; 58 | } 59 | 60 | items.Add(item); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/ColorHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.PlatformUI; 2 | using Microsoft.VisualStudio.Shell; 3 | using System.Windows.Media; 4 | 5 | namespace CodeNav.Helpers 6 | { 7 | public static class ColorHelper 8 | { 9 | public static SolidColorBrush ToBrush(Color color) 10 | { 11 | var brush = new SolidColorBrush(color); 12 | brush.Freeze(); 13 | return brush; 14 | } 15 | 16 | /// 17 | /// Convert from VSTheme EnvironmentColor to a XAML SolidColorBrush 18 | /// 19 | /// VSTheme EnvironmentColor key 20 | /// XAML SolidColorBrush 21 | public static SolidColorBrush ToBrush(ThemeResourceKey key) 22 | => new SolidColorBrush(ToMediaColor(VSColorTheme.GetThemedColor(key))); 23 | 24 | public static SolidColorBrush ToBrush(System.Drawing.Color color) 25 | => new SolidColorBrush(ToMediaColor(color)); 26 | 27 | public static Color ToMediaColor(System.Drawing.Color drawingColor) 28 | => Color.FromArgb(drawingColor.A, drawingColor.R, drawingColor.G, drawingColor.B); 29 | 30 | public static Color ToMediaColor(ThemeResourceKey key) 31 | => ToMediaColor(VSColorTheme.GetThemedColor(key)); 32 | 33 | public static System.Drawing.Color ToDrawingColor(Color color) 34 | => System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B); 35 | 36 | public static System.Drawing.Color ToDrawingColor(SolidColorBrush solidColorBrush) 37 | => ToDrawingColor(solidColorBrush.Color); 38 | 39 | public static System.Drawing.Color Transparent() 40 | => ToDrawingColor(Brushes.Transparent); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/LanguageHelper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using System.Threading.Tasks; 5 | 6 | namespace CodeNav.Helpers 7 | { 8 | public static class LanguageHelper 9 | { 10 | /// 11 | /// Convert a language string to a strong typed language enum 12 | /// 13 | /// string representing the syntaxnode language 14 | /// 15 | public static LanguageEnum GetLanguage(string? language) 16 | { 17 | switch (language) 18 | { 19 | case "Basic": 20 | case "Visual Basic": 21 | return LanguageEnum.VisualBasic; 22 | case "C#": 23 | case "CSharp": 24 | return LanguageEnum.CSharp; 25 | default: 26 | return LanguageEnum.Unknown; 27 | } 28 | } 29 | 30 | public static async Task GetActiveDocumentLanguage() 31 | { 32 | var document = await DocumentHelper.GetCodeAnalysisDocument(); 33 | 34 | if (document == null) 35 | { 36 | return LanguageEnum.Unknown; 37 | } 38 | 39 | var tree = await document.GetSyntaxTreeAsync(); 40 | 41 | if (tree == null) 42 | { 43 | return LanguageEnum.Unknown; 44 | } 45 | 46 | var root = await tree.GetRootAsync(); 47 | 48 | if (root == null) 49 | { 50 | return LanguageEnum.Unknown; 51 | } 52 | 53 | return GetLanguage(root.Language); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/LogHelper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Community.VisualStudio.Toolkit; 4 | using Microsoft.ApplicationInsights; 5 | using Newtonsoft.Json; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Diagnostics; 9 | using System.Reflection; 10 | using System.Security.Cryptography; 11 | using System.Text; 12 | 13 | namespace CodeNav.Helpers 14 | { 15 | public static class LogHelper 16 | { 17 | private static TelemetryClient? _client; 18 | private const string InstrumentationKey = "0913ac4a-1127-4d28-91cf-07673e70200f"; 19 | 20 | public static void GetClient() 21 | { 22 | _client = new TelemetryClient(); 23 | _client.Context.Session.Id = Guid.NewGuid().ToString(); 24 | _client.InstrumentationKey = InstrumentationKey; 25 | _client.Context.Component.Version = GetExecutingAssemblyVersion().ToString(); 26 | _client.Context.User.Id = GetUserId(); 27 | } 28 | 29 | public static void Log(string message, Exception? exception = null, 30 | object? additional = null, string language = "") 31 | { 32 | if (_client == null) 33 | { 34 | GetClient(); 35 | } 36 | 37 | if (_client == null) 38 | { 39 | return; 40 | } 41 | 42 | var properties = new Dictionary 43 | { 44 | { "version", GetExecutingAssemblyVersion().ToString() }, 45 | { "message", JsonConvert.SerializeObject(message) }, 46 | { "language", language }, 47 | { "additional", JsonConvert.SerializeObject(additional) }, 48 | { "vsVersion", VS.Shell.GetVsVersionAsync().Result?.ToString() ?? string.Empty } 49 | }; 50 | 51 | if (exception == null) 52 | { 53 | _client.TrackEvent(message, properties); 54 | } 55 | else 56 | { 57 | _client.TrackException(exception, properties); 58 | } 59 | } 60 | 61 | private static Version GetExecutingAssemblyVersion() 62 | { 63 | var ver = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); 64 | 65 | // read what's defined in [assembly: AssemblyFileVersion("1.2.3.4")] 66 | return new Version(ver.ProductMajorPart, ver.ProductMinorPart, ver.ProductBuildPart, ver.ProductPrivatePart); 67 | } 68 | 69 | private static string GetUserId() 70 | { 71 | var enc = Encoding.UTF8.GetBytes(Environment.UserName + Environment.MachineName); 72 | var hash = new MD5CryptoServiceProvider().ComputeHash(enc); 73 | return Convert.ToBase64String(hash); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/NavBarOverrider.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Microsoft.VisualStudio.Text.Editor; 4 | using System; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | 8 | namespace CodeNav.Helpers 9 | { 10 | public class NavBarOverrider 11 | { 12 | private readonly UIElement? _control; 13 | private readonly IWpfTextView? _wpfTextView; 14 | 15 | public NavBarOverrider(CodeNavMargin? margin) 16 | { 17 | if (margin == null) 18 | { 19 | return; 20 | } 21 | 22 | _control = margin._control as UIElement; 23 | _wpfTextView = margin._textView; 24 | 25 | if (_wpfTextView != null) 26 | { 27 | _wpfTextView.VisualElement.Loaded += FindNaviBar; 28 | _wpfTextView.VisualElement.Unloaded += ViewUnloaded; 29 | } 30 | } 31 | 32 | void FindNaviBar(object sender, RoutedEventArgs e) 33 | { 34 | var view = sender as FrameworkElement; 35 | 36 | var naviBar = view 37 | ?.GetParent(b => b.Name == "PART_ContentPanel") 38 | ?.GetFirstVisualChild(b => b.Name == "DropDownBarMargin"); 39 | 40 | if (naviBar == null) 41 | { 42 | UnloadEvents(); 43 | return; 44 | } 45 | 46 | var dropDown0 = naviBar.GetFirstVisualChild(c => c.Name == "DropDown0"); 47 | var dropDown1 = naviBar.GetFirstVisualChild(c => c.Name == "DropDown1"); 48 | var dropDown2 = naviBar.GetFirstVisualChild(c => c.Name == "DropDown2"); 49 | 50 | if (dropDown0 == null || dropDown1 == null || dropDown2 == null) 51 | { 52 | UnloadEvents(); 53 | return; 54 | } 55 | 56 | var container = dropDown1.GetParent(); 57 | 58 | if (container == null) 59 | { 60 | UnloadEvents(); 61 | } 62 | 63 | _control?.SetCurrentValue(Grid.ColumnSpanProperty, 5); 64 | container?.Children.Add(_control); 65 | 66 | if (dropDown0 != null && 67 | dropDown1 != null && 68 | dropDown2 != null) 69 | { 70 | dropDown0.Visibility = Visibility.Collapsed; 71 | dropDown1.Visibility = Visibility.Collapsed; 72 | dropDown2.Visibility = Visibility.Collapsed; 73 | } 74 | } 75 | 76 | void ViewUnloaded(object sender, EventArgs e) 77 | { 78 | UnloadEvents(); 79 | } 80 | 81 | void UnloadEvents() 82 | { 83 | if (_wpfTextView != null) 84 | { 85 | _wpfTextView.VisualElement.Loaded -= FindNaviBar; 86 | _wpfTextView.VisualElement.Unloaded -= ViewUnloaded; 87 | } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/PlaceholderHelper.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Models; 2 | using Microsoft.VisualStudio.Imaging.Interop; 3 | using Microsoft.VisualStudio.Imaging; 4 | using System.Collections.Generic; 5 | using System.Windows.Media; 6 | using Microsoft.VisualStudio.PlatformUI; 7 | 8 | namespace CodeNav.Helpers 9 | { 10 | public static class PlaceholderHelper 11 | { 12 | public static List CreateLoadingItem() 13 | => CreateItem("Loading...", KnownMonikers.Refresh); 14 | 15 | public static List CreateSelectDocumentItem() 16 | => CreateItem("Waiting for active code document...", KnownMonikers.DocumentOutline); 17 | 18 | public static List CreateLineThresholdPassedItem() 19 | => CreateItem("Click Refresh to load file...", KnownMonikers.DocumentError); 20 | 21 | private static List CreateItem(string name, ImageMoniker moniker) 22 | { 23 | return new List 24 | { 25 | new CodeNamespaceItem 26 | { 27 | Id = name, 28 | IsExpanded = true, 29 | Members = new List 30 | { 31 | new CodeClassItem 32 | { 33 | Name = name, 34 | FullName = name, 35 | Id = name, 36 | ForegroundColor = ColorHelper.ToMediaColor(EnvironmentColors.ToolWindowTextColorKey), 37 | BorderColor = Colors.DarkGray, 38 | Moniker = moniker, 39 | IsExpanded = true 40 | } 41 | } 42 | } 43 | }; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/SettingsHelper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using Newtonsoft.Json; 5 | using System; 6 | using System.Collections.ObjectModel; 7 | using System.Drawing; 8 | 9 | namespace CodeNav.Helpers 10 | { 11 | public static class SettingsHelper 12 | { 13 | private static bool? _useXmlComments; 14 | public static bool UseXMLComments 15 | { 16 | get 17 | { 18 | if (_useXmlComments == null) 19 | { 20 | _useXmlComments = General.Instance.UseXMLComments; 21 | } 22 | return _useXmlComments.Value; 23 | } 24 | set => _useXmlComments = value; 25 | } 26 | 27 | private static Font? _font; 28 | public static Font Font 29 | { 30 | get 31 | { 32 | if (_font == null) 33 | { 34 | _font = new Font(General.Instance.FontFamilyName, General.Instance.FontSize, General.Instance.FontStyle); 35 | } 36 | return _font; 37 | } 38 | set => _font = value; 39 | } 40 | 41 | private static ObservableCollection? _filterRules; 42 | public static ObservableCollection FilterRules 43 | { 44 | get => LoadFilterRules(); 45 | set => _filterRules = value; 46 | } 47 | 48 | public static void SaveFilterRules(ObservableCollection filterRules) 49 | { 50 | General.Instance.FilterRules = JsonConvert.SerializeObject(filterRules); 51 | General.Instance.Save(); 52 | } 53 | 54 | public static void Refresh() 55 | { 56 | _useXmlComments = null; 57 | _filterRules = null; 58 | _font = null; 59 | } 60 | 61 | private static ObservableCollection LoadFilterRules() 62 | { 63 | if (_filterRules != null) 64 | { 65 | return _filterRules; 66 | } 67 | 68 | try 69 | { 70 | _filterRules = JsonConvert.DeserializeObject>(General.Instance.FilterRules); 71 | } 72 | catch (Exception) 73 | { 74 | // Ignore error while loading filter rules 75 | } 76 | 77 | if (_filterRules == null) 78 | { 79 | _filterRules = new ObservableCollection(); 80 | } 81 | 82 | return _filterRules; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/SortHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CodeNav.Models; 4 | using CodeNav.Models.ViewModels; 5 | 6 | namespace CodeNav.Helpers 7 | { 8 | public static class SortHelper 9 | { 10 | public static List Sort(CodeDocumentViewModel viewModel) 11 | => Sort(viewModel.CodeDocument, viewModel.SortOrder); 12 | 13 | public static List Sort(List document, SortOrderEnum sortOrder) 14 | => sortOrder switch 15 | { 16 | SortOrderEnum.SortByFile => SortByFile(document), 17 | SortOrderEnum.SortByName => SortByName(document), 18 | _ => document, 19 | }; 20 | 21 | private static List SortByName(List document) 22 | { 23 | document = document.OrderBy(c => c.Name).ToList(); 24 | 25 | foreach (var item in document) 26 | { 27 | if (item is CodeClassItem codeClassItem) 28 | { 29 | codeClassItem.Members = SortByName(codeClassItem.Members); 30 | } 31 | if (item is CodeNamespaceItem codeNamespaceItem) 32 | { 33 | codeNamespaceItem.Members = SortByName(codeNamespaceItem.Members); 34 | } 35 | } 36 | 37 | return document; 38 | } 39 | 40 | private static List SortByFile(List document) 41 | { 42 | document = document.OrderBy(c => c.StartLine).ToList(); 43 | 44 | foreach (var item in document) 45 | { 46 | if (item is CodeClassItem codeClassItem) 47 | { 48 | codeClassItem.Members = SortByFile(codeClassItem.Members); 49 | } 50 | if (item is CodeNamespaceItem codeNamespaceItem) 51 | { 52 | codeNamespaceItem.Members = SortByFile(codeNamespaceItem.Members); 53 | } 54 | } 55 | 56 | return document; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/SymbolHelper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Microsoft.CodeAnalysis; 4 | using System; 5 | 6 | namespace CodeNav.Helpers 7 | { 8 | public static class SymbolHelper 9 | { 10 | public static T? GetSymbol(SemanticModel semanticModel, SyntaxNode member) 11 | { 12 | try 13 | { 14 | return (T?)semanticModel.GetDeclaredSymbol(member); 15 | } 16 | catch (ArgumentException e) 17 | { 18 | if (!e.Message.Contains("DeclarationSyntax") && 19 | !e.Message.Contains("SyntaxTree")) 20 | { 21 | LogHelper.Log("Error during mapping", e); 22 | } 23 | return default; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CodeNav.Shared/Helpers/SyntaxHelper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp; 5 | using Microsoft.CodeAnalysis.VisualBasic; 6 | using System; 7 | 8 | namespace CodeNav.Shared.Helpers 9 | { 10 | public static class SyntaxHelper 11 | { 12 | public static SemanticModel? GetCSharpSemanticModel(SyntaxTree tree) 13 | { 14 | SemanticModel semanticModel; 15 | 16 | try 17 | { 18 | var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); 19 | var compilation = CSharpCompilation.Create("CodeNavCompilation", new[] { tree }, new[] { mscorlib }); 20 | semanticModel = compilation.GetSemanticModel(tree); 21 | } 22 | catch (ArgumentException) 23 | { 24 | return null; 25 | } 26 | 27 | return semanticModel; 28 | } 29 | 30 | public static SemanticModel? GetVBSemanticModel(SyntaxTree tree) 31 | { 32 | SemanticModel semanticModel; 33 | 34 | try 35 | { 36 | var mscorlibVB = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); 37 | var compilationVB = VisualBasicCompilation.Create("CodeNavCompilation", new[] { tree }, new[] { mscorlibVB }); 38 | semanticModel = compilationVB.GetSemanticModel(tree); 39 | } 40 | catch (ArgumentException) // SyntaxTree not found to remove 41 | { 42 | return null; 43 | } 44 | 45 | return semanticModel; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CodeNav.Shared/ICodeViewUserControl.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using CodeNav.Models.ViewModels; 5 | using Microsoft.VisualStudio.Text.Editor; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Threading.Tasks; 9 | using System.Windows.Media; 10 | 11 | namespace CodeNav 12 | { 13 | public interface ICodeViewUserControl 14 | { 15 | CodeDocumentViewModel CodeDocumentViewModel { get; set; } 16 | 17 | /// 18 | /// Update the Code Document View Model 19 | /// 20 | /// Optional path to use as code source file 21 | /// Optional boolean to indicate to update documents that may contain too many lines 22 | void UpdateDocument(string filePath = "", bool force = false); 23 | 24 | void HighlightCurrentItem(CaretPositionChangedEventArgs e, Color backgroundBrushColor); 25 | 26 | void ToggleAll(bool isExpanded, List? root = null); 27 | 28 | void FilterBookmarks(); 29 | 30 | Task RegisterDocumentEvents(); 31 | 32 | IDisposable? CaretPositionChangedSubscription { get; set; } 33 | 34 | IDisposable? TextContentChangedSubscription { get; set; } 35 | 36 | IDisposable? UpdateWhileTypingSubscription { get; set; } 37 | 38 | IDisposable? FileActionOccurredSubscription { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/DelegateEventMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 7 | 8 | namespace CodeNav.Mappers 9 | { 10 | public static class DelegateEventMapper 11 | { 12 | public static CodeItem? MapDelegate(DelegateDeclarationSyntax? member, 13 | ICodeViewUserControl control, SemanticModel semanticModel) 14 | { 15 | if (member == null) 16 | { 17 | return null; 18 | } 19 | 20 | var item = BaseMapper.MapBase(member, member.Identifier, member.Modifiers, control, semanticModel); 21 | item.Kind = CodeItemKindEnum.Delegate; 22 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 23 | return item; 24 | } 25 | 26 | public static CodeItem? MapDelegate(VisualBasicSyntax.DelegateStatementSyntax? member, 27 | ICodeViewUserControl control, SemanticModel semanticModel) 28 | { 29 | if (member == null) 30 | { 31 | return null; 32 | } 33 | 34 | var item = BaseMapper.MapBase(member, member.Identifier, member.Modifiers, control, semanticModel); 35 | item.Kind = CodeItemKindEnum.Delegate; 36 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 37 | return item; 38 | } 39 | 40 | public static CodeItem? MapEvent(EventFieldDeclarationSyntax? member, 41 | ICodeViewUserControl control, SemanticModel semanticModel) 42 | { 43 | if (member == null) 44 | { 45 | return null; 46 | } 47 | 48 | var item = BaseMapper.MapBase(member, member.Declaration.Variables.First().Identifier, 49 | member.Modifiers, control, semanticModel); 50 | item.Kind = CodeItemKindEnum.Event; 51 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 52 | return item; 53 | } 54 | 55 | public static CodeItem? MapEvent(VisualBasicSyntax.EventBlockSyntax? member, 56 | ICodeViewUserControl control, SemanticModel semanticModel) 57 | { 58 | if (member == null) 59 | { 60 | return null; 61 | } 62 | 63 | var item = BaseMapper.MapBase(member, member.EventStatement.Identifier, 64 | member.EventStatement.Modifiers, control, semanticModel); 65 | item.Kind = CodeItemKindEnum.Event; 66 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 67 | return item; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/FieldMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | using System.Linq; 8 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 9 | using VisualBasic = Microsoft.CodeAnalysis.VisualBasic; 10 | using CodeNav.Helpers; 11 | 12 | namespace CodeNav.Mappers 13 | { 14 | public static class FieldMapper 15 | { 16 | public static CodeItem? MapField(FieldDeclarationSyntax? member, 17 | ICodeViewUserControl control, SemanticModel semanticModel) 18 | { 19 | if (member == null) 20 | { 21 | return null; 22 | } 23 | 24 | return MapField(member, member.Declaration.Variables.First().Identifier, member.Modifiers, control, semanticModel); 25 | } 26 | 27 | public static CodeItem? MapField(VisualBasicSyntax.FieldDeclarationSyntax? member, 28 | ICodeViewUserControl control, SemanticModel semanticModel) 29 | { 30 | if (member == null) 31 | { 32 | return null; 33 | } 34 | 35 | return MapField(member, member.Declarators.First().Names.First().Identifier, member.Modifiers, control, semanticModel); 36 | } 37 | 38 | private static CodeItem? MapField(SyntaxNode? member, SyntaxToken identifier, SyntaxTokenList modifiers, 39 | ICodeViewUserControl control, SemanticModel semanticModel) 40 | { 41 | if (member == null) 42 | { 43 | return null; 44 | } 45 | 46 | var item = BaseMapper.MapBase(member, identifier, modifiers, control, semanticModel); 47 | item.Kind = IsConstant(modifiers) 48 | ? CodeItemKindEnum.Constant 49 | : CodeItemKindEnum.Variable; 50 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 51 | 52 | if (TriviaSummaryMapper.HasSummary(member) && SettingsHelper.UseXMLComments) 53 | { 54 | item.Tooltip = TriviaSummaryMapper.Map(member); 55 | } 56 | 57 | return item; 58 | } 59 | 60 | private static bool IsConstant(SyntaxTokenList modifiers) 61 | { 62 | return modifiers.Any(m => m.RawKind == (int)SyntaxKind.ConstKeyword || 63 | m.RawKind == (int)VisualBasic.SyntaxKind.ConstKeyword); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/FontStyleMapper.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace CodeNav.Mappers 4 | { 5 | public static class FontStyleMapper 6 | { 7 | public static FontStyle Map(System.Drawing.FontStyle fontStyle) 8 | { 9 | switch (fontStyle) 10 | { 11 | case System.Drawing.FontStyle.Italic: 12 | return FontStyles.Italic; 13 | default: 14 | return FontStyles.Normal; 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/IdMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using System.Collections.Immutable; 6 | using System.Linq; 7 | using Zu.TypeScript.TsTypes; 8 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 9 | 10 | namespace CodeNav.Mappers 11 | { 12 | /// 13 | /// Creates an unique id for a CodeItem based on its name and parameters 14 | /// 15 | public static class IdMapper 16 | { 17 | public static string MapId(SyntaxToken identifier, ParameterListSyntax parameters) 18 | { 19 | return MapId(identifier.Text, parameters); 20 | } 21 | 22 | public static string MapId(SyntaxToken identifier, VisualBasicSyntax.ParameterListSyntax parameters, SemanticModel semanticModel) 23 | { 24 | return MapId(identifier.Text, parameters, semanticModel); 25 | } 26 | 27 | public static string MapId(string name, NodeArray? parameters) 28 | { 29 | if (parameters == null) 30 | { 31 | return name; 32 | } 33 | 34 | return name + string.Join(string.Empty, parameters.Select(p => p.IdentifierStr)); 35 | } 36 | 37 | public static string MapId(string name, ParameterListSyntax parameters) 38 | { 39 | return name + ParameterMapper.MapParameters(parameters, true, false); 40 | } 41 | 42 | public static string MapId(string name, VisualBasicSyntax.ParameterListSyntax? parameters, SemanticModel semanticModel) 43 | { 44 | return name + ParameterMapper.MapParameters(parameters, semanticModel, true, false); 45 | } 46 | 47 | public static string MapId(string name, ImmutableArray parameters, bool useLongNames, bool prettyPrint) 48 | { 49 | return name + MapParameters(parameters, useLongNames, prettyPrint); 50 | } 51 | 52 | private static string MapParameters(ImmutableArray parameters, bool useLongNames = false, bool prettyPrint = true) 53 | { 54 | var paramList = (from IParameterSymbol parameter in parameters select TypeMapper.Map(parameter.Type, useLongNames)).ToList(); 55 | return prettyPrint ? $"({string.Join(", ", paramList)})" : string.Join(string.Empty, paramList); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/IndexerMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using CodeNav.Models; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace CodeNav.Mappers 9 | { 10 | public class IndexerMapper 11 | { 12 | public static CodeItem? MapIndexer(IndexerDeclarationSyntax? member, 13 | ICodeViewUserControl control, SemanticModel semanticModel) 14 | { 15 | if (member == null) 16 | { 17 | return null; 18 | } 19 | 20 | var item = BaseMapper.MapBase(member, member.ThisKeyword, member.Modifiers, control, semanticModel); 21 | item.Type = TypeMapper.Map(member.Type); 22 | item.Parameters = ParameterMapper.MapParameters(member.ParameterList); 23 | item.Tooltip = TooltipMapper.Map(item.Access, item.Type, item.Name, item.Parameters); 24 | item.Kind = CodeItemKindEnum.Indexer; 25 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 26 | 27 | if (TriviaSummaryMapper.HasSummary(member) && SettingsHelper.UseXMLComments) 28 | { 29 | item.Tooltip = TriviaSummaryMapper.Map(member); 30 | } 31 | 32 | return item; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/ParameterMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using Microsoft.CodeAnalysis; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | using System.Linq; 7 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 8 | 9 | namespace CodeNav.Mappers 10 | { 11 | public static class ParameterMapper 12 | { 13 | /// 14 | /// Parse parameters from a method and return a formatted string back 15 | /// 16 | /// List of method parameters 17 | /// use fullNames for parameter types 18 | /// seperate types with a comma 19 | /// string listing all parameter types (eg. (int, string, bool)) 20 | public static string MapParameters(ParameterListSyntax? parameters, bool useLongNames = false, bool prettyPrint = true) 21 | { 22 | if (parameters == null) 23 | { 24 | return string.Empty; 25 | } 26 | 27 | var paramList = (from ParameterSyntax parameter in parameters.Parameters select TypeMapper.Map(parameter.Type, useLongNames)).ToList(); 28 | return prettyPrint ? $"({string.Join(", ", paramList)})" : string.Join(string.Empty, paramList); 29 | } 30 | 31 | public static string MapParameters(BracketedParameterListSyntax? parameters, bool useLongNames = false, bool prettyPrint = true) 32 | { 33 | if (parameters == null) 34 | { 35 | return string.Empty; 36 | } 37 | 38 | var paramList = (from ParameterSyntax parameter in parameters.Parameters select TypeMapper.Map(parameter.Type, useLongNames)).ToList(); 39 | return prettyPrint ? $"[{string.Join(", ", paramList)}]" : string.Join(string.Empty, paramList); 40 | } 41 | 42 | public static string MapParameters(VisualBasicSyntax.ParameterListSyntax? parameters, SemanticModel semanticModel, 43 | bool useLongNames = false, bool prettyPrint = true) 44 | { 45 | if (parameters == null) 46 | { 47 | return string.Empty; 48 | } 49 | 50 | var paramList = (from VisualBasicSyntax.ParameterSyntax parameter in parameters.Parameters select MapParameter(parameter, useLongNames, semanticModel)).ToList(); 51 | return prettyPrint ? $"({string.Join(", ", paramList)})" : string.Join(string.Empty, paramList); 52 | } 53 | 54 | private static string MapParameter(VisualBasicSyntax.ParameterSyntax? parameter, 55 | bool useLongNames, SemanticModel semanticModel) 56 | { 57 | if (parameter == null || 58 | semanticModel == null) 59 | { 60 | return string.Empty; 61 | } 62 | 63 | var symbol = SymbolHelper.GetSymbol(semanticModel, parameter); 64 | return TypeMapper.Map(symbol?.Type, useLongNames); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/RecordMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using CodeNav.Models; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | 8 | namespace CodeNav.Mappers 9 | { 10 | public static class RecordMapper 11 | { 12 | public static CodeFunctionItem? MapRecord(RecordDeclarationSyntax? member, 13 | ICodeViewUserControl control, SemanticModel semanticModel) 14 | { 15 | if (member == null) 16 | { 17 | return null; 18 | } 19 | 20 | var item = BaseMapper.MapBase(member, member.Identifier, member.Modifiers, control, semanticModel); 21 | item.Kind = CodeItemKindEnum.Record; 22 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 23 | item.Parameters = ParameterMapper.MapParameters(member.ParameterList); 24 | 25 | if (TriviaSummaryMapper.HasSummary(member) && SettingsHelper.UseXMLComments) 26 | { 27 | item.Tooltip = TriviaSummaryMapper.Map(member); 28 | } 29 | 30 | return item; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/StructMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Extensions; 4 | using CodeNav.Helpers; 5 | using CodeNav.Models; 6 | using Microsoft.CodeAnalysis; 7 | using Microsoft.CodeAnalysis.CSharp.Syntax; 8 | using System.Windows.Media; 9 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 10 | 11 | namespace CodeNav.Mappers 12 | { 13 | public static class StructMapper 14 | { 15 | public static CodeClassItem? MapStruct(StructDeclarationSyntax? member, 16 | ICodeViewUserControl control, SemanticModel semanticModel, SyntaxTree tree) 17 | { 18 | if (member == null) 19 | { 20 | return null; 21 | } 22 | 23 | var item = BaseMapper.MapBase(member, member.Identifier, member.Modifiers, control, semanticModel); 24 | item.Kind = CodeItemKindEnum.Struct; 25 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 26 | item.BorderColor = Colors.DarkGray; 27 | 28 | if (TriviaSummaryMapper.HasSummary(member) && SettingsHelper.UseXMLComments) 29 | { 30 | item.Tooltip = TriviaSummaryMapper.Map(member); 31 | } 32 | 33 | foreach (var structMember in member.Members) 34 | { 35 | item.Members.AddIfNotNull(SyntaxMapper.MapMember(structMember, tree, semanticModel, control)); 36 | } 37 | 38 | return item; 39 | } 40 | 41 | public static CodeClassItem? MapStruct(VisualBasicSyntax.StructureBlockSyntax? member, 42 | ICodeViewUserControl control, SemanticModel semanticModel, SyntaxTree tree) 43 | { 44 | if (member == null) 45 | { 46 | return null; 47 | } 48 | 49 | var item = BaseMapper.MapBase(member, member.StructureStatement.Identifier, 50 | member.StructureStatement.Modifiers, control, semanticModel); 51 | item.Kind = CodeItemKindEnum.Struct; 52 | item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access); 53 | item.BorderColor = Colors.DarkGray; 54 | 55 | if (TriviaSummaryMapper.HasSummary(member) && SettingsHelper.UseXMLComments) 56 | { 57 | item.Tooltip = TriviaSummaryMapper.Map(member); 58 | } 59 | 60 | foreach (var structMember in member.Members) 61 | { 62 | item.Members.AddIfNotNull(SyntaxMapper.MapMember(structMember, tree, semanticModel, control)); 63 | } 64 | 65 | return item; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/TooltipMapper.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using CodeNav.Models; 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 6 | 7 | namespace CodeNav.Mappers 8 | { 9 | public static class TooltipMapper 10 | { 11 | public static string Map(CodeItemAccessEnum access, string type, string name, ParameterListSyntax parameters) 12 | { 13 | return Map(access, type, name, ParameterMapper.MapParameters(parameters, true)); 14 | } 15 | 16 | public static string Map(CodeItemAccessEnum access, string type, string name, 17 | VisualBasicSyntax.ParameterListSyntax parameters, SemanticModel semanticModel) 18 | { 19 | return Map(access, type, name, ParameterMapper.MapParameters(parameters, semanticModel, true)); 20 | } 21 | 22 | public static string Map(CodeItemAccessEnum access, string type, string name, string extra) 23 | { 24 | var accessString = access == CodeItemAccessEnum.Unknown ? string.Empty : access.ToString(); 25 | return string.Join(" ", new[] { accessString, type, name, extra }.Where(s => !string.IsNullOrEmpty(s))); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/TriviaSummaryMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using Microsoft.CodeAnalysis; 4 | using Microsoft.CodeAnalysis.CSharp; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | using System; 7 | using System.Linq; 8 | using VisualBasic = Microsoft.CodeAnalysis.VisualBasic; 9 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 10 | 11 | namespace CodeNav.Mappers 12 | { 13 | public static class TriviaSummaryMapper 14 | { 15 | public static string Map(SyntaxNode member) 16 | { 17 | try 18 | { 19 | var commentTrivia = GetCommentTrivia(member); 20 | var summaryContent = GetCommentContent(commentTrivia, "summary"); 21 | return summaryContent.Replace("'''", string.Empty).Replace("///", string.Empty).Trim(); 22 | } 23 | catch (InvalidOperationException) 24 | { 25 | // Ignore Unexpected false 26 | } 27 | 28 | return string.Empty; 29 | } 30 | 31 | public static bool HasSummary(SyntaxNode member) 32 | { 33 | var commentTrivia = GetCommentTrivia(member); 34 | return commentTrivia.RawKind != (int)SyntaxKind.None; 35 | } 36 | 37 | private static SyntaxTrivia GetCommentTrivia(SyntaxNode member) 38 | { 39 | var leadingTrivia = member.GetLeadingTrivia(); 40 | return leadingTrivia.FirstOrDefault(t => t.RawKind == (int)SyntaxKind.SingleLineDocumentationCommentTrivia || 41 | t.RawKind == (int)VisualBasic.SyntaxKind.DocumentationCommentTrivia); 42 | } 43 | 44 | private static string GetCommentContent(SyntaxTrivia commentTrivia, string commentName) 45 | { 46 | var nodes = commentTrivia.GetStructure()?.ChildNodes(); 47 | var xmlElement = nodes.FirstOrDefault(n => ( 48 | n.RawKind == (int)SyntaxKind.XmlElement || 49 | n.RawKind == (int)VisualBasic.SyntaxKind.XmlElement 50 | ) 51 | && IsCommentNamed(n, commentName)); 52 | if (xmlElement is XmlElementSyntax xmlSyntax) 53 | { 54 | return xmlSyntax.Content.ToString(); 55 | } 56 | 57 | if (xmlElement is VisualBasicSyntax.XmlElementSyntax vbXmlSyntax) 58 | { 59 | return vbXmlSyntax.Content.ToString(); 60 | } 61 | 62 | return string.Empty; 63 | } 64 | 65 | private static bool IsCommentNamed(SyntaxNode node, string commentName) 66 | { 67 | if (node is XmlElementSyntax xmlSyntax) 68 | { 69 | return xmlSyntax.StartTag.Name.LocalName.ValueText.Equals(commentName); 70 | } 71 | 72 | if (node is VisualBasicSyntax.XmlElementSyntax vbXmlSyntax) 73 | { 74 | return vbXmlSyntax.StartTag.Name.ToString().Equals(commentName); 75 | } 76 | 77 | return false; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /CodeNav.Shared/Mappers/TypeMapper.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System.Linq; 4 | using System.Text.RegularExpressions; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp.Syntax; 7 | using VisualBasicSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax; 8 | 9 | namespace CodeNav.Mappers 10 | { 11 | public static class TypeMapper 12 | { 13 | public static string Map(ITypeSymbol? type, bool useLongNames = false) 14 | { 15 | if (type == null) 16 | { 17 | return string.Empty; 18 | } 19 | 20 | return Map(type.ToString(), useLongNames); 21 | } 22 | 23 | public static string Map(TypeSyntax? type, bool useLongNames = false) 24 | { 25 | if (type == null) 26 | { 27 | return string.Empty; 28 | } 29 | 30 | return Map(type.ToString(), useLongNames); 31 | } 32 | 33 | public static string Map(VisualBasicSyntax.TypeSyntax? type, bool useLongNames = false) 34 | { 35 | if (type == null) 36 | { 37 | return string.Empty; 38 | } 39 | 40 | return Map(type.ToString(), useLongNames); 41 | } 42 | 43 | public static string Map(string type, bool useLongNames = false) 44 | { 45 | if (useLongNames) 46 | { 47 | return type; 48 | } 49 | 50 | var match = new Regex("(.*)<(.*)>").Match(type); 51 | if (match.Success) 52 | { 53 | return $"{match.Groups[1].Value.Split('.').Last()}<{match.Groups[2].Value.Split('.').Last()}>"; 54 | } 55 | return type.Contains(".") ? type.Split('.').Last() : type; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/BookmarkStyle.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using Microsoft.VisualStudio.PlatformUI; 3 | using System.Windows.Media; 4 | 5 | namespace CodeNav.Models 6 | { 7 | public class BookmarkStyle : ObservableObject 8 | { 9 | private Color _backgroundColor; 10 | 11 | public Color BackgroundColor 12 | { 13 | get => _backgroundColor; 14 | set 15 | { 16 | SetProperty(ref _backgroundColor, value); 17 | NotifyPropertyChanged("BackgroundBrush"); 18 | } 19 | } 20 | 21 | private Color _foregroundColor; 22 | 23 | public Color ForegroundColor 24 | { 25 | get => _foregroundColor; 26 | set 27 | { 28 | SetProperty(ref _foregroundColor, value); 29 | NotifyPropertyChanged("ForegroundBrush"); 30 | } 31 | } 32 | 33 | public SolidColorBrush BackgroundBrush => ColorHelper.ToBrush(BackgroundColor); 34 | 35 | public SolidColorBrush ForegroundBrush => ColorHelper.ToBrush(ForegroundColor); 36 | 37 | public BookmarkStyle() 38 | { 39 | 40 | } 41 | 42 | public BookmarkStyle(Color backgroundColor, Color foregroundColor) 43 | { 44 | BackgroundColor = backgroundColor; 45 | ForegroundColor = foregroundColor; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeClassItem.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using Microsoft.VisualStudio.PlatformUI; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Windows; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | 12 | namespace CodeNav.Models 13 | { 14 | public class CodeClassItem : CodeItem, IMembers, ICodeCollapsible 15 | { 16 | public CodeClassItem() 17 | { 18 | Members = new List(); 19 | } 20 | 21 | public List Members { get; set; } 22 | 23 | public string Parameters { get; set; } = string.Empty; 24 | 25 | private Color _borderColor; 26 | public Color BorderColor 27 | { 28 | get 29 | { 30 | return _borderColor; 31 | } 32 | set 33 | { 34 | SetProperty(ref _borderColor, value); 35 | NotifyPropertyChanged("BorderBrush"); 36 | } 37 | } 38 | public SolidColorBrush BorderBrush 39 | { 40 | get 41 | { 42 | return ColorHelper.ToBrush(_borderColor); 43 | } 44 | } 45 | 46 | public event EventHandler? IsExpandedChanged; 47 | private bool _isExpanded; 48 | public bool IsExpanded 49 | { 50 | get { return _isExpanded; } 51 | set 52 | { 53 | if (_isExpanded != value) 54 | { 55 | SetProperty(ref _isExpanded, value); 56 | IsExpandedChanged?.Invoke(this, EventArgs.Empty); 57 | } 58 | } 59 | } 60 | 61 | /// 62 | /// Do we have any members that are not null and should be visible? 63 | /// If we don't hide the expander +/- symbol and the header border 64 | /// 65 | public Visibility HasMembersVisibility 66 | { 67 | get 68 | { 69 | return Members.Any(m => m != null && m.IsVisible == Visibility.Visible) 70 | ? Visibility.Visible 71 | : Visibility.Collapsed; 72 | } 73 | } 74 | 75 | public ICommand ToggleIsExpandedCommand => new DelegateCommand(ToggleIsExpanded); 76 | public void ToggleIsExpanded(object args) 77 | { 78 | IsDoubleClicked = true; 79 | IsExpanded = !IsExpanded; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeDepthGroupItem.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public class CodeDepthGroupItem : CodeClassItem 4 | { 5 | private int _selectedIndex; 6 | public int SelectedIndex 7 | { 8 | get => _selectedIndex; 9 | set => SetProperty(ref _selectedIndex, value); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeFunctionItem.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | namespace CodeNav.Models 4 | { 5 | public class CodeFunctionItem : CodeItem 6 | { 7 | public string Parameters { get; set; } = string.Empty; 8 | 9 | public string Type { get; set; } = string.Empty; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeInterfaceItem.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public class CodeInterfaceItem : CodeClassItem 4 | { 5 | } 6 | 7 | public class CodeImplementedInterfaceItem : CodeRegionItem 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeItemAccessEnum.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace CodeNav.Models 4 | { 5 | public enum CodeItemAccessEnum 6 | { 7 | [Description("")] 8 | Unknown, 9 | [Description("All")] 10 | All, 11 | [Description("Public")] 12 | Public, 13 | [Description("Private")] 14 | Private, 15 | [Description("Protected")] 16 | Protected, 17 | [Description("Internal")] 18 | Internal, 19 | [Description("Sealed")] 20 | Sealed 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeItemKindEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public enum CodeItemKindEnum 4 | { 5 | Unknown, 6 | All, 7 | Class, 8 | Constant, 9 | Constructor, 10 | Delegate, 11 | Enum, 12 | EnumMember, 13 | Event, 14 | ImplementedInterface, 15 | Indexer, 16 | Interface, 17 | Method, 18 | Namespace, 19 | Property, 20 | Region, 21 | Struct, 22 | Switch, 23 | SwitchSection, 24 | Variable, 25 | LocalFunction, 26 | BaseClass, 27 | StyleRule, 28 | PageRule, 29 | NamespaceRule, 30 | MediaRule, 31 | FontFaceRule, 32 | Record 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeNamespaceItem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | 5 | namespace CodeNav.Models 6 | { 7 | public class CodeNamespaceItem : CodeClassItem 8 | { 9 | public CodeNamespaceItem() 10 | { 11 | Members = new List(); 12 | } 13 | 14 | public Visibility IgnoreVisibility { get; set; } 15 | 16 | public Visibility NotIgnoreVisibility 17 | { 18 | get 19 | { 20 | return IgnoreVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodePropertyItem.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public class CodePropertyItem : CodeFunctionItem 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/CodeRegionItem.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public class CodeRegionItem : CodeClassItem 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/FilterRule.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public class FilterRule 4 | { 5 | public CodeItemAccessEnum Access { get; set; } 6 | 7 | public CodeItemKindEnum Kind { get; set; } 8 | 9 | public bool Visible { get; set; } 10 | 11 | public string Opacity { get; set; } = string.Empty; 12 | 13 | public bool HideIfEmpty { get; set; } 14 | 15 | public bool Ignore { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/ICodeCollapsible.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeNav.Models 4 | { 5 | public interface ICodeCollapsible 6 | { 7 | event EventHandler IsExpandedChanged; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/IMembers.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CodeNav.Models 4 | { 5 | public interface IMembers 6 | { 7 | List Members { get; set; } 8 | bool IsExpanded { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/LanguageEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public enum LanguageEnum 4 | { 5 | Unknown = 0, 6 | CSharp = 1, 7 | VisualBasic = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/MarginSideEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public enum MarginSideEnum 4 | { 5 | Left, 6 | Right, 7 | None, 8 | Top 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/SolutionStorageModel.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Models.ViewModels; 2 | using System.Collections.Generic; 3 | 4 | namespace CodeNav.Models 5 | { 6 | public class SolutionStorageModel 7 | { 8 | public List Documents = new List(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CodeNav.Shared/Models/SortOrderEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Models 2 | { 3 | public enum SortOrderEnum 4 | { 5 | Unknown = 0, 6 | SortByFile = 1, 7 | SortByName = 2 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CodeNav.Shared/Options/General.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using Community.VisualStudio.Toolkit; 3 | using System.Drawing; 4 | using System.Runtime.InteropServices; 5 | 6 | internal partial class OptionsProvider 7 | { 8 | [ComVisible(true)] 9 | public class GeneralOptions : BaseOptionPage { } 10 | } 11 | 12 | public class General : BaseOptionModel 13 | { 14 | public bool ShowFilterToolbar { get; set; } = true; 15 | 16 | public bool UseXMLComments { get; set; } = false; 17 | 18 | public bool ShowHistoryIndicators { get; set; } = true; 19 | 20 | public bool DisableHighlight { get; set; } = false; 21 | 22 | public int MarginSide { get; set; } = 0; 23 | 24 | public int AutoLoadLineThreshold { get; set; } = 0; 25 | 26 | public string FontFamilyName { get; set; } = "Segoe UI"; 27 | 28 | public float FontSize { get; set; } = 11.25f; 29 | 30 | public FontStyle FontStyle { get; set; } = FontStyle.Regular; 31 | 32 | public Color HighlightColor { get; set; } = ColorHelper.Transparent(); 33 | 34 | public Color BackgroundColor { get; set; } = ColorHelper.Transparent(); 35 | 36 | public double Width { get; set; } = 200; 37 | 38 | public bool ShowMargin { get; set; } = true; 39 | 40 | public string FilterRules { get; set; } = string.Empty; 41 | 42 | public int SortOrder { get; set; } = 0; 43 | 44 | public bool UpdateWhileTyping { get; set; } = false; 45 | 46 | public bool ShowRegions { get; set; } = true; 47 | } -------------------------------------------------------------------------------- /CodeNav.Shared/Styles/BookmarkButtonStyle.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 28 | 29 | -------------------------------------------------------------------------------- /CodeNav.Shared/Styles/ContextMenuStyle.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 28 | 29 | 33 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /CodeNav.Shared/ToolWindow/CodeNavToolWindow.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using System; 4 | using CodeNav.Helpers; 5 | using System.Runtime.InteropServices; 6 | using Community.VisualStudio.Toolkit; 7 | using Microsoft.VisualStudio.Shell; 8 | using Microsoft.VisualStudio.Imaging; 9 | using System.Threading.Tasks; 10 | using System.Windows; 11 | using System.Threading; 12 | 13 | namespace CodeNav.ToolWindow 14 | { 15 | public class CodeNavToolWindow : BaseToolWindow 16 | { 17 | private CodeViewUserControl? _control; 18 | 19 | public override string GetTitle(int toolWindowId) => "CodeNav"; 20 | 21 | public override Type PaneType => typeof(Pane); 22 | 23 | public override async Task CreateAsync(int toolWindowId, CancellationToken cancellationToken) 24 | { 25 | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); 26 | 27 | _control = new CodeViewUserControl(); 28 | 29 | _control.CodeDocumentViewModel.CodeDocument = PlaceholderHelper.CreateSelectDocumentItem(); 30 | 31 | return _control; 32 | } 33 | 34 | [Guid("88d7674e-67d3-4835-9e0e-aa893dfc985a")] 35 | public class Pane : ToolWindowPane 36 | { 37 | public Pane() 38 | { 39 | BitmapImageMoniker = KnownMonikers.DocumentOutline; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CodeNav.Shared/ToolWindow/CodeNavToolWindowCommand.cs: -------------------------------------------------------------------------------- 1 | using Community.VisualStudio.Toolkit; 2 | using Microsoft.VisualStudio.Shell; 3 | using Task = System.Threading.Tasks.Task; 4 | 5 | namespace CodeNav.ToolWindow 6 | { 7 | [Command(PackageIds.CodeNavToolWindowCommandId)] 8 | internal sealed class CodeNavToolWindowCommand : BaseCommand 9 | { 10 | protected override async Task ExecuteAsync(OleMenuCmdEventArgs e) 11 | => await CodeNavToolWindow.ShowAsync(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CodeNav.Shared/ToolWindow/CodeNavToolWindowPackage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Threading; 4 | using Community.VisualStudio.Toolkit; 5 | using Microsoft.VisualStudio.Shell; 6 | using Task = System.Threading.Tasks.Task; 7 | 8 | namespace CodeNav.ToolWindow 9 | { 10 | [Guid(PackageGuids.guidCodeNavToolWindowPackageString)] 11 | [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] 12 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] 13 | [ProvideToolWindow(typeof(CodeNavToolWindow.Pane))] 14 | [ProvideMenuResource("Menus.ctmenu", 1)] 15 | [ProvideProfile(typeof(OptionsProvider.GeneralOptions), "CodeNav", "CodeNav", 110, 110, false, DescriptionResourceID = 114)] 16 | public sealed class CodeNavToolWindowPackage : ToolkitPackage 17 | { 18 | protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) 19 | { 20 | this.RegisterToolWindows(); 21 | 22 | await this.RegisterCommandsAsync(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CodeNav.Shared/ViewModels/BookmarkStylesWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Models; 4 | using Microsoft.VisualStudio.PlatformUI; 5 | using System.Collections.Generic; 6 | 7 | namespace CodeNav.Shared.ViewModels 8 | { 9 | public class BookmarkStylesWindowViewModel : ObservableObject 10 | { 11 | private List _bookmarkStyles = new List(); 12 | 13 | public List BookmarkStyles 14 | { 15 | get => _bookmarkStyles; 16 | set => SetProperty(ref _bookmarkStyles, value); 17 | } 18 | 19 | private BookmarkStyle? _selectedBookmarkStyle; 20 | 21 | public BookmarkStyle? SelectedBookmarkStyle 22 | { 23 | get => _selectedBookmarkStyle; 24 | set => SetProperty(ref _selectedBookmarkStyle, value); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CodeNav.Shared/ViewModels/FilterWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Models; 2 | using Microsoft.VisualStudio.PlatformUI; 3 | using System.Collections.ObjectModel; 4 | 5 | namespace CodeNav.Shared.ViewModels 6 | { 7 | public class FilterWindowViewModel : ObservableObject 8 | { 9 | private ObservableCollection _filterRules = new ObservableCollection(); 10 | 11 | public ObservableCollection FilterRules 12 | { 13 | get => _filterRules; 14 | set => SetProperty(ref _filterRules, value); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodeNav.Shared/ViewModels/OptionsWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using CodeNav.Models; 5 | using Microsoft.VisualStudio.PlatformUI; 6 | using System.Drawing; 7 | using System.Windows.Media; 8 | using Color = System.Drawing.Color; 9 | 10 | namespace CodeNav.Shared.ViewModels 11 | { 12 | public class OptionsWindowViewModel : ObservableObject 13 | { 14 | private bool _showFilterToolbar = true; 15 | 16 | public bool ShowFilterToolbar 17 | { 18 | get => _showFilterToolbar; 19 | set => SetProperty(ref _showFilterToolbar, value); 20 | } 21 | 22 | private bool _UseXMLComments = false; 23 | 24 | public bool UseXMLComments 25 | { 26 | get => _UseXMLComments; 27 | set => SetProperty(ref _UseXMLComments, value); 28 | } 29 | 30 | private bool _showHistoryIndicators = true; 31 | 32 | public bool ShowHistoryIndicators 33 | { 34 | get => _showHistoryIndicators; 35 | set => SetProperty(ref _showHistoryIndicators, value); 36 | } 37 | 38 | private bool _showRegions = true; 39 | 40 | public bool ShowRegions 41 | { 42 | get => _showRegions; 43 | set => SetProperty(ref _showRegions, value); 44 | } 45 | 46 | private bool _disableHighlight = false; 47 | 48 | public bool DisableHighlight 49 | { 50 | get => _disableHighlight; 51 | set => SetProperty(ref _disableHighlight, value); 52 | } 53 | 54 | private bool _updateWhileTyping = false; 55 | 56 | public bool UpdateWhileTyping 57 | { 58 | get => _updateWhileTyping; 59 | set => SetProperty(ref _updateWhileTyping, value); 60 | } 61 | 62 | private MarginSideEnum _marginSide = MarginSideEnum.Left; 63 | 64 | public MarginSideEnum MarginSide 65 | { 66 | get => _marginSide; 67 | set => SetProperty(ref _marginSide, value); 68 | } 69 | 70 | private int _autoLoadLineThreshold = 0; 71 | 72 | public int AutoLoadLineThreshold 73 | { 74 | get => _autoLoadLineThreshold; 75 | set => SetProperty(ref _autoLoadLineThreshold, value); 76 | } 77 | 78 | private Font? _font; 79 | 80 | public Font? Font 81 | { 82 | get => _font; 83 | set => SetProperty(ref _font, value); 84 | } 85 | 86 | private Color _highlightColor; 87 | 88 | public Color HighlightColor 89 | { 90 | get => _highlightColor; 91 | set => SetProperty(ref _highlightColor, value); 92 | } 93 | 94 | public SolidColorBrush HighlightBrush => ColorHelper.ToBrush(_highlightColor); 95 | 96 | private Color _backgroundColor; 97 | 98 | public Color BackgroundColor 99 | { 100 | get => _backgroundColor; 101 | set => SetProperty(ref _backgroundColor, value); 102 | } 103 | 104 | public SolidColorBrush BackgroundBrush => ColorHelper.ToBrush(_backgroundColor); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /CodeNav.Shared/Windows/BookmarkStylesWindow.xaml: -------------------------------------------------------------------------------- 1 |  17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | 50 | 51 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 72 | 73 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /CodeNav.Shared/Windows/BookmarkStylesWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using CodeNav.Models.ViewModels; 5 | using CodeNav.Shared.ViewModels; 6 | using Microsoft.VisualStudio.PlatformUI; 7 | using Microsoft.VisualStudio.Shell; 8 | using System.Windows; 9 | using System.Windows.Forms; 10 | 11 | namespace CodeNav.Windows 12 | { 13 | public partial class BookmarkStylesWindow : DialogWindow 14 | { 15 | private readonly CodeDocumentViewModel _codeDocumentViewModel; 16 | 17 | public BookmarkStylesWindow(CodeDocumentViewModel codeDocumentViewModel) 18 | { 19 | _codeDocumentViewModel = codeDocumentViewModel; 20 | 21 | InitializeComponent(); 22 | 23 | Loaded += BookmarkStylesWindow_Loaded; 24 | } 25 | 26 | private async void BookmarkStylesWindow_Loaded(object sender, RoutedEventArgs e) 27 | { 28 | DataContext = new BookmarkStylesWindowViewModel 29 | { 30 | BookmarkStyles = await BookmarkHelper.GetBookmarkStyles(_codeDocumentViewModel) 31 | }; 32 | } 33 | 34 | private BookmarkStylesWindowViewModel? ViewModel 35 | => DataContext as BookmarkStylesWindowViewModel; 36 | 37 | private void BackgroundClick(object sender, RoutedEventArgs e) 38 | { 39 | if (ViewModel == null || 40 | ViewModel.SelectedBookmarkStyle == null) 41 | { 42 | return; 43 | } 44 | 45 | var colorDialog = new ColorDialog(); 46 | if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 47 | { 48 | ViewModel.SelectedBookmarkStyle.BackgroundColor = ColorHelper.ToMediaColor(colorDialog.Color); 49 | } 50 | } 51 | 52 | private void ForegroundClick(object sender, RoutedEventArgs e) 53 | { 54 | if (ViewModel == null || 55 | ViewModel.SelectedBookmarkStyle == null) 56 | { 57 | return; 58 | } 59 | 60 | var colorDialog = new ColorDialog(); 61 | if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 62 | { 63 | ViewModel.SelectedBookmarkStyle.ForegroundColor = ColorHelper.ToMediaColor(colorDialog.Color); 64 | } 65 | } 66 | 67 | private void OkClick(object sender, RoutedEventArgs e) 68 | { 69 | if (ViewModel == null) 70 | { 71 | return; 72 | } 73 | 74 | BookmarkHelper.SetBookmarkStyles(_codeDocumentViewModel, ViewModel.BookmarkStyles).FireAndForget(); 75 | 76 | Close(); 77 | } 78 | 79 | private void CancelClick(object sender, RoutedEventArgs e) 80 | { 81 | Close(); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /CodeNav.Shared/Windows/FilterWindow.xaml: -------------------------------------------------------------------------------- 1 |  17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 34 | 35 | 39 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /CodeNav.Shared/Windows/FilterWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | #nullable enable 2 | 3 | using CodeNav.Helpers; 4 | using CodeNav.Models; 5 | using CodeNav.Shared.ViewModels; 6 | using Microsoft.VisualStudio.PlatformUI; 7 | using System.Linq; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | 11 | namespace CodeNav.Windows 12 | { 13 | public partial class FilterWindow : DialogWindow 14 | { 15 | private DataGridCell? _cell; 16 | 17 | public FilterWindow() 18 | { 19 | InitializeComponent(); 20 | 21 | Loaded += FilterWindow_Loaded; 22 | } 23 | 24 | private void FilterWindow_Loaded(object sender, RoutedEventArgs e) 25 | { 26 | DataContext = new FilterWindowViewModel 27 | { 28 | FilterRules = SettingsHelper.FilterRules 29 | }; 30 | } 31 | 32 | private FilterWindowViewModel? ViewModel => DataContext as FilterWindowViewModel; 33 | 34 | private void OkClick(object sender, RoutedEventArgs e) 35 | { 36 | if (ViewModel == null) 37 | { 38 | return; 39 | } 40 | 41 | SettingsHelper.SaveFilterRules(ViewModel.FilterRules); 42 | 43 | Close(); 44 | } 45 | 46 | private void CancelClick(object sender, RoutedEventArgs e) 47 | { 48 | Close(); 49 | } 50 | 51 | private void AddClick(object sender, RoutedEventArgs e) 52 | { 53 | if (ViewModel == null) 54 | { 55 | return; 56 | } 57 | 58 | ViewModel.FilterRules.Add(new FilterRule()); 59 | } 60 | 61 | private void DeleteClick(object sender, RoutedEventArgs e) 62 | { 63 | if (_cell == null || 64 | ViewModel == null || 65 | !(_cell.DataContext is FilterRule filterRule)) 66 | { 67 | return; 68 | } 69 | 70 | ViewModel.FilterRules.Remove(filterRule); 71 | } 72 | 73 | private void DataGrid_Selected(object sender, RoutedEventArgs e) 74 | { 75 | if (e.OriginalSource.GetType() != typeof(DataGridCell) || 76 | !(sender is DataGrid grid)) 77 | { 78 | return; 79 | } 80 | 81 | grid.BeginEdit(e); 82 | 83 | var cell = e.OriginalSource as DataGridCell; 84 | 85 | _cell = cell; 86 | 87 | var comboBox = WpfHelper 88 | .FindChildrenByType(cell) 89 | .FirstOrDefault(); 90 | 91 | if (comboBox != null) 92 | { 93 | comboBox.IsDropDownOpen = true; 94 | } 95 | 96 | var checkBox = WpfHelper 97 | .FindChildrenByType(cell) 98 | .FirstOrDefault(); 99 | 100 | if (checkBox != null) 101 | { 102 | checkBox.IsChecked = !checkBox.IsChecked; 103 | } 104 | 105 | var textBox = WpfHelper 106 | .FindChildrenByType(cell) 107 | .FirstOrDefault(); 108 | 109 | if (textBox != null) 110 | { 111 | textBox.SelectAll(); 112 | } 113 | } 114 | 115 | private void DataGrid_Unloaded(object sender, RoutedEventArgs e) 116 | { 117 | if (!(sender is DataGrid grid)) 118 | { 119 | return; 120 | } 121 | 122 | grid.CancelEdit(DataGridEditingUnit.Row); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /CodeNav.Tests/Files/CodeNavTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CodeNav.Models; 4 | 5 | #pragma warning disable 6 | 7 | namespace CodeNav.Tests 8 | { 9 | public class CodeNavTest 10 | { 11 | public CodeNavTest() 12 | { 13 | 14 | } 15 | 16 | public const string Constant = "CodeNav"; 17 | 18 | protected int Version = 1; 19 | 20 | public bool Field = true; 21 | 22 | 23 | private int _secret = 2; 24 | 25 | int NoModifierProperty { get; set; } 26 | 27 | private int PrivateProperty { get; set; } 28 | 29 | public int PublicMethod(int a, int b) 30 | { 31 | return a + b; 32 | } 33 | 34 | public int PublicMethod(int a, int b, int c) 35 | { 36 | // Overloading method 37 | return a + b + c; 38 | } 39 | 40 | private int PrivateMethod(int a, int b) 41 | { 42 | return a - b; 43 | } 44 | 45 | protected void ProtectedMethod(int a, int b) 46 | { 47 | 48 | } 49 | 50 | public float Property { get; set; } 51 | 52 | private void GetListOfStrings(List lines) { } 53 | 54 | public List ReturnListOfCodeItems() 55 | { 56 | return new List(); 57 | } 58 | 59 | public delegate void ChangedEventHandler(object sender, EventArgs e); 60 | protected event ChangedEventHandler Changed; 61 | 62 | #region Region 63 | 64 | public bool RegionMethod() 65 | { 66 | return false; 67 | } 68 | 69 | public int RegionProperty 70 | { 71 | get; set; 72 | } 73 | 74 | public const string RegionString = "CodeNav"; 75 | 76 | public bool RegionMethod(bool overload) 77 | { 78 | return true; 79 | } 80 | 81 | #endregion 82 | 83 | public struct Structure 84 | { 85 | public int StructureProperty { get; } 86 | public const int StructureConstant = 42; 87 | 88 | private void StructureMethod() 89 | { 90 | } 91 | } 92 | 93 | internal class InternalClass 94 | { 95 | internal const int InternalConstant = 42; 96 | internal int InternalMethod() 97 | { 98 | return 42; 99 | } 100 | 101 | internal string InternalProperty { get; set; } 102 | } 103 | } 104 | 105 | public interface ICodeNavTest2 106 | { 107 | int InterfaceMethod(); 108 | int InterfaceMethod(int input); 109 | int InterfaceProperty { get; } 110 | } 111 | 112 | public class CodeNavTest2 : ICodeNavTest2 113 | { 114 | public int InterfaceMethod() 115 | { 116 | return 0; 117 | } 118 | 119 | public int InterfaceMethod(int input) 120 | { 121 | // Overloading within the same interface 122 | return input; 123 | } 124 | 125 | public int InterfaceMethod(int a, int b) 126 | { 127 | // Overloading outside the interface 128 | return a + b; 129 | } 130 | 131 | public void NonInterfaceMethod() 132 | { 133 | 134 | } 135 | 136 | public int InterfaceProperty { get; } 137 | } 138 | 139 | public enum DayEnum 140 | { 141 | Monday, 142 | Tueday, 143 | Wednesday, 144 | Thursday, 145 | Friday, 146 | Saturday, 147 | Sunday 148 | } 149 | } 150 | 151 | #pragma warning restore 152 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/JavaScript/TestFunction.js: -------------------------------------------------------------------------------- 1 | function firstFunction() { 2 | //Basic function 3 | } 4 | 5 | function secondFunction(input) { 6 | //Function with parameter 7 | } 8 | 9 | // Assigned function 10 | var assignedFunction = function (a, b) { return a * b }; 11 | 12 | // Using the Function constructor 13 | var myFunction = new Function("a", "b", "return a * b"); 14 | 15 | // Arrow functions - ES6 16 | const x = (x, y) => x * y; 17 | 18 | // Inner functions 19 | function outerFunction() { 20 | function innerFunction() { 21 | 22 | } 23 | 24 | var assignedInnerFunction = function (a, b) { return a * b }; 25 | } 26 | 27 | async function asyncFunction() { 28 | // Async function 29 | } -------------------------------------------------------------------------------- /CodeNav.Tests/Files/JavaScript/TestVariable.js: -------------------------------------------------------------------------------- 1 | var firstVariable; 2 | 3 | var assignedVariable = 1; -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestEmptyClass.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests 2 | { 3 | class CodeNavTestEmptyClass 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestEmptyInterface.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | 4 | } 5 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestIndexers.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | class TestIndexers 4 | { 5 | internal string this[int index] 6 | { 7 | get { return "some value"; } 8 | set { /* Do something. */ } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestInterface.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | interface ITestInterface 4 | { 5 | int InterfaceMethod(); 6 | int InterfaceMethod(int input); 7 | int InterfaceProperty { get; } 8 | } 9 | 10 | public class ImplementingClass : ITestInterface 11 | { 12 | public int InterfaceMethod() 13 | { 14 | return 0; 15 | } 16 | 17 | public int InterfaceMethod(int input) 18 | { 19 | // Overloading within the same interface 20 | return input; 21 | } 22 | 23 | public int InterfaceMethod(int a, int b) 24 | { 25 | // Overloading outside the interface 26 | return a + b; 27 | } 28 | 29 | public void NonInterfaceMethod() 30 | { 31 | 32 | } 33 | 34 | public int InterfaceProperty { get; } 35 | } 36 | 37 | public class ImplementingClass2 : ITestInterface 38 | { 39 | #region ITestInterface implementation 40 | 41 | public int InterfaceMethod() 42 | { 43 | return 0; 44 | } 45 | 46 | public int InterfaceMethod(int input) 47 | { 48 | // Overloading within the same interface 49 | return input; 50 | } 51 | 52 | public int InterfaceProperty { get; } 53 | 54 | #endregion 55 | 56 | public int InterfaceMethod(int a, int b) 57 | { 58 | // Overloading outside the interface 59 | return a + b; 60 | } 61 | 62 | public void NonInterfaceMethod() 63 | { 64 | 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestInterface2.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | interface ITestInterface1 4 | { 5 | int InterfaceMethod1(); 6 | } 7 | 8 | interface ITestInterface2 : ITestInterface1 9 | { 10 | int InterfaceMethod2(); 11 | } 12 | 13 | class ImplementingClass1 : ITestInterface2 14 | { 15 | public int InterfaceMethod1() 16 | { 17 | return 0; 18 | } 19 | 20 | public int InterfaceMethod2() 21 | { 22 | return 0; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestInterface3.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | interface ITestInterface3 4 | { 5 | int InterfaceMethod1(); 6 | } 7 | 8 | interface ITestInterface4 9 | { 10 | int InterfaceMethod2(); 11 | } 12 | 13 | interface ITestInterface5 : ITestInterface4 14 | { 15 | int InterfaceMethod3(); 16 | } 17 | 18 | class BaseClass : ITestInterface5 19 | { 20 | public int InterfaceMethod2() 21 | { 22 | throw new System.NotImplementedException(); 23 | } 24 | 25 | public int InterfaceMethod3() 26 | { 27 | throw new System.NotImplementedException(); 28 | } 29 | } 30 | 31 | class ImplementingClass3 : BaseClass, ITestInterface3 32 | { 33 | public int InterfaceMethod1() 34 | { 35 | throw new System.NotImplementedException(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestInterface4.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | interface Interface2 4 | { 5 | int Interface2Method(); 6 | } 7 | 8 | interface Interface1 : Interface2 9 | { 10 | int Interface1Method(); 11 | } 12 | 13 | class ClassB : Interface1 14 | { 15 | public int Interface1Method() 16 | { 17 | throw new System.NotImplementedException(); 18 | } 19 | 20 | public int Interface2Method() 21 | { 22 | throw new System.NotImplementedException(); 23 | } 24 | } 25 | 26 | class ClassA : ClassB, Interface1 27 | { 28 | public void ClassAMethod() { } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestInterfaceRegion.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | interface IRegionTestInterface 4 | { 5 | int InterfaceMethod(); 6 | int InterfaceMethod(int input); 7 | int InterfaceProperty { get; } 8 | 9 | #region 10 | int RegionMethod(); 11 | #endregion 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestMethodsWithComments.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | class TestMethodsWithComments 4 | { 5 | /// 6 | /// Super important summary 7 | /// 8 | public void MethodWithComment() 9 | { 10 | 11 | } 12 | 13 | public void MethodWithoutComment() 14 | { 15 | 16 | } 17 | 18 | /// 19 | /// Multiple comment - summary 20 | /// 21 | /// 22 | /// Multiple comment - remarks 23 | /// 24 | public void MethodWithMultipleComment() 25 | { 26 | 27 | } 28 | 29 | /// 30 | /// Multiple comment - remarks 31 | /// 32 | /// 33 | /// Multiple comment - summary 34 | /// 35 | public void MethodWithReorderedComment() 36 | { 37 | 38 | } 39 | 40 | internal string this[int index] 41 | { 42 | get { return "some value"; } 43 | set { /* Do something. */ } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestNamespaceRegions.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | #region Classes 4 | class TestNamespaceRegions 5 | { 6 | public void testMethod() 7 | { 8 | 9 | } 10 | } 11 | #endregion 12 | } 13 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestNestedNamespaces.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests 2 | { 3 | namespace NestedNamespace 4 | { 5 | public class ClassInNestedNamespace { } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestNestedRegions.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | public class TestNestedRegions 4 | { 5 | #region ParentRegion 6 | 7 | public void ParentRegionFunction() 8 | { 9 | 10 | } 11 | 12 | #region ChildRegion 13 | public void ChildRegionFunction() 14 | { 15 | 16 | } 17 | 18 | #endregion 19 | 20 | #endregion 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestNoNamespace.cs: -------------------------------------------------------------------------------- 1 | public class TestNoNamespace 2 | { 3 | 4 | } -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestPartial1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeNav.Tests.Files 4 | { 5 | public interface IPartial1 6 | { 7 | void Partial1Method(); 8 | } 9 | 10 | public partial class TestPartial : IPartial1 11 | { 12 | public void Partial1Method() 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestPartial2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeNav.Tests.Files 4 | { 5 | public interface IPartial2 6 | { 7 | void Partial2Method(); 8 | } 9 | 10 | public partial class TestPartial : IPartial2 11 | { 12 | public void Partial2Method() 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #pragma warning disable 4 | 5 | namespace CodeNav.Tests.Files 6 | { 7 | public class TestProperties 8 | { 9 | public int PropertyGetSet { get; set; } 10 | public int PropertyGet { get; } 11 | public int PropertySet 12 | { 13 | set 14 | { 15 | 16 | } 17 | } 18 | 19 | private int _property; 20 | public int Property => _property; 21 | } 22 | } 23 | 24 | #pragma warning restore 25 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestRegions.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 2 | 3 | namespace CodeNav.Tests.Files 4 | { 5 | public class Class2 6 | { 7 | #region R1 8 | 9 | #region R15 10 | public const int nestedRegionConstant = 1; 11 | 12 | #region R16 13 | int i1 = 0; 14 | #endregion 15 | 16 | #endregion 17 | 18 | public void Test1() 19 | { 20 | #region R11 21 | int i1 = 0; 22 | #endregion 23 | 24 | #region R12 25 | int i2 = 0; 26 | #endregion 27 | 28 | #region R13 29 | int i3 = 0; 30 | #endregion 31 | 32 | #region R14 33 | int i4 = 0; 34 | #endregion 35 | } 36 | 37 | public void Test2() 38 | { 39 | 40 | } 41 | 42 | #endregion 43 | 44 | public void OutsideRegionFunction() 45 | { 46 | 47 | } 48 | 49 | #region R2 50 | public void SiblingRegionFunction() 51 | { 52 | 53 | } 54 | 55 | void _MethodWithoutAccessModifier() 56 | { 57 | 58 | } 59 | #endregion 60 | } 61 | } 62 | 63 | #pragma warning restore -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestRegionsNoName.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | public class TestRegionsNoName 4 | { 5 | #region 6 | public void RegionFunction() 7 | { 8 | 9 | } 10 | #endregion 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestSealed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeNav.Tests 4 | { 5 | public sealed class SealedBaseClass 6 | { 7 | public void Display() 8 | { 9 | Console.WriteLine("This is a sealed class which can't be further inherited"); 10 | } 11 | } 12 | 13 | public class BaseClass 14 | { 15 | public virtual void BaseMethod() { } 16 | public virtual int BaseProperty { get; set; } 17 | } 18 | 19 | public class InheritingClass : BaseClass 20 | { 21 | public sealed override void BaseMethod() 22 | { 23 | } 24 | 25 | public sealed override int BaseProperty { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestSorting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeNav.Tests.Files 4 | { 5 | class TestSorting 6 | { 7 | void C() 8 | { 9 | 10 | } 11 | 12 | void B() 13 | { 14 | 15 | } 16 | 17 | void A() 18 | { 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestSwitch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CodeNav.Tests.Files 8 | { 9 | class TestSwitch 10 | { 11 | void TestSwitchFunction() 12 | { 13 | var i = 0; 14 | 15 | switch (i) 16 | { 17 | case 0: 18 | return; 19 | case 1: 20 | return; 21 | default: 22 | return; 23 | } 24 | } 25 | 26 | void TestSwitchInBlockFunction() 27 | { 28 | var i = 0; 29 | 30 | { 31 | switch (i) 32 | { 33 | case 0: 34 | return; 35 | case 1: 36 | return; 37 | default: 38 | return; 39 | } 40 | } 41 | } 42 | 43 | void TestSwitchInTryCatchFunction() 44 | { 45 | var i = 0; 46 | 47 | try { 48 | switch (i) 49 | { 50 | case 0: 51 | return; 52 | case 1: 53 | return; 54 | default: 55 | return; 56 | } 57 | } 58 | catch(Exception) 59 | { 60 | 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestUsingsInNamespace.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | class TestUsingsInNamespace 10 | { 11 | public TestUsingsInNamespace() 12 | { 13 | 14 | } 15 | 16 | private void PrivateMethod(int a, int b) 17 | { 18 | return; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/TestVisibility.cs: -------------------------------------------------------------------------------- 1 | namespace CodeNav.Tests.Files 2 | { 3 | class TestVisibility 4 | { 5 | /* Empty class 6 | * Should be shown or hidden depending on the setting 7 | */ 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestClasses.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | 3 | End Class 4 | 5 | Public Class Class2 6 | Inherits Class1 7 | 8 | End Class 9 | 10 | -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestFields.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | 3 | Public Const Constant As String = "CodeNav" 4 | 5 | Protected Version As Integer = 1 6 | 7 | Public Field As Boolean = True 8 | 9 | Private _secret As int = 2 10 | 11 | Dim LocalType = "string" 12 | 13 | End Class -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestInterfaces.vb: -------------------------------------------------------------------------------- 1 | Interface IValue 2 | Sub Render() 3 | End Interface -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestMethods.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | 3 | Public Sub New(ByVal Value As String) 4 | mstrLine = Value 5 | End Sub 6 | 7 | Function Area(ByVal radius As Double) As Double 8 | Return Math.PI * Math.Pow(radius, 2) 9 | End Function 10 | 11 | Friend Sub SubInsteadOfFunction(ByVal diam As Integer) 12 | 13 | End Sub 14 | 15 | Function ShorthandFunction$(ByVal input$) 16 | 17 | End Function 18 | 19 | End Class -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestMethodsWithComments.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | 3 | ''' 4 | ''' Super important summary 5 | ''' 6 | Function FunctionWithComment() 7 | 8 | End Function 9 | 10 | Function FunctionWithoutComment() 11 | 12 | End Function 13 | 14 | ''' 15 | ''' Multiple comment - summary 16 | ''' 17 | ''' Special returns 18 | Function FunctionWithMultipleComment() 19 | 20 | End Function 21 | 22 | ''' Special returns 23 | ''' 24 | ''' Multiple comment - summary 25 | ''' 26 | Function FunctionWithReorderedComment() 27 | 28 | End Function 29 | 30 | End Class -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestModules.vb: -------------------------------------------------------------------------------- 1 | Module Module1 2 | 3 | ''' 4 | ''' Levels of importance. 5 | ''' 6 | Enum Importance 7 | None = 0 8 | Trivial = 1 9 | Regular = 2 10 | Important = 3 11 | Critical = 4 12 | End Enum 13 | 14 | Sub Main() 15 | Dim value As Importance = Importance.Critical 16 | ' Select the enum and print a value. 17 | Select Case value 18 | Case Importance.Trivial 19 | Console.WriteLine("Not true") 20 | Return 21 | Case Importance.Critical 22 | Console.WriteLine("True") 23 | Exit Select 24 | End Select 25 | End Sub 26 | 27 | End Module -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestNamespaces.vb: -------------------------------------------------------------------------------- 1 | Namespace Perls 2 | Class Website 3 | Public Shared Sub Execute() 4 | Console.WriteLine("Perls Website") 5 | End Sub 6 | End Class 7 | End Namespace -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestProperties.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | 3 | Property fullName() As String 4 | Get 5 | End Get 6 | Set(ByVal Value As String) 7 | End Set 8 | End Property 9 | 10 | Property fullName() As String 11 | Get 12 | End Get 13 | End Property 14 | 15 | Property fullName() As String 16 | Set(ByVal Value As String) 17 | End Set 18 | End Property 19 | 20 | Property fullName() As String 21 | End Property 22 | 23 | Public Property fullName$ 24 | End Property 25 | End Class -------------------------------------------------------------------------------- /CodeNav.Tests/Files/VisualBasic/TestRegions.vb: -------------------------------------------------------------------------------- 1 | Public Class Class1 2 | Public Property outsideRegion$ 3 | End Property 4 | 5 | #Region "FirstRegion" 6 | 7 | Public Property insideRegion$ 8 | End Property 9 | 10 | #End Region 11 | 12 | End Class -------------------------------------------------------------------------------- /CodeNav.Tests/HelperTests/HighlightHelperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using CodeNav.Mappers; 3 | using CodeNav.Models; 4 | using CodeNav.Models.ViewModels; 5 | using NUnit.Framework; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Windows; 11 | using System.Windows.Media; 12 | 13 | namespace CodeNav.Tests.HelperTests 14 | { 15 | [TestFixture] 16 | public class HighlightHelperTests 17 | { 18 | [Test] 19 | public void CurrentItemShouldBeHighlighted() 20 | { 21 | var document = new CodeDocumentViewModel 22 | { 23 | CodeDocument = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestProperties.cs"), null) 24 | }; 25 | 26 | HighlightHelper.HighlightCurrentItem(document, Brushes.Green.Color, 13); 27 | 28 | var highlightedClass = (document.CodeDocument.First() as IMembers).Members.First() as CodeClassItem; 29 | var highlightedItem = highlightedClass.Members[2]; 30 | 31 | Assert.AreEqual(FontWeights.Bold, highlightedItem.FontWeight); 32 | Assert.AreEqual(Brushes.Red.Color, highlightedItem.ForegroundColor); 33 | Assert.AreEqual(Brushes.Blue.Color, highlightedItem.NameBackgroundColor); 34 | Assert.AreEqual(Brushes.Green.Color, highlightedClass.BorderColor); 35 | } 36 | 37 | [Test] 38 | public void OnlyOneItemShouldBeHighlighted() 39 | { 40 | var document = new CodeDocumentViewModel 41 | { 42 | CodeDocument = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestProperties.cs"), null) 43 | }; 44 | 45 | HighlightHelper.HighlightCurrentItem(document, Brushes.Green.Color, 15); 46 | 47 | HighlightHelper.HighlightCurrentItem(document, Brushes.Green.Color, 20); 48 | 49 | 50 | var highlightedItems = new List(); 51 | FindHighlightedItems(highlightedItems, document.CodeDocument); 52 | 53 | Assert.AreEqual(1, highlightedItems.Count); 54 | } 55 | 56 | private void FindHighlightedItems(List found, List source) 57 | { 58 | foreach (var item in source) 59 | { 60 | if (item.Kind == CodeItemKindEnum.Property && ( 61 | item.FontWeight == FontWeights.Bold || 62 | item.BackgroundColor == Brushes.Blue.Color || 63 | item.ForegroundColor == Brushes.Red.Color)) 64 | { 65 | found.Add(item); 66 | } 67 | 68 | if (item is IMembers) 69 | { 70 | FindHighlightedItems(found, (item as IMembers).Members); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CodeNav.Tests/HelperTests/LanguageHelperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using CodeNav.Models; 3 | using NUnit.Framework; 4 | 5 | namespace CodeNav.Tests.HelperTests 6 | { 7 | [TestFixture] 8 | public class LanguageHelperTests 9 | { 10 | [TestCase(LanguageEnum.CSharp, "C#")] 11 | [TestCase(LanguageEnum.VisualBasic, "Basic")] 12 | [TestCase(LanguageEnum.VisualBasic, "Visual Basic")] 13 | [TestCase(LanguageEnum.Unknown, "F#")] 14 | public void ItemsSorting(LanguageEnum expectedLanguage, string languageName) 15 | { 16 | Assert.AreEqual(expectedLanguage, LanguageHelper.GetLanguage(languageName)); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CodeNav.Tests/HelperTests/SortHelperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using CodeNav.Mappers; 3 | using CodeNav.Models; 4 | using CodeNav.Models.ViewModels; 5 | using NUnit.Framework; 6 | using System; 7 | using System.IO; 8 | using System.Linq; 9 | 10 | namespace CodeNav.Tests.HelperTests 11 | { 12 | [TestFixture] 13 | public class SortHelperTests 14 | { 15 | [TestCase(SortOrderEnum.SortByFile, new string[] { "C", "B", "A" })] 16 | [TestCase(SortOrderEnum.SortByName, new string[] { "A", "B", "C" })] 17 | public void ItemsSorting(SortOrderEnum sortOrder, string[] methodNames) 18 | { 19 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestSorting.cs"), null); 20 | var viewModel = new CodeDocumentViewModel { CodeDocument = document, SortOrder = sortOrder }; 21 | 22 | viewModel.CodeDocument = SortHelper.Sort(viewModel); 23 | 24 | var sortingClass = (document.First() as IMembers).Members.First() as CodeClassItem; 25 | 26 | Assert.AreEqual(methodNames[0], sortingClass.Members.First().Name); 27 | Assert.AreEqual(methodNames[1], sortingClass.Members[1].Name); 28 | Assert.AreEqual(methodNames[2], sortingClass.Members.Last().Name); 29 | 30 | Assert.AreEqual(sortOrder, viewModel.SortOrder); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CodeNav.Tests/HelperTests/VisibilityHelperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Helpers; 2 | using CodeNav.Mappers; 3 | using CodeNav.Models; 4 | using CodeNav.Models.ViewModels; 5 | using NUnit.Framework; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Collections.ObjectModel; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Windows; 12 | 13 | namespace CodeNav.Tests.HelperTests 14 | { 15 | [TestFixture] 16 | public class VisibilityHelperTests 17 | { 18 | [TestCase(false, Visibility.Visible)] 19 | [TestCase(true, Visibility.Collapsed)] 20 | public void EmptyItemsShouldRespectSetting(bool hideItemsWithoutChildren, Visibility expectedVisibility) 21 | { 22 | var document = new CodeDocumentViewModel 23 | { 24 | CodeDocument = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestVisibility.cs"), null) 25 | }; 26 | 27 | SettingsHelper.FilterRules = new ObservableCollection(new List 28 | { 29 | new FilterRule 30 | { 31 | Access = CodeItemAccessEnum.All, 32 | Kind = CodeItemKindEnum.Class, 33 | Visible = true, 34 | HideIfEmpty = hideItemsWithoutChildren 35 | } 36 | }); 37 | 38 | VisibilityHelper.SetCodeItemVisibility(document.CodeDocument); 39 | 40 | var firstClass = (document.CodeDocument.First() as IMembers).Members.First() as CodeClassItem; 41 | 42 | Assert.AreEqual(expectedVisibility, firstClass.IsVisible); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/JavaScript/TestFunctions.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Languages.JS.Mappers; 2 | using CodeNav.Models; 3 | using NUnit.Framework; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | 9 | namespace CodeNav.Tests.MapperTests.JavaScript 10 | { 11 | [TestFixture] 12 | public class TestFunctions 13 | { 14 | List document; 15 | CodeClassItem root; 16 | 17 | [OneTimeSetUp] 18 | public void Init() 19 | { 20 | document = SyntaxMapperJS.Map(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\JavaScript\\TestFunction.js"), null); 21 | 22 | Assert.IsTrue(document.Any()); 23 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 24 | root = (document.First() as CodeNamespaceItem).Members.First() as CodeClassItem; 25 | } 26 | 27 | [Test] 28 | public void TestBasicFunction() 29 | { 30 | Assert.AreEqual("firstFunction", root.Members.FirstOrDefault().Name); 31 | Assert.AreEqual(3, root.Members.FirstOrDefault().EndLine); 32 | Assert.AreEqual(0, root.Members.FirstOrDefault().Span.Start); 33 | Assert.AreEqual(51, root.Members.FirstOrDefault().Span.End); 34 | } 35 | 36 | [Test] 37 | public void TestFunctionWithParams() 38 | { 39 | Assert.AreEqual("secondFunction", root.Members[1].Name); 40 | Assert.AreEqual("(input)", (root.Members[1] as CodeFunctionItem).Parameters); 41 | } 42 | 43 | [Test] 44 | public void TestAssignedFunction() 45 | { 46 | Assert.AreEqual("assignedFunction", root.Members[2].Name); 47 | Assert.AreEqual("(a, b)", (root.Members[2] as CodeFunctionItem).Parameters); 48 | } 49 | 50 | [Test] 51 | public void TestFunctionConstructor() 52 | { 53 | Assert.AreEqual("myFunction", root.Members[3].Name); 54 | Assert.AreEqual("()", (root.Members[3] as CodeFunctionItem).Parameters); 55 | } 56 | 57 | [Test] 58 | public void TestArrowFunction() 59 | { 60 | Assert.AreEqual("x", root.Members[4].Name); 61 | Assert.AreEqual("(x, y)", (root.Members[4] as CodeFunctionItem).Parameters); 62 | } 63 | 64 | [Test] 65 | public void TestOuterInnerFunction() 66 | { 67 | Assert.AreEqual("outerFunction", root.Members[5].Name); 68 | Assert.AreEqual(2, (root.Members[5] as CodeClassItem).Members.Count); 69 | Assert.AreEqual("innerFunction", (root.Members[5] as CodeClassItem).Members.FirstOrDefault().Name); 70 | Assert.AreEqual("assignedInnerFunction", (root.Members[5] as CodeClassItem).Members[1].Name); 71 | Assert.AreEqual("(a, b)", ((root.Members[5] as CodeClassItem).Members[1] as CodeFunctionItem).Parameters); 72 | } 73 | 74 | [Test] 75 | public void TestAsyncFunction() 76 | { 77 | Assert.AreEqual("asyncFunction", root.Members[6].Name); 78 | Assert.AreEqual(27, root.Members[6].StartLine); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/JavaScript/TestVariables.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Languages.JS.Mappers; 2 | using CodeNav.Models; 3 | using NUnit.Framework; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | 9 | namespace CodeNav.Tests.MapperTests.JavaScript 10 | { 11 | [TestFixture] 12 | public class TestVariables 13 | { 14 | List document; 15 | CodeClassItem root; 16 | 17 | [OneTimeSetUp] 18 | public void Init() 19 | { 20 | document = SyntaxMapperJS.Map(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\JavaScript\\TestVariable.js"), null); 21 | 22 | Assert.IsTrue(document.Any()); 23 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 24 | root = (document.First() as CodeNamespaceItem).Members.First() as CodeClassItem; 25 | } 26 | 27 | [Test] 28 | public void TestBasicVariable() 29 | { 30 | Assert.AreEqual("firstVariable", root.Members.FirstOrDefault().Name); 31 | } 32 | 33 | [Test] 34 | public void TestAssignedVariable() 35 | { 36 | Assert.AreEqual("assignedVariable", root.Members[1].Name); 37 | Assert.AreEqual(3, root.Members[1].StartLine); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestClasses 12 | { 13 | [Test] 14 | public void ModulesShouldBeOkVB() 15 | { 16 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestModules.vb"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a class 21 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 22 | 23 | // Inner item should be a class 24 | var innerClass = document.First() as CodeClassItem; 25 | 26 | Assert.True(innerClass.Members.Any()); 27 | } 28 | 29 | [Test] 30 | public void ClassInheritanceShouldBeOkVB() 31 | { 32 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestClasses.vb"), null); 33 | 34 | Assert.IsTrue(document.Any()); 35 | 36 | // First item should be a base class 37 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 38 | var innerClass = document.First() as CodeClassItem; 39 | 40 | // Second item should be an inheriting class 41 | Assert.AreEqual(CodeItemKindEnum.Class, document.Last().Kind); 42 | var inheritingClass = document.Last() as CodeClassItem; 43 | 44 | Assert.AreEqual(" : Class1", inheritingClass.Parameters); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestEmptyClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Windows; 5 | using CodeNav.Mappers; 6 | using CodeNav.Models; 7 | using NUnit.Framework; 8 | 9 | namespace CodeNav.Tests.MapperTests 10 | { 11 | [TestFixture] 12 | public class TestEmptyClass 13 | { 14 | [Test] 15 | public void ShouldBeVisible() 16 | { 17 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestEmptyClass.cs"), null); 18 | 19 | Assert.IsTrue(document.Any()); 20 | 21 | // First item should be a namespace 22 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 23 | 24 | // Namespace item should have members 25 | Assert.IsTrue((document.First() as IMembers).Members.Any()); 26 | 27 | // Inner item should be a class 28 | var innerClass = (document.First() as IMembers).Members.First() as CodeClassItem; 29 | Assert.AreEqual(CodeItemKindEnum.Class, innerClass.Kind); 30 | Assert.AreEqual("CodeNavTestEmptyClass", innerClass.Name); 31 | 32 | // Class should be visible 33 | Assert.AreEqual(Visibility.Visible, innerClass.IsVisible); 34 | 35 | // Since it does not have members, it should not show the expander symbol 36 | Assert.AreEqual(Visibility.Collapsed, innerClass.HasMembersVisibility); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestEmptyInterface.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestEmptyInterface 12 | { 13 | [Test] 14 | public void ShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestEmptyInterface.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should not have members 24 | Assert.IsTrue(!(document.First() as IMembers).Members.Any()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestEnums 12 | { 13 | [Test] 14 | public void EnumsShouldBeOkVB() 15 | { 16 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestModules.vb"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | var innerEnum = (document.First() as IMembers).Members.First() as CodeClassItem; 21 | 22 | // First inner item should be an enum 23 | Assert.AreEqual(CodeItemKindEnum.Enum, innerEnum.Kind); 24 | 25 | // Enum should have 5 members 26 | Assert.AreEqual(5, innerEnum.Members.Count()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestFields.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestFields 12 | { 13 | [Test] 14 | public void ShouldBeOkVB() 15 | { 16 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestFields.vb"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a class 21 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 22 | 23 | // Inner item should be a class 24 | var innerClass = document.First() as CodeClassItem; 25 | 26 | // Class should have properties 27 | var publicConst = innerClass.Members.First() as CodeItem; 28 | Assert.AreEqual(CodeItemAccessEnum.Public, publicConst.Access); 29 | Assert.AreEqual(CodeItemKindEnum.Constant, publicConst.Kind); 30 | 31 | var protectedVersion = innerClass.Members[1] as CodeItem; 32 | Assert.AreEqual(CodeItemAccessEnum.Protected, protectedVersion.Access); 33 | Assert.AreEqual(CodeItemKindEnum.Variable, protectedVersion.Kind); 34 | 35 | var publicField = innerClass.Members[2] as CodeItem; 36 | Assert.AreEqual(CodeItemAccessEnum.Public, publicField.Access); 37 | Assert.AreEqual(CodeItemKindEnum.Variable, publicField.Kind); 38 | 39 | var privateSecret = innerClass.Members[3] as CodeItem; 40 | Assert.AreEqual(CodeItemAccessEnum.Private, privateSecret.Access); 41 | Assert.AreEqual(CodeItemKindEnum.Variable, privateSecret.Kind); 42 | 43 | var local = innerClass.Members.Last() as CodeItem; 44 | Assert.AreEqual(CodeItemAccessEnum.Private, local.Access); 45 | Assert.AreEqual(CodeItemKindEnum.Variable, local.Kind); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestIndexers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestIndexers 12 | { 13 | [Test] 14 | public void ShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestIndexers.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Inner item should be a class 24 | var innerClass = (document.First() as CodeNamespaceItem).Members.First() as CodeClassItem; 25 | 26 | // Class should have an indexer 27 | var indexer = innerClass.Members.First() as CodeFunctionItem; 28 | 29 | Assert.AreEqual(CodeItemKindEnum.Indexer, indexer.Kind); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestInterface2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestInterface2 12 | { 13 | [Test] 14 | public void TestNestedInterfaceShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestInterface2.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have 3 members 24 | Assert.AreEqual(3, (document.First() as IMembers).Members.Count); 25 | 26 | // Second item should be the implementing class 27 | var implementingClass = (document.First() as IMembers).Members.Last() as CodeClassItem; 28 | 29 | Assert.AreEqual(CodeItemKindEnum.Class, implementingClass.Kind); 30 | Assert.AreEqual(2, implementingClass.Members.Count); 31 | 32 | var implementedInterface1 = implementingClass.Members.First() as CodeImplementedInterfaceItem; 33 | var implementedInterface2 = implementingClass.Members.Last() as CodeImplementedInterfaceItem; 34 | 35 | Assert.AreEqual(CodeItemKindEnum.ImplementedInterface, implementedInterface1.Kind); 36 | Assert.AreEqual(1, implementedInterface1.Members.Count); 37 | 38 | Assert.AreEqual(CodeItemKindEnum.ImplementedInterface, implementedInterface2.Kind); 39 | Assert.AreEqual(1, implementedInterface2.Members.Count); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestInterface3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestInterface3 12 | { 13 | [Test] 14 | public void TestBaseImplementedInterfaceShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestInterface3.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // last item should be the implementing class 21 | var implementingClass = (document.First() as IMembers).Members.Last() as CodeClassItem; 22 | 23 | Assert.AreEqual(CodeItemKindEnum.Class, implementingClass.Kind); 24 | Assert.AreEqual(1, implementingClass.Members.Count); 25 | 26 | var implementedInterface = implementingClass.Members.First() as CodeImplementedInterfaceItem; 27 | 28 | Assert.AreEqual(CodeItemKindEnum.ImplementedInterface, implementedInterface.Kind); 29 | Assert.AreEqual(1, implementedInterface.Members.Count); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestInterface4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestInterface4 12 | { 13 | [Test] 14 | public void TestClassImplementedInterfaceAndBaseImplementedInterfaceShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestInterface4.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // last item should be the implementing class 21 | var implementingClass = (document.First() as IMembers).Members.Last() as CodeClassItem; 22 | 23 | Assert.AreEqual(CodeItemKindEnum.Class, implementingClass.Kind); 24 | Assert.AreEqual(1, implementingClass.Members.Count); 25 | 26 | var method = implementingClass.Members.First() as CodeFunctionItem; 27 | 28 | Assert.AreEqual(CodeItemKindEnum.Method, method.Kind); 29 | Assert.AreEqual("ClassAMethod", method.Name); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestMethodsWithComments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Helpers; 5 | using CodeNav.Mappers; 6 | using CodeNav.Models; 7 | using NUnit.Framework; 8 | 9 | namespace CodeNav.Tests.MapperTests 10 | { 11 | [TestFixture] 12 | public class TestMethodsWithComments 13 | { 14 | [Test] 15 | public void ShouldBeOk() 16 | { 17 | SettingsHelper.UseXMLComments = true; 18 | 19 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestMethodsWithComments.cs"), null); 20 | 21 | Assert.IsTrue(document.Any()); 22 | 23 | // First item should be a namespace 24 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 25 | 26 | // Inner item should be a class 27 | var innerClass = (document.First() as CodeNamespaceItem).Members.First() as CodeClassItem; 28 | 29 | // Class should have a method 30 | var methodWithComment = innerClass.Members.First() as CodeFunctionItem; 31 | 32 | Assert.AreEqual("Super important summary", methodWithComment.Tooltip); 33 | 34 | // Class should have a method 35 | var methodWithoutComment = innerClass.Members[1] as CodeFunctionItem; 36 | 37 | Assert.AreEqual("Public void MethodWithoutComment ()", methodWithoutComment.Tooltip); 38 | 39 | // Class should have a method 40 | var methodWithMultipleComment = innerClass.Members[2] as CodeFunctionItem; 41 | 42 | Assert.AreEqual("Multiple comment - summary", methodWithMultipleComment.Tooltip); 43 | 44 | // Class should have a method 45 | var methodWithReorderedComment = innerClass.Members[3] as CodeFunctionItem; 46 | 47 | Assert.AreEqual("Multiple comment - summary", methodWithReorderedComment.Tooltip); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestNamespaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestNamespaces 12 | { 13 | [Test] 14 | public void NestedNamespacesShouldHaveCorrectStructure() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestNestedNamespaces.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have members 24 | Assert.IsTrue((document.First() as IMembers).Members.Any()); 25 | 26 | // Inner item should also be a namespace 27 | var innerNamespace = (document.First() as IMembers).Members.First() as CodeNamespaceItem; 28 | Assert.AreEqual(CodeItemKindEnum.Namespace, innerNamespace.Kind); 29 | 30 | // That inner namespace should have members 31 | Assert.IsTrue(innerNamespace.Members.Any()); 32 | 33 | // That member should be a class 34 | var innerClass = (innerNamespace as IMembers).Members.First() as CodeClassItem; 35 | Assert.AreEqual(CodeItemKindEnum.Class, innerClass.Kind); 36 | Assert.AreEqual("ClassInNestedNamespace", innerClass.Name); 37 | } 38 | 39 | [Test] 40 | public void NamespacesShouldBeOKVB() 41 | { 42 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestNamespaces.vb"), null); 43 | 44 | Assert.IsTrue(document.Any()); 45 | 46 | // First item should be a namespace 47 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 48 | 49 | // Namespace item should have members 50 | Assert.IsTrue((document.First() as IMembers).Members.Any()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestNestedRegions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestNestedRegions 12 | { 13 | [Test] 14 | public void NestedRegionsShouldWork() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestNestedRegions.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have members 24 | Assert.IsTrue((document.First() as IMembers).Members.Any()); 25 | 26 | // Namespace should have 1 member 27 | Assert.AreEqual(1, (document.First() as IMembers).Members.Count); 28 | 29 | // Inner item should be a class 30 | var innerClass = (document.First() as IMembers).Members.First() as CodeClassItem; 31 | Assert.AreEqual(CodeItemKindEnum.Class, innerClass.Kind); 32 | 33 | // That inner class should have members 34 | Assert.IsTrue(innerClass.Members.Any()); 35 | 36 | // That member should be a region 37 | var parentRegion = (innerClass as IMembers).Members.First() as CodeRegionItem; 38 | Assert.AreEqual(CodeItemKindEnum.Region, parentRegion.Kind); 39 | Assert.AreEqual("#ParentRegion", parentRegion.Name); 40 | 41 | // That parent region should have members 42 | Assert.IsTrue(parentRegion.Members.Any()); 43 | 44 | // That member should be a region 45 | var innerRegion = (parentRegion as IMembers).Members.First() as CodeRegionItem; 46 | Assert.AreEqual(CodeItemKindEnum.Region, innerRegion.Kind); 47 | Assert.AreEqual("#ChildRegion", innerRegion.Name); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestNoNamespace.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestNoNamespace 12 | { 13 | [Test] 14 | public void ShouldHaveCorrectStructure() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestNoNamespace.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a class 21 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestProperties.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestProperties 12 | { 13 | [Test] 14 | public void ShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestProperties.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have 1 member 24 | Assert.AreEqual(1, (document.First() as IMembers).Members.Count); 25 | 26 | // Inner item should be a class 27 | var innerClass = (document.First() as IMembers).Members.First() as CodeClassItem; 28 | 29 | // Inheriting class should have properties 30 | var propertyGetSet = innerClass.Members.First() as CodeFunctionItem; 31 | Assert.AreEqual(" {get,set}", propertyGetSet.Parameters); 32 | 33 | var propertyGet = innerClass.Members[1] as CodeFunctionItem; 34 | Assert.AreEqual(" {get}", propertyGet.Parameters); 35 | 36 | var propertySet = innerClass.Members[2] as CodeFunctionItem; 37 | Assert.AreEqual(" {set}", propertySet.Parameters); 38 | 39 | var property = innerClass.Members.Last() as CodeFunctionItem; 40 | Assert.IsNull(property.Parameters); 41 | } 42 | 43 | [Test] 44 | public void ShouldBeOkVB() 45 | { 46 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestProperties.vb"), null); 47 | 48 | Assert.IsTrue(document.Any()); 49 | 50 | // First item should be a namespace 51 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 52 | 53 | // Inner item should be a class 54 | var innerClass = document.First() as CodeClassItem; 55 | 56 | // Class should have properties 57 | var propertyGetSet = innerClass.Members.First() as CodeFunctionItem; 58 | Assert.AreEqual(" {get,set}", propertyGetSet.Parameters); 59 | 60 | var propertyGet = innerClass.Members[1] as CodeFunctionItem; 61 | Assert.AreEqual(" {get}", propertyGet.Parameters); 62 | 63 | var propertySet = innerClass.Members[2] as CodeFunctionItem; 64 | Assert.AreEqual(" {set}", propertySet.Parameters); 65 | 66 | var property = innerClass.Members[3] as CodeFunctionItem; 67 | Assert.IsNull(property.Parameters); 68 | 69 | var propertyShorthand = innerClass.Members[4] as CodeFunctionItem; 70 | Assert.AreEqual("String", property.Type); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestSealed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestSealed 12 | { 13 | [Test] 14 | public void TestSealedShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestSealed.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have 3 members 24 | Assert.AreEqual(3, (document.First() as IMembers).Members.Count); 25 | 26 | // Inner item should be a sealed class 27 | var sealedBaseClass = (document.First() as IMembers).Members.First() as CodeClassItem; 28 | Assert.AreEqual(CodeItemKindEnum.Class, sealedBaseClass.Kind); 29 | Assert.AreEqual("SealedBaseClass", sealedBaseClass.Name); 30 | Assert.AreEqual(CodeItemAccessEnum.Sealed, sealedBaseClass.Access); 31 | 32 | // Inheriting Class should be there 33 | var inheritingClass = (document.First() as IMembers).Members.Last() as CodeClassItem; 34 | Assert.AreEqual(CodeItemKindEnum.Class, inheritingClass.Kind); 35 | Assert.AreEqual("InheritingClass", inheritingClass.Name); 36 | Assert.AreEqual(CodeItemAccessEnum.Public, inheritingClass.Access); 37 | Assert.AreEqual(" : BaseClass", inheritingClass.Parameters); 38 | 39 | // Inheriting class should have sealed property 40 | var sealedProperty = inheritingClass.Members.Last() as CodeFunctionItem; 41 | Assert.AreEqual(CodeItemKindEnum.Property, sealedProperty.Kind); 42 | Assert.AreEqual("BaseProperty", sealedProperty.Name); 43 | Assert.AreEqual(CodeItemAccessEnum.Sealed, sealedProperty.Access); 44 | Assert.AreEqual(" {get,set}", sealedProperty.Parameters); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestSwitch.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Mappers; 2 | using CodeNav.Models; 3 | using NUnit.Framework; 4 | using System; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestSwitch 12 | { 13 | [Test] 14 | public void TestSwitchShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestSwitch.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have 1 member 24 | Assert.AreEqual(1, (document.First() as IMembers).Members.Count); 25 | 26 | // Inner item should be a class 27 | var innerClass = (document.First() as IMembers).Members.First() as CodeClassItem; 28 | Assert.AreEqual(CodeItemKindEnum.Class, innerClass.Kind); 29 | 30 | // Class should have 3 methods 31 | Assert.AreEqual(3, innerClass.Members.Count); 32 | 33 | // First method should have a switch inside 34 | var method = innerClass.Members.First(); 35 | var switchStatement = (method as IMembers).Members.First(); 36 | Assert.AreEqual(CodeItemKindEnum.Switch, switchStatement.Kind); 37 | 38 | // Second method should have a switch inside 39 | var secondMethod = innerClass.Members[1]; 40 | var secondSwitchStatement = (secondMethod as IMembers).Members.First(); 41 | Assert.AreEqual(CodeItemKindEnum.Switch, secondSwitchStatement.Kind); 42 | 43 | // last method should have a switch inside 44 | var lastMethod = innerClass.Members.Last(); 45 | var lastSwitchStatement = (lastMethod as IMembers).Members.First(); 46 | Assert.AreEqual(CodeItemKindEnum.Switch, lastSwitchStatement.Kind); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TestUsingsInNamespace.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests 9 | { 10 | [TestFixture] 11 | public class TestUsingsInNamespace 12 | { 13 | [Test] 14 | public void TestUsingsInNamespaceShouldBeOk() 15 | { 16 | var document = SyntaxMapper.MapDocument(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\TestUsingsInNamespace.cs"), null); 17 | 18 | Assert.IsTrue(document.Any()); 19 | 20 | // First item should be a namespace 21 | Assert.AreEqual(CodeItemKindEnum.Namespace, document.First().Kind); 22 | 23 | // Namespace item should have 1 member 24 | Assert.AreEqual(1, (document.First() as IMembers).Members.Count); 25 | 26 | // Item should be a class 27 | var innerClass = (document.First() as IMembers).Members.First() as CodeClassItem; 28 | 29 | Assert.AreEqual(CodeItemKindEnum.Class, innerClass.Kind); 30 | Assert.AreEqual(2, innerClass.Members.Count); 31 | 32 | Assert.AreEqual(CodeItemKindEnum.Constructor, innerClass.Members.First().Kind); 33 | Assert.AreEqual(CodeItemKindEnum.Method, innerClass.Members.Last().Kind); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TooltipMapperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Mappers; 2 | using CodeNav.Models; 3 | using NUnit.Framework; 4 | 5 | namespace CodeNav.Tests.MapperTests 6 | { 7 | [TestFixture] 8 | public class TooltipMapperTests 9 | { 10 | [TestCase(CodeItemAccessEnum.Public, "int", "Property", "{get, set}", "Public int Property {get, set}")] 11 | [TestCase(CodeItemAccessEnum.Private, "string", "Property", "{get}", "Private string Property {get}")] 12 | [TestCase(CodeItemAccessEnum.Unknown, "int", "Property", "{set}", "int Property {set}")] 13 | [TestCase(CodeItemAccessEnum.Public, "", "Constructor", "", "Public Constructor")] 14 | [TestCase(CodeItemAccessEnum.Private, "List", "Property", "", "Private List Property")] 15 | [TestCase(CodeItemAccessEnum.Private, "System.Generic.Collection.List", "", "Helpers.Property", 16 | "Private System.Generic.Collection.List Helpers.Property")] 17 | public void ShouldMapMethodOk(CodeItemAccessEnum access, string type, string name, string extra, string expected) 18 | { 19 | var tooltip = TooltipMapper.Map(access, type, name, extra); 20 | Assert.AreEqual(expected, tooltip); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/TypeMapperTests.cs: -------------------------------------------------------------------------------- 1 | using CodeNav.Mappers; 2 | using NUnit.Framework; 3 | 4 | namespace CodeNav.Tests.MapperTests 5 | { 6 | [TestFixture] 7 | public class TypeMapperTests 8 | { 9 | [TestCase("System.Generic.Collection.List", true, "System.Generic.Collection.List")] 10 | [TestCase("System.Generic.Collection.List", false, "List")] 11 | [TestCase("CodeNav.Models.CodeItem", true, "CodeNav.Models.CodeItem")] 12 | [TestCase("CodeNav.Models.CodeItem", false, "CodeItem")] 13 | public void ShouldMapTypeOk(string type, bool useLongNames, string expected) 14 | { 15 | var actual = TypeMapper.Map(type, useLongNames); 16 | Assert.AreEqual(expected, actual); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/VisualBasic/TestMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Mappers; 5 | using CodeNav.Models; 6 | using NUnit.Framework; 7 | 8 | namespace CodeNav.Tests.MapperTests.VisualBasic 9 | { 10 | [TestFixture] 11 | public class TestMethods 12 | { 13 | CodeClassItem _innerClass; 14 | 15 | [OneTimeSetUp] 16 | public void Setup() 17 | { 18 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestMethods.vb"), null); 19 | 20 | Assert.IsTrue(document.Any()); 21 | 22 | // First item should be a class 23 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 24 | 25 | // Inner item should be a class 26 | _innerClass = document.First() as CodeClassItem; 27 | } 28 | 29 | [Test] 30 | public void ConstructorShouldBeOkVB() 31 | { 32 | // Class should have a constructor 33 | var constructor = _innerClass.Members.First() as CodeFunctionItem; 34 | Assert.AreEqual(CodeItemAccessEnum.Public, constructor.Access); 35 | Assert.AreEqual(CodeItemKindEnum.Constructor, constructor.Kind); 36 | Assert.AreEqual("New", constructor.Name); 37 | } 38 | 39 | [Test] 40 | public void FunctionShouldBeOkVB() 41 | { 42 | // Class should have a function 43 | var method = _innerClass.Members[1] as CodeFunctionItem; 44 | Assert.AreEqual(CodeItemAccessEnum.Private, method.Access); 45 | Assert.AreEqual(CodeItemKindEnum.Method, method.Kind); 46 | Assert.AreEqual("Area", method.Name); 47 | Assert.AreEqual("Double", method.Type); 48 | Assert.AreEqual("(Double)", method.Parameters); 49 | } 50 | 51 | [Test] 52 | public void SubShouldBeOkVB() 53 | { 54 | // Class should have a sub 55 | var method = _innerClass.Members[2] as CodeFunctionItem; 56 | Assert.AreEqual(CodeItemAccessEnum.Internal, method.Access); 57 | Assert.AreEqual(CodeItemKindEnum.Method, method.Kind); 58 | Assert.AreEqual("SubInsteadOfFunction", method.Name); 59 | Assert.AreEqual("Void", method.Type); 60 | } 61 | 62 | [Test] 63 | public void FunctionShorthandShouldBeOkVB() 64 | { 65 | // Class should have a sub 66 | var method = _innerClass.Members[3] as CodeFunctionItem; 67 | Assert.AreEqual(CodeItemAccessEnum.Private, method.Access); 68 | Assert.AreEqual(CodeItemKindEnum.Method, method.Kind); 69 | Assert.AreEqual("ShorthandFunction$", method.Name); 70 | Assert.AreEqual("String", method.Type); 71 | Assert.AreEqual("(String)", method.Parameters); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /CodeNav.Tests/MapperTests/VisualBasic/TestMethodsWithComments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using CodeNav.Helpers; 5 | using CodeNav.Mappers; 6 | using CodeNav.Models; 7 | using NUnit.Framework; 8 | 9 | namespace CodeNav.Tests.MapperTests.VisualBasic 10 | { 11 | [TestFixture] 12 | public class TestMethodsWithComments 13 | { 14 | [Test] 15 | public void ShouldBeOk() 16 | { 17 | SettingsHelper.UseXMLComments = true; 18 | 19 | var document = SyntaxMapper.MapDocumentVB(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Files\\VisualBasic\\TestMethodsWithComments.vb"), null); 20 | 21 | Assert.IsTrue(document.Any()); 22 | 23 | // First item should be a namespace 24 | Assert.AreEqual(CodeItemKindEnum.Class, document.First().Kind); 25 | 26 | // Inner item should be a class 27 | var innerClass = document.First() as CodeClassItem; 28 | 29 | // Class should have a method 30 | var methodWithComment = innerClass.Members.First() as CodeFunctionItem; 31 | 32 | Assert.AreEqual("Super important summary", methodWithComment.Tooltip); 33 | 34 | // Class should have a method 35 | var methodWithoutComment = innerClass.Members[1] as CodeFunctionItem; 36 | 37 | Assert.AreEqual("Private Object FunctionWithoutComment ()", methodWithoutComment.Tooltip); 38 | 39 | // Class should have a method 40 | var methodWithMultipleComment = innerClass.Members[2] as CodeFunctionItem; 41 | 42 | Assert.AreEqual("Multiple comment - summary", methodWithMultipleComment.Tooltip); 43 | 44 | // Class should have a method 45 | var methodWithReorderedComment = innerClass.Members[3] as CodeFunctionItem; 46 | 47 | Assert.AreEqual("Multiple comment - summary", methodWithReorderedComment.Tooltip); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CodeNav.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CodeNav.Nunit")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CodeNav.Nunit")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3ff290dc-dce3-4b6c-b3b9-0ce6b995e908")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CodeNav.VS2019/CodeNavToolWindowCommandTable.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by VSIX Synchronizer 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace CodeNav 7 | { 8 | using System; 9 | 10 | /// 11 | /// Helper class that exposes all GUIDs used across VS Package. 12 | /// 13 | internal sealed partial class PackageGuids 14 | { 15 | public const string guidCodeNavToolWindowPackageString = "5c1c8131-1371-4401-8a3e-70e47c8ac0ec"; 16 | public static Guid guidCodeNavToolWindowPackage = new Guid(guidCodeNavToolWindowPackageString); 17 | } 18 | /// 19 | /// Helper class that encapsulates all CommandIDs uses across VS Package. 20 | /// 21 | internal sealed partial class PackageIds 22 | { 23 | public const int CodeNavToolWindowCommandId = 0x0100; 24 | } 25 | } -------------------------------------------------------------------------------- /CodeNav.VS2019/CodeNavToolWindowCommandTable.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CodeNav.VS2019/DocumentOutline_256x.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/CodeNav.VS2019/DocumentOutline_256x.ico -------------------------------------------------------------------------------- /CodeNav.VS2019/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("CodeNav")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("CodeNav")] 9 | [assembly: AssemblyCopyright("")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] 17 | -------------------------------------------------------------------------------- /CodeNav.VS2019/Resources/DocumentOutline_256x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/CodeNav.VS2019/Resources/DocumentOutline_256x.png -------------------------------------------------------------------------------- /CodeNav.VS2019/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | CodeNav 2019 6 | Show the code structure of your current document 7 | https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav 8 | Resources\LICENSE 9 | https://github.com/sboulema/CodeNav/blob/master/README.md 10 | https://github.com/sboulema/CodeNav/releases 11 | Resources\DocumentOutline_256x.png 12 | Resources\Preview-small.png 13 | code, structure, navigation, map, codemap 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /CodeNav.VS2022/CodeNavToolWindowCommandTable.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------------ 2 | // 3 | // This file was generated by VSIX Synchronizer 4 | // 5 | // ------------------------------------------------------------------------------ 6 | namespace CodeNav 7 | { 8 | using System; 9 | 10 | /// 11 | /// Helper class that exposes all GUIDs used across VS Package. 12 | /// 13 | internal sealed partial class PackageGuids 14 | { 15 | public const string guidCodeNavToolWindowPackageString = "5c1c8131-1371-4401-8a3e-70e47c8ac0ec"; 16 | public static Guid guidCodeNavToolWindowPackage = new Guid(guidCodeNavToolWindowPackageString); 17 | } 18 | /// 19 | /// Helper class that encapsulates all CommandIDs uses across VS Package. 20 | /// 21 | internal sealed partial class PackageIds 22 | { 23 | public const int CodeNavToolWindowCommandId = 0x0100; 24 | } 25 | } -------------------------------------------------------------------------------- /CodeNav.VS2022/CodeNavToolWindowCommandTable.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CodeNav.VS2022/DocumentOutline_256x.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/CodeNav.VS2022/DocumentOutline_256x.ico -------------------------------------------------------------------------------- /CodeNav.VS2022/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("CodeNav")] 5 | [assembly: AssemblyDescription("")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("CodeNav")] 9 | [assembly: AssemblyCopyright("")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | 13 | [assembly: ComVisible(false)] 14 | 15 | [assembly: AssemblyVersion("1.0.0.0")] 16 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /CodeNav.VS2022/Resources/DocumentOutline_256x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/CodeNav.VS2022/Resources/DocumentOutline_256x.png -------------------------------------------------------------------------------- /CodeNav.VS2022/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | CodeNav 2022 6 | Show the code structure of your current document 7 | https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav 8 | Resources\LICENSE 9 | https://github.com/sboulema/CodeNav/blob/master/README.md 10 | https://github.com/sboulema/CodeNav/releases 11 | Resources\DocumentOutline_256x.png 12 | Resources\Preview-small.png 13 | code, structure, navigation, map, codemap 14 | 15 | 16 | 17 | amd64 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - 2021 Samir Boulema 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeNav 2 | Visual Studio extension to show the code structure of your current document 3 | 4 | [![Build Status](https://github.com/sboulema/CodeNav/actions/workflows/workflow.yml/badge.svg)](https://github.com/sboulema/CodeNav/actions/workflows/workflow.yml) 5 | [![Sponsor](https://img.shields.io/badge/-Sponsor-fafbfc?logo=GitHub%20Sponsors)](https://github.com/sponsors/sboulema) 6 | 7 | ## Features 8 | - Quickly see all the important methods and properties in your document. 9 | - Never get lost during a refactoring of a super long document. 10 | - Clicking on an item in the list will take you to that location in the document. 11 | - Sort by file order or by name 12 | - Toggle visibility by double-clicking the splitter bar 13 | - Dark theme support 14 | - Show as an editor margin (left side / right side / top side / hidden) 15 | - Show as a separate toolwindow (View -> Other Windows -> CodeNav) 16 | - Filter items by kind (method, property), access (public, private), name and bookmark 17 | - Cursor position will be reflected by highlighting the current method in the list 18 | - Customizable fonts 19 | - Synced collapsing/expanding regions 20 | - Collapse/Expand all regions 21 | - Colored Bookmarks 22 | - History/edit indicators 23 | 24 | ## Language support 25 | - C# 26 | - Visual Basic 27 | - JavaScript 28 | - CSS 29 | 30 | ## Installing 31 | [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav) [![Visual Studio Marketplace](https://img.shields.io/vscode-marketplace/v/SamirBoulema.CodeNav.svg?style=flat)](https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav) 32 | 33 | [Github Releases](https://github.com/sboulema/CodeNav/releases) 34 | 35 | [Open VSIX Gallery](http://vsixgallery.com/extension/CodeNav.Samir%20Boulema.19687465-dc94-413d-ad72-6141e90c94d4/) 36 | 37 | ## Screenshots 38 | ![Preview](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Preview.png) ![Preview-Dark](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Preview-dark.png) 39 | 40 | ![Top Margin](https://i.imgur.com/5ymPOxe.jpg) 41 | 42 | #### Filter window 43 | ![Filter window](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Filters.png) 44 | 45 | #### Options window 46 | ![Options window](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Options%20-%20General.png) ![Options window](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Options%20-%20Fonts.png) 47 | 48 | #### Tool window 49 | ![Tool window](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/ToolWindow.png) 50 | 51 | #### Bookmarks 52 | ![Bookmarks](https://i.imgur.com/SqLgsXw.png) ![Bookmark styles](https://raw.githubusercontent.com/sboulema/CodeNav/main/Resources/Bookmark%20styles.png) -------------------------------------------------------------------------------- /Resources/Bookmark styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Bookmark styles.png -------------------------------------------------------------------------------- /Resources/CodeNavToolWindowCommandTable.vsct: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Resources/DocumentOutline_256x.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/DocumentOutline_256x.ico -------------------------------------------------------------------------------- /Resources/DocumentOutline_256x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/DocumentOutline_256x.png -------------------------------------------------------------------------------- /Resources/Filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Filters.png -------------------------------------------------------------------------------- /Resources/Options - Fonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Options - Fonts.png -------------------------------------------------------------------------------- /Resources/Options - General.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Options - General.png -------------------------------------------------------------------------------- /Resources/Preview-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Preview-dark.png -------------------------------------------------------------------------------- /Resources/Preview-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Preview-small.png -------------------------------------------------------------------------------- /Resources/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/Preview.png -------------------------------------------------------------------------------- /Resources/ToolWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sboulema/CodeNav/28d3209cb11fbe3fca3ebaa202f84ebffd9470d1/Resources/ToolWindow.png -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /publish-manifest.VS2019.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/vsix-publish", 3 | "categories": [ "coding", "documentation", "modeling" ], 4 | "identity": { 5 | "internalName": "CodeNav" 6 | }, 7 | "overview": "readme.md", 8 | "priceCategory": "free", 9 | "publisher": "SamirBoulema", 10 | "private": false, 11 | "qna": true, 12 | "repo": "https://github.com/sboulema/CodeNav" 13 | } -------------------------------------------------------------------------------- /publish-manifest.VS2022.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/vsix-publish", 3 | "categories": [ "coding", "documentation", "modeling" ], 4 | "identity": { 5 | "internalName": "CodeNav2022" 6 | }, 7 | "overview": "readme.md", 8 | "priceCategory": "free", 9 | "publisher": "SamirBoulema", 10 | "private": false, 11 | "qna": true, 12 | "repo": "https://github.com/sboulema/CodeNav" 13 | } --------------------------------------------------------------------------------