Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
- 'feature/**'

env:
version: '10.5.${{ github.run_number }}'
version: '10.6.${{ github.run_number }}'
dotnetVersion: '8'
repoUrl: ${{ github.server_url }}/${{ github.repository }}
vsixPath: src/CodeNav/bin/Release/net472/CodeNav.vsix
Expand Down
4 changes: 4 additions & 0 deletions docs/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ Here is a list of links to helpful pages I needed when developing this extension
- [CompositeExtension Sample](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/CompositeExtension)
- [The CheckBox control](https://wpf-tutorial.com/basic-controls/the-checkbox-control/)
- [Sorting enum by a custom attribute](https://stackoverflow.com/questions/61091166/sorting-enum-by-a-custom-attribute)
- [TextView methods](https://github.com/llvm-mirror/clang/blob/master/tools%2Fclang-format-vs%2FClangFormat%2FVsix.cs#L34)
- [TextView methods 2](https://github.com/msomeone/PeasyMotion/blob/466eaad0f0e731928c645b10f5f43f3519631ea0/Shared/VsMethodExtensions.cs#L115)
- [TextView methods 3](https://github.com/VsixCommunity/Community.VisualStudio.Toolkit/blob/8624a25f504d7fc0bab5fa3434ce95be2466f438/src/toolkit/Community.VisualStudio.Toolkit.Shared/Windows/WindowFrame.cs#L232)
- [Get Path of the document from IWpfTextView for non cs files](https://stackoverflow.com/questions/48068134/get-path-of-the-document-from-iwpftextview-for-non-cs-files)

## VSExtensibility Issues
- [#545 - Feature request: Text Editor: Collapse/Expand ranges](https://github.com/microsoft/VSExtensibility/issues/545)
Expand Down
6 changes: 3 additions & 3 deletions src/CodeNav.OutOfProc/ExtensionEntrypoint.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CodeNav.OutOfProc.Helpers;
using CodeNav.OutOfProc.Services;
using CodeNav.OutOfProc.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.Extensibility;

Expand Down Expand Up @@ -37,6 +36,7 @@ protected override void InitializeServices(IServiceCollection serviceCollection)
// As of now, any instance that ingests VisualStudioExtensibility is required to be added as a scoped
// service.
serviceCollection.AddScoped<OutputWindowService>();
serviceCollection.AddScoped<OutliningHelper>();
serviceCollection.AddScoped<OutliningService>();
serviceCollection.AddScoped<WindowFrameService>();
}
}
7 changes: 6 additions & 1 deletion src/CodeNav.OutOfProc/Helpers/SortHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using CodeNav.OutOfProc.Services;
using CodeNav.OutOfProc.ViewModels;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Editor;

namespace CodeNav.OutOfProc.Helpers;

Expand Down Expand Up @@ -41,7 +42,11 @@ public static async Task ChangeSort(

ApplySort(codeDocumentService.CodeDocumentViewModel, sortOrder);

await codeDocumentService.UpdateCodeDocumentViewModel(clientContext.Extensibility, textViewSnapshot, cancellationToken);
await codeDocumentService.UpdateCodeDocumentViewModel(
clientContext.Extensibility,
textViewSnapshot.FilePath,
textViewSnapshot.Document.Text.CopyToString(),
cancellationToken);
}

/// <summary>
Expand Down
18 changes: 0 additions & 18 deletions src/CodeNav.OutOfProc/Languages/CSharp/Mappers/DocumentMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,12 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Editor;
using Microsoft.VisualStudio.ProjectSystem.Query;

namespace CodeNav.OutOfProc.Languages.CSharp.Mappers;

public class DocumentMapper
{
/// <summary>
/// Map text document to list of code items.
/// </summary>
/// <param name="documentSnapshot">Document snapshot with latest version of text</param>
/// <param name="excludeFilePath">File path of the document snaphot, used to exclude the saved version of the text</param>
/// <param name="codeDocumentViewModel">Current view model connected to the CodeNav tool window</param>
/// <param name="extensibility">Visual Studio extensibility used to retrieve all solution files for compilation</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>List of code items</returns>
public static async Task<List<CodeItem>> MapDocument(
ITextDocumentSnapshot documentSnapshot,
string? excludeFilePath,
CodeDocumentViewModel codeDocumentViewModel,
VisualStudioExtensibility extensibility,
CancellationToken cancellationToken)
=> await MapDocument(documentSnapshot.Text.CopyToString(), excludeFilePath, codeDocumentViewModel, extensibility, cancellationToken);

/// <summary>
/// Map text document to list of code items.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/CodeNav.OutOfProc/Models/DocumentView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace CodeNav.OutOfProc.Models;

public sealed class DocumentView
{
public string FilePath { get; set; } = string.Empty;

public string Text { get; set; } = string.Empty;

public bool IsDocumentFrame { get; set; }
}
38 changes: 21 additions & 17 deletions src/CodeNav.OutOfProc/Services/CodeDocumentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
using CodeNav.OutOfProc.Models;
using CodeNav.OutOfProc.ViewModels;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Editor;
using Microsoft.VisualStudio.Extensibility.UI;
using System.Windows;

namespace CodeNav.OutOfProc.Services;

public class CodeDocumentService(
OutputWindowService logService,
OutliningHelper outliningHelper)
OutliningService outliningService,
WindowFrameService windowFrameService)
{
/// <summary>
/// DataContext for the tool window.
Expand All @@ -34,17 +34,19 @@ public class CodeDocumentService(

public OutputWindowService LogService => logService;

public OutliningHelper OutliningHelper => outliningHelper;
public OutliningService OutliningService => outliningService;

public async Task<CodeDocumentViewModel> UpdateCodeDocumentViewModel(
VisualStudioExtensibility? extensibility,
ITextViewSnapshot? textView,
string? filePath,
string? text,
CancellationToken cancellationToken)
{
try
{
if (extensibility == null ||
textView == null)
string.IsNullOrEmpty(filePath) ||
string.IsNullOrEmpty(text))
{
return CodeDocumentViewModel;
}
Expand All @@ -60,20 +62,20 @@ public async Task<CodeDocumentViewModel> UpdateCodeDocumentViewModel(

// Get the new list of code items
var codeItems = await DocumentMapper.MapDocument(
textView.Document,
textView.FilePath,
text,
filePath,
CodeDocumentViewModel,
extensibility,
cancellationToken);

await logService.WriteInfo(textView, $"Found '{codeItems.Count}' code items");
await logService.WriteInfo(filePath, $"Found '{codeItems.Count}' code items");

// Getting the new code items is done, cancel creating a loading placeholder
await loadingCancellationTokenSource.CancelAsync();

// Set properties on the CodeDocumentViewModel that are needed for other features
CodeDocumentViewModel.CodeDocumentService = this;
CodeDocumentViewModel.FilePath = textView.FilePath ?? string.Empty;
CodeDocumentViewModel.FilePath = filePath ?? string.Empty;

if (!codeItems.Any())
{
Expand All @@ -85,37 +87,39 @@ public async Task<CodeDocumentViewModel> UpdateCodeDocumentViewModel(
// And update the DataContext for the tool window
CodeDocumentViewModel.CodeItems = SortHelper.Sort(codeItems, CodeDocumentViewModel.SortOrder);

await logService.WriteInfo(textView, $"Sorted code items on '{CodeDocumentViewModel.SortOrder}'");
await logService.WriteInfo(filePath, $"Sorted code items on '{CodeDocumentViewModel.SortOrder}'");

// Apply highlights
HighlightHelper.UnHighlight(CodeDocumentViewModel);

await logService.WriteInfo(textView, $"Remove highlight from all code items");
await logService.WriteInfo(filePath, $"Remove highlight from all code items");

// Apply current visibility settings to the document
VisibilityHelper.SetCodeItemVisibility(CodeDocumentViewModel, CodeDocumentViewModel.CodeItems, CodeDocumentViewModel.FilterRules);

await logService.WriteInfo(textView, $"Set code item visibility");
await logService.WriteInfo(filePath, $"Set code item visibility");

// Apply filter rules
FilterRuleHelper.ApplyFilterRules(CodeDocumentViewModel, CodeDocumentViewModel.CodeItems, CodeDocumentViewModel.FilterRules);

await logService.WriteInfo(textView, $"Set code item filter rules");
await logService.WriteInfo(filePath, $"Set code item filter rules");

// Apply history items
HistoryHelper.ApplyHistoryIndicator(CodeDocumentViewModel);

await logService.WriteInfo(textView, $"Apply history indicators");
await logService.WriteInfo(filePath, $"Apply history indicators");

// Apply bookmarks
BookmarkHelper.ApplyBookmarkIndicator(CodeDocumentViewModel);

await logService.WriteInfo(textView, $"Apply bookmark indicators");
await logService.WriteInfo(filePath, $"Apply bookmark indicators");

// Apply outlining
await OutliningHelper.SubscribeToRegionEvents(CodeDocumentViewModel);
await OutliningService.SubscribeToRegionEvents(CodeDocumentViewModel);

await logService.WriteInfo(textView, $"Apply outlining");
await logService.WriteInfo(filePath, $"Apply outlining");

await windowFrameService.SubscribeToWindowFrameEvents();

return CodeDocumentViewModel;
}
Expand Down
2 changes: 2 additions & 0 deletions src/CodeNav.OutOfProc/Services/IOutOfProcService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public interface IOutOfProcService

Task SetCodeItemIsExpanded(int spanStart, int spanEnd, bool isExpanded);

Task ProcessActiveFrameChanged(string documentViewJsonString);

public static class Configuration
{
public const string ServiceName = "CodeNav.OutOfProcService";
Expand Down
45 changes: 30 additions & 15 deletions src/CodeNav.OutOfProc/Services/OutOfProcService.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
using CodeNav.OutOfProc.Helpers;
using CodeNav.OutOfProc.Models;
using Microsoft.ServiceHub.Framework;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Shell;
using System.Text.Json;

namespace CodeNav.OutOfProc.Services;

[VisualStudioContribution]
internal class OutOfProcService : IOutOfProcService, IBrokeredService
internal class OutOfProcService(
VisualStudioExtensibility extensibility,
CodeDocumentService codeDocumentService) : IOutOfProcService, IBrokeredService
{
private readonly VisualStudioExtensibility _extensibility;
private readonly CodeDocumentService _codeDocumentService;

public OutOfProcService(
VisualStudioExtensibility extensibility,
CodeDocumentService codeDocumentService)
{
_extensibility = extensibility;
_codeDocumentService = codeDocumentService;
}

public static BrokeredServiceConfiguration BrokeredServiceConfiguration
=> new(IOutOfProcService.Configuration.ServiceName, IOutOfProcService.Configuration.ServiceVersion, typeof(OutOfProcService))
{
Expand All @@ -29,11 +21,34 @@ public static BrokeredServiceConfiguration BrokeredServiceConfiguration

public async Task SetCodeItemIsExpanded(int spanStart, int spanEnd, bool isExpanded)
{
OutliningHelper.SetIsExpanded(_codeDocumentService.CodeDocumentViewModel, spanStart, spanEnd, isExpanded);
OutliningService.SetIsExpanded(codeDocumentService.CodeDocumentViewModel, spanStart, spanEnd, isExpanded);
}

public async Task ProcessActiveFrameChanged(string documentViewJsonString)
{
var documentView = JsonSerializer.Deserialize<DocumentView>(documentViewJsonString);

// Conditions:
// - Frame is null
// - Frame did not change
// - Frame is not a document frame
// Actions:
// - Do nothing
if (documentView?.IsDocumentFrame != true)
{
return;
}

// Frame has changed and has a text document, so we need to update the list of code items
await codeDocumentService.UpdateCodeDocumentViewModel(
extensibility,
documentView.FilePath,
documentView.Text,
default);
}

public async Task DoSomethingAsync(CancellationToken cancellationToken)
{
await _extensibility.Shell().ShowPromptAsync("Hello from in-proc! (Showing this message from (out-of-proc)", PromptOptions.OK, cancellationToken);
await extensibility.Shell().ShowPromptAsync("Hello from in-proc! (Showing this message from (out-of-proc)", PromptOptions.OK, cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
using Microsoft.VisualStudio.Extensibility.Helpers;
using System.Text.Json;

namespace CodeNav.OutOfProc.Helpers;
namespace CodeNav.OutOfProc.Services;

public class OutliningHelper : DisposableObject
public class OutliningService : DisposableObject
{
private readonly VisualStudioExtensibility _extensibility;
private readonly Task _initializationTask;
private IInProcService? _inProcService;

public OutliningHelper(VisualStudioExtensibility extensibility)
public OutliningService(VisualStudioExtensibility extensibility)
{
_extensibility = extensibility;
_initializationTask = Task.Run(InitializeAsync);
Expand Down Expand Up @@ -49,7 +49,7 @@
outlineRegions!.ForEach(outlineRegion =>
SetIsExpanded(codeDocumentViewModel, outlineRegion.SpanStart, outlineRegion.SpanEnd, outlineRegion.IsExpanded));
}
catch (Exception e)

Check warning on line 52 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 52 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 52 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used

Check warning on line 52 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used
{
// TODO: Add logging
}
Expand All @@ -62,7 +62,7 @@
Assumes.NotNull(_inProcService);
await _inProcService.CollapseOutlineRegion(start, length);
}
catch (Exception e)

Check warning on line 65 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 65 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 65 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used

Check warning on line 65 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used
{
// TODO: Add logging
}
Expand All @@ -75,7 +75,7 @@
Assumes.NotNull(_inProcService);
await _inProcService.ExpandOutlineRegion(start, length);
}
catch (Exception e)

Check warning on line 78 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 78 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build

The variable 'e' is declared but never used

Check warning on line 78 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used

Check warning on line 78 in src/CodeNav.OutOfProc/Services/OutliningService.cs

View workflow job for this annotation

GitHub Actions / 🛠️ Build 2022

The variable 'e' is declared but never used
{
// TODO: Add logging
}
Expand All @@ -83,29 +83,29 @@

public static async Task CollapseOutlineRegion(CodeItem codeItem)
{
if (codeItem.CodeDocumentViewModel?.CodeDocumentService?.OutliningHelper == null)
if (codeItem.CodeDocumentViewModel?.CodeDocumentService?.OutliningService == null)
{
return;
}

await codeItem
.CodeDocumentViewModel
.CodeDocumentService
.OutliningHelper
.OutliningService
.CollapseOutlineRegion(codeItem.OutlineSpan.Start, codeItem.OutlineSpan.Length);
}

public static async Task ExpandOutlineRegion(CodeItem codeItem)
{
if (codeItem.CodeDocumentViewModel?.CodeDocumentService?.OutliningHelper == null)
if (codeItem.CodeDocumentViewModel?.CodeDocumentService?.OutliningService == null)
{
return;
}

await codeItem
.CodeDocumentViewModel
.CodeDocumentService
.OutliningHelper
.OutliningService
.ExpandOutlineRegion(codeItem.OutlineSpan.Start, codeItem.OutlineSpan.Length);
}

Expand Down
8 changes: 2 additions & 6 deletions src/CodeNav.OutOfProc/Services/OutputWindowService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Documents;
using Microsoft.VisualStudio.Extensibility.Editor;
using Microsoft.VisualStudio.Extensibility.Helpers;

namespace CodeNav.OutOfProc.Services;
Expand All @@ -19,14 +18,11 @@ public OutputWindowService(VisualStudioExtensibility extensibility)
_initializationTask = Task.Run(InitializeAsync);
}

public async Task WriteInfo(ITextViewSnapshot textView, string text)
=> await WriteInfo(Path.GetFileName(textView.FilePath), text);

public async Task WriteInfo(Uri? FilePath, string text)
=> await WriteInfo(Path.GetFileName(FilePath?.AbsolutePath), text);

public async Task WriteInfo(string? fileName, string text)
=> await WriteLine($"[Info] [{fileName}] {text}");
public async Task WriteInfo(string? filePath, string text)
=> await WriteLine($"[Info] [{Path.GetFileName(filePath)}] {text}");

public async Task WriteLine(string text)
{
Expand Down
Loading
Loading