{"id":13629670,"url":"https://github.com/devlooped/SmallSharp","last_synced_at":"2025-04-17T09:35:44.624Z","repository":{"id":40296080,"uuid":"300154250","full_name":"devlooped/SmallSharp","owner":"devlooped","description":"Create, edit and run multiple C# top-level programs  in the same project by just selecting the startup program from the start  button.","archived":false,"fork":false,"pushed_at":"2024-11-01T01:44:57.000Z","size":7043,"stargazers_count":286,"open_issues_count":2,"forks_count":12,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-11-02T17:03:53.102Z","etag":null,"topics":["console-application","csharp","csharp-sourcegenerator","learning","visual-studio"],"latest_commit_sha":null,"homepage":"https://clarius.org/SmallSharp","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devlooped.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":".github/FUNDING.yml","license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"devlooped"}},"created_at":"2020-10-01T05:19:49.000Z","updated_at":"2024-10-13T17:50:28.000Z","dependencies_parsed_at":"2024-01-06T09:54:46.974Z","dependency_job_id":"5f188877-d707-424c-a1d6-195dd69d5840","html_url":"https://github.com/devlooped/SmallSharp","commit_stats":null,"previous_names":["kzu/smallsharp"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2FSmallSharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2FSmallSharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2FSmallSharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devlooped%2FSmallSharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devlooped","download_url":"https://codeload.github.com/devlooped/SmallSharp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223751369,"owners_count":17196624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["console-application","csharp","csharp-sourcegenerator","learning","visual-studio"],"created_at":"2024-08-01T22:01:16.175Z","updated_at":"2025-04-17T09:35:44.592Z","avatar_url":"https://github.com/devlooped.png","language":"C#","readme":"![Icon](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/icon-32.png) SmallSharp\n============\n\n[![Version](https://img.shields.io/nuget/v/SmallSharp.svg?color=royalblue)](https://www.nuget.org/packages/SmallSharp) [![Downloads](https://img.shields.io/nuget/dt/SmallSharp?color=darkmagenta)](https://www.nuget.org/packages/SmallSharp) [![License](https://img.shields.io/github/license/devlooped/SmallSharp.svg?color=blue)](https://github.com/devlooped/SmallSharp/blob/main/LICENSE) [![GH CI Status](https://github.com/devlooped/SmallSharp/workflows/build/badge.svg?branch=main)](https://github.com/devlooped/avatar/actions?query=branch%3Amain+workflow%3Abuild+) \n\n![Icon](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/SmallSharpDemo.gif)\n\n\u003c!-- #content --\u003e\nCreate, edit and run multiple C# top-level programs in the same project 😍\n\n## Why\n\nThe new-ish C# [top-level programs](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements) \nallow a very intuitive, simple and streamlined experience for quickly spiking or learning C#. \n\nOne missing thing since their introduction in Visual Studio is that you can only have one such \ntop-level program in a project. This means that in order to prototype or learn a different area \nof .NET, you'd be forced to either replace your previous top-level program or change it to be a \nnon-compile item somehow so you can keep it around (i.e. rename to a `.txt` or change its build action).\n\n**SmallSharp** allows you to select which file should be the top-level program to run, right from \nthe Start button/dropdown (for compilation and launch/debug). Moreover, it will monitor the active \nfile you're editing, and automatically make it the startup file for you!\n\n![start button](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/launchSettings.png)\n\nThis list is automatically kept in sync as you add more `.cs` files to the project. When you select \none target C# file, that becomes the only top-level program to be compiled, so you don't have to \nmodify any of the others since they automatically become *None* items.\n\nAll compile files directly under the project directory root are considered top-level programs for \nselection and compilation purposes. If you need to share code among them, you can place them in \nsubdirectories and those will behave like normal compile items.\n\n## Usage\n\nThere is no need to install any Visual Studio extension. SmallSharp works by just installing the \n[SmallSharp](https://nuget.org/packages/SmallSharp) nuget package in a C# console project.\n\n1. Create a new Console project:\n\n![New Project Dialog](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/NewConsoleProject.png)\n\n   By default, this new console project may not be set up to target `net5.0` or use the latest C# version. \n   So click on the project node, and the project file will open in the editor. Make sure you either:\n\n  * Target the recommended framework version (i.e. net6.0):\n\n```xml\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enet6.0\u003c/TargetFramework\u003e\n  \u003c/PropertyGroup\u003e\n\n\u003c/Project\u003e\n```\n\n  * Or use latest C# language version if targeting another framework:\n\n```xml\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enet472\u003c/TargetFramework\u003e\n    \u003cLangVersion\u003elatest\u003c/LangVersion\u003e\n  \u003c/PropertyGroup\u003e\n\n\u003c/Project\u003e\n```\n \n1. Install the **SmallSharp** nuget package using your preferred method:\n\n  * From the Dependencies node, Manage NuGet Packages dialog:\n\n![New Project Dialog](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/NuGetPackage.png)\n\n   * By just adding it directly to the .csproj:\n\n```xml\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"SmallSharp\" Version=\"*\" /\u003e\n  \u003c/ItemGroup\u003e\n```\n\n   * Via the dotnet CLI:\n\n```\n\u003e dotnet add package SmallSharp\n```\n\n   * Via the Package Manager console:\n\n```\nPM\u003e install-package SmallSharp\n```\n\n3. Now open that Program.cs and make changes to the new concise top-level program such as:\n\n```csharp\nusing System;\nusing static System.Console;\n\nWriteLine(\"Hello World!\");\n```\n\nKeep adding as many top-level programs as you need, and switch between them easily by simply \nchanging the active document.\n\n![Demo](https://raw.githubusercontent.com/devlooped/SmallSharp/main/assets/img/TrackSelection.gif)\n\n\n## How It Works\n\nThis nuget package leverages in concert the following standalone and otherwise \nunrelated features of the compiler, nuget, Visual Studio and MSBuild:\n\n1. The C# compiler only allows one top-level program per compilation.\n2. Launch profiles (the entries in the Run dropdown) are populated from the Properties\\launchSettings.json file\n3. Whenever changed, the dropdown selection is persisted as the `$(ActiveDebugProfile)` MSBuild property in a file \n   named after the project with the `.user` extension\n4. This file is imported before NuGet-provided MSBuild targets\n5. The `$(DefaultItemExcludesInProjectFolder)` MSBuild property allows excluding items at the project-level from \n   the automatically added items by the SDK.\n\nUsing the above features in concert, **SmallSharp** essentially does the following:\n\n* Monitor the active document in VS and emit it as a `launchSettings.json` profile and set it as \n   the `$(ActiveDebugProfile)`.\n\n* Exclude `.cs` files at the project level from being included as `\u003cCompile\u003e` by the default SDK \n  includes and include them explicitly as `\u003cNone\u003e` instead so they show up in the solution explorer. \n  This prevents the compiler from causing an error for multiple top-level programs.\n\n* Explicitly include as `\u003cCompile\u003e` only the `$(ActiveDebugProfile)` property value.\n\nThis basically mean that this it will also work consistently if you use `dotnet run` from the command-line, \nsince the \"Main\" file selection is performed exclusively via MSBuild item manipulation.\n\nFinally, there is some lovely COM-based magic to access the active Visual Studio IDE (via DTE) to monitor \nthe currently opened source file to keep it in sync with the launch profile. This is done purely using \npublic COM primitives and equally public VSSDK nuget packages their APIs. This enables some useful integration \nwith the IDE without requiring installing a VS extension from the marketplace and deal with gracefully \ndegrading functionality.\n\n\u003e NOTE: If active document tracking fails to initialize properly restarting Visual Studio will almost \n\u003e always fix it. Once tracking starts, it will work consistently from that point on. The Start dropdown \n\u003e is always available as a fallback in case of issues.\n\n\u003c!-- include https://github.com/devlooped/sponsors/raw/main/footer.md --\u003e\n# Sponsors \n\n\u003c!-- sponsors.md --\u003e\n[![Clarius Org](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/clarius.png \"Clarius Org\")](https://github.com/clarius)\n[![MFB Technologies, Inc.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/MFB-Technologies-Inc.png \"MFB Technologies, Inc.\")](https://github.com/MFB-Technologies-Inc)\n[![Torutek](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/torutek-gh.png \"Torutek\")](https://github.com/torutek-gh)\n[![DRIVE.NET, Inc.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/drivenet.png \"DRIVE.NET, Inc.\")](https://github.com/drivenet)\n[![Keith Pickford](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Keflon.png \"Keith Pickford\")](https://github.com/Keflon)\n[![Thomas Bolon](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/tbolon.png \"Thomas Bolon\")](https://github.com/tbolon)\n[![Kori Francis](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/kfrancis.png \"Kori Francis\")](https://github.com/kfrancis)\n[![Toni Wenzel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/twenzel.png \"Toni Wenzel\")](https://github.com/twenzel)\n[![Uno Platform](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/unoplatform.png \"Uno Platform\")](https://github.com/unoplatform)\n[![Dan Siegel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/dansiegel.png \"Dan Siegel\")](https://github.com/dansiegel)\n[![Reuben Swartz](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/rbnswartz.png \"Reuben Swartz\")](https://github.com/rbnswartz)\n[![Jacob Foshee](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jfoshee.png \"Jacob Foshee\")](https://github.com/jfoshee)\n[![](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Mrxx99.png \"\")](https://github.com/Mrxx99)\n[![Eric Johnson](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/eajhnsn1.png \"Eric Johnson\")](https://github.com/eajhnsn1)\n[![Ix Technologies B.V.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/IxTechnologies.png \"Ix Technologies B.V.\")](https://github.com/IxTechnologies)\n[![David JENNI](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/davidjenni.png \"David JENNI\")](https://github.com/davidjenni)\n[![Jonathan ](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Jonathan-Hickey.png \"Jonathan \")](https://github.com/Jonathan-Hickey)\n[![Charley Wu](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/akunzai.png \"Charley Wu\")](https://github.com/akunzai)\n[![Jakob Tikjøb Andersen](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jakobt.png \"Jakob Tikjøb Andersen\")](https://github.com/jakobt)\n[![Tino Hager](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/tinohager.png \"Tino Hager\")](https://github.com/tinohager)\n[![Ken Bonny](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/KenBonny.png \"Ken Bonny\")](https://github.com/KenBonny)\n[![Simon Cropp](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/SimonCropp.png \"Simon Cropp\")](https://github.com/SimonCropp)\n[![agileworks-eu](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/agileworks-eu.png \"agileworks-eu\")](https://github.com/agileworks-eu)\n[![sorahex](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/sorahex.png \"sorahex\")](https://github.com/sorahex)\n[![Zheyu Shen](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/arsdragonfly.png \"Zheyu Shen\")](https://github.com/arsdragonfly)\n[![Vezel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/vezel-dev.png \"Vezel\")](https://github.com/vezel-dev)\n[![ChilliCream](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/ChilliCream.png \"ChilliCream\")](https://github.com/ChilliCream)\n[![4OTC](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/4OTC.png \"4OTC\")](https://github.com/4OTC)\n[![Vincent Limo](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/v-limo.png \"Vincent Limo\")](https://github.com/v-limo)\n[![Jordan S. Jones](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jordansjones.png \"Jordan S. Jones\")](https://github.com/jordansjones)\n[![domischell](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/DominicSchell.png \"domischell\")](https://github.com/DominicSchell)\n\n\n\u003c!-- sponsors.md --\u003e\n\n[![Sponsor this project](https://raw.githubusercontent.com/devlooped/sponsors/main/sponsor.png \"Sponsor this project\")](https://github.com/sponsors/devlooped)\n\u0026nbsp;\n\n[Learn more about GitHub Sponsors](https://github.com/sponsors)\n\n\u003c!-- https://github.com/devlooped/sponsors/raw/main/footer.md --\u003e\n","funding_links":["https://github.com/sponsors/devlooped","https://github.com/sponsors"],"categories":["Do not want to test 112 ( old ISourceGenerator )"],"sub_categories":["1. [ThisAssembly](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlooped%2FSmallSharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevlooped%2FSmallSharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevlooped%2FSmallSharp/lists"}