RoslynPad is a cross-platform C# editor built on Roslyn (compiler services) and AvalonEdit. It supports Windows (WPF) and macOS/Linux (Avalonia).
RoslynPad.Runtime → Injected into user scripts (.Dump() extension methods)
RoslynPad.Roslyn → Core Roslyn integration, workspace management
RoslynPad.Build → Script compilation, NuGet restore, process execution
RoslynPad.Themes → VS Code theme parsing
RoslynPad.Common.UI → Shared ViewModels, services (platform-agnostic)
RoslynPad.Editor.* → Code editor components (Windows/Avalonia variants)
RoslynPad.Roslyn.* → Platform-specific Roslyn UI (glyphs, etc.)
RoslynPad/RoslynPad.Avalonia → Application entry points
Platform code follows this pattern:
- Abstract base in
RoslynPad.Common.UI(e.g.,MainViewModel) - Concrete implementations with platform suffix (e.g.,
MainViewModelWindows,MainViewModelAvalonia) AVALONIApreprocessor symbol distinguishes platforms in shared editor code
RoslynHost- Central Roslyn services host using MEF compositionRoslynWorkspace- Per-document Roslyn workspace extendingMicrosoft.CodeAnalysis.WorkspaceExecutionHost- Compiles and executes scripts in separate processes via JSON IPCMainViewModel- Application state and document managementOpenDocumentViewModel- Individual document state, execution, NuGet integration
# Build cross-platform app (default for VS Code)
dotnet build src/RoslynPad.Avalonia
# Build full solution (Windows required for WPF projects)
dotnet build RoslynPad.sln
# CI build with binary log
dotnet build -bl -c Release -m:1 RoslynPad.slnRequires .NET 10 SDK (see global.json). Also install .NET 8 SDK for LTS library targets.
Uses System.Composition (MEF2), not Microsoft.Extensions.DependencyInjection:
// Export service
[Export(typeof(IMyService)), Shared]
public class MyService : IMyService { }
// Constructor injection
[Export(typeof(MyViewModel)), Shared]
[method: ImportingConstructor]
public class MyViewModel(IMyService service) : NotificationObject { }The [Shared] attribute indicates singleton lifetime.
- Platform-specific classes:
*Windows,*Avaloniasuffix - Private fields:
_camelCase - Static fields:
s_camelCase
- Inherit from
NotificationObject(providesINotifyPropertyChanged, error tracking) - Use
SetProperty(ref field, value)for property change notification - Commands via
ICommandProvider.Create()/CreateAsync()
RoslynPad relies heavily on IgnoresAccessChecksToGenerator, which generates [assembly: IgnoresAccessChecksTo("AssemblyName")] attributes for Roslyn assemblies. This allows accessing non-public members and features that aren't part of Roslyn's public API surface.
Benefits:
- Enables consuming internal Roslyn features required for rich editor functionality
- Allows integration with internal workspace and completion APIs
Trade-offs:
- Roslyn version upgrades can break the build - internal APIs may change, be renamed, or removed between versions
- When upgrading Roslyn packages, expect to fix compilation errors where internal members have changed
- Requires careful testing after any Roslyn version bump
Relevant internal namespaces are exposed in RoslynPad.Roslyn.csproj.
When modifying platform-agnostic code (especially in RoslynPad.Common.UI, RoslynPad.Roslyn, or RoslynPad.Build), verify changes compile on both WPF and Avalonia targets.
RoslynPad.Runtime is injected into executed user scripts. It:
- Multi-targets
net8.0;netstandard2.0for broad compatibility - Provides
.Dump()extension methods - Has no external dependencies
- Communicates with host via JSON over stdout/stdin
Scripts in deploy/ handle release packaging:
# From deploy/ directory - builds platform packages
./CreatePackages.ps1 # Runs on current OS, creates packages for that platform
# NuGet publishing (for library packages)
./PushNuGet.ps1 # Packs and pushes to nuget.orgPlatform Packaging:
- Windows: Uses WPF project (
RoslynPad), creates.zip+.appx(Microsoft Store), updates winget manifests - macOS: Uses Avalonia project, creates
.dmg(requiresappdmgvia npm) and.tgz - Linux: Uses Avalonia project, creates
.tgz
Key Details:
Common.ps1- Shared functions, reads version fromDirectory.Build.props- Windows packages run on Windows, macOS/Linux packages run on macOS
dotnet publish -r <rid>withContinuousIntegrationBuild=truefor reproducible builds- Version is centrally defined as
RoslynPadVersioninDirectory.Build.props
Directory.Build.props- Shared build settings, version numbers, target frameworksDirectory.Packages.props- Central package version managementsrc/RoslynPad.Build/ExecutionHost.cs- Script execution enginesrc/RoslynPad.Roslyn/RoslynHost.cs- Roslyn service compositionsrc/RoslynPad.Common.UI/ViewModels/- Core application ViewModelsdeploy/CreatePackages.ps1- Release packaging script
- Make sure to update this document when making significant changes to the repo.