Browse Source

Merge branch 'v2_2489_scroll-scrollbar-new' of tig:BDisp/Terminal.Gui into BDisp-v2_2489_scroll-scrollbar-new

Tig 11 months ago
parent
commit
5279af1c84
100 changed files with 1830 additions and 4321 deletions
  1. 37 0
      .filenesting.json
  2. 8 8
      .github/workflows/api-docs.yml
  3. 2 2
      .github/workflows/codeql-analysis.yml
  4. 88 27
      .github/workflows/dotnet-core.yml
  5. 4 4
      .github/workflows/publish.yml
  6. 46 12
      .gitignore
  7. 33 0
      .vsconfig
  8. 0 23
      Analyzers/Directory.Build.props
  9. 0 21
      Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Program.cs
  10. 0 25
      Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Terminal.Gui.Analyzers.Internal.Debugging.csproj
  11. 0 48
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/EnumMemberValues.cs
  12. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum.cs
  13. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt.cs
  14. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt_NoFastIsDefined.cs
  15. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt.cs
  16. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt_NoFastIsDefined.cs
  17. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_NoFastIsDefined.cs
  18. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum.cs
  19. 0 51
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitInt.cs
  20. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitUInt.cs
  21. 0 46
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum.cs
  22. 0 48
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitInt.cs
  23. 0 46
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitUint.cs
  24. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum.cs
  25. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitInt.cs
  26. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitUInt.cs
  27. 0 329
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGeneratorTests.cs
  28. 0 111
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/IndentedTextWriterExtensionsTests.cs
  29. 0 47
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj
  30. 0 3
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj.DotSettings
  31. 0 20
      Analyzers/Terminal.Gui.Analyzers.Internal/AccessibilityExtensions.cs
  32. 0 8
      Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Shipped.md
  33. 0 4
      Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Unshipped.md
  34. 0 117
      Analyzers/Terminal.Gui.Analyzers.Internal/Analyzers/GenerateEnumExtensionMethodsAttributeAnalyzer.cs
  35. 0 3
      Analyzers/Terminal.Gui.Analyzers.Internal/ApiCompatExcludedAttributes.txt
  36. 0 27
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/AssemblyExtendedEnumTypeAttribute.cs
  37. 0 37
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/ExtensionsForEnumTypeAttribute.cs
  38. 0 110
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/GenerateEnumExtensionMethodsAttribute.cs
  39. 0 14
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/IExtensionsForEnumTypeAttribute.cs
  40. 0 11
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IEqualityOperators.cs
  41. 0 6
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IntrinsicAttribute.cs
  42. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/NumericExtensions.cs
  43. 0 204
      Analyzers/Terminal.Gui.Analyzers.Internal/Constants/Strings.cs
  44. 0 235
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/CodeWriter.cs
  45. 0 443
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsGenerationInfo.cs
  46. 0 452
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGenerator.cs
  47. 0 38
      Analyzers/Terminal.Gui.Analyzers.Internal/IGeneratedTypeMetadata.cs
  48. 0 28
      Analyzers/Terminal.Gui.Analyzers.Internal/IStandardCSharpCodeGenerator.cs
  49. 0 71
      Analyzers/Terminal.Gui.Analyzers.Internal/IndentedTextWriterExtensions.cs
  50. 0 8
      Analyzers/Terminal.Gui.Analyzers.Internal/Properties/launchSettings.json
  51. 0 63
      Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj
  52. 0 4
      Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj.DotSettings
  53. 12 6
      CONTRIBUTING.md
  54. 2 5
      CommunityToolkitExample/CommunityToolkitExample.csproj
  55. 1 1
      CommunityToolkitExample/Program.cs
  56. 0 6
      Directory.Build.props
  57. 0 5
      Directory.Build.targets
  58. 21 20
      Example/Example.cs
  59. 2 2
      FSharpExample/FSharpExample.fsproj
  60. 36 442
      FSharpExample/Program.fs
  61. 34 23
      GitVersion.yml
  62. 22 0
      NativeAot/NativeAot.csproj
  63. 113 0
      NativeAot/Program.cs
  64. 18 0
      NativeAot/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml
  65. 18 0
      NativeAot/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml
  66. 13 0
      NativeAot/Properties/launchSettings.json
  67. 5 0
      NativeAot/Publish_linux-x64_Debug.sh
  68. 5 0
      NativeAot/Publish_linux-x64_Release.sh
  69. 5 0
      NativeAot/Publish_osx-x64_Debug.sh
  70. 5 0
      NativeAot/Publish_osx-x64_Release.sh
  71. 10 0
      NativeAot/README.md
  72. 10 0
      NoSamples.slnf
  73. 122 17
      README.md
  74. 0 3
      ReactiveExample/FodyWeavers.xml
  75. 0 26
      ReactiveExample/FodyWeavers.xsd
  76. 126 174
      ReactiveExample/LoginView.cs
  77. 38 43
      ReactiveExample/LoginViewModel.cs
  78. 1 1
      ReactiveExample/Program.cs
  79. 1 1
      ReactiveExample/README.md
  80. 3 3
      ReactiveExample/ReactiveExample.csproj
  81. 24 0
      ReactiveExample/ViewExtensions.cs
  82. 2 2
      Release.ps1
  83. 10 0
      Release.slnf
  84. 0 117
      Scripts/Terminal.Gui.PowerShell.Analyzers.psd1
  85. 0 96
      Scripts/Terminal.Gui.PowerShell.Analyzers.psm1
  86. 0 6
      Scripts/Terminal.Gui.PowerShell.Core.psm1
  87. 1 1
      Scripts/Terminal.Gui.PowerShell.psd1
  88. 112 0
      SelfContained/Program.cs
  89. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Debug.pubxml
  90. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Release.pubxml
  91. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Debug.pubxml
  92. 16 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Release.pubxml
  93. 17 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml
  94. 17 0
      SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml
  95. 9 0
      SelfContained/README.md
  96. 25 0
      SelfContained/SelfContained.csproj
  97. 31 0
      Showcase.md
  98. 29 0
      Terminal.Gui/Application/Application.Driver.cs
  99. 214 0
      Terminal.Gui/Application/Application.Initialization.cs
  100. 434 0
      Terminal.Gui/Application/Application.Keyboard.cs

+ 37 - 0
.filenesting.json

@@ -0,0 +1,37 @@
+{
+  "help": "https://go.microsoft.com/fwlink/?linkid=866610",
+  "root": true,
+
+  "dependentFileProviders": {
+    "add": {
+      "addedExtension": {},
+      "pathSegment": {
+        "add": {
+          ".*": [
+            ".config",
+            ".cs",
+            ".json",
+            ".resx"
+          ]
+        }
+      },
+      "extensionToExtension": {
+        "add": {
+          ".designer.cs": [
+            ".resx"
+          ],
+          ".cs.d.ts": [
+            ".cs"
+          ]
+        }
+      },
+      "fileToFile": {
+        "add": {
+          "package-lock.json": [
+            "package.json"
+          ]
+        }
+      }
+    }
+  }
+}

+ 8 - 8
.github/workflows/api-docs.yml

@@ -2,7 +2,7 @@ name: Build and publish API docs
 
 
 on:
 on:
   push:
   push:
-    branches: [main, develop, v2_develop]
+    branches: [v1_release, v2_develop]
 
 
 permissions:
 permissions:
   id-token: write 
   id-token: write 
@@ -17,11 +17,11 @@ jobs:
     runs-on: windows-latest
     runs-on: windows-latest
     steps:
     steps:
     - name: Checkout
     - name: Checkout
-      if: github.ref_name == 'main' ||  github.ref_name == 'develop'
+      #if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       uses: actions/checkout@v4
       uses: actions/checkout@v4
 
 
     - name: DocFX Build
     - name: DocFX Build
-      if: github.ref_name == 'main' ||  github.ref_name == 'develop'
+      #if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       working-directory: docfx
       working-directory: docfx
       run: |
       run: |
         dotnet tool install -g docfx
         dotnet tool install -g docfx
@@ -31,17 +31,17 @@ jobs:
       continue-on-error: false
       continue-on-error: false
 
 
     - name: Setup Pages
     - name: Setup Pages
-      if: github.ref_name == 'main' ||  github.ref_name == 'develop'
-      uses: actions/configure-pages@v4
+      #if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
+      uses: actions/configure-pages@v5
       
       
     - name: Upload artifact
     - name: Upload artifact
-      if: github.ref_name == 'main' ||  github.ref_name == 'develop'
+      #if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       uses: actions/upload-pages-artifact@v3
       uses: actions/upload-pages-artifact@v3
       with:
       with:
         path: docfx/_site
         path: docfx/_site
        
        
     - name: Deploy to GitHub Pages
     - name: Deploy to GitHub Pages
-      if: github.ref_name == 'main' ||  github.ref_name == 'develop'
+      if: github.ref_name == 'v1_release' ||  github.ref_name == 'v1_develop'
       id: deployment
       id: deployment
       uses: actions/deploy-pages@v4
       uses: actions/deploy-pages@v4
       with:
       with:
@@ -49,7 +49,7 @@ jobs:
 
 
     - name: v2_develop Repository Dispatch ${{ github.ref_name }}
     - name: v2_develop Repository Dispatch ${{ github.ref_name }}
       if: github.ref_name == 'v2_develop'
       if: github.ref_name == 'v2_develop'
-      uses: peter-evans/repository-dispatch@v2
+      uses: peter-evans/repository-dispatch@v3
       with:
       with:
         token: ${{ secrets.V2DOCS_TOKEN }}
         token: ${{ secrets.V2DOCS_TOKEN }}
         repository: gui-cs/Terminal.GuiV2Docs
         repository: gui-cs/Terminal.GuiV2Docs

+ 2 - 2
.github/workflows/codeql-analysis.yml

@@ -4,7 +4,7 @@ name: "Code scanning"
 
 
 on:
 on:
   push:
   push:
-    branches: [main]
+    branches: [main, v2_release]
     paths-ignore:
     paths-ignore:
       - '**/*.md'
       - '**/*.md'
       - '**/*.txt'
       - '**/*.txt'
@@ -12,7 +12,7 @@ on:
       - docs
       - docs
       - docfx
       - docfx
   pull_request:
   pull_request:
-    branches: [main]
+    branches: [main, v2_release]
     paths-ignore:
     paths-ignore:
       - '**/*.md'
       - '**/*.md'
       - '**/*.txt'
       - '**/*.txt'

+ 88 - 27
.github/workflows/dotnet-core.yml

@@ -2,19 +2,33 @@ name: Build & Test Terminal.Gui with .NET Core
 
 
 on:
 on:
   push:
   push:
-    branches: [ main, develop, v2_develop ]
+    branches: [ v2_release, v2_develop ]
+    paths-ignore:
+      - '**.md'
   pull_request:
   pull_request:
-    branches: [ main, develop, v2_develop ]
-
+    branches: [ v2_release, v2_develop ]
+    paths-ignore:
+      - '**.md'
+      
 jobs:
 jobs:
-  build_and_test:
+  build_and_test_debug:
 
 
-    runs-on: windows-latest
+    runs-on: ${{ matrix.os }}
+    strategy:
+      # Turn off fail-fast to let all runners run even if there are errors
+      fail-fast: true
+      matrix:
+        os: [ ubuntu-latest, windows-latest, macos-latest ]
 
 
+    timeout-minutes: 10
     steps:
     steps:
-    - uses: actions/checkout@v4
-    
-    - name: Setup dotnet
+
+# Build (Debug)
+
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup .NET Core
       uses: actions/setup-dotnet@v4
       uses: actions/setup-dotnet@v4
       with:
       with:
         dotnet-version: 8.x
         dotnet-version: 8.x
@@ -27,26 +41,73 @@ jobs:
     - name: Build Debug
     - name: Build Debug
       run: dotnet build --configuration Debug --no-restore
       run: dotnet build --configuration Debug --no-restore
 
 
+# Test
+    # Note: The --blame and VSTEST_DUMP_PATH stuff is needed to diagnose the test runner crashing on ubuntu/mac
+    # See https://github.com/microsoft/vstest/issues/2952 for why the --blame stuff below is needed.
+    # Without it, the test runner crashes on ubuntu (but not Windows or mac)
+
+    - name: MacOS - Patch test runner settings to stop on fail
+      if: runner.os == 'macOS'
+      run: |
+        brew install gnu-sed
+        gsed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
+
+    - name: Windows/Linux - Patch test runner settings to stop on fail
+      if: runner.os != 'macOS'
+      run: |
+          sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
+
+    - name: Set VSTEST_DUMP_PATH
+      shell: bash
+      run: echo "{VSTEST_DUMP_PATH}={logs/${{ runner.os }}/}" >> $GITHUB_ENV
+
     - name: Test
     - name: Test
       run: |
       run: |
-        sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
-        dotnet test --no-restore --verbosity normal --collect:"XPlat Code Coverage"  --settings UnitTests/coverlet.runsettings --blame
-        mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
+       dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings --diag:logs/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always 
+     
+       # mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
 
 
-    # Note: this step is currently not writing to the gist for some reason
-    - name: Create Test Coverage Badge
-      uses: simon-k/[email protected]
-      id: create_coverage_badge
+    - name: Upload Test Logs
+      if: always()
+      uses: actions/upload-artifact@v4
       with:
       with:
-        label: Unit Test Coverage
-        color: brightgreen
-        path: UnitTests/TestResults/coverage.opencover.xml
-        gist-filename: code-coverage.json
-        # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27
-        gist-id: 90ef67a684cb71db1817921a970f8d27
-        gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}   
-
-    - name: Print Code Coverage
-      run: |
-        echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
-        echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"
+        name: test-logs-${{ runner.os }}
+        path: |
+          logs/    
+          UnitTests/TestResults/
+  
+
+  build_release:
+    # Ensure that RELEASE builds are not broken
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup .NET Core
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 8.x
+        dotnet-quality: 'ga'
+
+    - name: Build Release
+      run: dotnet build --configuration Release
+
+
+    # Note: this step is currently not writing to the gist for some reason
+    # - name: Create Test Coverage Badge
+    #   uses: simon-k/[email protected]
+    #   id: create_coverage_badge
+    #   with:
+    #     label: Unit Test Coverage
+    #     color: brightgreen
+    #     path: UnitTests/TestResults/coverage.opencover.xml
+    #     gist-filename: code-coverage.json
+    #     # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27
+    #     gist-id: 90ef67a684cb71db1817921a970f8d27
+    #     gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}   
+
+    # - name: Print Code Coverage
+    #   run: |
+    #     echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
+    #     echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"

+ 4 - 4
.github/workflows/publish.yml

@@ -2,7 +2,7 @@ name: Publish Terminal.Gui
 
 
 on:
 on:
   push:
   push:
-    branches: [ main, develop, v2_release, v2_develop ]
+    branches: [ v1_release, v1_develop, v2_release, v2_develop ]
     tags:
     tags:
       - v*
       - v*
     paths-ignore:
     paths-ignore:
@@ -19,13 +19,13 @@ jobs:
         fetch-depth: 0 # fetch-depth is needed for GitVersion
         fetch-depth: 0 # fetch-depth is needed for GitVersion
 
 
     - name: Install GitVersion 
     - name: Install GitVersion 
-      uses: gittools/actions/gitversion/setup@v0
+      uses: gittools/actions/gitversion/setup@v2
       with:
       with:
           versionSpec: '5.x'
           versionSpec: '5.x'
           includePrerelease: true
           includePrerelease: true
 
 
     - name: Determine Version
     - name: Determine Version
-      uses: gittools/actions/gitversion/execute@v0
+      uses: gittools/actions/gitversion/execute@v2
       with:
       with:
         useConfigFile: true
         useConfigFile: true
         #additionalArguments: /b develop
         #additionalArguments: /b develop
@@ -43,8 +43,8 @@ jobs:
     - name: Build Release
     - name: Build Release
       run: |
       run: |
         dotnet-gitversion /updateprojectfiles
         dotnet-gitversion /updateprojectfiles
-        dotnet build ./Analyzers/Terminal.Gui.Analyzers.Internal --no-incremental --nologo --force --configuration Release
         dotnet build --no-incremental --nologo --force --configuration Release
         dotnet build --no-incremental --nologo --force --configuration Release
+        dotnet test --configuration Release
 
 
     - name: Pack
     - name: Pack
       run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' 
       run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' 

+ 46 - 12
.gitignore

@@ -1,29 +1,63 @@
-bin
-obj
-~$*
+# Build artifacts
+[Bb]in/
+[Oo]bj/
+[Rr]elease/
+[Dd]ebug/
+[Xx]64/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+
+# User-local settings and caches
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
 *.userprefs
 *.userprefs
+_ReSharper.**
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+.devcontainer/
+.vscode/
+.vs/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Roslyn generated cs files
+**.g.cs
+
+# Common temporary files
+~$*
 *~
 *~
-packages
-.vs
 
 
-# User-specific files
-*.user
+# NuGet Stuff
+*.nupkg
+*.snupkg
+# Exclude everything in packages directory except the packages/build directory
+**/[Pp]ackages/*
+!**/[Pp]ackages/build/
 
 
 # API Docs
 # API Docs
 docfx/api
 docfx/api
 docfx/_site
 docfx/_site
 
 
-# Unit Tests
+# Test Results
 UnitTests/TestResults
 UnitTests/TestResults
 TestResults
 TestResults
 
 
-#git merge files
+# git merge files
 *.orig
 *.orig
-
-.vscode/
+*.theirs
+*.ours
 
 
 demo.*
 demo.*
 
 
 *.deb
 *.deb
 
 
-*.tui/
+*.tui/
+
+*.dotCover

+ 33 - 0
.vsconfig

@@ -0,0 +1,33 @@
+{
+  "version": "1.0",
+  "components": [
+    "Microsoft.VisualStudio.Component.DependencyValidation.Community",
+    "Microsoft.VisualStudio.Component.CoreEditor",
+    "Microsoft.VisualStudio.Workload.CoreEditor",
+    "Microsoft.Net.Component.4.8.SDK",
+    "Microsoft.Net.Component.4.7.2.TargetingPack",
+    "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+    "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+    "Microsoft.Component.MSBuild",
+    "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+    "Microsoft.VisualStudio.Component.TextTemplating",
+    "Microsoft.VisualStudio.Component.NuGet",
+    "Microsoft.VisualStudio.Component.ManagedDesktop.Core",
+    "Microsoft.NetCore.Component.Runtime.8.0",
+    "Microsoft.NetCore.Component.SDK",
+    "Microsoft.VisualStudio.Component.FSharp",
+    "Microsoft.NetCore.Component.DevelopmentTools",
+    "Microsoft.VisualStudio.Component.AppInsights.Tools",
+    "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+    "Microsoft.Net.Component.4.6.2.TargetingPack",
+    "Microsoft.Net.Component.4.8.1.TargetingPack",
+    "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
+    "Microsoft.VisualStudio.Component.NuGet.BuildTools",
+    "Microsoft.Net.Component.4.6.TargetingPack",
+    "Microsoft.VisualStudio.Component.VSSDK",
+    "Microsoft.VisualStudio.ComponentGroup.VisualStudioExtension.Prerequisites",
+    "Microsoft.Component.CodeAnalysis.SDK",
+    "Microsoft.VisualStudio.Workload.VisualStudioExtension"
+  ],
+  "extensions": []
+}

+ 0 - 23
Analyzers/Directory.Build.props

@@ -1,23 +0,0 @@
-<Project>
-  <PropertyGroup>
-    <Nullable>enable</Nullable>
-    <AnalysisLevel>latest-recommended</AnalysisLevel>
-    <WarningLevel>7</WarningLevel>
-    <CharacterSet>UTF-8</CharacterSet>
-    <Deterministic>true</Deterministic>
-    <UTF8OutPut>true</UTF8OutPut>
-    <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
-    <NoLogo>True</NoLogo>
-    <DefineTrace>True</DefineTrace>
-  </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
-    <PackageReference Include="JetBrains.ExternalAnnotations" Version="10.2.147" />
-  </ItemGroup>
-  <ItemGroup>
-      <Using Include="System.Buffers" />
-      <Using Include="System.Collections.Specialized" />
-      <Using Include="System.Numerics" />
-      <Using Include="System.Runtime.CompilerServices" />
-  </ItemGroup>
-</Project>

+ 0 - 21
Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Program.cs

@@ -1,21 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Debugging;
-
-class Program
-{
-    static void Main (string [] args)
-    {
-        
-    }
-}
-
-[GenerateEnumExtensionMethods]
-public enum TestEnum
-{
-    Zero = 0,
-    One,
-    Two = 2,
-    Three,
-    Six = 6
-}

+ 0 - 25
Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Terminal.Gui.Analyzers.Internal.Debugging.csproj

@@ -1,25 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-  </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.9.2" PrivateAssets="all" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-
-</Project>

+ 0 - 48
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/EnumMemberValues.cs

@@ -1,48 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-internal class SignedEnumMemberValues
-{
-    internal const int Bit31 = ~0b_01111111_11111111_11111111_11111111;
-    internal const int Bit30 =  0b_01000000_00000000_00000000_00000000;
-    internal const int Bit29 =  0b_00100000_00000000_00000000_00000000;
-    internal const int Bit28 =  0b_00010000_00000000_00000000_00000000;
-    internal const int Bit27 =  0b_00001000_00000000_00000000_00000000;
-    internal const int Bit26 =  0b_00000100_00000000_00000000_00000000;
-    internal const int Bit25 =  0b_00000010_00000000_00000000_00000000;
-    internal const int Bit24 =  0b_00000001_00000000_00000000_00000000;
-    internal const int Bit23 =  0b_00000000_10000000_00000000_00000000;
-    internal const int Bit22 =  0b_00000000_01000000_00000000_00000000;
-    internal const int Bit21 =  0b_00000000_00100000_00000000_00000000;
-    internal const int Bit20 =  0b_00000000_00010000_00000000_00000000;
-    internal const int Bit19 =  0b_00000000_00001000_00000000_00000000;
-    internal const int Bit18 =  0b_00000000_00000100_00000000_00000000;
-    internal const int Bit17 =  0b_00000000_00000010_00000000_00000000;
-    internal const int Bit16 =  0b_00000000_00000001_00000000_00000000;
-    internal const int Bit15 =  0b_00000000_00000000_10000000_00000000;
-    internal const int Bit14 =  0b_00000000_00000000_01000000_00000000;
-    internal const int Bit13 =  0b_00000000_00000000_00100000_00000000;
-    internal const int Bit12 =  0b_00000000_00000000_00010000_00000000;
-    internal const int Bit11 =  0b_00000000_00000000_00001000_00000000;
-    internal const int Bit10 =  0b_00000000_00000000_00000100_00000000;
-    internal const int Bit09 =  0b_00000000_00000000_00000010_00000000;
-    internal const int Bit08 =  0b_00000000_00000000_00000001_00000000;
-    internal const int Bit07 =  0b_00000000_00000000_00000000_10000000;
-    internal const int Bit06 =  0b_00000000_00000000_00000000_01000000;
-    internal const int Bit05 =  0b_00000000_00000000_00000000_00100000;
-    internal const int Bit04 =  0b_00000000_00000000_00000000_00010000;
-    internal const int Bit03 =  0b_00000000_00000000_00000000_00001000;
-    internal const int Bit02 =  0b_00000000_00000000_00000000_00000100;
-    internal const int Bit01 =  0b_00000000_00000000_00000000_00000010;
-    internal const int Bit00 =  0b_00000000_00000000_00000000_00000001;
-    internal const int All_0 =  0;
-    internal const int All_1 =  ~All_0;
-    internal const int Alternating_01 = 0b_01010101_01010101_01010101_01010101;
-    internal const int Alternating_10 = ~Alternating_01;
-    internal const int EvenBytesHigh = 0b_00000000_11111111_00000000_11111111;
-    internal const int OddBytesHigh = ~EvenBytesHigh;
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum_ExplicitInt
-{
-    Bit31 = BasicEnum_ExplicitInt.Bit31,
-    Bit30 = BasicEnum_ExplicitInt.Bit30,
-    Bit29 = BasicEnum_ExplicitInt.Bit29,
-    Bit28 = BasicEnum_ExplicitInt.Bit28,
-    Bit27 = BasicEnum_ExplicitInt.Bit27,
-    Bit26 = BasicEnum_ExplicitInt.Bit26,
-    Bit25 = BasicEnum_ExplicitInt.Bit25,
-    Bit24 = BasicEnum_ExplicitInt.Bit24,
-    Bit23 = BasicEnum_ExplicitInt.Bit23,
-    Bit22 = BasicEnum_ExplicitInt.Bit22,
-    Bit21 = BasicEnum_ExplicitInt.Bit21,
-    Bit20 = BasicEnum_ExplicitInt.Bit20,
-    Bit19 = BasicEnum_ExplicitInt.Bit19,
-    Bit18 = BasicEnum_ExplicitInt.Bit18,
-    Bit17 = BasicEnum_ExplicitInt.Bit17,
-    Bit16 = BasicEnum_ExplicitInt.Bit16,
-    Bit15 = BasicEnum_ExplicitInt.Bit15,
-    Bit14 = BasicEnum_ExplicitInt.Bit14,
-    Bit13 = BasicEnum_ExplicitInt.Bit13,
-    Bit12 = BasicEnum_ExplicitInt.Bit12,
-    Bit11 = BasicEnum_ExplicitInt.Bit11,
-    Bit10 = BasicEnum_ExplicitInt.Bit10,
-    Bit09 = BasicEnum_ExplicitInt.Bit09,
-    Bit08 = BasicEnum_ExplicitInt.Bit08,
-    Bit07 = BasicEnum_ExplicitInt.Bit07,
-    Bit06 = BasicEnum_ExplicitInt.Bit06,
-    Bit05 = BasicEnum_ExplicitInt.Bit05,
-    Bit04 = BasicEnum_ExplicitInt.Bit04,
-    Bit03 = BasicEnum_ExplicitInt.Bit03,
-    Bit02 = BasicEnum_ExplicitInt.Bit02,
-    Bit01 = BasicEnum_ExplicitInt.Bit01,
-    Bit00 = BasicEnum_ExplicitInt.Bit00,
-    All_0 = BasicEnum_ExplicitInt.All_0,
-    All_1 = BasicEnum_ExplicitInt.All_1,
-    Alternating_01 = BasicEnum_ExplicitInt.Alternating_01,
-    Alternating_10 = BasicEnum_ExplicitInt.Alternating_10,
-    EvenBytesHigh = BasicEnum_ExplicitInt.EvenBytesHigh,
-    OddBytesHigh = BasicEnum_ExplicitInt.OddBytesHigh
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt_NoFastIsDefined.cs

@@ -1,50 +0,0 @@
-// ReSharper disable EnumUnderlyingTypeIsInt
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_ExplicitInt_NoFastIsDefined : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 = 0b_01000000_00000000_00000000_00000000,
-    Bit29 = 0b_00100000_00000000_00000000_00000000,
-    Bit28 = 0b_00010000_00000000_00000000_00000000,
-    Bit27 = 0b_00001000_00000000_00000000_00000000,
-    Bit26 = 0b_00000100_00000000_00000000_00000000,
-    Bit25 = 0b_00000010_00000000_00000000_00000000,
-    Bit24 = 0b_00000001_00000000_00000000_00000000,
-    Bit23 = 0b_00000000_10000000_00000000_00000000,
-    Bit22 = 0b_00000000_01000000_00000000_00000000,
-    Bit21 = 0b_00000000_00100000_00000000_00000000,
-    Bit20 = 0b_00000000_00010000_00000000_00000000,
-    Bit19 = 0b_00000000_00001000_00000000_00000000,
-    Bit18 = 0b_00000000_00000100_00000000_00000000,
-    Bit17 = 0b_00000000_00000010_00000000_00000000,
-    Bit16 = 0b_00000000_00000001_00000000_00000000,
-    Bit15 = 0b_00000000_00000000_10000000_00000000,
-    Bit14 = 0b_00000000_00000000_01000000_00000000,
-    Bit13 = 0b_00000000_00000000_00100000_00000000,
-    Bit12 = 0b_00000000_00000000_00010000_00000000,
-    Bit11 = 0b_00000000_00000000_00001000_00000000,
-    Bit10 = 0b_00000000_00000000_00000100_00000000,
-    Bit09 = 0b_00000000_00000000_00000010_00000000,
-    Bit08 = 0b_00000000_00000000_00000001_00000000,
-    Bit07 = 0b_00000000_00000000_00000000_10000000,
-    Bit06 = 0b_00000000_00000000_00000000_01000000,
-    Bit05 = 0b_00000000_00000000_00000000_00100000,
-    Bit04 = 0b_00000000_00000000_00000000_00010000,
-    Bit03 = 0b_00000000_00000000_00000000_00001000,
-    Bit02 = 0b_00000000_00000000_00000000_00000100,
-    Bit01 = 0b_00000000_00000000_00000000_00000010,
-    Bit00 = 0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt_NoFastIsDefined.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_ExplicitUInt_NoFastIsDefined : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_NoFastIsDefined.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_NoFastIsDefined
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum.cs

@@ -1,50 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="FlagsEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 51
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitInt.cs

@@ -1,51 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-/// <summary>
-///     Same as <see cref="FlagsEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitUInt.cs

@@ -1,50 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="FlagsEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 46
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum.cs

@@ -1,46 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum without explicitly-defined backing type and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = unchecked((int)0b_10101010_10101010_10101010_10101010),
-    OddBytesHigh = unchecked((int)0b_11111111_00000000_11111111_00000000),
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-}

+ 0 - 48
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitInt.cs

@@ -1,48 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum with explicitly-defined backing type of int and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = unchecked((int)0b_10101010_10101010_10101010_10101010),
-    OddBytesHigh = unchecked((int)0b_11111111_00000000_11111111_00000000),
-    EvenBytesHigh = unchecked((int)0b_00000000_11111111_00000000_11111111),
-}

+ 0 - 46
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitUint.cs

@@ -1,46 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum with explicitly-defined backing type of uint and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0 = 0b_00000000_00000000_00000000_00000000u,
-    All_1 = 0b_11111111_11111111_11111111_11111111u,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101u,
-    Alternating_10 = 0b_10101010_10101010_10101010_10101010u,
-    OddBytesHigh   = 0b_11111111_00000000_11111111_00000000u,
-    EvenBytesHigh  = 0b_00000000_11111111_00000000_11111111u,
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum without explicitly-defined backing type and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitInt.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum with explicitly-defined backing type of int and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitUInt.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum with explicitly-defined backing type of uint and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0 = 0b_00000000_00000000_00000000_00000000u,
-    All_1 = 0b_11111111_11111111_11111111_11111111u
-}

+ 0 - 329
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGeneratorTests.cs

@@ -1,329 +0,0 @@
-using System.Collections.Concurrent;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using NUnit.Framework.Interfaces;
-using NUnit.Framework.Internal;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions;
-
-[TestFixture]
-[Category ("Source Generators")]
-[TestOf (typeof (EnumExtensionMethodsIncrementalGenerator))]
-[Parallelizable (ParallelScope.Children)]
-public class EnumExtensionMethodsIncrementalGeneratorTests
-{
-    private static bool _isInitialized;
-
-    /// <summary>All enum types declared in the test assembly.</summary>
-    private static readonly ObservableCollection<Type> AllEnumTypes = [];
-
-    /// <summary>
-    ///     All enum types without a <see cref="GenerateEnumExtensionMethodsAttribute"/>, <see cref="AllEnumTypes"/>
-    /// </summary>
-    private static readonly HashSet<Type> BoringEnumTypes = [];
-
-    /// <summary>All extension classes generated for enums with our attribute.</summary>
-    private static readonly ObservableCollection<Type> EnumExtensionClasses = [];
-
-    private static readonly ConcurrentDictionary<Type, EnumData> ExtendedEnumTypeMappings = [];
-    private static IEnumerable<Type> ExtendedEnumTypes => ExtendedEnumTypeMappings.Keys;
-
-    private static readonly ReaderWriterLockSlim InitializationLock = new ();
-
-    private static IEnumerable<AssemblyExtendedEnumTypeAttribute> GetAssemblyExtendedEnumTypeAttributes () =>
-        Assembly.GetExecutingAssembly ()
-                .GetCustomAttributes<AssemblyExtendedEnumTypeAttribute> ();
-
-    private static IEnumerable<TestCaseData> Get_AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute_Cases ()
-    {
-        return GetAssemblyExtendedEnumTypeAttributes ()
-            .Select (
-                     static attr => new TestCaseData (attr)
-                     {
-                         TestName = $"{nameof (AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute)}({attr.EnumType.Name},{attr.ExtensionClass.Name})",
-                         HasExpectedResult = true,
-                         ExpectedResult = true
-                     });
-    }
-
-    [Test]
-    [Category ("Attributes")]
-    [TestCaseSource (nameof (Get_AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute_Cases))]
-    public bool AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute (AssemblyExtendedEnumTypeAttribute attr)
-    {
-        Assume.That (attr, Is.Not.Null);
-        Assume.That (attr.EnumType, Is.Not.Null);
-        Assume.That (attr.EnumType!.IsEnum);
-
-        return attr.EnumType.IsDefined (typeof (GenerateEnumExtensionMethodsAttribute));
-    }
-
-    private const string AssemblyExtendedEnumTypeAttributeEnumPropertyName =
-        $"{nameof (AssemblyExtendedEnumTypeAttribute)}.{nameof (AssemblyExtendedEnumTypeAttribute.EnumType)}";
-
-    [Test]
-    [Category("Attributes")]
-    public void AssemblyExtendedEnumTypeAttribute_ExtensionClassHasExpectedReverseMappingAttribute ([ValueSource(nameof(GetAssemblyExtendedEnumTypeAttributes))]AssemblyExtendedEnumTypeAttribute attr)
-    {
-        Assume.That (attr, Is.Not.Null);
-        Assume.That (attr.ExtensionClass, Is.Not.Null);
-        Assume.That (attr.ExtensionClass!.IsClass);
-        Assume.That (attr.ExtensionClass!.IsSealed);
-
-        Assert.That (attr.ExtensionClass.IsDefined (typeof (ExtensionsForEnumTypeAttribute<>)));
-    }
-
-    [Test]
-    [Category("Attributes")]
-    public void ExtendedEnum_AssemblyHasMatchingAttribute ([ValueSource(nameof(GetExtendedEnum_EnumData))]EnumData enumData)
-    {
-        Assume.That (enumData, Is.Not.Null);
-        Assume.That (enumData.EnumType, Is.Not.Null);
-        Assume.That (enumData.EnumType!.IsEnum);
-
-        Assert.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void BoringEnum_DoesNotHaveExtensions ([ValueSource (nameof (BoringEnumTypes))] Type enumType)
-    {
-        Assume.That (enumType.IsEnum);
-
-        Assert.That (enumType, Has.No.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void ExtendedEnum_FastIsDefinedFalse_DoesNotHaveFastIsDefined ([ValueSource (nameof (GetExtendedEnumTypes_FastIsDefinedFalse))] EnumData enumData)
-    {
-        Assume.That (enumData.EnumType.IsEnum);
-        Assume.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        Assume.That (enumData.GeneratorAttribute, Is.Not.Null);
-        Assume.That (enumData.GeneratorAttribute, Is.EqualTo (enumData.EnumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> ()));
-        Assume.That (enumData.GeneratorAttribute, Has.Property ("FastIsDefined").False);
-        Assume.That (enumData.ExtensionClass, Is.Not.Null);
-
-        Assert.That (enumData.ExtensionClass!.GetMethod ("FastIsDefined"), Is.Null);
-    }
-
-    [Test]
-    public void ExtendedEnum_StaticExtensionClassExists ([ValueSource (nameof (ExtendedEnumTypes))] Type enumType)
-    {
-        Assume.That (enumType.IsEnum);
-        Assume.That (enumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        ITypeInfo enumTypeInfo = new TypeWrapper (enumType);
-        Assume.That (enumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void ExtendedEnum_FastIsDefinedTrue_HasFastIsDefined ([ValueSource (nameof (GetExtendedEnumTypes_FastIsDefinedTrue))] EnumData enumData)
-    {
-        Assume.That (enumData.EnumType, Is.Not.Null);
-        Assume.That (enumData.EnumType.IsEnum);
-        Assume.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        Assume.That (enumData.ExtensionClass, Is.Not.Null);
-        ITypeInfo extensionClassTypeInfo = new TypeWrapper (enumData.ExtensionClass!);
-        Assume.That (extensionClassTypeInfo.IsStaticClass);
-        Assume.That (enumData.GeneratorAttribute, Is.Not.Null);
-        Assume.That (enumData.GeneratorAttribute, Is.EqualTo (enumData.EnumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> ()));
-        Assume.That (enumData.GeneratorAttribute, Has.Property ("FastIsDefined").True);
-
-        MethodInfo? fastIsDefinedMethod = enumData.ExtensionClass!.GetMethod ("FastIsDefined");
-
-        Assert.That (fastIsDefinedMethod, Is.Not.Null);
-        Assert.That (fastIsDefinedMethod, Has.Attribute<ExtensionAttribute> ());
-        IMethodInfo[] extensionMethods = extensionClassTypeInfo.GetMethodsWithAttribute<ExtensionAttribute> (false);
-
-
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnum_EnumData ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values;
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<Type> GetBoringEnumTypes ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return BoringEnumTypes;
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnumTypes_FastIsDefinedFalse ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values.Where (static t => t.GeneratorAttribute?.FastIsDefined is false);
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnumTypes_FastIsDefinedTrue ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values.Where (static t => t.GeneratorAttribute?.FastIsDefined is true);
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static void Initialize ()
-    {
-        if (!InitializationLock.IsUpgradeableReadLockHeld || !InitializationLock.TryEnterWriteLock (5000))
-        {
-            return;
-        }
-
-        try
-        {
-            if (_isInitialized)
-            {
-                return;
-            }
-
-            AllEnumTypes.CollectionChanged += AllEnumTypes_CollectionChanged;
-            EnumExtensionClasses.CollectionChanged += EnumExtensionClasses_OnCollectionChanged;
-
-            Type [] allAssemblyTypes = Assembly
-                                       .GetExecutingAssembly ()
-                                       .GetTypes ();
-
-            IEnumerable<Type> allEnumTypes = allAssemblyTypes.Where (IsDefinedEnum);
-
-            foreach (Type type in allEnumTypes)
-            {
-                AllEnumTypes.Add (type);
-            }
-
-            foreach (Type type in allAssemblyTypes.Where (static t => t.IsClass && t.IsDefined (typeof (ExtensionsForEnumTypeAttribute<>))))
-            {
-                EnumExtensionClasses.Add (type);
-            }
-
-            _isInitialized = true;
-        }
-        finally
-        {
-            InitializationLock.ExitWriteLock ();
-        }
-
-        return;
-
-        static bool IsDefinedEnum (Type t) { return t is { IsEnum: true, IsGenericType: false, IsConstructedGenericType: false, IsTypeDefinition: true }; }
-
-        static void AllEnumTypes_CollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
-        {
-            if (e.Action is not NotifyCollectionChangedAction.Add and not NotifyCollectionChangedAction.Replace || e.NewItems is null)
-            {
-                return;
-            }
-
-            foreach (Type enumType in e.NewItems.OfType<Type> ())
-            {
-                if (enumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> () is not { } generatorAttribute)
-                {
-                    BoringEnumTypes.Add (enumType);
-
-                    continue;
-                }
-
-                ExtendedEnumTypeMappings.AddOrUpdate (
-                                               enumType,
-                                               CreateNewEnumData,
-                                               UpdateGeneratorAttributeProperty,
-                                               generatorAttribute);
-            }
-        }
-
-        static EnumData CreateNewEnumData (Type tEnum, GenerateEnumExtensionMethodsAttribute attr) { return new (tEnum, attr); }
-
-        static EnumData UpdateGeneratorAttributeProperty (Type tEnum, EnumData data, GenerateEnumExtensionMethodsAttribute attr)
-        {
-            data.GeneratorAttribute ??= attr;
-
-            return data;
-        }
-
-        static void EnumExtensionClasses_OnCollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
-        {
-            if (e.Action != NotifyCollectionChangedAction.Add)
-            {
-                return;
-            }
-
-            foreach (Type extensionClassType in e.NewItems!.OfType<Type> ())
-            {
-                if (extensionClassType.GetCustomAttribute (typeof (ExtensionsForEnumTypeAttribute<>), false) is not IExtensionsForEnumTypeAttributes
-                        {
-                            EnumType.IsEnum: true
-                        } extensionForAttribute)
-                {
-                    continue;
-                }
-
-                ExtendedEnumTypeMappings [extensionForAttribute.EnumType].ExtensionClass ??= extensionClassType;
-            }
-        }
-    }
-
-    public sealed record EnumData (
-        Type EnumType,
-        GenerateEnumExtensionMethodsAttribute? GeneratorAttribute = null,
-        Type? ExtensionClass = null,
-        IExtensionsForEnumTypeAttributes? ExtensionForEnumTypeAttribute = null)
-    {
-        public Type? ExtensionClass { get; set; } = ExtensionClass;
-
-        public IExtensionsForEnumTypeAttributes? ExtensionForEnumTypeAttribute { get; set; } = ExtensionForEnumTypeAttribute;
-        public GenerateEnumExtensionMethodsAttribute? GeneratorAttribute { get; set; } = GeneratorAttribute;
-    }
-}

+ 0 - 111
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/IndentedTextWriterExtensionsTests.cs

@@ -1,111 +0,0 @@
-using System.CodeDom.Compiler;
-using System.Text;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests;
-
-[TestFixture]
-[Category ("Extension Methods")]
-[TestOf (typeof (IndentedTextWriterExtensions))]
-[Parallelizable (ParallelScope.Children)]
-public class IndentedTextWriterExtensionsTests
-{
-    [Test]
-    public void Pop_Decrements ()
-    {
-        StringBuilder sb = new (0);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw);
-        writer.Indent = 5;
-
-        Assume.That (writer.Indent, Is.EqualTo (5));
-
-        writer.Pop ();
-        Assert.That (writer.Indent, Is.EqualTo (4));
-    }
-
-    [Test]
-    public void Pop_WithClosing_WritesAndPops ([Values ("}", ")", "]")] string scopeClosing)
-    {
-        StringBuilder sb = new (256);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-        writer.Indent = 5;
-        writer.Flush ();
-        Assume.That (writer.Indent, Is.EqualTo (5));
-        Assume.That (sb.Length, Is.Zero);
-
-        // Need to write something first, or IndentedTextWriter won't emit the indentation for the first call.
-        // So we'll write an empty line.
-        writer.WriteLine ();
-
-        for (ushort indentCount = 5; indentCount > 0;)
-        {
-            writer.Pop (scopeClosing);
-            Assert.That (writer.Indent, Is.EqualTo (--indentCount));
-        }
-
-        writer.Flush ();
-        var result = sb.ToString ();
-
-        Assert.That (
-                     result,
-                     Is.EqualTo (
-                                 $"""
-                                  
-                                          {scopeClosing}
-                                        {scopeClosing}
-                                      {scopeClosing}
-                                    {scopeClosing}
-                                  {scopeClosing}
-
-                                  """));
-    }
-
-    [Test]
-    public void Push_Increments ()
-    {
-        StringBuilder sb = new (32);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-
-        for (int indentCount = 0; indentCount < 5; indentCount++)
-        {
-            writer.Push ();
-            Assert.That (writer.Indent, Is.EqualTo (indentCount + 1));
-        }
-    }
-
-    [Test]
-    public void Push_WithOpening_WritesAndPushes ([Values ('{', '(', '[')] char scopeOpening)
-    {
-        StringBuilder sb = new (256);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-
-        for (ushort indentCount = 0; indentCount < 5;)
-        {
-            writer.Push ("Opening UninterestingEnum", scopeOpening);
-            Assert.That (writer.Indent, Is.EqualTo (++indentCount));
-        }
-
-        writer.Flush ();
-        var result = sb.ToString ();
-
-        Assert.That (
-                     result,
-                     Is.EqualTo (
-                                 $"""
-                                  Opening UninterestingEnum
-                                  {scopeOpening}
-                                    Opening UninterestingEnum
-                                    {scopeOpening}
-                                      Opening UninterestingEnum
-                                      {scopeOpening}
-                                        Opening UninterestingEnum
-                                        {scopeOpening}
-                                          Opening UninterestingEnum
-                                          {scopeOpening}
-
-                                  """));
-    }
-}

+ 0 - 47
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj

@@ -1,47 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <LangVersion>12</LangVersion>
-    <IsPackable>false</IsPackable>
-    <IsTestProject>true</IsTestProject>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <DebugType>portable</DebugType>
-    <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
-    <PackageReference Include="NUnit" Version="4.1.0" />
-    <PackageReference Include="NUnit.Analyzers" Version="4.2.0">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
-    </PackageReference>
-    <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-
-  <ItemGroup>
-    <Using Include="NUnit.Framework" />
-    <Using Include="Terminal.Gui" />
-    <Using Include="Terminal.Gui.Analyzers" />
-    <Using Include="Terminal.Gui.Analyzers.Internal" />
-  </ItemGroup>
-
-</Project>

+ 0 - 3
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj.DotSettings

@@ -1,3 +0,0 @@
-<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=generators_005Cenumextensions_005Cenumdefinitions_005Cwithgenerator/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=generators_005Cenumextensions_005Cenumdefinitions_005Cwithoutgenerator/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 0 - 20
Analyzers/Terminal.Gui.Analyzers.Internal/AccessibilityExtensions.cs

@@ -1,20 +0,0 @@
-using Microsoft.CodeAnalysis;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-internal static class AccessibilityExtensions
-{
-    internal static string ToCSharpString (this Accessibility value)
-    {
-        return value switch
-        {
-            Accessibility.Public => "public",
-            Accessibility.Internal => "internal",
-            Accessibility.Private => "private",
-            Accessibility.Protected => "protected",
-            Accessibility.ProtectedAndInternal => "private protected",
-            Accessibility.ProtectedOrInternal => "protected internal",
-            _ => string.Empty
-        };
-    }
-}

+ 0 - 8
Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Shipped.md

@@ -1,8 +0,0 @@
-## Release 1.0
-
-### New Rules
-
-Rule ID | Category | Severity | Notes
---------|----------|----------|--------------------
-TG0001  |   Usage  |  Error   | TG0001_GlobalNamespaceNotSupported
-TG0002  |   Usage  |  Error   | TG0002_UnderlyingTypeNotSupported

+ 0 - 4
Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Unshipped.md

@@ -1,4 +0,0 @@
-### New Rules
-
-Rule ID | Category | Severity | Notes
---------|----------|----------|--------------------

+ 0 - 117
Analyzers/Terminal.Gui.Analyzers.Internal/Analyzers/GenerateEnumExtensionMethodsAttributeAnalyzer.cs

@@ -1,117 +0,0 @@
-#define JETBRAINS_ANNOTATIONS
-using System.Collections.Immutable;
-using System.Linq;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.Diagnostics;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-namespace Terminal.Gui.Analyzers.Internal.Analyzers;
-
-/// <summary>
-///     Design-time analyzer that checks for proper use of <see cref="GenerateEnumExtensionMethodsAttribute"/>.
-/// </summary>
-[DiagnosticAnalyzer (LanguageNames.CSharp)]
-[UsedImplicitly]
-internal sealed class GenerateEnumExtensionMethodsAttributeAnalyzer : DiagnosticAnalyzer
-{
-    // ReSharper disable once InconsistentNaming
-    private static readonly DiagnosticDescriptor TG0001_GlobalNamespaceNotSupported = new (
-                                                                                           // ReSharper restore InconsistentNaming
-                                                                                           "TG0001",
-                                                                                           $"{nameof (GenerateEnumExtensionMethodsAttribute)} not supported on global enums",
-                                                                                           "{0} is in the global namespace, which is not supported by the source generator ({1}) used by {2}. Move the enum to a namespace or remove the attribute.",
-                                                                                           "Usage",
-                                                                                           DiagnosticSeverity.Error,
-                                                                                           true,
-                                                                                           null,
-                                                                                           null,
-                                                                                           WellKnownDiagnosticTags.NotConfigurable,
-                                                                                           WellKnownDiagnosticTags.Compiler);
-
-    // ReSharper disable once InconsistentNaming
-    private static readonly DiagnosticDescriptor TG0002_UnderlyingTypeNotSupported = new (
-                                                                                          "TG0002",
-                                                                                          $"{nameof (GenerateEnumExtensionMethodsAttribute)} not supported for this enum type",
-                                                                                          "{0} has an underlying type of {1}, which is not supported by the source generator ({2}) used by {3}. Only enums backed by int or uint are supported.",
-                                                                                          "Usage",
-                                                                                          DiagnosticSeverity.Error,
-                                                                                          true,
-                                                                                          null,
-                                                                                          null,
-                                                                                          WellKnownDiagnosticTags.NotConfigurable,
-                                                                                          WellKnownDiagnosticTags.Compiler);
-
-    /// <inheritdoc/>
-    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } =
-        [
-            TG0001_GlobalNamespaceNotSupported,
-            TG0002_UnderlyingTypeNotSupported
-        ];
-
-    /// <inheritdoc/>
-    public override void Initialize (AnalysisContext context)
-    {
-        context.ConfigureGeneratedCodeAnalysis (GeneratedCodeAnalysisFlags.None);
-        context.EnableConcurrentExecution ();
-
-        context.RegisterSyntaxNodeAction (CheckAttributeLocations, SyntaxKind.EnumDeclaration);
-
-        return;
-
-        static void CheckAttributeLocations (SyntaxNodeAnalysisContext analysisContext)
-        {
-            ISymbol? symbol = analysisContext.SemanticModel.GetDeclaredSymbol (analysisContext.Node) as INamedTypeSymbol;
-
-            if (symbol is not INamedTypeSymbol { EnumUnderlyingType: { } } enumSymbol)
-            {
-                // Somehow not even an enum declaration.
-                // Skip it.
-                return;
-            }
-
-            // Check attributes for those we care about and react accordingly.
-            foreach (AttributeData attributeData in enumSymbol.GetAttributes ())
-            {
-                if (attributeData.AttributeClass?.Name != nameof (GenerateEnumExtensionMethodsAttribute))
-                {
-                    // Just skip - not an interesting attribute.
-                    continue;
-                }
-
-                // Check enum underlying type for supported types (int and uint, currently)
-                // Report TG0002 if unsupported underlying type.
-                if (enumSymbol.EnumUnderlyingType is not { SpecialType: SpecialType.System_Int32 or SpecialType.System_UInt32 })
-                {
-                    analysisContext.ReportDiagnostic (
-                                                      Diagnostic.Create (
-                                                                         TG0002_UnderlyingTypeNotSupported,
-                                                                         enumSymbol.Locations.FirstOrDefault (),
-                                                                         enumSymbol.Name,
-                                                                         enumSymbol.EnumUnderlyingType.Name,
-                                                                         nameof (EnumExtensionMethodsIncrementalGenerator),
-                                                                         nameof (GenerateEnumExtensionMethodsAttribute)
-                                                                        )
-                                                     );
-                }
-
-                // Check enum namespace (only non-global supported, currently)
-                // Report TG0001 if in the global namespace.
-                if (enumSymbol.ContainingSymbol is not INamespaceSymbol { IsGlobalNamespace: false })
-                {
-                    analysisContext.ReportDiagnostic (
-                                                      Diagnostic.Create (
-                                                                         TG0001_GlobalNamespaceNotSupported,
-                                                                         enumSymbol.Locations.FirstOrDefault (),
-                                                                         enumSymbol.Name,
-                                                                         nameof (EnumExtensionMethodsIncrementalGenerator),
-                                                                         nameof (GenerateEnumExtensionMethodsAttribute)
-                                                                        )
-                                                     );
-                }
-            }
-        }
-    }
-}

+ 0 - 3
Analyzers/Terminal.Gui.Analyzers.Internal/ApiCompatExcludedAttributes.txt

@@ -1,3 +0,0 @@
-N:System.Runtime.CompilerServices
-N:System.Diagnostics.CodeAnalysis
-N:System.Numerics

+ 0 - 27
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/AssemblyExtendedEnumTypeAttribute.cs

@@ -1,27 +0,0 @@
-// ReSharper disable ClassNeverInstantiated.Global
-// ReSharper disable once RedundantNullableDirective
-#nullable enable
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>Assembly attribute declaring a known pairing of an <see langword="enum" /> type to an extension class.</summary>
-/// <remarks>This attribute should only be written by internal source generators for Terminal.Gui. No other usage of any kind is supported.</remarks>
-[System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple = true)]
-internal sealed class AssemblyExtendedEnumTypeAttribute : System.Attribute
-{
-    /// <summary>Creates a new instance of <see cref="AssemblyExtendedEnumTypeAttribute" /> from the provided parameters.</summary>
-    /// <param name="enumType">The <see cref="System.Type" /> of an <see langword="enum" /> decorated with a <see cref="GenerateEnumExtensionMethodsAttribute" />.</param>
-    /// <param name="extensionClass">The <see cref="System.Type" /> of the <see langword="class" /> decorated with an <see cref="ExtensionsForEnumTypeAttribute{TEnum}" /> referring to the same type as <paramref name="enumType" />.</param>
-    public AssemblyExtendedEnumTypeAttribute (System.Type enumType, System.Type extensionClass)
-    {
-        EnumType = enumType;
-        ExtensionClass = extensionClass;
-    }
-    ///<summary>An <see langword="enum" /> type that has been extended by Terminal.Gui source generators.</summary>
-    public System.Type EnumType { get; init; }
-    ///<summary>A class containing extension methods for <see cref="EnumType"/>.</summary>
-    public System.Type ExtensionClass { get; init; }
-
-    /// <inheritdoc />
-    public override string ToString () => $"{EnumType.Name},{ExtensionClass.Name}";
-}

+ 0 - 37
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/ExtensionsForEnumTypeAttribute.cs

@@ -1,37 +0,0 @@
-// ReSharper disable RedundantNameQualifier
-// ReSharper disable RedundantNullableDirective
-// ReSharper disable UnusedType.Global
-#pragma warning disable IDE0001, IDE0240
-#nullable enable
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Attribute written by the source generator for <see langword="enum" /> extension classes, for easier analysis and reflection.
-/// </summary>
-/// <remarks>
-///     Properties are just convenient shortcuts to properties of <typeparamref name="TEnum"/>.
-/// </remarks>
-[System.AttributeUsage (System.AttributeTargets.Class | System.AttributeTargets.Interface)]
-internal sealed class ExtensionsForEnumTypeAttribute<TEnum>: System.Attribute, IExtensionsForEnumTypeAttributes where TEnum : struct, System.Enum
-{
-    /// <summary>
-    ///     The namespace-qualified name of <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumFullName => EnumType.FullName!;
-
-    /// <summary>
-    ///     The unqualified name of <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumName => EnumType.Name;
-
-    /// <summary>
-    ///     The namespace containing <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumNamespace => EnumType.Namespace!;
-
-    /// <summary>
-    ///     The <see cref="System.Type"/> given by <see langword="typeof"/>(<typeparamref name="TEnum"/>).
-    /// </summary>
-    public System.Type EnumType => typeof (TEnum);
-}

+ 0 - 110
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/GenerateEnumExtensionMethodsAttribute.cs

@@ -1,110 +0,0 @@
-// ReSharper disable RedundantNullableDirective
-// ReSharper disable RedundantUsingDirective
-// ReSharper disable ClassNeverInstantiated.Global
-
-#nullable enable
-using System;
-using Attribute = System.Attribute;
-using AttributeUsageAttribute = System.AttributeUsageAttribute;
-using AttributeTargets = System.AttributeTargets;
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Used to enable source generation of a common set of extension methods for enum types.
-/// </summary>
-[AttributeUsage (AttributeTargets.Enum)]
-internal sealed class GenerateEnumExtensionMethodsAttribute : Attribute
-{
-    /// <summary>
-    ///     The name of the generated static class.
-    /// </summary>
-    /// <remarks>
-    ///     If unspecified, null, empty, or only whitespace, defaults to the name of the enum plus "Extensions".<br/>
-    ///     No other validation is performed, so illegal values will simply result in compiler errors.
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public string? ClassName { get; set; }
-
-    /// <summary>
-    ///     The namespace in which to place the generated static class containing the extension methods.
-    /// </summary>
-    /// <remarks>
-    ///     If unspecified, null, empty, or only whitespace, defaults to the namespace of the enum.<br/>
-    ///     No other validation is performed, so illegal values will simply result in compiler errors.
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public string? ClassNamespace { get; set; }
-
-    /// <summary>
-    ///     Whether to generate a fast, zero-allocation, non-boxing, and reflection-free alternative to the built-in
-    ///     <see cref="Enum.HasFlag"/> method.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         Default: false
-    ///     </para>
-    ///     <para>
-    ///         If the enum is not decorated with <see cref="FlagsAttribute"/>, this option has no effect.
-    ///     </para>
-    ///     <para>
-    ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-    ///         with the same value will be skipped.
-    ///     </para>
-    ///     <para>
-    ///         Overloads taking the enum type itself as well as the underlying type of the enum will be generated, enabling
-    ///         avoidance of implicit or explicit cast overhead.
-    ///     </para>
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public bool FastHasFlags { get; set; }
-
-    /// <summary>
-    ///     Whether to generate a fast, zero-allocation, and reflection-free alternative to the built-in
-    ///     <see cref="Enum.IsDefined"/> method,
-    ///     using a switch expression as a hard-coded reverse mapping of numeric values to explicitly-named members.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         Default: true
-    ///     </para>
-    ///     <para>
-    ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-    ///         with the same value will be skipped.
-    ///     </para>
-    ///     <para>
-    ///         As with <see cref="Enum.IsDefined"/> the source generator only considers explicitly-named members.<br/>
-    ///         Generation of values which represent valid bitwise combinations of members of enums decorated with
-    ///         <see cref="FlagsAttribute"/> is not affected by this property.
-    ///     </para>
-    /// </remarks>
-    public bool FastIsDefined { get; init; } = true;
-
-    /// <summary>
-    ///     Gets a <see langword="bool"/> value indicating if this <see cref="GenerateEnumExtensionMethodsAttribute"/> instance
-    ///     contains default values only. See <see href="#remarks">remarks</see> of this method or documentation on properties of this type for details.
-    /// </summary>
-    /// <returns>
-    ///     A <see langword="bool"/> value indicating if all property values are default for this
-    ///     <see cref="GenerateEnumExtensionMethodsAttribute"/> instance.
-    /// </returns>
-    /// <remarks>
-    ///     Default values that will result in a <see langword="true"/> return value are:<br/>
-    ///     <see cref="FastIsDefined"/> &amp;&amp; !<see cref="FastHasFlags"/> &amp;&amp; <see cref="ClassName"/>
-    ///     <see langword="is"/> <see langword="null"/> &amp;&amp; <see cref="ClassNamespace"/> <see langword="is"/>
-    ///     <see langword="null"/>
-    /// </remarks>
-    public override bool IsDefaultAttribute ()
-    {
-        return FastIsDefined
-               && !FastHasFlags
-               && ClassName is null
-               && ClassNamespace is null;
-    }
-}

+ 0 - 14
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/IExtensionsForEnumTypeAttribute.cs

@@ -1,14 +0,0 @@
-// ReSharper disable All
-
-using System;
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Interface to simplify general enumeration of constructed generic types for
-///     <see cref="ExtensionsForEnumTypeAttribute{TEnum}"/>
-/// </summary>
-internal interface IExtensionsForEnumTypeAttributes
-{
-    Type EnumType { get; }
-}

+ 0 - 11
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IEqualityOperators.cs

@@ -1,11 +0,0 @@
-// ReSharper disable once CheckNamespace
-namespace System.Numerics;
-/// <summary>
-/// Included for compatibility with .net7+, but has no members.
-/// Thus it cannot be explicitly used in generator code.
-/// Use it for static analysis only.
-/// </summary>
-/// <typeparam name="T">The left operand type.</typeparam>
-/// <typeparam name="T1">The right operand type.</typeparam>
-/// <typeparam name="T2">The return type.</typeparam>
-internal interface IEqualityOperators<T, T1, T2>;

+ 0 - 6
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IntrinsicAttribute.cs

@@ -1,6 +0,0 @@
-namespace System.Runtime.CompilerServices;
-
-[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
-public sealed class IntrinsicAttribute : Attribute
-{
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/NumericExtensions.cs

@@ -1,43 +0,0 @@
-// ReSharper disable once CheckNamespace
-namespace Terminal.Gui.Analyzers.Internal.Compatibility;
-
-/// <summary>
-///     Extension methods for <see langword="int"/> and <see langword="uint"/> types.
-/// </summary>
-/// <remarks>
-///     This is mostly just for backward compatibility with netstandard2.0.
-/// </remarks>
-public static class NumericExtensions
-{
-    /// <summary>
-    ///     Gets the population count (number of bits set to 1) of this 32-bit value.
-    /// </summary>
-    /// <param name="value">The value to get the population count of.</param>
-    /// <remarks>
-    ///     The algorithm is the well-known SWAR (SIMD Within A Register) method for population count.<br/>
-    ///     Included for hardware- and runtime- agnostic support for the equivalent of the x86 popcnt instruction, since
-    ///     System.Numerics.Intrinsics isn't available in netstandard2.0.<br/>
-    ///     It performs the operation simultaneously on 4 bytes at a time, rather than the naive method of testing all 32 bits
-    ///     individually.<br/>
-    ///     Most compilers can recognize this and turn it into a single platform-specific instruction, when available.
-    /// </remarks>
-    /// <returns>
-    ///     An unsigned 32-bit integer value containing the population count of <paramref name="value"/>.
-    /// </returns>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static uint GetPopCount (this uint value)
-    {
-        unchecked
-        {
-            value -= (value >> 1) & 0x55555555;
-            value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
-            value = (value + (value >> 4)) & 0x0F0F0F0F;
-
-            return (value * 0x01010101) >> 24;
-        }
-    }
-
-    /// <inheritdoc cref="GetPopCount(uint)"/>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static uint GetPopCount (this int value) { return GetPopCount (Unsafe.As<int, uint> (ref value)); }
-}

+ 0 - 204
Analyzers/Terminal.Gui.Analyzers.Internal/Constants/Strings.cs

@@ -1,204 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-
-using System;
-using System.CodeDom.Compiler;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Constants;
-
-/// <summary>String constants for frequently-used boilerplate.</summary>
-/// <remarks>These are for performance, instead of using Roslyn to build it all during execution of analyzers.</remarks>
-internal static class Strings
-{
-    internal const string AnalyzersAttributesNamespace = $"{InternalAnalyzersNamespace}.Attributes";
-
-    internal const string AssemblyExtendedEnumTypeAttributeFullName = $"{AnalyzersAttributesNamespace}.{nameof (AssemblyExtendedEnumTypeAttribute)}";
-
-    internal const string DefaultTypeNameSuffix = "Extensions";
-
-    internal const string FallbackClassNamespace = $"{TerminalGuiRootNamespace}";
-
-    internal const string InternalAnalyzersNamespace = $"{AnalyzersRootNamespace}.Internal";
-
-    internal const string TerminalGuiRootNamespace = "Terminal.Gui";
-
-    private const string AnalyzersRootNamespace = $"{TerminalGuiRootNamespace}.Analyzers";
-    private const string NetStandard20CompatibilityNamespace = $"{InternalAnalyzersNamespace}.Compatibility";
-
-    /// <summary>
-    ///     Names of dotnet namespaces and types. Included as compile-time constants to avoid unnecessary work for the Roslyn
-    ///     source generators.
-    /// </summary>
-    /// <remarks>Implemented as nested static types because XmlDoc doesn't work on namespaces.</remarks>
-    internal static class DotnetNames
-    {
-        /// <summary>Fully-qualified attribute type names. Specific applications (uses) are in <see cref="Applications"/>.</summary>
-        internal static class Attributes
-        {
-            /// <inheritdoc cref="CompilerGeneratedAttribute"/>
-            internal const string CompilerGenerated = $"{Namespaces.System_Runtime_CompilerServices}.{nameof (CompilerGeneratedAttribute)}";
-
-            /// <inheritdoc cref="DebuggerNonUserCodeAttribute"/>
-            internal const string DebuggerNonUserCode = $"{Namespaces.System_Diagnostics}.{nameof (DebuggerNonUserCodeAttribute)}";
-
-            /// <inheritdoc cref="ExcludeFromCodeCoverageAttribute"/>
-            internal const string ExcludeFromCodeCoverage = $"{Namespaces.System_Diagnostics_CodeAnalysis}.{nameof (ExcludeFromCodeCoverageAttribute)}";
-
-            internal const string Flags = $"{Namespaces.SystemNs}.{nameof (FlagsAttribute)}";
-
-            internal const string GeneratedCode = $"{Namespaces.System_CodeDom_Compiler}.{nameof (GeneratedCodeAttribute)}";
-
-            /// <inheritdoc cref="MethodImplOptions.AggressiveInlining"/>
-            /// <remarks>Use of this attribute should be carefully evaluated.</remarks>
-            internal const string MethodImpl = $"{Namespaces.System_Runtime_CompilerServices}.{nameof (MethodImplAttribute)}";
-
-            /// <summary>Attributes formatted for use in code, including square brackets.</summary>
-            internal static class Applications
-            {
-                // ReSharper disable MemberHidesStaticFromOuterClass
-                internal const string Flags = $"[{Attributes.Flags}]";
-
-                /// <inheritdoc cref="System.CodeDom.Compiler.GeneratedCodeAttribute"/>
-                internal const string GeneratedCode = $"""[{Attributes.GeneratedCode}("{InternalAnalyzersNamespace}","1.0")]""";
-
-                /// <inheritdoc cref="MethodImplOptions.AggressiveInlining"/>
-                /// <remarks>Use of this attribute should be carefully evaluated.</remarks>
-                internal const string AggressiveInlining = $"[{MethodImpl}({Types.MethodImplOptions}.{nameof (MethodImplOptions.AggressiveInlining)})]";
-
-                /// <inheritdoc cref="DebuggerNonUserCodeAttribute"/>
-                internal const string DebuggerNonUserCode = $"[{Attributes.DebuggerNonUserCode}]";
-
-                /// <inheritdoc cref="CompilerGeneratedAttribute"/>
-                internal const string CompilerGenerated = $"[{Attributes.CompilerGenerated}]";
-
-                /// <inheritdoc cref="ExcludeFromCodeCoverageAttribute"/>
-                internal const string ExcludeFromCodeCoverage = $"[{Attributes.ExcludeFromCodeCoverage}]";
-
-                // ReSharper restore MemberHidesStaticFromOuterClass
-            }
-        }
-
-        /// <summary>Names of dotnet namespaces.</summary>
-        internal static class Namespaces
-        {
-            internal const string SystemNs = nameof (System);
-            // ReSharper disable InconsistentNaming
-            internal const string System_CodeDom = $"{SystemNs}.{nameof (System.CodeDom)}";
-            internal const string System_CodeDom_Compiler = $"{System_CodeDom}.{nameof (System.CodeDom.Compiler)}";
-            internal const string System_ComponentModel = $"{SystemNs}.{nameof (System.ComponentModel)}";
-            internal const string System_Diagnostics = $"{SystemNs}.{nameof (System.Diagnostics)}";
-            internal const string System_Diagnostics_CodeAnalysis = $"{System_Diagnostics}.{nameof (System.Diagnostics.CodeAnalysis)}";
-            internal const string System_Numerics = $"{SystemNs}.{nameof (System.Numerics)}";
-            internal const string System_Runtime = $"{SystemNs}.{nameof (System.Runtime)}";
-            internal const string System_Runtime_CompilerServices = $"{System_Runtime}.{nameof (System.Runtime.CompilerServices)}";
-            // ReSharper restore InconsistentNaming
-        }
-
-        internal static class Types
-        {
-            internal const string Attribute = $"{Namespaces.SystemNs}.{nameof (System.Attribute)}";
-            internal const string AttributeTargets = $"{Namespaces.SystemNs}.{nameof (System.AttributeTargets)}";
-            internal const string AttributeUsageAttribute = $"{Namespaces.SystemNs}.{nameof (System.AttributeUsageAttribute)}";
-
-            internal const string MethodImplOptions =
-                $"{Namespaces.System_Runtime_CompilerServices}.{nameof (System.Runtime.CompilerServices.MethodImplOptions)}";
-        }
-    }
-
-    internal static class Templates
-    {
-        internal const string AutoGeneratedCommentBlock = $"""
-                                                           //------------------------------------------------------------------------------
-                                                           // <auto-generated>
-                                                           //   This file and the code it contains was generated by a source generator in
-                                                           //   the {InternalAnalyzersNamespace} library.
-                                                           //
-                                                           //   Modifications to this file are not supported and will be lost when
-                                                           //   source generation is triggered, either implicitly or explicitly.
-                                                           // </auto-generated>
-                                                           //------------------------------------------------------------------------------
-                                                           """;
-
-        /// <summary>
-        ///     A set of explicit type aliases to work around Terminal.Gui having name collisions with types like
-        ///     <see cref="System.Attribute"/>.
-        /// </summary>
-        internal const string DotnetExplicitTypeAliasUsingDirectives = $"""
-                                                                        using Attribute = {DotnetNames.Types.Attribute};
-                                                                        using AttributeUsageAttribute = {DotnetNames.Types.AttributeUsageAttribute};
-                                                                        using GeneratedCode = {DotnetNames.Attributes.GeneratedCode};
-                                                                        """;
-
-        /// <summary>Using directives for common namespaces in generated code.</summary>
-        internal const string DotnetNamespaceUsingDirectives = $"""
-                                                                using {DotnetNames.Namespaces.SystemNs};
-                                                                using {DotnetNames.Namespaces.System_CodeDom};
-                                                                using {DotnetNames.Namespaces.System_CodeDom_Compiler};
-                                                                using {DotnetNames.Namespaces.System_ComponentModel};
-                                                                using {DotnetNames.Namespaces.System_Numerics};
-                                                                using {DotnetNames.Namespaces.System_Runtime};
-                                                                using {DotnetNames.Namespaces.System_Runtime_CompilerServices};
-                                                                """;
-
-        /// <summary>
-        ///     A set of empty namespaces that MAY be referenced in generated code, especially in using statements,
-        ///     which are always included to avoid additional complexity due to conditional compilation.
-        /// </summary>
-        internal const string DummyNamespaceDeclarations = $$"""
-                                                             // These are dummy declarations to avoid complexity with conditional compilation.
-                                                             #pragma warning disable IDE0079 // Remove unnecessary suppression
-                                                             #pragma warning disable RCS1259 // Remove empty syntax
-                                                             namespace {{TerminalGuiRootNamespace}} { }
-                                                             namespace {{AnalyzersRootNamespace}} { }
-                                                             namespace {{InternalAnalyzersNamespace}} { }
-                                                             namespace {{NetStandard20CompatibilityNamespace}} { }
-                                                             namespace {{AnalyzersAttributesNamespace}} { }
-                                                             #pragma warning restore RCS1259 // Remove empty syntax
-                                                             #pragma warning restore IDE0079 // Remove unnecessary suppression
-                                                             """;
-
-        internal const string StandardHeader = $"""
-                                                {AutoGeneratedCommentBlock}
-                                                // ReSharper disable RedundantUsingDirective
-                                                // ReSharper disable once RedundantNullableDirective
-                                                {NullableContextDirective}
-
-                                                {StandardUsingDirectivesText}
-                                                """;
-
-        /// <summary>
-        ///     Standard set of using directives for generated extension method class files.
-        ///     Not all are always needed, but all are included so we don't have to worry about it.
-        /// </summary>
-        internal const string StandardUsingDirectivesText = $"""
-                                                             {DotnetNamespaceUsingDirectives}
-                                                             {DotnetExplicitTypeAliasUsingDirectives}
-                                                             using {TerminalGuiRootNamespace};
-                                                             using {AnalyzersRootNamespace};
-                                                             using {InternalAnalyzersNamespace};
-                                                             using {AnalyzersAttributesNamespace};
-                                                             using {NetStandard20CompatibilityNamespace};
-                                                             """;
-
-        internal const string AttributesForGeneratedInterfaces = $"""
-                                                                  {DotnetNames.Attributes.Applications.GeneratedCode}
-                                                                  {DotnetNames.Attributes.Applications.CompilerGenerated}
-                                                                  """;
-
-        internal const string AttributesForGeneratedTypes = $"""
-                                                             {DotnetNames.Attributes.Applications.GeneratedCode}
-                                                             {DotnetNames.Attributes.Applications.CompilerGenerated}
-                                                             {DotnetNames.Attributes.Applications.DebuggerNonUserCode}
-                                                             {DotnetNames.Attributes.Applications.ExcludeFromCodeCoverage}
-                                                             """;
-
-        /// <summary>
-        ///     Preprocessor directive to enable nullability context for generated code.<br/>
-        ///     This should always be emitted, as it applies only to generated code.<br/>
-        ///     As such, generated code MUST be properly annotated.
-        /// </summary>
-        internal const string NullableContextDirective = "#nullable enable";
-    }
-}

+ 0 - 235
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/CodeWriter.cs

@@ -1,235 +0,0 @@
-using System;
-using System.CodeDom.Compiler;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Text;
-using Microsoft.CodeAnalysis.Text;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     The class responsible for turning an <see cref="EnumExtensionMethodsGenerationInfo"/>
-///     into actual C# code.
-/// </summary>
-/// <remarks>Try to use this type as infrequently as possible.</remarks>
-/// <param name="metadata">
-///     A reference to an <see cref="IGeneratedTypeMetadata{TSelf}"/> which will be used
-///     to generate the extension class code. The object will not be validated,
-///     so it is critical that it be correct and remain unchanged while in use
-///     by an instance of this class. Behavior if those rules are not followed
-///     is undefined.
-/// </param>
-[SuppressMessage ("CodeQuality", "IDE0079", Justification = "Suppressions here are intentional and the warnings they disable are just noise.")]
-internal sealed class CodeWriter (in EnumExtensionMethodsGenerationInfo metadata) : IStandardCSharpCodeGenerator<EnumExtensionMethodsGenerationInfo>
-{
-    // Using the null suppression operator here because this will always be
-    // initialized to non-null before a reference to it is returned.
-    private SourceText _sourceText = null!;
-
-    /// <inheritdoc/>
-    public EnumExtensionMethodsGenerationInfo Metadata
-    {
-        [MethodImpl (MethodImplOptions.AggressiveInlining)]
-        [return: NotNull]
-        get;
-        [param: DisallowNull]
-        set;
-    } = metadata;
-
-    /// <inheritdoc/>
-    public ref readonly SourceText GenerateSourceText (Encoding? encoding = null)
-    {
-        encoding ??= Encoding.UTF8;
-        _sourceText = SourceText.From (GetFullSourceText (), encoding);
-
-        return ref _sourceText;
-    }
-
-    /// <summary>
-    ///     Gets the using directive for the namespace containing the enum,
-    ///     if different from the extension class namespace, or an empty string, if they are the same.
-    /// </summary>
-    private string EnumNamespaceUsingDirective => Metadata.TargetTypeNamespace != Metadata.GeneratedTypeNamespace
-
-                                                      // ReSharper disable once HeapView.ObjectAllocation
-                                                      ? $"using {Metadata.TargetTypeNamespace};"
-                                                      : string.Empty;
-
-    private string EnumTypeKeyword => Metadata.EnumBackingTypeCode switch
-                                      {
-                                          TypeCode.Int32 => "int",
-                                          TypeCode.UInt32 => "uint",
-                                          _ => string.Empty
-                                      };
-
-    /// <summary>Gets the class declaration line.</summary>
-    private string ExtensionClassDeclarationLine => $"public static partial class {Metadata.GeneratedTypeName}";
-
-    // ReSharper disable once HeapView.ObjectAllocation
-    /// <summary>Gets the XmlDoc for the extension class declaration.</summary>
-    private string ExtensionClassDeclarationXmlDoc =>
-        $"/// <summary>Extension methods for the <see cref=\"{Metadata.TargetTypeFullName}\"/> <see langword=\"enum\" /> type.</summary>";
-
-    // ReSharper disable once HeapView.ObjectAllocation
-    /// <summary>Gets the extension class file-scoped namespace directive.</summary>
-    private string ExtensionClassNamespaceDirective => $"namespace {Metadata.GeneratedTypeNamespace};";
-
-    /// <summary>
-    ///     An attribute to decorate the extension class with for easy mapping back to the target enum type, for reflection and
-    ///     analysis.
-    /// </summary>
-    private string ExtensionsForTypeAttributeLine => $"[ExtensionsForEnumType<{Metadata.TargetTypeFullName}>]";
-
-    /// <summary>
-    ///     Creates the code for the FastHasFlags method.
-    /// </summary>
-    /// <remarks>
-    ///     Since the generator already only writes code for enums backed by <see langword="int"/> and <see langword="uint"/>,
-    ///     this method is safe, as we'll always be using a DWORD.
-    /// </remarks>
-    /// <param name="w">An instance of an <see cref="IndentedTextWriter"/> to write to.</param>
-    private void GetFastHasFlagsMethods (IndentedTextWriter w)
-    {
-        // The version taking the same enum type as the check value.
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified flags are set in the current value of this <see cref=\"{Metadata.TargetTypeFullName}\" />.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-
-        w.WriteLine (
-                     $"/// <returns>True, if all flags present in <paramref name=\"checkFlags\" /> are also present in the current value of the <see cref=\"{Metadata.TargetTypeFullName}\" />.<br />Otherwise false.</returns>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastHasFlags (this {Metadata.TargetTypeFullName} e, {Metadata.TargetTypeFullName} checkFlags)");
-        w.WriteLine ($"ref uint enumCurrentValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref e);");
-        w.WriteLine ($"ref uint checkFlagsValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref checkFlags);");
-        w.WriteLine ("return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;");
-        w.Pop ();
-
-        // The version taking the underlying type of the enum as the check value.
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified mask bits are set in the current value of this <see cref=\"{Metadata.TargetTypeFullName}\" />.</summary>");
-
-        w.WriteLine (
-                     $"/// <param name=\"e\">The <see cref=\"{Metadata.TargetTypeFullName}\" /> value to check against the <paramref name=\"mask\" /> value.</param>");
-        w.WriteLine ("/// <param name=\"mask\">A mask to apply to the current value.</param>");
-
-        w.WriteLine (
-                     $"/// <returns>True, if all bits set to 1 in the mask are also set to 1 in the current value of the <see cref=\"{Metadata.TargetTypeFullName}\" />.<br />Otherwise false.</returns>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastHasFlags (this {Metadata.TargetTypeFullName} e, {EnumTypeKeyword} mask)");
-        w.WriteLine ($"ref {EnumTypeKeyword} enumCurrentValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},{EnumTypeKeyword}> (ref e);");
-        w.WriteLine ("return (enumCurrentValueRef & mask) == mask;");
-        w.Pop ();
-    }
-
-    /// <summary>
-    ///     Creates the code for the FastIsDefined method.
-    /// </summary>
-    [SuppressMessage ("ReSharper", "SwitchStatementHandlesSomeKnownEnumValuesWithDefault", Justification = "Only need to handle int and uint.")]
-    [SuppressMessage ("ReSharper", "SwitchStatementMissingSomeEnumCasesNoDefault", Justification = "Only need to handle int and uint.")]
-    private void GetFastIsDefinedMethod (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified <see langword=\"{EnumTypeKeyword}\" /> value is explicitly defined as a named value of the <see cref=\"{Metadata.TargetTypeFullName}\" /> <see langword=\"enum\" /> type.</summary>");
-
-        w.WriteLine (
-                     "/// <remarks>Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are not explicitly named will return false.</remarks>");
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastIsDefined (this {Metadata.TargetTypeFullName} e, {EnumTypeKeyword} value)");
-        w.Push ("return value switch");
-
-        switch (Metadata.EnumBackingTypeCode)
-        {
-            case TypeCode.Int32:
-                foreach (int definedValue in Metadata._intMembers)
-                {
-                    w.WriteLine ($"{definedValue:D} => true,");
-                }
-
-                break;
-            case TypeCode.UInt32:
-                foreach (uint definedValue in Metadata._uIntMembers)
-                {
-                    w.WriteLine ($"{definedValue:D} => true,");
-                }
-
-                break;
-        }
-
-        w.WriteLine ("_ => false");
-
-        w.Pop ("};");
-        w.Pop ();
-    }
-
-    private string GetFullSourceText ()
-    {
-        StringBuilder sb = new (
-                                $"""
-                                 {Strings.Templates.StandardHeader}
-
-                                 [assembly: {Strings.AssemblyExtendedEnumTypeAttributeFullName} (typeof({Metadata.TargetTypeFullName}), typeof({Metadata.GeneratedTypeFullName}))]
-
-                                 {EnumNamespaceUsingDirective}
-                                 {ExtensionClassNamespaceDirective}
-                                 {ExtensionClassDeclarationXmlDoc}
-                                 {Strings.Templates.AttributesForGeneratedTypes}
-                                 {ExtensionsForTypeAttributeLine}
-                                 {ExtensionClassDeclarationLine}
-                                 
-                                 """,
-                                4096);
-
-        using IndentedTextWriter w = new (new StringWriter (sb));
-        w.Push ();
-
-        GetNamedValuesToInt32Method (w);
-        GetNamedValuesToUInt32Method (w);
-
-        if (Metadata.GenerateFastIsDefined)
-        {
-            GetFastIsDefinedMethod (w);
-        }
-
-        if (Metadata.GenerateFastHasFlags)
-        {
-            GetFastHasFlagsMethods (w);
-        }
-
-        w.Pop ();
-
-        w.Flush ();
-
-        return sb.ToString ();
-    }
-
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    private void GetNamedValuesToInt32Method (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Directly converts this <see cref=\"{Metadata.TargetTypeFullName}\" /> value to an <see langword=\"int\" /> value with the same binary representation.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-        w.Push ($"{Metadata.Accessibility.ToCSharpString ()} static int AsInt32 (this {Metadata.TargetTypeFullName} e)");
-        w.WriteLine ($"return Unsafe.As<{Metadata.TargetTypeFullName},int> (ref e);");
-        w.Pop ();
-    }
-
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    private void GetNamedValuesToUInt32Method (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Directly converts this <see cref=\"{Metadata.TargetTypeFullName}\" /> value to a <see langword=\"uint\" /> value with the same binary representation.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-        w.Push ($"{Metadata.Accessibility.ToCSharpString ()} static uint AsUInt32 (this {Metadata.TargetTypeFullName} e)");
-        w.WriteLine ($"return Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref e);");
-        w.Pop ();
-    }
-}

+ 0 - 443
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsGenerationInfo.cs

@@ -1,443 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Threading;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     Type containing the information necessary to generate code according to the declared attribute values,
-///     as well as the actual code to create the corresponding source code text, to be used in the
-///     source generator pipeline.
-/// </summary>
-/// <remarks>
-///     Minimal validation is performed by this type.<br/>
-///     Errors in analyzed source code will result in generation failure or broken output.<br/>
-///     This type is not intended for use outside of Terminal.Gui library development.
-/// </remarks>
-internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetadata<EnumExtensionMethodsGenerationInfo>,
-                                                            IEqualityOperators<EnumExtensionMethodsGenerationInfo, EnumExtensionMethodsGenerationInfo, bool>
-{
-    private const int ExplicitFastHasFlagsMask  = 0b_0100;
-    private const int ExplicitFastIsDefinedMask = 0b_1000;
-    private const int ExplicitNameMask          = 0b_0010;
-    private const int ExplicitNamespaceMask     = 0b_0001;
-    private const string GeneratorAttributeFullyQualifiedName = $"{GeneratorAttributeNamespace}.{GeneratorAttributeName}";
-    private const string GeneratorAttributeName = nameof (GenerateEnumExtensionMethodsAttribute);
-    private const string GeneratorAttributeNamespace = Strings.AnalyzersAttributesNamespace;
-
-    /// <summary>
-    ///     Type containing the information necessary to generate code according to the declared attribute values,
-    ///     as well as the actual code to create the corresponding source code text, to be used in the
-    ///     source generator pipeline.
-    /// </summary>
-    /// <param name="enumNamespace">The fully-qualified namespace of the enum type, without assembly name.</param>
-    /// <param name="enumTypeName">
-    ///     The name of the enum type, as would be given by <see langword="nameof"/> on the enum's type
-    ///     declaration.
-    /// </param>
-    /// <param name="typeNamespace">
-    ///     The fully-qualified namespace in which to place the generated code, without assembly name. If omitted or explicitly
-    ///     null, uses the value provided in <paramref name="enumNamespace"/>.
-    /// </param>
-    /// <param name="typeName">
-    ///     The name of the generated class. If omitted or explicitly null, appends "Extensions" to the value of
-    ///     <paramref name="enumTypeName"/>.
-    /// </param>
-    /// <param name="enumBackingTypeCode">The backing type of the enum. Defaults to <see cref="int"/>.</param>
-    /// <param name="generateFastHasFlags">
-    ///     Whether to generate a fast HasFlag alternative. (Default: true) Ignored if the enum does not also have
-    ///     <see cref="FlagsAttribute"/>.
-    /// </param>
-    /// <param name="generateFastIsDefined">Whether to generate a fast IsDefined alternative. (Default: true)</param>
-    /// <remarks>
-    ///     Minimal validation is performed by this type.<br/>
-    ///     Errors in analyzed source code will result in generation failure or broken output.<br/>
-    ///     This type is not intended for use outside of Terminal.Gui library development.
-    /// </remarks>
-    public EnumExtensionMethodsGenerationInfo (
-        string enumNamespace,
-        string enumTypeName,
-        string? typeNamespace = null,
-        string? typeName = null,
-        TypeCode enumBackingTypeCode = TypeCode.Int32,
-        bool generateFastHasFlags = true,
-        bool generateFastIsDefined = true
-    ) : this (enumNamespace, enumTypeName, enumBackingTypeCode)
-    {
-        GeneratedTypeNamespace = typeNamespace ?? enumNamespace;
-        GeneratedTypeName = typeName ?? string.Concat (enumTypeName, Strings.DefaultTypeNameSuffix);
-        GenerateFastHasFlags = generateFastHasFlags;
-        GenerateFastIsDefined = generateFastIsDefined;
-    }
-
-    public EnumExtensionMethodsGenerationInfo (string enumNamespace, string enumTypeName, TypeCode enumBackingType)
-    {
-        // Interning these since they're rather unlikely to change.
-        string enumInternedNamespace = string.Intern (enumNamespace);
-        string enumInternedName = string.Intern (enumTypeName);
-        TargetTypeNamespace = enumInternedNamespace;
-        TargetTypeName = enumInternedName;
-        EnumBackingTypeCode = enumBackingType;
-    }
-
-    [AccessedThroughProperty (nameof (EnumBackingTypeCode))]
-    private readonly TypeCode _enumBackingTypeCode;
-
-    [AccessedThroughProperty (nameof (GeneratedTypeName))]
-    private string? _generatedTypeName;
-
-    [AccessedThroughProperty (nameof (GeneratedTypeNamespace))]
-    private string? _generatedTypeNamespace;
-
-    private BitVector32 _discoveredProperties = new (0);
-
-    /// <summary>The name of the extension class.</summary>
-    public string? GeneratedTypeName
-    {
-        get => _generatedTypeName ?? string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-        set => _generatedTypeName = value ?? string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-    }
-
-    /// <summary>The namespace for the extension class.</summary>
-    /// <remarks>
-    ///     Value is not validated by the set accessor.<br/>
-    ///     Get accessor will never return null and is thus marked [NotNull] for static analysis, even though the property is
-    ///     declared as a nullable <see langword="string?"/>.<br/>If the backing field for this property is null, the get
-    ///     accessor will return <see cref="TargetTypeNamespace"/> instead.
-    /// </remarks>
-    public string? GeneratedTypeNamespace
-    {
-        get => _generatedTypeNamespace ?? TargetTypeNamespace;
-        set => _generatedTypeNamespace = value ?? TargetTypeNamespace;
-    }
-
-    /// <inheritdoc/>
-    public string TargetTypeFullName => string.Concat (TargetTypeNamespace, ".", TargetTypeName);
-
-    /// <inheritdoc/>
-    public Accessibility Accessibility
-    {
-        get;
-        [UsedImplicitly]
-        internal set;
-    } = Accessibility.Public;
-
-    /// <inheritdoc/>
-    public TypeKind TypeKind => TypeKind.Class;
-
-    /// <inheritdoc/>
-    public bool IsRecord => false;
-
-    /// <inheritdoc/>
-    public bool IsClass => true;
-
-    /// <inheritdoc/>
-    public bool IsStruct => false;
-
-    /// <inheritdoc/>
-    public bool IsByRefLike => false;
-
-    /// <inheritdoc/>
-    public bool IsSealed => false;
-
-    /// <inheritdoc/>
-    public bool IsAbstract => false;
-
-    /// <inheritdoc/>
-    public bool IsEnum => false;
-
-    /// <inheritdoc/>
-    public bool IsStatic => true;
-
-    /// <inheritdoc/>
-    public bool IncludeInterface => false;
-
-    public string GeneratedTypeFullName => $"{GeneratedTypeNamespace}.{GeneratedTypeName}";
-
-    /// <summary>Whether to generate the extension class as partial (Default: true)</summary>
-    public bool IsPartial => true;
-
-    /// <summary>The fully-qualified namespace of the source enum type.</summary>
-    public string TargetTypeNamespace
-    {
-        get;
-        [UsedImplicitly]
-        set;
-    }
-
-    /// <summary>The UNQUALIFIED name of the source enum type.</summary>
-    public string TargetTypeName
-    {
-        get;
-        [UsedImplicitly]
-        set;
-    }
-
-    /// <summary>
-    ///     The backing type for the enum.
-    /// </summary>
-    /// <remarks>For simplicity and formality, only System.Int32 and System.UInt32 are supported at this time.</remarks>
-    public TypeCode EnumBackingTypeCode
-    {
-        get => _enumBackingTypeCode;
-        init
-        {
-            if (value is not TypeCode.Int32 and not TypeCode.UInt32)
-            {
-                throw new NotSupportedException ("Only System.Int32 and System.UInt32 are supported at this time.");
-            }
-
-            _enumBackingTypeCode = value;
-        }
-    }
-
-    /// <summary>
-    ///     Whether a fast alternative to the built-in Enum.HasFlag method will be generated (Default: false)
-    /// </summary>
-    public bool GenerateFastHasFlags { [UsedImplicitly] get; set; }
-
-    /// <summary>Whether a switch-based IsDefined replacement will be generated (Default: true)</summary>
-    public bool GenerateFastIsDefined { [UsedImplicitly]get; set; } = true;
-
-    internal ImmutableHashSet<int>? _intMembers;
-    internal ImmutableHashSet<uint>? _uIntMembers;
-
-    /// <summary>
-    ///     Fully-qualified name of the extension class
-    /// </summary>
-    internal string FullyQualifiedClassName => $"{GeneratedTypeNamespace}.{GeneratedTypeName}";
-
-    /// <summary>
-    ///     Whether a Flags was found on the enum type.
-    /// </summary>
-    internal bool HasFlagsAttribute {[UsedImplicitly] get; set; }
-
-    private static readonly SymbolDisplayFormat FullyQualifiedSymbolDisplayFormatWithoutGlobal =
-        SymbolDisplayFormat.FullyQualifiedFormat
-                           .WithGlobalNamespaceStyle (
-                                                      SymbolDisplayGlobalNamespaceStyle.Omitted);
-
-
-    internal bool TryConfigure (INamedTypeSymbol enumSymbol, CancellationToken cancellationToken)
-    {
-        using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cts.Token.ThrowIfCancellationRequested ();
-
-        ImmutableArray<AttributeData> attributes = enumSymbol.GetAttributes ();
-
-        // This is theoretically impossible, but guarding just in case and canceling if it does happen.
-        if (attributes.Length == 0)
-        {
-            cts.Cancel (true);
-
-            return false;
-        }
-
-        // Check all attributes provided for anything interesting.
-        // Attributes can be in any order, so just check them all and adjust at the end if necessary.
-        // Note that we do not perform as strict validation on actual usage of the attribute, at this stage,
-        // because the analyzer should have already thrown errors for invalid uses like global namespace
-        // or unsupported enum underlying types.
-        foreach (AttributeData attr in attributes)
-        {
-            cts.Token.ThrowIfCancellationRequested ();
-            string? attributeFullyQualifiedName = attr.AttributeClass?.ToDisplayString (FullyQualifiedSymbolDisplayFormatWithoutGlobal);
-
-            // Skip if null or not possibly an attribute we care about
-            if (attributeFullyQualifiedName is null or not { Length: >= 5 })
-            {
-                continue;
-            }
-
-            switch (attributeFullyQualifiedName)
-            {
-                // For Flags enums
-                case Strings.DotnetNames.Attributes.Flags:
-                {
-                    HasFlagsAttribute = true;
-                }
-
-                    continue;
-
-                // For the attribute that started this whole thing
-                case GeneratorAttributeFullyQualifiedName:
-
-                {
-                    // If we can't successfully complete this method,
-                    // something is wrong enough that we may as well just stop now.
-                    if (!TryConfigure (attr, cts.Token))
-                    {
-                        if (cts.Token.CanBeCanceled)
-                        {
-                            cts.Cancel ();
-                        }
-
-                        return false;
-                    }
-                }
-
-                    continue;
-            }
-        }
-
-        // Now get the members, if we know we'll need them.
-        if (GenerateFastIsDefined || GenerateFastHasFlags)
-        {
-            if (EnumBackingTypeCode == TypeCode.Int32)
-            {
-                PopulateIntMembersHashSet (enumSymbol);
-            }
-            else if (EnumBackingTypeCode == TypeCode.UInt32)
-            {
-                PopulateUIntMembersHashSet (enumSymbol);
-            }
-        }
-
-        return true;
-    }
-
-    private void PopulateIntMembersHashSet (INamedTypeSymbol enumSymbol)
-    {
-        ImmutableArray<ISymbol> enumMembers = enumSymbol.GetMembers ();
-        IEnumerable<IFieldSymbol> fieldSymbols = enumMembers.OfType<IFieldSymbol> ();
-        _intMembers = fieldSymbols.Select (static m => m.HasConstantValue ? (int)m.ConstantValue : 0).ToImmutableHashSet ();
-    }
-    private void PopulateUIntMembersHashSet (INamedTypeSymbol enumSymbol)
-    {
-        _uIntMembers = enumSymbol.GetMembers ().OfType<IFieldSymbol> ().Select (static m => (uint)m.ConstantValue).ToImmutableHashSet ();
-    }
-
-    private bool HasExplicitFastHasFlags
-    {
-        [UsedImplicitly]get => _discoveredProperties [ExplicitFastHasFlagsMask];
-        set => _discoveredProperties [ExplicitFastHasFlagsMask] = value;
-    }
-
-    private bool HasExplicitFastIsDefined
-    {
-        [UsedImplicitly]get => _discoveredProperties [ExplicitFastIsDefinedMask];
-        set => _discoveredProperties [ExplicitFastIsDefinedMask] = value;
-    }
-
-    private bool HasExplicitTypeName
-    {
-        get => _discoveredProperties [ExplicitNameMask];
-        set => _discoveredProperties [ExplicitNameMask] = value;
-    }
-
-    private bool HasExplicitTypeNamespace
-    {
-        get => _discoveredProperties [ExplicitNamespaceMask];
-        set => _discoveredProperties [ExplicitNamespaceMask] = value;
-    }
-
-    [MemberNotNullWhen (true, nameof (_generatedTypeName), nameof (_generatedTypeNamespace))]
-    private bool TryConfigure (AttributeData attr, CancellationToken cancellationToken)
-    {
-        using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cts.Token.ThrowIfCancellationRequested ();
-
-        if (attr is not { NamedArguments.Length: > 0 })
-        {
-            // Just a naked attribute, so configure with appropriate defaults.
-            GeneratedTypeNamespace = TargetTypeNamespace;
-            GeneratedTypeName = string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-
-            return true;
-        }
-
-        cts.Token.ThrowIfCancellationRequested ();
-
-        foreach (KeyValuePair<string, TypedConstant> kvp in attr.NamedArguments)
-        {
-            string? propName = kvp.Key;
-            TypedConstant propValue = kvp.Value;
-
-            cts.Token.ThrowIfCancellationRequested ();
-
-            // For every property name and value pair, set associated metadata
-            // property, if understood.
-            switch (propName, propValue)
-            {
-                // Null or empty string doesn't make sense, so skip if it happens.
-                case (null, _):
-                case ("", _):
-                    continue;
-
-                // ClassName is specified, not explicitly null, and at least 1 character long.
-                case (AttributeProperties.TypeNamePropertyName, { IsNull: false, Value: string { Length: > 1 } classNameProvidedValue }):
-                    if (string.IsNullOrWhiteSpace (classNameProvidedValue))
-                    {
-                        return false;
-                    }
-
-                    GeneratedTypeName = classNameProvidedValue;
-                    HasExplicitTypeName = true;
-
-                    continue;
-
-                // Class namespace is specified, not explicitly null, and at least 1 character long.
-                case (AttributeProperties.TypeNamespacePropertyName, { IsNull: false, Value: string { Length: > 1 } classNamespaceProvidedValue }):
-
-                    if (string.IsNullOrWhiteSpace (classNamespaceProvidedValue))
-                    {
-                        return false;
-                    }
-
-                    GeneratedTypeNamespace = classNamespaceProvidedValue;
-                    HasExplicitTypeNamespace = true;
-
-                    continue;
-
-                // FastHasFlags is specified
-                case (AttributeProperties.FastHasFlagsPropertyName, { IsNull: false } fastHasFlagsConstant):
-                    GenerateFastHasFlags = fastHasFlagsConstant.Value is true;
-                    HasExplicitFastHasFlags = true;
-
-                    continue;
-
-                // FastIsDefined is specified
-                case (AttributeProperties.FastIsDefinedPropertyName, { IsNull: false } fastIsDefinedConstant):
-                    GenerateFastIsDefined = fastIsDefinedConstant.Value is true;
-                    HasExplicitFastIsDefined = true;
-
-                    continue;
-            }
-        }
-
-        // The rest is simple enough it's not really worth worrying about cancellation, so don't bother from here on...
-
-        // Configure anything that wasn't specified that doesn't have an implicitly safe default
-        if (!HasExplicitTypeName || _generatedTypeName is null)
-        {
-            _generatedTypeName = string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-        }
-
-        if (!HasExplicitTypeNamespace || _generatedTypeNamespace is null)
-        {
-            _generatedTypeNamespace = TargetTypeNamespace;
-        }
-
-        if (!HasFlagsAttribute)
-        {
-            GenerateFastHasFlags = false;
-        }
-
-        return true;
-    }
-
-    private static class AttributeProperties
-    {
-        internal const string FastHasFlagsPropertyName = nameof (GenerateEnumExtensionMethodsAttribute.FastHasFlags);
-        internal const string FastIsDefinedPropertyName = nameof (GenerateEnumExtensionMethodsAttribute.FastIsDefined);
-        internal const string TypeNamePropertyName = nameof (GenerateEnumExtensionMethodsAttribute.ClassName);
-        internal const string TypeNamespacePropertyName = nameof (GenerateEnumExtensionMethodsAttribute.ClassNamespace);
-    }
-}

+ 0 - 452
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGenerator.cs

@@ -1,452 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Text;
-using System.Threading;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     Incremental code generator for enums decorated with <see cref="GenerateEnumExtensionMethodsAttribute"/>.
-/// </summary>
-[SuppressMessage ("CodeQuality", "IDE0079", Justification = "Suppressions here are intentional and the warnings they disable are just noise.")]
-[Generator (LanguageNames.CSharp)]
-public sealed class EnumExtensionMethodsIncrementalGenerator : IIncrementalGenerator
-{
-    private const string ExtensionsForEnumTypeAttributeFullyQualifiedName = $"{Strings.AnalyzersAttributesNamespace}.{ExtensionsForEnumTypeAttributeName}";
-    private const string ExtensionsForEnumTypeAttributeName = "ExtensionsForEnumTypeAttribute";
-    private const string GeneratorAttributeFullyQualifiedName = $"{Strings.AnalyzersAttributesNamespace}.{GeneratorAttributeName}";
-    private const string GeneratorAttributeName = nameof (GenerateEnumExtensionMethodsAttribute);
-
-    /// <summary>Fully-qualified symbol name format without the "global::" prefix.</summary>
-    private static readonly SymbolDisplayFormat _fullyQualifiedSymbolDisplayFormatWithoutGlobal =
-        SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle (SymbolDisplayGlobalNamespaceStyle.Omitted);
-
-    /// <inheritdoc/>
-    /// <remarks>
-    ///     <para>
-    ///         Basically, this method is called once by the compiler, and is responsible for wiring up
-    ///         everything important about how source generation works.
-    ///     </para>
-    ///     <para>
-    ///         See in-line comments for specifics of what's going on.
-    ///     </para>
-    ///     <para>
-    ///         Note that <paramref name="context"/> is everything in the compilation,
-    ///         except for code generated by this generator or generators which have not yet executed.<br/>
-    ///         The methods registered to perform generation get called on-demand by the host (the IDE,
-    ///         compiler, etc), sometimes as often as every single keystroke.
-    ///     </para>
-    /// </remarks>
-    public void Initialize (IncrementalGeneratorInitializationContext context)
-    {
-        // Write out namespaces that may be used later. Harmless to declare them now and will avoid
-        // additional processing and potential omissions later on.
-        context.RegisterPostInitializationOutput (GenerateDummyNamespaces);
-
-        // This executes the delegate given to it immediately after Roslyn gets all set up.
-        // 
-        // As written, this will result in the GenerateEnumExtensionMethodsAttribute code
-        // being added to the environment, so that it can be used without having to actually
-        // be declared explicitly in the target project.
-        // This is important, as it guarantees the type will exist and also guarantees it is
-        // defined exactly as the generator expects it to be defined.
-        context.RegisterPostInitializationOutput (GenerateAttributeSources);
-
-        // Next up, we define our pipeline.
-        // To do so, we create one or more IncrementalValuesProvider<T> objects, each of which
-        // defines on stage of analysis or generation as needed.
-        //
-        // Critically, these must be as fast and efficient as reasonably possible because,
-        // once the pipeline is registered, this stuff can get called A LOT.
-        //
-        // Note that declaring these doesn't really do much of anything unless they are given to the
-        // RegisterSourceOutput method at the end of this method.
-        //
-        // The delegates are not actually evaluated right here. That is triggered by changes being
-        // made to the source code.
-
-        // This provider grabs attributes that pass our filter and then creates lightweight
-        // metadata objects to be used in the final code generation step.
-        // It also preemptively removes any nulls from the collection before handing things off
-        // to the code generation logic.
-        IncrementalValuesProvider<EnumExtensionMethodsGenerationInfo?> enumGenerationInfos =
-            context
-                .SyntaxProvider
-
-                // This method is a highly-optimized (and highly-recommended) filter on the incoming
-                // code elements that only bothers to present code that is annotated with the specified
-                // attribute, by its fully-qualified name, as a string, which is the first parameter.
-                //
-                // Two delegates are passed to it, in the second and third parameters.
-                //
-                // The second parameter is a filter predicate taking each SyntaxNode that passes the
-                // name filter above, and then refines that result.
-                //
-                // It is critical that the filter predicate be as simple and fast as possible, as it
-                // will be called a ton, triggered by keystrokes or anything else that modifies code
-                // in or even related to (in either direction) the pre-filtered code.
-                // It should collect metadata only and not actually generate any code.
-                // It must return a boolean indicating whether the supplied SyntaxNode should be
-                // given to the transform delegate at all.
-                // 
-                // The third parameter is the "transform" delegate.
-                // That one only runs when code is changed that passed both the attribute name filter
-                // and the filter predicate in the second parameter.
-                // It will be called for everything that passes both of those, so it can still happen
-                // a lot, but should at least be pretty close.
-                // In our case, it should be 100% accurate, since we're using OUR attribute, which can
-                // only be applied to enum types in the first place.
-                //
-                // That delegate is responsible for creating some sort of lightweight data structure
-                // which can later be used to generate the actual source code for output.
-                //
-                // THIS DELEGATE DOES NOT GENERATE CODE!
-                // However, it does need to return instances of the metadata class in use that are either
-                // null or complete enough to generate meaningful code from, later on.
-                //
-                // We then filter out any that were null with the .Where call at the end, so that we don't
-                // know or care about them when it's time to generate code.
-                //
-                // While the syntax of that .Where call is the same as LINQ, that is actually a
-                // highly-optimized implementation specifically for this use.
-                .ForAttributeWithMetadataName (
-                                               GeneratorAttributeFullyQualifiedName,
-                                               IsPotentiallyInterestingDeclaration,
-                                               GatherMetadataForCodeGeneration
-                                              )
-                .WithTrackingName ("CollectEnumMetadata")
-                .Where (static eInfo => eInfo is { });
-
-        // Finally, we wire up any IncrementalValuesProvider<T> instances above to the appropriate
-        // delegate that takes the SourceProductionContext that is current at run-time and an instance of
-        // our metadata type and takes appropriate action.
-        // Typically that means generating code from that metadata and adding it to the compilation via
-        // the received context object.
-        //
-        // As with everything else , the delegate will be invoked once for each item that passed
-        // all of the filters above, so we get to write that method from the perspective of a single
-        // enum type declaration.
-
-        context.RegisterSourceOutput (enumGenerationInfos, GenerateSourceFromGenerationInfo);
-    }
-
-    private static EnumExtensionMethodsGenerationInfo? GatherMetadataForCodeGeneration (
-        GeneratorAttributeSyntaxContext context,
-        CancellationToken cancellationToken
-    )
-    {
-        var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cancellationToken.ThrowIfCancellationRequested ();
-
-        // If it's not an enum symbol, we don't care.
-        // EnumUnderlyingType is null for non-enums, so this validates it's an enum declaration.
-        if (context.TargetSymbol is not INamedTypeSymbol { EnumUnderlyingType: { } } namedSymbol)
-        {
-            return null;
-        }
-
-        INamespaceSymbol? enumNamespaceSymbol = namedSymbol.ContainingNamespace;
-
-        if (enumNamespaceSymbol is null or { IsGlobalNamespace: true })
-        {
-            // Explicitly choosing not to support enums in the global namespace.
-            // The corresponding analyzer will report this.
-            return null;
-        }
-
-        string enumName = namedSymbol.Name;
-
-        string enumNamespace = enumNamespaceSymbol.ToDisplayString (_fullyQualifiedSymbolDisplayFormatWithoutGlobal);
-
-        TypeCode enumTypeCode = namedSymbol.EnumUnderlyingType.Name switch
-                                {
-                                    "UInt32" => TypeCode.UInt32,
-                                    "Int32" => TypeCode.Int32,
-                                    _ => TypeCode.Empty
-                                };
-
-        EnumExtensionMethodsGenerationInfo info = new (
-                                                       enumNamespace,
-                                                       enumName,
-                                                       enumTypeCode
-                                                      );
-
-        if (!info.TryConfigure (namedSymbol, cts.Token))
-        {
-            cts.Cancel ();
-            cts.Token.ThrowIfCancellationRequested ();
-        }
-
-        return info;
-    }
-
-
-    private static void GenerateAttributeSources (IncrementalGeneratorPostInitializationContext postInitializationContext)
-    {
-        postInitializationContext
-            .AddSource (
-                        $"{nameof (IExtensionsForEnumTypeAttributes)}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable All
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-                                           using System;
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Interface to simplify general enumeration of constructed generic types for
-                                           ///     <see cref="ExtensionsForEnumTypeAttribute{TEnum}"/>
-                                           /// </summary>
-                                           {{Strings.Templates.AttributesForGeneratedInterfaces}}
-                                           public interface IExtensionsForEnumTypeAttributes
-                                           {
-                                               System.Type EnumType { get; }
-                                           }
-
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{nameof (AssemblyExtendedEnumTypeAttribute)}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable All
-                                           #nullable enable
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>Assembly attribute declaring a known pairing of an <see langword="enum" /> type to an extension class.</summary>
-                                           /// <remarks>This attribute should only be written by internal source generators for Terminal.Gui. No other usage of any kind is supported.</remarks>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, AllowMultiple = true)]
-                                           public sealed class {{nameof(AssemblyExtendedEnumTypeAttribute)}} : System.Attribute
-                                           {
-                                               /// <summary>Creates a new instance of <see cref="AssemblyExtendedEnumTypeAttribute" /> from the provided parameters.</summary>
-                                               /// <param name="enumType">The <see cref="System.Type" /> of an <see langword="enum" /> decorated with a <see cref="GenerateEnumExtensionMethodsAttribute" />.</param>
-                                               /// <param name="extensionClass">The <see cref="System.Type" /> of the <see langword="class" /> decorated with an <see cref="ExtensionsForEnumTypeAttribute{TEnum}" /> referring to the same type as <paramref name="enumType" />.</param>
-                                               public AssemblyExtendedEnumTypeAttribute (System.Type enumType, System.Type extensionClass)
-                                               {
-                                                   EnumType = enumType;
-                                                   ExtensionClass = extensionClass;
-                                               }
-                                               /// <summary>An <see langword="enum" /> type that has been extended by Terminal.Gui source generators.</summary>
-                                               public System.Type EnumType { get; init; }
-                                               /// <summary>A class containing extension methods for <see cref="EnumType"/>.</summary>
-                                               public System.Type ExtensionClass { get; init; }
-                                               /// <inheritdoc />
-                                               public override string ToString () => $"{EnumType.Name},{ExtensionClass.Name}";
-                                           }
-
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{GeneratorAttributeFullyQualifiedName}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           {{Strings.Templates.StandardHeader}}
-                                           
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Used to enable source generation of a common set of extension methods for enum types.
-                                           /// </summary>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [{{Strings.DotnetNames.Types.AttributeUsageAttribute}} ({{Strings.DotnetNames.Types.AttributeTargets}}.Enum)]
-                                           public sealed class {{GeneratorAttributeName}} : {{Strings.DotnetNames.Types.Attribute}}
-                                           {
-                                               /// <summary>
-                                               ///     The name of the generated static class.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     If unspecified, null, empty, or only whitespace, defaults to the name of the enum plus "Extensions".<br/>
-                                               ///     No other validation is performed, so illegal values will simply result in compiler errors.
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public string? ClassName { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     The namespace in which to place the generated static class containing the extension methods.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     If unspecified, null, empty, or only whitespace, defaults to the namespace of the enum.<br/>
-                                               ///     No other validation is performed, so illegal values will simply result in compiler errors.
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public string? ClassNamespace { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     Whether to generate a fast, zero-allocation, non-boxing, and reflection-free alternative to the built-in
-                                               ///     <see cref="Enum.HasFlag"/> method.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     <para>
-                                               ///         Default: false
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If the enum is not decorated with <see cref="Flags"/>, this option has no effect.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-                                               ///         with the same value will be skipped.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         Overloads taking the enum type itself as well as the underlying type of the enum will be generated, enabling
-                                               ///         avoidance of implicit or explicit cast overhead.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public bool FastHasFlags { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     Whether to generate a fast, zero-allocation, and reflection-free alternative to the built-in
-                                               ///     <see cref="Enum.IsDefined"/> method,
-                                               ///     using a switch expression as a hard-coded reverse mapping of numeric values to explicitly-named members.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     <para>
-                                               ///         Default: true
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-                                               ///         with the same value will be skipped.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         As with <see cref="Enum.IsDefined"/> the source generator only considers explicitly-named members.<br/>
-                                               ///         Generation of values which represent valid bitwise combinations of members of enums decorated with
-                                               ///         <see cref="Flags"/> is not affected by this property.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public bool FastIsDefined { get; init; } = true;
-                                           
-                                               /// <summary>
-                                               ///     Gets a <see langword="bool"/> value indicating if this <see cref="GenerateEnumExtensionMethodsAttribute"/> instance
-                                               ///     contains default values only. See <see href="#remarks">remarks</see> of this method or documentation on properties of this type for details.
-                                               /// </summary>
-                                               /// <returns>
-                                               ///     A <see langword="bool"/> value indicating if all property values are default for this
-                                               ///     <see cref="GenerateEnumExtensionMethodsAttribute"/> instance.
-                                               /// </returns>
-                                               /// <remarks>
-                                               ///     Default values that will result in a <see langword="true"/> return value are:<br/>
-                                               ///     <see cref="FastIsDefined"/> &amp;&amp; !<see cref="FastHasFlags"/> &amp;&amp; <see cref="ClassName"/>
-                                               ///     <see langword="is"/> <see langword="null"/> &amp;&amp; <see cref="ClassNamespace"/> <see langword="is"/>
-                                               ///     <see langword="null"/>
-                                               /// </remarks>
-                                               public override bool IsDefaultAttribute ()
-                                               {
-                                                   return FastIsDefined
-                                                          && !FastHasFlags
-                                                          && ClassName is null
-                                                          && ClassNamespace is null;
-                                               }
-                                           }
-                                           
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{ExtensionsForEnumTypeAttributeFullyQualifiedName}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable RedundantNameQualifier
-                                           // ReSharper disable RedundantNullableDirective
-                                           // ReSharper disable UnusedType.Global
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-                                           #nullable enable
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Attribute written by the source generator for enum extension classes, for easier analysis and reflection.
-                                           /// </summary>
-                                           /// <remarks>
-                                           ///     Properties are just convenient shortcuts to properties of <typeparamref name="TEnum"/>.
-                                           /// </remarks>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [System.AttributeUsageAttribute (System.AttributeTargets.Class | System.AttributeTargets.Interface)]
-                                           public sealed class {{ExtensionsForEnumTypeAttributeName}}<TEnum>: System.Attribute, IExtensionsForEnumTypeAttributes where TEnum : struct, Enum
-                                           {
-                                               /// <summary>
-                                               ///     The namespace-qualified name of <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumFullName => EnumType.FullName!;
-                                           
-                                               /// <summary>
-                                               ///     The unqualified name of <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumName => EnumType.Name;
-                                           
-                                               /// <summary>
-                                               ///     The namespace containing <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumNamespace => EnumType.Namespace!;
-                                           
-                                               /// <summary>
-                                               ///     The <see cref="Type"/> given by <see langword="typeof"/>(<typeparamref name="TEnum"/>).
-                                               /// </summary>
-                                               public Type EnumType => typeof (TEnum);
-                                           }
-                                           
-                                           """,
-                                         Encoding.UTF8));
-    }
-
-    [SuppressMessage ("Roslynator", "RCS1267", Justification = "Intentionally used so that Spans are used.")]
-    private static void GenerateDummyNamespaces (IncrementalGeneratorPostInitializationContext postInitializeContext)
-    {
-        postInitializeContext.AddSource (
-                                         string.Concat (Strings.InternalAnalyzersNamespace, "Namespaces.g.cs"),
-                                         SourceText.From (Strings.Templates.DummyNamespaceDeclarations, Encoding.UTF8));
-    }
-
-    private static void GenerateSourceFromGenerationInfo (SourceProductionContext context, EnumExtensionMethodsGenerationInfo? enumInfo)
-    {
-        // Just in case we still made it this far with a null...
-        if (enumInfo is not { })
-        {
-            return;
-        }
-
-        CodeWriter writer = new (enumInfo);
-
-        context.AddSource ($"{enumInfo.FullyQualifiedClassName}.g.cs", writer.GenerateSourceText ());
-    }
-
-    /// <summary>
-    ///     Returns true if <paramref name="syntaxNode"/> is an EnumDeclarationSyntax
-    ///     whose parent is a NamespaceDeclarationSyntax, FileScopedNamespaceDeclarationSyntax, or a
-    ///     (Class|Struct)DeclarationSyntax.<br/>
-    ///     Additional filtering is performed in later stages.
-    /// </summary>
-    private static bool IsPotentiallyInterestingDeclaration (SyntaxNode syntaxNode, CancellationToken cancellationToken)
-    {
-        cancellationToken.ThrowIfCancellationRequested ();
-
-        return syntaxNode is
-               {
-                   RawKind: 8858, //(int)SyntaxKind.EnumDeclaration,
-                   Parent.RawKind: 8845 //(int)SyntaxKind.FileScopedNamespaceDeclaration
-                                   or 8842 //(int)SyntaxKind.NamespaceDeclaration
-                                   or 8855 //(int)SyntaxKind.ClassDeclaration
-                                   or 8856 //(int)SyntaxKind.StructDeclaration
-                                   or 9068 //(int)SyntaxKind.RecordStructDeclaration
-                                   or 9063 //(int)SyntaxKind.RecordDeclaration
-               };
-    }
-}

+ 0 - 38
Analyzers/Terminal.Gui.Analyzers.Internal/IGeneratedTypeMetadata.cs

@@ -1,38 +0,0 @@
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-/// <summary>
-/// Interface for all generators to use for their metadata classes.
-/// </summary>
-/// <typeparam name="TSelf">The type implementing this interface.</typeparam>
-internal interface IGeneratedTypeMetadata<out TSelf> where TSelf : IGeneratedTypeMetadata<TSelf>
-{
-    [UsedImplicitly]
-    string GeneratedTypeNamespace { get; }
-    [UsedImplicitly]
-    string? GeneratedTypeName { get; }
-    [UsedImplicitly]
-    string GeneratedTypeFullName { get; }
-    [UsedImplicitly]
-    string TargetTypeNamespace { get; }
-    [UsedImplicitly]
-    string TargetTypeName { get; }
-    string TargetTypeFullName { get; }
-    [UsedImplicitly]
-    Accessibility Accessibility { get; }
-    TypeKind TypeKind { get; }
-    bool IsRecord { get; }
-    bool IsClass { get; }
-    bool IsStruct { get; }
-    [UsedImplicitly]
-    bool IsPartial { get; }
-    bool IsByRefLike { get; }
-    bool IsSealed { get; }
-    bool IsAbstract { get; }
-    bool IsEnum { get; }
-    bool IsStatic { get; }
-    [UsedImplicitly]
-    bool IncludeInterface { get; }
-}

+ 0 - 28
Analyzers/Terminal.Gui.Analyzers.Internal/IStandardCSharpCodeGenerator.cs

@@ -1,28 +0,0 @@
-using System.Text;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis.Text;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-internal interface IStandardCSharpCodeGenerator<T> where T : IGeneratedTypeMetadata<T>
-{
-    /// <summary>
-    ///     Generates and returns the full source text corresponding to <see cref="Metadata"/>,
-    ///     in the requested <paramref name="encoding"/> or <see cref="Encoding.UTF8"/> if not provided.
-    /// </summary>
-    /// <param name="encoding">
-    ///     The <see cref="Encoding"/> of the generated source text or <see cref="Encoding.UTF8"/> if not
-    ///     provided.
-    /// </param>
-    /// <returns></returns>
-    [UsedImplicitly]
-    [SkipLocalsInit]
-    ref readonly SourceText GenerateSourceText (Encoding? encoding = null);
-
-    /// <summary>
-    ///     A type implementing <see cref="IGeneratedTypeMetadata{T}"/> which
-    ///     will be used for source generation.
-    /// </summary>
-    [UsedImplicitly]
-    T Metadata { get; set; }
-}

+ 0 - 71
Analyzers/Terminal.Gui.Analyzers.Internal/IndentedTextWriterExtensions.cs

@@ -1,71 +0,0 @@
-using System.CodeDom.Compiler;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-/// <summary>
-///     Just a simple set of extension methods to increment and decrement the indentation
-///     level of an <see cref="IndentedTextWriter"/> via push and pop terms, and to avoid having
-///     explicit values all over the place.
-/// </summary>
-public static class IndentedTextWriterExtensions
-{
-    /// <summary>
-    ///     Decrements <see cref="IndentedTextWriter.Indent"/> by 1, but only if it is greater than 0.
-    /// </summary>
-    /// <returns>
-    ///     The resulting indentation level of the <see cref="IndentedTextWriter"/>.
-    /// </returns>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static int Pop (this IndentedTextWriter w, string endScopeDelimiter = "}")
-    {
-        if (w.Indent > 0)
-        {
-            w.Indent--;
-            w.WriteLine (endScopeDelimiter);
-        }
-        return w.Indent;
-    }
-
-    /// <summary>
-    ///     Decrements <see cref="IndentedTextWriter.Indent"/> by 1 and then writes a closing curly brace.
-    /// </summary>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static void PopCurly (this IndentedTextWriter w, bool withSemicolon = false)
-    {
-        w.Indent--;
-
-        if (withSemicolon)
-        {
-            w.WriteLine ("};");
-        }
-        else
-        {
-            w.WriteLine ('}');
-        }
-    }
-
-    /// <summary>
-    ///     Increments <see cref="IndentedTextWriter.Indent"/> by 1, with optional parameters to customize the scope push.
-    /// </summary>
-    /// <param name="w">An instance of an <see cref="IndentedTextWriter"/>.</param>
-    /// <param name="declaration">
-    ///     The first line to be written before indenting and before the optional <paramref name="scopeDelimiter"/> line or
-    ///     null if not needed.
-    /// </param>
-    /// <param name="scopeDelimiter">
-    ///     An opening delimiter to write. Written before the indentation and after <paramref name="declaration"/> (if provided). Default is an opening curly brace.
-    /// </param>
-    /// <remarks>Calling with no parameters will write an opening curly brace and a line break at the current indentation and then increment.</remarks>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static void Push (this IndentedTextWriter w, string? declaration = null, char scopeDelimiter = '{')
-    {
-        if (declaration is { Length: > 0 })
-        {
-            w.WriteLine (declaration);
-        }
-
-        w.WriteLine (scopeDelimiter);
-
-        w.Indent++;
-    }
-}

+ 0 - 8
Analyzers/Terminal.Gui.Analyzers.Internal/Properties/launchSettings.json

@@ -1,8 +0,0 @@
-{
-  "profiles": {
-    "InternalAnalyzers Debug": {
-      "commandName": "DebugRoslynComponent",
-      "targetProject": "..\\Terminal.Gui.Analyzers.Internal.Debugging\\Terminal.Gui.Analyzers.Internal.Debugging.csproj"
-    }
-  }
-}

+ 0 - 63
Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj

@@ -1,63 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-    <PropertyGroup>
-        <!-- 
-        Do not remove netstandard2.0 from the TargetFramework.
-        Visual Studio requires that Analyzers/Generators target netstandard2.0 to work properly.
-        Also do not change this to TargetFrameworks without fully understanding the behavior change that implies.
-        -->
-        <TargetFramework>netstandard2.0</TargetFramework>
-    </PropertyGroup>
-
-    <PropertyGroup>
-        <OutputType>Library</OutputType>
-        <LangVersion>12</LangVersion>
-        <RootNamespace>Terminal.Gui.Analyzers.Internal</RootNamespace>
-        <ImplicitUsings>disable</ImplicitUsings>
-        <InvariantGlobalization>true</InvariantGlobalization>
-        <EnableNETAnalyzers>true</EnableNETAnalyzers>
-        <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
-        <CodeAnalysisIgnoreGeneratedCode>true</CodeAnalysisIgnoreGeneratedCode>
-        <ProduceReferenceAssembly>true</ProduceReferenceAssembly>
-        <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
-        <GenerateDocumentationFile>True</GenerateDocumentationFile>
-        <IsRoslynComponent>true</IsRoslynComponent>
-        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
-    </PropertyGroup>
-
-    <ItemGroup>
-      <ApiCompatExcludeAttributesFile Include="ApiCompatExcludedAttributes.txt" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <Compile Remove="Compatibility/*.cs" />
-    </ItemGroup>
-
-    <PropertyGroup>
-        <!-- Disabling some useless warnings caused by the netstandard2.0 target -->
-        <NoWarn>$(NoWarn);nullable;CA1067</NoWarn>
-    </PropertyGroup>
-    <ItemGroup>                           
-        <Compile Include="Compatibility/IEqualityOperators.cs" />             
-        <Compile Include="Compatibility/NumericExtensions.cs" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
-        <AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <PackageReference Include="Meziantou.Polyfill" Version="1.0.38" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.Analyzers" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.CSharp" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" PrivateAssets="all" />
-        <PackageReference Include="System.Runtime.Extensions" Version="4.3.1" PrivateAssets="all" />
-        <PackageReference Include="System.Runtime.Numerics" Version="4.3.0" PrivateAssets="all" />
-    </ItemGroup>
-</Project>

+ 0 - 4
Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj.DotSettings

@@ -1,4 +0,0 @@
-<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String>
-	<s:String x:Key="/Default/CodeInspection/Highlighting/UsageCheckingInspectionLevel/@EntryValue">InternalsOnly</s:String>
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=compatibility/@EntryIndexedValue">False</s:Boolean></wpf:ResourceDictionary>

+ 12 - 6
CONTRIBUTING.md

@@ -10,8 +10,8 @@ We welcome contributions from the community. See [Issues](https://github.com/gui
 
 
 Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. 
 Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. 
 
 
-* The `main` branch is always stable, and always matches the most recently released Nuget package.
-* The `develop` branch is where new development and bug-fixes happen. It is the default branch.
+* The `v1_release_` and `v2_release` branches are always stable, and always matches the most recently released Nuget package.
+* The `v1__develop` and `v2_develop` branches are where new development and bug-fixes happen. `v2_develop` is the default Github branch.
 
 
 ### Forking Terminal.Gui
 ### Forking Terminal.Gui
 
 
@@ -33,11 +33,11 @@ You now have your own fork and a local repo that references it as `origin`. Your
 
 
 ### Starting to Make a Change
 ### Starting to Make a Change
 
 
-Ensure your local `develop` (for v1) or `v2_develop` (for v2) branch is up-to-date with `upstream` (`github.com/gui-cs/Terminal.Gui`):
+Ensure your local `v1_develop` (for v1) or `v2_develop` (for v2) branch is up-to-date with `upstream` (`github.com/gui-cs/Terminal.Gui`):
 ```powershell
 ```powershell
 cd ./Terminal.Gui
 cd ./Terminal.Gui
-git checkout develop
-git pull upstream develop
+git checkout v2_develop
+git pull upstream v2_develop
 ```
 ```
 
 
 Create a new local branch:
 Create a new local branch:
@@ -90,7 +90,13 @@ remote:
 
 
 Follow the template instructions found on Github.
 Follow the template instructions found on Github.
 
 
-## Terminal.Gui Coding Style
+## Tenets for [gui-cs](www.github.com/gui-cs) Code Style (Unless you have better ones)
+
+* **Six-Year-Old Reading Level** - Our code style is biased towards code readability and away from terseness. This is *Systems Software* and needs to stand the test of time. Code should be structured and use variable names that make it readable by a 6-year-old, and comments in code are encouraged. 
+* **Consistency, Consistency, Consistency** - We adopt and document our standards for code style and then enforce them ruthlessly. For example, we require code reviews to pay attention to code style, not just functionality. 
+* **Don't be Weird** - Like all developers we have opinions, but our opinions on code style are tempered by existing standards. We are biased towards code style that used by Microsoft and other leading dotnet developers. For example, we choose 4 spaces for indentation instead of 8.
+* **Set and Forget** - We embrace and encourage the use of technology that makes it easy for contributors to apply best-practice code-style, such as ReSharper. As we do so we are mindful that tools can cause hidden issues and merge hell.
+* **Documentation is the Spec** - We care deeply about providing delightful developer documentation and are sticklers for grammar and clarity. If the code and the docs conflict, we are biased to believe what we wrote in the API documentation. This drives a virtuous cycle of clear thinking.
 
 
 **Terminal.Gui** uses a derivative of the [Microsoft C# Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions), with any deviations from those (somewhat older) conventions codified in the .editorconfig for the solution, as well as even more specific definitions in team-shared dotsettings files, used by ReSharper and Rider.\
 **Terminal.Gui** uses a derivative of the [Microsoft C# Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions), with any deviations from those (somewhat older) conventions codified in the .editorconfig for the solution, as well as even more specific definitions in team-shared dotsettings files, used by ReSharper and Rider.\
 Before you commit code, please run the formatting rules on **only the code file(s) you have modified**, in one of the following ways, in order of most preferred to least preferred:
 Before you commit code, please run the formatting rules on **only the code file(s) you have modified**, in one of the following ways, in order of most preferred to least preferred:

+ 2 - 5
CommunityToolkitExample/CommunityToolkitExample.csproj

@@ -8,11 +8,8 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
-  </ItemGroup>
-
-  <ItemGroup>
+    <PackageReference Include="CommunityToolkit.Mvvm" Version="[8.2.2,9)" />
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="[8,9)" />
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
   </ItemGroup>
 
 

+ 1 - 1
CommunityToolkitExample/Program.cs

@@ -12,7 +12,7 @@ public static class Program
         Services = ConfigureServices ();
         Services = ConfigureServices ();
         Application.Init ();
         Application.Init ();
         Application.Run (Services.GetRequiredService<LoginView> ());
         Application.Run (Services.GetRequiredService<LoginView> ());
-        Application.Top.Dispose();
+        Application.Top?.Dispose();
         Application.Shutdown ();
         Application.Shutdown ();
     }
     }
 
 

+ 0 - 6
Directory.Build.props

@@ -1,6 +0,0 @@
-<Project>
-  <ItemGroup>
-    <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="all" />
-    <PackageReference Include="JetBrains.ExternalAnnotations" Version="10.2.147" PrivateAssets="all" />
-  </ItemGroup>
-</Project>

+ 0 - 5
Directory.Build.targets

@@ -1,5 +0,0 @@
-<Project>
-  <PropertyGroup>
-    <DefineConstants>$(DefineConstants);DIMAUTO</DefineConstants>
-  </PropertyGroup>
-</Project>

+ 21 - 20
Example/Example.cs

@@ -6,19 +6,19 @@
 using System;
 using System;
 using Terminal.Gui;
 using Terminal.Gui;
 
 
-var app = Application.Run<ExampleWindow> ();
-
-Console.WriteLine ($"Username: {app.UserNameText.Text}");
-
-app.Dispose ();
+Application.Run<ExampleWindow> ().Dispose ();
 
 
 // Before the application exits, reset Terminal.Gui for clean shutdown
 // Before the application exits, reset Terminal.Gui for clean shutdown
 Application.Shutdown ();
 Application.Shutdown ();
 
 
+// To see this output on the screen it must be done after shutdown,
+// which restores the previous screen.
+Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+
 // Defines a top-level window with border and title
 // Defines a top-level window with border and title
 public class ExampleWindow : Window
 public class ExampleWindow : Window
 {
 {
-    public TextField UserNameText;
+    public static string UserName;
 
 
     public ExampleWindow ()
     public ExampleWindow ()
     {
     {
@@ -27,7 +27,7 @@ public class ExampleWindow : Window
         // Create input components and labels
         // Create input components and labels
         var usernameLabel = new Label { Text = "Username:" };
         var usernameLabel = new Label { Text = "Username:" };
 
 
-        UserNameText = new TextField
+        var userNameText = new TextField
         {
         {
             // Position text field adjacent to the label
             // Position text field adjacent to the label
             X = Pos.Right (usernameLabel) + 1,
             X = Pos.Right (usernameLabel) + 1,
@@ -46,7 +46,7 @@ public class ExampleWindow : Window
             Secret = true,
             Secret = true,
 
 
             // align with the text box above
             // align with the text box above
-            X = Pos.Left (UserNameText),
+            X = Pos.Left (userNameText),
             Y = Pos.Top (passwordLabel),
             Y = Pos.Top (passwordLabel),
             Width = Dim.Fill ()
             Width = Dim.Fill ()
         };
         };
@@ -64,19 +64,20 @@ public class ExampleWindow : Window
 
 
         // When login button is clicked display a message popup
         // When login button is clicked display a message popup
         btnLogin.Accept += (s, e) =>
         btnLogin.Accept += (s, e) =>
-                            {
-                                if (UserNameText.Text == "admin" && passwordText.Text == "password")
-                                {
-                                    MessageBox.Query ("Logging In", "Login Successful", "Ok");
-                                    Application.RequestStop ();
-                                }
-                                else
-                                {
-                                    MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
-                                }
-                            };
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
 
 
         // Add the views to the Window
         // Add the views to the Window
-        Add (usernameLabel, UserNameText, passwordLabel, passwordText, btnLogin);
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
     }
     }
 }
 }

+ 2 - 2
FSharpExample/FSharpExample.fsproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <AssemblyVersion>1.6.2.0</AssemblyVersion>
     <AssemblyVersion>1.6.2.0</AssemblyVersion>
     <FileVersion>1.6.2.0</FileVersion>
     <FileVersion>1.6.2.0</FileVersion>
     <InformationalVersion>1.6.2+Branch.main.Sha.b6eeb6321685af474ffc17b1390ff1d4894a90c5</InformationalVersion>
     <InformationalVersion>1.6.2+Branch.main.Sha.b6eeb6321685af474ffc17b1390ff1d4894a90c5</InformationalVersion>
@@ -14,6 +14,6 @@
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Update="FSharp.Core" Version="6.0.0" />
+    <PackageReference Update="FSharp.Core" Version="8.0.300" />
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 36 - 442
FSharpExample/Program.fs

@@ -1,454 +1,48 @@
-open System
-open System.Diagnostics
-open System.Globalization
-open System.IO
-open NStack
-open Terminal.Gui
+open Terminal.Gui
 
 
-let ustr (x: string) = ustring.Make(x)
-let mutable ml2 = Unchecked.defaultof<Label>
-let mutable ml = Unchecked.defaultof<Label>
-let mutable menu = Unchecked.defaultof<MenuBar>
-let mutable menuKeysStyle = Unchecked.defaultof<CheckBox>
-let mutable menuAutoMouseNav = Unchecked.defaultof<CheckBox>
-
-type Box10x (x: int, y: int) =
-    inherit View (Rect(x, y, 20, 10))
-    let w = 40
-    let h = 50
-
-    new () =
-        new Box10x ()
-
-    member _.GetContentSize () =
-        Size (w, h)
-
-    member _.SetCursorPosition (_ : Point) =
-        raise (NotImplementedException())
-
-    override this.Redraw (_: Rect) =
-        Application.Driver.SetAttribute this.ColorScheme.Focus
-        do
-        let mutable y = 0
-        while y < h do
-        this.Move (0, y)
-        Application.Driver.AddStr (ustr (string y))
-        do
-        let mutable x = 0
-        while x < w - (y.ToString ()).Length do
-            if (string y).Length < w
-            then Application.Driver.AddStr (ustr " ")
-            x <- x + 1
-        y <- y + 1
-
-type Filler (rect: Rect) =
-    inherit View(rect)
-    new () =
-        new Filler ()
-
-    override this.Redraw (_: Rect) =
-        Application.Driver.SetAttribute this.ColorScheme.Focus
-        let mutable f = this.Frame
-        do
-        let mutable y = 0
-        while y < f.Width do
-        this.Move (0, y)
-        do
-        let mutable x = 0
-        while x < f.Height do
-            let r =
-                match x % 3 with
-                | 0 ->
-                    Application.Driver.AddRune ((Rune ((string y).ToCharArray (0, 1)).[0]))
-                    if y > 9 then
-                        Application.Driver.AddRune ((Rune ((string y).ToCharArray (1, 1)).[0]))
-                    Rune '.'
-                | 1 -> Rune 'o'
-                | _ -> Rune 'O'
-            Application.Driver.AddRune r
-            x <- x + 1
-        y <- y + 1
-
-let ShowTextAlignments () =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel", true)
-    cancelButton.add_Clicked (Action (Application.RequestStop))
-
-    let container = new Dialog (ustr "Text Alignments", 50, 20, okButton, cancelButton)
-    let txt = "Hello world, how are you doing today"
-    container.Add (
-        new Label (Rect(0, 1, 40, 3), ustr ((sprintf "%O-%O" 1) txt), TextAlignment = TextAlignment.Left),
-        new Label (Rect(0, 3, 40, 3), ustr ((sprintf "%O-%O" 2) txt), TextAlignment = TextAlignment.Right),
-        new Label (Rect(0, 5, 40, 3), ustr ((sprintf "%O-%O" 3) txt), TextAlignment = TextAlignment.Centered),
-        new Label (Rect(0, 7, 40, 3), ustr ((sprintf "%O-%O" 4) txt), TextAlignment = TextAlignment.Justified))
-    Application.Run container
-
-let ShowEntries (container: View) =
-    let scrollView = 
-        new ScrollView (Rect (50, 10, 20, 8),
-            ContentSize = Size (20, 50),
-            ShowVerticalScrollIndicator = true,
-            ShowHorizontalScrollIndicator = true)
-    scrollView.Add (new Filler (Rect (0, 0, 40, 40)))
-    let scrollView2 = 
-        new ScrollView (Rect (72, 10, 3, 3),
-            ContentSize = Size (100, 100),
-            ShowVerticalScrollIndicator = true,
-            ShowHorizontalScrollIndicator = true)
-    scrollView2.Add (new Box10x (0, 0))
-    let progress = new ProgressBar (Rect(68, 1, 10, 1))
-    let timer = Func<MainLoop, bool> (fun _ ->
-        progress.Pulse ()
-        true)
-
-    Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300.), timer) |> ignore
-
-    let login =
-        new Label (ustr "Login: ",
-            X = Pos.At 3,
-            Y = Pos.At 6)
-    let password =
-        new Label (ustr "Password: ",
-            X = Pos.Left login,
-            Y = Pos.Bottom login + Pos.At 1)
-    let loginText =
-        new TextField (ustr "",
-            X = Pos.Right password,
-            Y = Pos.Top login,
-            Width = Dim.op_Implicit 40)
-    let passText =
-        new TextField (ustr "",
-            Secret = true,
-            X = Pos.Left loginText,
-            Y = Pos.Top password,
-            Width = Dim.Width loginText)
-    let tf = new Button (3, 19, ustr "Ok")
-    container.Add (login, loginText, password, passText,
-        new FrameView (Rect (3, 10, 25, 6), ustr "Options",
-            [| new CheckBox (1, 0, ustr "Remember me")
-               new RadioGroup (1, 2, 
-                [| ustr "_Personal"; ustr "_Company"|])|]),
-        new ListView (Rect (59, 6, 16, 4),
-                [| "First row"
-                   "<>"
-                   "This is a very long row that should overflow what is shown"
-                   "4th"
-                   "There is an empty slot on the second row"
-                   "Whoa"
-                   "This is so cool" |]),
-        scrollView, scrollView2, tf,
-        new Button (10, 19, ustr "Cancel"),
-        new TimeField (3, 20, DateTime.Now.TimeOfDay),
-        new TimeField (23, 20, DateTime.Now.TimeOfDay, true),
-        new DateField (3, 22, DateTime.Now),
-        new DateField (23, 22, DateTime.Now, true),
-        progress,
-        new Label (3, 24, ustr "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"),
-        menuKeysStyle,
-        menuAutoMouseNav)
-    container.SendSubviewToBack tf
-
-let NewFile () =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel", true)
-    cancelButton.add_Clicked (Action (Application.RequestStop))
-
-    let d = new Dialog (ustr "New File", 50, 20, okButton, cancelButton)
-    ml2 <- new Label (1, 1, ustr "Mouse Debug Line")
-    d.Add ml2
-    Application.Run d
-
-let GetFileName () =
-    let mutable fname = Unchecked.defaultof<_>
-    for s in [| "/etc/passwd"; "c:\\windows\\win.ini" |] do
-        if File.Exists s
-        then fname <- s
-    fname
-
-let Editor (top: Toplevel) =
-    let tframe = top.Frame
-    let ntop = new Toplevel(tframe)
-    let menu = 
-        new MenuBar(
-            [| MenuBarItem (ustr "_File",
-                 [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]);
-                    MenuBarItem (ustr "_Edit",
-                        [| MenuItem (ustr "_Copy", ustring.Empty, Unchecked.defaultof<_>)
-                           MenuItem (ustr "C_ut", ustring.Empty, Unchecked.defaultof<_>)
-                           MenuItem (ustr "_Paste", ustring.Empty, Unchecked.defaultof<_>) |]) |])
-    ntop.Add menu
-    let fname = GetFileName ()
-    let win = 
-        new Window (
-            ustr (if not (isNull fname) then fname else "Untitled"),
-            X = Pos.At 0,
-            Y = Pos.At 1,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    ntop.Add win
-    let text = new TextView (Rect(0, 0, (tframe.Width - 2), (tframe.Height - 3)))
-    if fname <> Unchecked.defaultof<_>
-    then text.Text <- ustr (File.ReadAllText fname)
-    win.Add text
-    Application.Run ntop
-
-let Quit () =
-    MessageBox.Query (50, 7, ustr "Quit Demo", ustr "Are you sure you want to quit this demo?", ustr "Yes", ustr "No") = 0
-
-let Close () =
-    MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "There is nothing to close", ustr "Ok")
-    |> ignore
-
-let Open () =
-    let d = new OpenDialog (ustr "Open", ustr "Open a file", AllowsMultipleSelection = true)
-    Application.Run d
-    if not d.Canceled
-        then MessageBox.Query (50, 7, ustr "Selected File", ustr (String.Join (", ", d.FilePaths)), ustr "Ok") |> ignore
-
-let ShowHex (top: Toplevel) =
-    let tframe = top.Frame
-    let ntop = new Toplevel (tframe)
-    let menu = 
-        new MenuBar (
-            [| MenuBarItem (ustr "_File",
-                 [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]) |])
-    ntop.Add menu
-    let win =
-        new Window (ustr "/etc/passwd",
-            X = Pos.At 0,
-            Y = Pos.At 1,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    ntop.Add win
-    let fname = GetFileName ()
-    let source = File.OpenRead fname
-    let hex = 
-        new HexView (source,
-            X = Pos.At 0,
-            Y = Pos.At 0,
-            Width = Dim.Fill (),
-            Height = Dim.Fill ())
-    win.Add hex
-    Application.Run ntop
-
-type MenuItemDetails () =
-    inherit MenuItem ()
-    new (title: ustring, help: ustring, action: Action) as this =
-        MenuItemDetails ()
-        then
-            this.Title <- title
-            this.Help <- help
-            this.Action <- action
-
-    static member Instance (mi: MenuItem) =
-        (mi.GetMenuItem ()) :?> MenuItemDetails
-
-type MenuItemDelegate = delegate of MenuItemDetails -> MenuItem
-
-let ShowMenuItem (mi: MenuItemDetails) =
-    MessageBox.Query (70, 7, ustr (mi.Title.ToString ()),
-        ustr ((sprintf "%O selected. Is from submenu: %O" (mi.Title.ToString ())) (mi.GetMenuBarItem ())), ustr "Ok")
-    |> ignore
-
-let MenuKeysStyleToggled (_: bool) =
-    menu.UseKeysUpDownAsKeysLeftRight <- menuKeysStyle.Checked
-
-let MenuAutoMouseNavToggled (_: bool) =
-    menu.WantMousePositionReports <- menuAutoMouseNav.Checked
-
-let Copy () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
-    then textField.Copy ()
+type ExampleWindow() as this =
+    inherit Window()
+    
+    do
+        this.Title <- sprintf "Example App (%O to quit)" Application.QuitKey
 
 
-let Cut () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
-    then textField.Cut ()
+        // Create input components and labels
+        let usernameLabel = new Label(Text = "Username:")
 
 
-let Paste () =
-    let textField = menu.LastFocused :?> TextField
-    if textField <> Unchecked.defaultof<_>
-    then textField.Paste ()
+        let userNameText = new TextField(X = Pos.Right(usernameLabel) + Pos.op_Implicit(1), Width = Dim.Fill())
 
 
-let Help () =
-    MessageBox.Query (50, 7, ustr "Help", ustr "This is a small help\nBe kind.", ustr "Ok")
-    |> ignore
+        let passwordLabel = new Label(Text = "Password:", X = Pos.Left(usernameLabel), Y = Pos.Bottom(usernameLabel) +  Pos.op_Implicit(1))
 
 
-let Load () =
-    MessageBox.Query (50, 7, ustr "Load", ustr "This is a small load\nBe kind.", ustr "Ok")
-    |> ignore
+        let passwordText = new TextField(Secret = true, X = Pos.Left(userNameText), Y = Pos.Top(passwordLabel), Width = Dim.Fill())
 
 
-let Save () =
-    MessageBox.Query (50, 7, ustr "Save ", ustr "This is a small save\nBe kind.", ustr "Ok")
-    |> ignore
+        // Create login button
+        let btnLogin = new Button(Text = "Login", Y = Pos.Bottom(passwordLabel) +  Pos.op_Implicit(1), X = Pos.Center(), IsDefault = true)
 
 
-let ListSelectionDemo (multiple: bool) =
-    let okButton = new Button (ustr "Ok", true)
-    okButton.add_Clicked (Action (Application.RequestStop))
-    let cancelButton = new Button (ustr "Cancel")
-    cancelButton.add_Clicked (Action (Application.RequestStop))
+        // When login button is clicked display a message popup
+        btnLogin.Accept.Add(fun _ ->
+            if userNameText.Text = "admin" && passwordText.Text = "password" then
+                MessageBox.Query("Logging In", "Login Successful", "Ok") |> ignore
+                ExampleWindow.UserName <- userNameText.Text.ToString()
+                Application.RequestStop()
+            else
+                MessageBox.ErrorQuery("Logging In", "Incorrect username or password", "Ok") |> ignore
+        )
 
 
-    let d = new Dialog (ustr "Selection Demo", 60, 20, okButton, cancelButton)
-    let animals = ResizeArray<_> ()
-    animals.AddRange([| "Alpaca"; "Llama"; "Lion"; "Shark"; "Goat" |])
-    let msg =
-        new Label (ustr "Use space bar or control-t to toggle selection",
-            X = Pos.At 1,
-            Y = Pos.At 1,
-            Width = Dim.Fill () - Dim.op_Implicit 1,
-            Height = Dim.op_Implicit 1)
-    let list =
-        new ListView (animals,
-            X = Pos.At 1,
-            Y = Pos.At 3,
-            Width = Dim.Fill () - Dim.op_Implicit 4,
-            Height = Dim.Fill () - Dim.op_Implicit 4,
-            AllowsMarking = true,
-            AllowsMultipleSelection = multiple)
-    d.Add (msg, list)
-    Application.Run d
-    let mutable result = ""
-    do
-        let mutable i = 0
-        while i < animals.Count do
-        if list.Source.IsMarked i
-        then result <- result + animals.[i] + " "
-        i <- i + 1
-    MessageBox.Query (60, 10, ustr "Selected Animals", ustr (if result = "" then "No animals selected" else result), ustr "Ok") |> ignore
+        // Add the views to the Window
+        this.Add(usernameLabel, userNameText, passwordLabel, passwordText, btnLogin)
 
 
-let OnKeyDownPressUpDemo () =
-    let closeButton = new Button (ustr "Close")
-    closeButton.add_Clicked (Action (Application.RequestStop))
+    static member val UserName = "" with get, set
 
 
-    let container = new Dialog (ustr "KeyDown & KeyPress & KeyUp demo", 80, 20, closeButton, Width = Dim.Fill (), Height = Dim.Fill ())
+[<EntryPoint>]
+let main argv =
+    Application.Init()
+    Application.Run<ExampleWindow>().Dispose()
     
     
-    let list = ResizeArray<_> ()
-    let listView = 
-        new ListView (list,
-            X = Pos.At 0,
-            Y = Pos.At 0,
-            Width = Dim.Fill () - Dim.op_Implicit 1,
-            Height = Dim.Fill () - Dim.op_Implicit 2,
-            ColorScheme = Colors.TopLevel)
-    container.Add (listView)
+    // Before the application exits, reset Terminal.Gui for clean shutdown
+    Application.Shutdown()
     
     
-    let keyDownPressUp (keyEvent: KeyEvent, updown: string) =
-        match updown with
-        | "Down"
-        | "Up"
-        | "Press" -> 
-            list.Add (keyEvent.ToString ())    
-        | _ -> failwithf "Unknown: %s" updown
-        listView.MoveDown ()
-
-    container.add_KeyDown(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Down") |> ignore))
-    container.add_KeyPress(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Press") |> ignore))
-    container.add_KeyUp(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Up") |> ignore))
-    Application.Run (container)
-
-let Main () =
-    if Debugger.IsAttached then
-        CultureInfo.DefaultThreadCurrentUICulture <- CultureInfo.GetCultureInfo ("en-US")
-    Application.Init()
-    let top = Application.Top
-    let margin = 3
-    let win = 
-        new Window (ustr "Hello",
-            X = Pos.At 1,
-            Y = Pos.At 1,
-            Width = Dim.Fill () - Dim.op_Implicit margin,
-            Height = Dim.Fill () - Dim.op_Implicit margin)
-    let menuItems =
-        [|MenuItemDetails (ustr "F_ind",ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Replace", ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Item1", ustr "", Unchecked.defaultof<_>);
-            MenuItemDetails (ustr "_Also From Sub Menu", ustr "", Unchecked.defaultof<_>)|]
-    menuItems.[0].Action <- fun _ -> ShowMenuItem (menuItems.[0])
-    menuItems.[1].Action <- fun _ -> ShowMenuItem (menuItems.[1])
-    menuItems.[2].Action <- fun _ -> ShowMenuItem (menuItems.[2])
-    menuItems.[3].Action <- fun _ -> ShowMenuItem (menuItems.[3])
-    menu <-
-        new MenuBar (
-            [| MenuBarItem(ustr "_File",
-                    [| MenuItem (ustr "Text _Editor Demo", ustring.Empty, (fun () -> Editor top))
-                       MenuItem (ustr "_New", ustr "Creates new file", fun () -> NewFile())
-                       MenuItem (ustr "_Open", ustring.Empty, fun () -> Open())
-                       MenuItem (ustr "_Hex", ustring.Empty, (fun () -> ShowHex top))
-                       MenuItem (ustr "_Close", ustring.Empty, (fun () -> Close()))
-                       MenuItem (ustr "_Disabled", ustring.Empty, (fun () -> ()), (fun () -> false))
-                       Unchecked.defaultof<_>
-                       MenuItem (ustr "_Quit", ustring.Empty, (fun () -> if Quit() then top.Running <- false)) |])
-               MenuBarItem (ustr "_Edit",
-                    [| MenuItem (ustr "_Copy", ustring.Empty, fun () -> Copy())
-                       MenuItem (ustr "C_ut", ustring.Empty, fun () -> Cut())
-                       MenuItem (ustr "_Paste", ustring.Empty, fun () -> Paste())
-                       MenuBarItem (ustr "_Find and Replace",
-                           [| menuItems.[0] :> MenuItem
-                              menuItems.[1] :> MenuItem |]) :> MenuItem
-                       menuItems.[3] :> MenuItem
-                    |])
-               MenuBarItem (ustr "_List Demos", 
-                    [| MenuItem (ustr "Select _Multiple Items", ustring.Empty, (fun () -> ListSelectionDemo true))
-                       MenuItem (ustr "Select _Single Item", ustring.Empty, (fun () -> ListSelectionDemo false)) |])   
-               MenuBarItem (ustr "A_ssorted",
-                    [| MenuItem (ustr "_Show text alignments", ustring.Empty, (fun () -> ShowTextAlignments())) 
-                       MenuItem (ustr "_OnKeyDown/Press/Up", ustring.Empty, (fun () -> OnKeyDownPressUpDemo())) |])
-               MenuBarItem (ustr "_Test Menu and SubMenus",
-                    [| MenuBarItem (ustr "SubMenu1Item_1",
-                            [| MenuBarItem (ustr "SubMenu2Item_1",
-                                    [| MenuBarItem (ustr "SubMenu3Item_1",
-                                            [| menuItems.[2] :> MenuItem |]) :> MenuItem
-                                    |]) :> MenuItem
-                            |]) :> MenuItem
-                    |])
-               MenuBarItem (ustr "_About...", ustr "Demonstrates top-level menu item", (fun () -> MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "This is a demo app for gui.cs", ustr "Ok") |> ignore)) |])
-    menuKeysStyle <- new CheckBox (3, 25, ustr "UseKeysUpDownAsKeysLeftRight", true)
-    menuKeysStyle.add_Toggled (Action<bool> (MenuKeysStyleToggled))
-    menuAutoMouseNav <- new CheckBox (40, 25, ustr "UseMenuAutoNavigation", true)
-    menuAutoMouseNav.add_Toggled (Action<bool> (MenuAutoMouseNavToggled))
-    ShowEntries win
-    let mutable count = 0
-    ml <- new Label (Rect (3, 17, 47, 1), ustr "Mouse: ")
-    Application.RootMouseEvent <- Action<MouseEvent> (
-            fun (me: MouseEvent) ->
-                ml.Text <- ustr (
-                     (((sprintf "Mouse: (%O,%O) - %O %O" me.X) me.Y) me.Flags) (count <- count + 1; count)))
-    let test = new Label (3, 18, ustr "Se iniciará el análisis")
-    win.Add test
-    win.Add ml
-    let drag = new Label (ustr "Drag: ", X = Pos.At 70, Y = Pos.At 24)
-    let dragText = 
-        new TextField (ustr "",
-            X = Pos.Right drag,
-            Y = Pos.Top drag,
-            Width = Dim.op_Implicit 40)
-    let statusBar = new StatusBar ([|
-        StatusItem(Key.F1, ustr "~F1~ Help", Action Help)
-        StatusItem(Key.F2, ustr "~F2~ Load", Action Load)
-        StatusItem(Key.F3, ustr "~F3~ Save", Action Save)
-        StatusItem(Key.Q, ustr "~^Q~ Quit", fun () -> if (Quit()) then top.Running <- false) |])
-    win.Add (drag, dragText)
-    let bottom = new Label (ustr "This should go on the bottom of the same top-level!")
-    win.Add bottom
-    let bottom2 = new Label (ustr "This should go on the bottom of another top-level!")
-    top.Add bottom2
-    top.add_LayoutComplete (Action<View.LayoutEventArgs>
-        (fun e ->
-            bottom.X <- win.X
-            bottom.Y <- Pos.Bottom win - Pos.Top win - Pos.At margin
-            bottom2.X <- Pos.Left win
-            bottom2.Y <- Pos.Bottom win)
-        )
-    top.Add win
-    top.Add (menu, statusBar)
-    Application.Run ()
-    Application.Shutdown ();
-
-module Demo =
-    [<EntryPoint>]
-    let main _ =
-        Main ()
-        0
+    // To see this output on the screen it must be done after shutdown,
+    // which restores the previous screen.
+    printfn "Username: %s" ExampleWindow.UserName
+    
+    0 // return an integer exit code

+ 34 - 23
GitVersion.yml

@@ -1,39 +1,50 @@
 mode: ContinuousDeployment
 mode: ContinuousDeployment
 tag-prefix: '[vV]'
 tag-prefix: '[vV]'
-continuous-delivery-fallback-tag: pre
+continuous-delivery-fallback-tag: dev
 branches:
 branches:
-  develop:
-    mode: ContinuousDeployment
-    tag: pre
-    regex: develop
-    source-branches:
-    - main
-    pre-release-weight: 100
-
   v2_develop:
   v2_develop:
     mode: ContinuousDeployment
     mode: ContinuousDeployment
-    tag: pre
+    tag: dev
     regex: ^v2_develop?[/-]
     regex: ^v2_develop?[/-]
-    is-release-branch: true
     tracks-release-branches: true
     tracks-release-branches: true
-    #is-source-branch-for: ['v2']
+    is-source-branch-for: ['v2_release']
     source-branches: []
     source-branches: []
 
 
-  main:
-    tag: rc
-    increment: Patch
-    source-branches:
-    - develop
-    - main
-  feature:
-    tag: useBranchName
-    regex: ^features?[/-]
+  v2_release:
+    mode: ContinuousDeployment
+    tag: prealpha
+    regex: v2_release
+    is-release-branch: true
+    source-branches: ['v2_develop']
+
+  v1_develop:
+    mode: ContinuousDeployment
+    tag: dev
+    regex: v1_develop
     source-branches:
     source-branches:
-    - develop
-    - main
+    - v1_release
+    pre-release-weight: 100
+
+  v1_release:
+    mode: ContinuousDeployment
+    regex: v1_release
+    is-release-branch: true
+    source-branches: ['v1_develop']
+
   pull-request:
   pull-request:
+    mode: ContinuousDeployment
     tag: PullRequest.{BranchName}
     tag: PullRequest.{BranchName}
     increment: Inherit
     increment: Inherit
+    tag-number-pattern: '[/-](?<number>\d+)'
+    regex: ^(pull|pull\-requests|pr)[/-]
+    source-branches:
+    - v2_develop
+    - v2_release
+    - feature
+    - support
+    - hotfix
+    pre-release-weight: 30000
+
 ignore:
 ignore:
   sha: []
   sha: []
 
 

+ 22 - 0
NativeAot/NativeAot.csproj

@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+    <PublishAot>true</PublishAot>
+    <InvariantGlobalization>false</InvariantGlobalization>
+  </PropertyGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <PackageReference Include="Terminal.Gui" Version="[2.0.0-v2-develop.2189,3)" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+</Project>

+ 113 - 0
NativeAot/Program.cs

@@ -0,0 +1,113 @@
+// This is a test application for a native Aot file.
+
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using Terminal.Gui;
+
+namespace NativeAot;
+
+public static class Program
+{
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.Application.Init(ConsoleDriver, String)")]
+    [RequiresDynamicCode ("Calls Terminal.Gui.Application.Init(ConsoleDriver, String)")]
+    private static void Main (string [] args)
+    {
+        Application.Init ();
+
+        #region The code in this region is not intended for use in a native Aot self-contained. It's just here to make sure there is no functionality break with localization in Terminal.Gui using self-contained
+
+        if (Equals(Thread.CurrentThread.CurrentUICulture, CultureInfo.InvariantCulture) && Application.SupportedCultures!.Count == 0)
+        {
+            // Only happens if the project has <InvariantGlobalization>true</InvariantGlobalization>
+            Debug.Assert (Application.SupportedCultures.Count == 0);
+        }
+        else
+        {
+            Debug.Assert (Application.SupportedCultures!.Count > 0);
+            Debug.Assert (Equals (CultureInfo.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
+        }
+
+        #endregion
+
+        ExampleWindow app = new ();
+        Application.Run (app);
+
+        // Dispose the app object before shutdown
+        app.Dispose ();
+
+        // Before the application exits, reset Terminal.Gui for clean shutdown
+        Application.Shutdown ();
+
+        // To see this output on the screen it must be done after shutdown,
+        // which restores the previous screen.
+        Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+    }
+}
+
+// Defines a top-level window with border and title
+public class ExampleWindow : Window
+{
+    public static string? UserName;
+
+    public ExampleWindow ()
+    {
+        Title = $"Example App ({Application.QuitKey} to quit)";
+
+        // Create input components and labels
+        var usernameLabel = new Label { Text = "Username:" };
+
+        var userNameText = new TextField
+        {
+            // Position text field adjacent to the label
+            X = Pos.Right (usernameLabel) + 1,
+
+            // Fill remaining horizontal space
+            Width = Dim.Fill ()
+        };
+
+        var passwordLabel = new Label
+        {
+            Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1
+        };
+
+        var passwordText = new TextField
+        {
+            Secret = true,
+
+            // align with the text box above
+            X = Pos.Left (userNameText),
+            Y = Pos.Top (passwordLabel),
+            Width = Dim.Fill ()
+        };
+
+        // Create login button
+        var btnLogin = new Button
+        {
+            Text = "Login",
+            Y = Pos.Bottom (passwordLabel) + 1,
+
+            // center the login button horizontally
+            X = Pos.Center (),
+            IsDefault = true
+        };
+
+        // When login button is clicked display a message popup
+        btnLogin.Accept += (s, e) =>
+        {
+            if (userNameText.Text == "admin" && passwordText.Text == "password")
+            {
+                MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                UserName = userNameText.Text;
+                Application.RequestStop ();
+            }
+            else
+            {
+                MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+            }
+        };
+
+        // Add the views to the Window
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
+    }
+}

+ 18 - 0
NativeAot/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishSingleFile>false</PublishSingleFile>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 18 - 0
NativeAot/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishSingleFile>false</PublishSingleFile>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 13 - 0
NativeAot/Properties/launchSettings.json

@@ -0,0 +1,13 @@
+{
+  "profiles": {
+    "NativeAot": {
+      "commandName": "Project"
+    },
+    "WSL : UICatalog": {
+      "commandName": "Executable",
+      "executablePath": "wsl",
+      "commandLineArgs": "dotnet NativeAot.dll",
+      "distributionName": ""
+    }
+  }
+}

+ 5 - 0
NativeAot/Publish_linux-x64_Debug.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+dotnet clean
+dotnet build
+dotnet publish -c Debug -r linux-x64 --self-contained

+ 5 - 0
NativeAot/Publish_linux-x64_Release.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+dotnet clean
+dotnet build
+dotnet publish -c Release -r linux-x64 --self-contained

+ 5 - 0
NativeAot/Publish_osx-x64_Debug.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+dotnet clean
+dotnet build
+dotnet publish -c Debug -r osx-x64 --self-contained

+ 5 - 0
NativeAot/Publish_osx-x64_Release.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+dotnet clean
+dotnet build
+dotnet publish -c Release -r osx-x64 --self-contained

+ 10 - 0
NativeAot/README.md

@@ -0,0 +1,10 @@
+# Terminal.Gui C# SelfContained
+
+This project aims to test the `Terminal.Gui` library to create a simple `native AOT` `self-container` GUI application in C#, ensuring that all its features are available.
+
+With `Debug` the `.csproj` is used and with `Release` the latest `nuget package` is used, either in `Solution Configurations` or in `Profile Publish` or in the `Publish_linux-x64` or in the `Publish_osx-x64` files.
+Unlike self-contained single-file publishing, native AOT publishing must be generated on the same platform as the target execution version. Therefore, if the target execution is Linux, then the publishing must be generated on a Linux operating system. Attempting to generate on Windows for the Linux target will throw an exception.
+
+To publish the `native AOT` file in `Debug` or `Release` mode, it is not necessary to select it in the `Solution Configurations`, just choose the `Debug` or `Release` configuration in the `Publish Profile` or the `*.sh` files.
+
+When executing the file directly from the `native AOT` file and needing to debug it, it will be necessary to attach it to the debugger, just like any other standalone application and selecting `Native Code`.

+ 10 - 0
NoSamples.slnf

@@ -0,0 +1,10 @@
+{
+  "solution": {
+    "path": "Terminal.sln",
+    "projects": [
+      "Terminal.Gui\\Terminal.Gui.csproj",
+      "UICatalog\\UICatalog.csproj",
+      "UnitTests\\UnitTests.csproj"
+    ]
+  }
+}

+ 122 - 17
README.md

@@ -1,17 +1,16 @@
 ![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.Gui/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
 ![Terminal.Gui](https://socialify.git.ci/gui-cs/Terminal.Gui/image?description=1&font=Rokkitt&forks=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2Fgui-cs%2FTerminal.Gui%2Fdevelop%2Fdocfx%2Fimages%2Flogo.png&name=1&owner=1&pattern=Circuit%20Board&stargazers=1&theme=Auto)
 ![.NET Core](https://github.com/gui-cs/Terminal.Gui/workflows/.NET%20Core/badge.svg?branch=develop)
 ![.NET Core](https://github.com/gui-cs/Terminal.Gui/workflows/.NET%20Core/badge.svg?branch=develop)
-![Code scanning - action](https://github.com/gui-cs/Terminal.Gui/workflows/Code%20scanning%20-%20action/badge.svg)
 [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui)
 [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui)
 ![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
 ![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27/raw/code-coverage.json)
 [![Downloads](https://img.shields.io/nuget/dt/Terminal.Gui)](https://www.nuget.org/packages/Terminal.Gui)
 [![Downloads](https://img.shields.io/nuget/dt/Terminal.Gui)](https://www.nuget.org/packages/Terminal.Gui)
 [![License](https://img.shields.io/github/license/gui-cs/gui.cs.svg)](LICENSE)
 [![License](https://img.shields.io/github/license/gui-cs/gui.cs.svg)](LICENSE)
 ![Bugs](https://img.shields.io/github/issues/gui-cs/gui.cs/bug)
 ![Bugs](https://img.shields.io/github/issues/gui-cs/gui.cs/bug)
 
 
-***The current, stable, release of Terminal.Gui is [v1.x](https://www.nuget.org/packages/Terminal.Gui). It is stable, rich, and broadly used. The team is now focused on designing and building a significant upgrade we're referring to as `v2`. Therefore:***
- * *`v1` is now in maintenance mode, meaning we will accept PRs for v1.x (the `develop` branch) only for issues impacting existing functionality.*
- * *All new development happens on the `v2_develop` branch. See the V2 discussion [here](https://github.com/gui-cs/Terminal.GuiV2Docs/discussions/1940).*
- * *Developers are encouraged to continue building on [v1.x](https://www.nuget.org/packages/Terminal.Gui) until we announce `v2` is stable.*
-
+* The current, stable, release of Terminal.Gui v1 is [![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui).
+* The current `prealpha` release of Terminal.Gui v2 can be found on [Nuget](https://www.nuget.org/packages/Terminal.Gui).
+* Developers starting new TUI projects are encouraged to target `v2`. The API is signifcantly changed, and significantly improved. There will be breaking changes in the API before Beta, but the core API is stable.
+* `v1` is in maintenance mode and we will only accept PRs for issues impacting existing functionality.
+ 
 **Terminal.Gui**: A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix.
 **Terminal.Gui**: A toolkit for building rich console apps for .NET, .NET Core, and Mono that works on Windows, the Mac, and Linux/Unix.
 
 
 ![Sample app](docfx/images/sample.gif)
 ![Sample app](docfx/images/sample.gif)
@@ -36,23 +35,129 @@ dotnet run
 * [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
 * [API Documentation](https://gui-cs.github.io/Terminal.GuiV2Docs/api/Terminal.Gui.html)
 * [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
 * [Documentation Home](https://gui-cs.github.io/Terminal.GuiV2Docs)
 
 
+The above documentation matches the most recent Nuget release from the `v2_develop` branch. Get the [v1 documentation here](This is the v2 API documentation. For v1 go here: https://gui-cs.github.io/Terminal.Gui/api/Terminal.Gui.html)
+
+See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. 
+
 ## Showcase & Examples
 ## Showcase & Examples
 
 
-* **[UI Catalog](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/UICatalog)** - The UI Catalog project provides an easy to use and extend sample illustrating the capabilities of **Terminal.Gui**. Run `dotnet run --project UICatalog` to run the UI Catalog.
-* **[C# Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
-* **[F# Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
-* **[Reactive Example](https://github.com/gui-cs/Terminal.GuiV2Docs/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers.
-* **[PowerShell's `Out-ConsoleGridView`](https://github.com/PowerShell/GraphicalTools)** - `OCGV` sends the output from a command to an interactive table. 
-* **[F7History](https://github.com/gui-cs/F7History)** - Graphical Command History for PowerShell (built on PowerShell's `Out-ConsoleGridView`).
-* **[PoshRedisViewer](https://github.com/En3Tho/PoshRedisViewer)** - A compact Redis viewer module for PowerShell written in F#.
-* **[PoshDotnetDumpAnalyzeViewer](https://github.com/En3Tho/PoshDotnetDumpAnalyzeViewer)** - dotnet-dump UI module for PowerShell.
-* **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
+**Terminal.Gui** can be used with any .Net language to create feature rich and robust applications.  
+[Showcase](https://github.com/gui-cs/Terminal.Gui/blob/develop/Showcase.md) is a place where you can find all kind of projects from simple examples to advanced real world apps that fully utilize capabilities of the toolkit.  
+The team is looking forward to seeing new amazing projects made by the community to be added there!
+
+## Sample Usage in C#
+
+The following example shows a basic Terminal.Gui application in C#:
+
+```csharp
+// This is a simple example application.  For the full range of functionality
+// see the UICatalog project
+
+// A simple Terminal.Gui example in C# - using C# 9.0 Top-level statements
+
+using System;
+using Terminal.Gui;
+
+Application.Run<ExampleWindow> ().Dispose ();
+
+// Before the application exits, reset Terminal.Gui for clean shutdown
+Application.Shutdown ();
+
+// To see this output on the screen it must be done after shutdown,
+// which restores the previous screen.
+Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+
+// Defines a top-level window with border and title
+public class ExampleWindow : Window
+{
+    public static string UserName;
+
+    public ExampleWindow ()
+    {
+        Title = $"Example App ({Application.QuitKey} to quit)";
+
+        // Create input components and labels
+        var usernameLabel = new Label { Text = "Username:" };
+
+        var userNameText = new TextField
+        {
+            // Position text field adjacent to the label
+            X = Pos.Right (usernameLabel) + 1,
+
+            // Fill remaining horizontal space
+            Width = Dim.Fill ()
+        };
+
+        var passwordLabel = new Label
+        {
+            Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1
+        };
+
+        var passwordText = new TextField
+        {
+            Secret = true,
+
+            // align with the text box above
+            X = Pos.Left (userNameText),
+            Y = Pos.Top (passwordLabel),
+            Width = Dim.Fill ()
+        };
+
+        // Create login button
+        var btnLogin = new Button
+        {
+            Text = "Login",
+            Y = Pos.Bottom (passwordLabel) + 1,
+
+            // center the login button horizontally
+            X = Pos.Center (),
+            IsDefault = true
+        };
+
+        // When login button is clicked display a message popup
+        btnLogin.Accept += (s, e) =>
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
+
+        // Add the views to the Window
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
+    }
+}
+```
+
+When run the application looks as follows:
+
+![Simple Usage app](./docfx/images/Example.png)
+
+## Installing
+
+Use NuGet to install the `Terminal.Gui` NuGet package: https://www.nuget.org/packages/Terminal.Gui
+
+### Installation in .NET Core Projects
+
+To install Terminal.Gui into a .NET Core project, use the `dotnet` CLI tool with this command.
+
+```
+dotnet add package Terminal.Gui
+```
+
+Or, you can use the [Terminal.Gui.Templates](https://github.com/gui-cs/Terminal.Gui.templates).
 
 
 ## Contributing
 ## Contributing
 
 
-See [CONTRIBUTING.md](https://github.com/gui-cs/Terminal.GuiV2Docs/blob/master/CONTRIBUTING.md).
+See [CONTRIBUTING.md](./CONTRIBUTING.md).
 
 
-Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.GuiV2Docs/issues?q=is%3Aopen+is%3Aissue+label%3Adesign).
+Debates on architecture and design can be found in Issues tagged with [design](https://github.com/gui-cs/Terminal.Gui/issues?q=is%3Aopen+is%3Aissue+label%3Av2+label%3Adesign).
 
 
 ## History
 ## History
 
 

+ 0 - 3
ReactiveExample/FodyWeavers.xml

@@ -1,3 +0,0 @@
-<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
-  <ReactiveUI />
-</Weavers>

+ 0 - 26
ReactiveExample/FodyWeavers.xsd

@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
-  <!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
-  <xs:element name="Weavers">
-    <xs:complexType>
-      <xs:all>
-        <xs:element name="ReactiveUI" minOccurs="0" maxOccurs="1" type="xs:anyType" />
-      </xs:all>
-      <xs:attribute name="VerifyAssembly" type="xs:boolean">
-        <xs:annotation>
-          <xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
-        </xs:annotation>
-      </xs:attribute>
-      <xs:attribute name="VerifyIgnoreCodes" type="xs:string">
-        <xs:annotation>
-          <xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
-        </xs:annotation>
-      </xs:attribute>
-      <xs:attribute name="GenerateXsd" type="xs:boolean">
-        <xs:annotation>
-          <xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
-        </xs:annotation>
-      </xs:attribute>
-    </xs:complexType>
-  </xs:element>
-</xs:schema>

+ 126 - 174
ReactiveExample/LoginView.cs

@@ -8,20 +8,137 @@ namespace ReactiveExample;
 
 
 public class LoginView : Window, IViewFor<LoginViewModel>
 public class LoginView : Window, IViewFor<LoginViewModel>
 {
 {
-    private readonly CompositeDisposable _disposable = new ();
+    private const string SuccessMessage = "The input is valid!";
+    private const string ErrorMessage = "Please enter a valid user name and password.";
+    private const string ProgressMessage = "Logging in...";
+    private const string IdleMessage = "Press 'Login' to log in.";
+
+    private readonly CompositeDisposable _disposable = [];
 
 
     public LoginView (LoginViewModel viewModel)
     public LoginView (LoginViewModel viewModel)
     {
     {
         Title = $"Reactive Extensions Example - {Application.QuitKey} to Exit";
         Title = $"Reactive Extensions Example - {Application.QuitKey} to Exit";
         ViewModel = viewModel;
         ViewModel = viewModel;
-        Label usernameLengthLabel = UsernameLengthLabel (TitleLabel ());
-        TextField usernameInput = UsernameInput (usernameLengthLabel);
-        Label passwordLengthLabel = PasswordLengthLabel (usernameLengthLabel);
-        TextField passwordInput = PasswordInput (passwordLengthLabel);
-        Label validationLabel = ValidationLabel (passwordInput);
-        Button loginButton = LoginButton (validationLabel);
-        Button clearButton = ClearButton (loginButton);
-        LoginProgressLabel (clearButton);
+        var title = this.AddControl<Label> (x => x.Text = "Login Form");
+        var unLengthLabel = title.AddControlAfter<Label> ((previous, unLength) =>
+            {
+                unLength.X = Pos.Left (previous);
+                unLength.Y = Pos.Top (previous) + 1;
+
+                ViewModel
+                    .WhenAnyValue (x => x.UsernameLength)
+                    .Select (length => $"_Username ({length} characters):")
+                    .BindTo (unLength, x => x.Text)
+                    .DisposeWith (_disposable);
+            });
+        unLengthLabel.AddControlAfter<TextField> ((previous, unInput) =>
+            {
+                unInput.X = Pos.Right (previous) + 1;
+                unInput.Y = Pos.Top (previous);
+                unInput.Width = 40;
+                unInput.Text = ViewModel.Username;
+
+                ViewModel
+                    .WhenAnyValue (x => x.Username)
+                    .BindTo (unInput, x => x.Text)
+                    .DisposeWith (_disposable);
+
+                unInput
+                    .Events ()
+                    .TextChanged
+                    .Select (_ => unInput.Text)
+                    .DistinctUntilChanged ()
+                    .BindTo (ViewModel, x => x.Username)
+                    .DisposeWith (_disposable);
+            });
+        unLengthLabel.AddControlAfter<Label> ((previous, pwLength) =>
+            {
+                pwLength.X = Pos.Left (previous);
+                pwLength.Y = Pos.Top (previous) + 1;
+
+                ViewModel
+                    .WhenAnyValue (x => x.PasswordLength)
+                    .Select (length => $"_Password ({length} characters):")
+                    .BindTo (pwLength, x => x.Text)
+                    .DisposeWith (_disposable);
+            })
+            .AddControlAfter<TextField> ((previous, pwInput) =>
+            {
+                pwInput.X = Pos.Right (previous) + 1;
+                pwInput.Y = Pos.Top (previous);
+                pwInput.Width = 40;
+                pwInput.Text = ViewModel.Password;
+
+                ViewModel
+                    .WhenAnyValue (x => x.Password)
+                    .BindTo (pwInput, x => x.Text)
+                    .DisposeWith (_disposable);
+
+                pwInput
+                    .Events ()
+                    .TextChanged
+                    .Select (_ => pwInput.Text)
+                    .DistinctUntilChanged ()
+                    .BindTo (ViewModel, x => x.Password)
+                    .DisposeWith (_disposable);
+            })
+            .AddControlAfter<Label> ((previous, validation) =>
+            {
+                validation.X = Pos.Left (previous);
+                validation.Y = Pos.Top (previous) + 1;
+                validation.Text = ErrorMessage;
+
+                ViewModel
+                    .WhenAnyValue (x => x.IsValid)
+                    .Select (valid => valid ? SuccessMessage : ErrorMessage)
+                    .BindTo (validation, x => x.Text)
+                    .DisposeWith (_disposable);
+
+                ViewModel
+                    .WhenAnyValue (x => x.IsValid)
+                    .Select (valid => valid ? Colors.ColorSchemes ["Base"] : Colors.ColorSchemes ["Error"])
+                    .BindTo (validation, x => x.ColorScheme)
+                    .DisposeWith (_disposable);
+            })
+            .AddControlAfter<Button> ((previous, login) =>
+            {
+                login.X = Pos.Left (previous);
+                login.Y = Pos.Top (previous) + 1;
+                login.Text = "_Login";
+
+                login
+                    .Events ()
+                    .Accept
+                    .InvokeCommand (ViewModel, x => x.Login)
+                    .DisposeWith (_disposable);
+            })
+            .AddControlAfter<Button> ((previous, clear) =>
+            {
+                clear.X = Pos.Left (previous);
+                clear.Y = Pos.Top (previous) + 1;
+                clear.Text = "_Clear";
+
+                clear
+                    .Events ()
+                    .Accept
+                    .InvokeCommand (ViewModel, x => x.ClearCommand)
+                    .DisposeWith (_disposable);
+            })
+            .AddControlAfter<Label> ((previous, progress) =>
+            {
+                progress.X = Pos.Left (previous);
+                progress.Y = Pos.Top (previous) + 1;
+                progress.Width = 40;
+                progress.Height = 1;
+                progress.Text = IdleMessage;
+
+                ViewModel
+                    .WhenAnyObservable (x => x.Login.IsExecuting)
+                    .Select (executing => executing ? ProgressMessage : IdleMessage)
+                    .ObserveOn (RxApp.MainThreadScheduler)
+                    .BindTo (progress, x => x.Text)
+                    .DisposeWith (_disposable);
+            });
     }
     }
 
 
     public LoginViewModel ViewModel { get; set; }
     public LoginViewModel ViewModel { get; set; }
@@ -37,169 +154,4 @@ public class LoginView : Window, IViewFor<LoginViewModel>
         _disposable.Dispose ();
         _disposable.Dispose ();
         base.Dispose (disposing);
         base.Dispose (disposing);
     }
     }
-
-    private Button ClearButton (View previous)
-    {
-        var clearButton = new Button
-        {
-            X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Text = "_Clear"
-        };
-
-        clearButton
-            .Events ()
-            .Accept
-            .InvokeCommand (ViewModel, x => x.Clear)
-            .DisposeWith (_disposable);
-        Add (clearButton);
-
-        return clearButton;
-    }
-
-    private Button LoginButton (View previous)
-    {
-        var loginButton = new Button
-        {
-            X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Text = "_Login"
-        };
-
-        loginButton
-            .Events ()
-            .Accept
-            .InvokeCommand (ViewModel, x => x.Login)
-            .DisposeWith (_disposable);
-        Add (loginButton);
-
-        return loginButton;
-    }
-
-    private Label LoginProgressLabel (View previous)
-    {
-        var progress = "Logging in...";
-        var idle = "Press 'Login' to log in.";
-
-        var loginProgressLabel = new Label
-        {
-            X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Width = 40, Height = 1, Text = idle
-        };
-
-        ViewModel
-            .WhenAnyObservable (x => x.Login.IsExecuting)
-            .Select (executing => executing ? progress : idle)
-            .ObserveOn (RxApp.MainThreadScheduler)
-            .BindTo (loginProgressLabel, x => x.Text)
-            .DisposeWith (_disposable);
-        Add (loginProgressLabel);
-
-        return loginProgressLabel;
-    }
-
-    private TextField PasswordInput (View previous)
-    {
-        var passwordInput = new TextField
-        {
-            X = Pos.Right (previous) + 1, Y = Pos.Top (previous), Width = 40, Text = ViewModel.Password
-        };
-
-        ViewModel
-            .WhenAnyValue (x => x.Password)
-            .BindTo (passwordInput, x => x.Text)
-            .DisposeWith (_disposable);
-
-        passwordInput
-            .Events ()
-            .TextChanged
-            .Select (old => passwordInput.Text)
-            .DistinctUntilChanged ()
-            .BindTo (ViewModel, x => x.Password)
-            .DisposeWith (_disposable);
-        Add (passwordInput);
-
-        return passwordInput;
-    }
-
-    private Label PasswordLengthLabel (View previous)
-    {
-        var passwordLengthLabel = new Label { X = Pos.Left (previous), Y = Pos.Top (previous) + 1, };
-
-        ViewModel
-            .WhenAnyValue (x => x.PasswordLength)
-            .Select (length => $"_Password ({length} characters):")
-            .BindTo (passwordLengthLabel, x => x.Text)
-            .DisposeWith (_disposable);
-        Add (passwordLengthLabel);
-
-        return passwordLengthLabel;
-    }
-
-    private Label TitleLabel ()
-    {
-        var label = new Label { Text = "Login Form" };
-        Add (label);
-
-        return label;
-    }
-
-    private TextField UsernameInput (View previous)
-    {
-        var usernameInput = new TextField
-        {
-            X = Pos.Right (previous) + 1, Y = Pos.Top (previous), Width = 40, Text = ViewModel.Username
-        };
-
-        ViewModel
-            .WhenAnyValue (x => x.Username)
-            .BindTo (usernameInput, x => x.Text)
-            .DisposeWith (_disposable);
-
-        usernameInput
-            .Events ()
-            .TextChanged
-            .Select (old => usernameInput.Text)
-            .DistinctUntilChanged ()
-            .BindTo (ViewModel, x => x.Username)
-            .DisposeWith (_disposable);
-        Add (usernameInput);
-
-        return usernameInput;
-    }
-
-    private Label UsernameLengthLabel (View previous)
-    {
-        var usernameLengthLabel = new Label { X = Pos.Left (previous), Y = Pos.Top (previous) + 1 };
-
-        ViewModel
-            .WhenAnyValue (x => x.UsernameLength)
-            .Select (length => $"_Username ({length} characters):")
-            .BindTo (usernameLengthLabel, x => x.Text)
-            .DisposeWith (_disposable);
-        Add (usernameLengthLabel);
-
-        return usernameLengthLabel;
-    }
-
-    private Label ValidationLabel (View previous)
-    {
-        var error = "Please enter a valid user name and password.";
-        var success = "The input is valid!";
-
-        var validationLabel = new Label
-        {
-           X = Pos.Left (previous), Y = Pos.Top (previous) + 1, Text = error
-        };
-
-        ViewModel
-            .WhenAnyValue (x => x.IsValid)
-            .Select (valid => valid ? success : error)
-            .BindTo (validationLabel, x => x.Text)
-            .DisposeWith (_disposable);
-
-        ViewModel
-            .WhenAnyValue (x => x.IsValid)
-            .Select (valid => valid ? Colors.ColorSchemes ["Base"] : Colors.ColorSchemes ["Error"])
-            .BindTo (validationLabel, x => x.ColorScheme)
-            .DisposeWith (_disposable);
-        Add (validationLabel);
-
-        return validationLabel;
-    }
 }
 }

+ 38 - 43
ReactiveExample/LoginViewModel.cs

@@ -5,7 +5,7 @@ using System.Reactive.Linq;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using ReactiveUI;
 using ReactiveUI;
-using ReactiveUI.Fody.Helpers;
+using ReactiveUI.SourceGenerators;
 
 
 namespace ReactiveExample;
 namespace ReactiveExample;
 
 
@@ -21,41 +21,53 @@ namespace ReactiveExample;
 // See also: https://www.reactiveui.net../docs/handbook/data-persistence/
 // See also: https://www.reactiveui.net../docs/handbook/data-persistence/
 //
 //
 [DataContract]
 [DataContract]
-public class LoginViewModel : ReactiveObject
+public partial class LoginViewModel : ReactiveObject
 {
 {
-    private readonly ObservableAsPropertyHelper<bool> _isValid;
-    private readonly ObservableAsPropertyHelper<int> _passwordLength;
-    private readonly ObservableAsPropertyHelper<int> _usernameLength;
+    [IgnoreDataMember]
+    [ObservableAsProperty] private bool _isValid;
 
 
-    public LoginViewModel ()
-    {
-        IObservable<bool> canLogin = this.WhenAnyValue (
-                                                        x => x.Username,
-                                                        x => x.Password,
-                                                        (username, password) =>
-                                                            !string.IsNullOrEmpty (username) && !string.IsNullOrEmpty (password)
-                                                       );
+    [IgnoreDataMember]
+    [ObservableAsProperty] private int _passwordLength;
 
 
-        _isValid = canLogin.ToProperty (this, x => x.IsValid);
+    [IgnoreDataMember]
+    [ObservableAsProperty] private int _usernameLength;
 
 
-        Login = ReactiveCommand.CreateFromTask<CancelEventArgs> (
-                                                                 e => Task.Delay (TimeSpan.FromSeconds (1)),
-                                                                 canLogin
-                                                                );
+    [DataMember]
+    [Reactive] private string _password = string.Empty;
 
 
-        _usernameLength = this
+    [DataMember]
+    [Reactive] private string _username = string.Empty;
+
+    public LoginViewModel ()
+    {
+        InitializeCommands ();
+        IObservable<bool> canLogin = this.WhenAnyValue
+            (
+                x => x.Username,
+                x => x.Password,
+                (username, password) =>
+                    !string.IsNullOrEmpty (username) && !string.IsNullOrEmpty (password)
+            );
+
+        _isValidHelper = canLogin.ToProperty (this, x => x.IsValid);
+
+        Login = ReactiveCommand.CreateFromTask<HandledEventArgs>
+            (
+                e => Task.Delay (TimeSpan.FromSeconds (1)),
+                canLogin
+            );
+
+        _usernameLengthHelper = this
                           .WhenAnyValue (x => x.Username)
                           .WhenAnyValue (x => x.Username)
                           .Select (name => name.Length)
                           .Select (name => name.Length)
                           .ToProperty (this, x => x.UsernameLength);
                           .ToProperty (this, x => x.UsernameLength);
 
 
-        _passwordLength = this
+        _passwordLengthHelper = this
                           .WhenAnyValue (x => x.Password)
                           .WhenAnyValue (x => x.Password)
                           .Select (password => password.Length)
                           .Select (password => password.Length)
                           .ToProperty (this, x => x.PasswordLength);
                           .ToProperty (this, x => x.PasswordLength);
 
 
-        Clear = ReactiveCommand.Create<CancelEventArgs> (e => { });
-
-        Clear.Subscribe (
+        ClearCommand.Subscribe (
                          unit =>
                          unit =>
                          {
                          {
                              Username = string.Empty;
                              Username = string.Empty;
@@ -64,26 +76,9 @@ public class LoginViewModel : ReactiveObject
                         );
                         );
     }
     }
 
 
-    [IgnoreDataMember]
-    public ReactiveCommand<CancelEventArgs, Unit> Clear { get; }
-
-    [IgnoreDataMember]
-    public bool IsValid => _isValid.Value;
-
-    [IgnoreDataMember]
-    public ReactiveCommand<CancelEventArgs, Unit> Login { get; }
-
-    [Reactive]
-    [DataMember]
-    public string Password { get; set; } = string.Empty;
-
-    [IgnoreDataMember]
-    public int PasswordLength => _passwordLength.Value;
-
-    [Reactive]
-    [DataMember]
-    public string Username { get; set; } = string.Empty;
+    [ReactiveCommand]
+    public void Clear (HandledEventArgs args) { }
 
 
     [IgnoreDataMember]
     [IgnoreDataMember]
-    public int UsernameLength => _usernameLength.Value;
+    public ReactiveCommand<HandledEventArgs, Unit> Login { get; }
 }
 }

+ 1 - 1
ReactiveExample/Program.cs

@@ -12,7 +12,7 @@ public static class Program
         RxApp.MainThreadScheduler = TerminalScheduler.Default;
         RxApp.MainThreadScheduler = TerminalScheduler.Default;
         RxApp.TaskpoolScheduler = TaskPoolScheduler.Default;
         RxApp.TaskpoolScheduler = TaskPoolScheduler.Default;
         Application.Run (new LoginView (new LoginViewModel ()));
         Application.Run (new LoginView (new LoginViewModel ()));
-        Application.Top.Dispose();
+        Application.Top.Dispose ();
         Application.Shutdown ();
         Application.Shutdown ();
     }
     }
 }
 }

+ 1 - 1
ReactiveExample/README.md

@@ -1,4 +1,4 @@
-This is a sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers.
+This is a sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [ObservableEvents](https://github.com/reactivemarbles/ObservableEvents) — a Source Generator that turns events into observable wrappers.
 
 
 <img src="https://user-images.githubusercontent.com/6759207/94748621-646a7280-038a-11eb-8ea0-34629dc799b3.gif" width="450">
 <img src="https://user-images.githubusercontent.com/6759207/94748621-646a7280-038a-11eb-8ea0-34629dc799b3.gif" width="450">
 
 

+ 3 - 3
ReactiveExample/ReactiveExample.csproj

@@ -11,9 +11,9 @@
     <InformationalVersion>2.0</InformationalVersion>
     <InformationalVersion>2.0</InformationalVersion>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
-    <PackageReference Include="ReactiveUI" Version="20.0.1" />
-    <PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
+    <PackageReference Include="ReactiveUI" Version="[20.1.1,21)" />
+    <PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="[1.3.1,2)" PrivateAssets="all" />
+    <PackageReference Include="ReactiveUI.SourceGenerators" Version="[1.0.3,2)" PrivateAssets="all" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />

+ 24 - 0
ReactiveExample/ViewExtensions.cs

@@ -0,0 +1,24 @@
+using System;
+using Terminal.Gui;
+
+namespace ReactiveExample;
+public static class ViewExtensions
+{
+    public static (Window MainView, TOut LastControl) AddControl<TOut> (this Window view, Action<TOut> action)
+        where TOut : View, new()
+    {
+        TOut result = new ();
+        action (result);
+        view.Add (result);
+        return (view, result);
+    }
+
+    public static (Window MainView, TOut LastControl) AddControlAfter<TOut> (this (Window MainView, View LastControl) view, Action<View, TOut> action)
+        where TOut : View, new()
+    {
+        TOut result = new ();
+        action (view.LastControl, result);
+        view.MainView.Add (result);
+        return (view.MainView, result);
+    }
+}

+ 2 - 2
Release.ps1

@@ -5,8 +5,8 @@ param(
     [int]$Version
     [int]$Version
 )
 )
 
 
-$branch = "v2_develop"
-$tag = "v2.0.0-alpha.$Version"
+$branch = "v2_release"
+$tag = "$Version-prealpha"
 $releaseMessage = "Release $tag"
 $releaseMessage = "Release $tag"
 
 
 try {
 try {

+ 10 - 0
Release.slnf

@@ -0,0 +1,10 @@
+{
+  "solution": {
+    "path": "Terminal.sln",
+    "projects": [
+      "Terminal.Gui\\Terminal.Gui.csproj",
+      "UICatalog\\UICatalog.csproj",
+      "UnitTests\\UnitTests.csproj"
+    ]
+  }
+}

+ 0 - 117
Scripts/Terminal.Gui.PowerShell.Analyzers.psd1

@@ -1,117 +0,0 @@
-#
-# Module manifest for module 'Terminal.Gui.Powershell.Analyzers'
-#
-# Generated by: Brandon Thetford (GitHub @dodexahedron)
-#
-# Generated on: 4/24/2024
-#
-
-@{
-
-# Script module or binary module file associated with this manifest.
-RootModule = ''
-
-# Version number of this module.
-ModuleVersion = '1.0.0'
-
-# Supported PSEditions
-CompatiblePSEditions = @('Core')
-
-# ID used to uniquely identify this module
-GUID = '3e85001d-6539-4cf1-b71c-ec9e983f7fc8'
-
-# Author of this module
-Author = 'Brandon Thetford (GitHub @dodexahedron)'
-
-# Company or vendor of this module
-CompanyName = 'The Terminal.Gui Project'
-
-# Copyright statement for this module
-Copyright = '(c) Brandon Thetford (GitHub @dodexahedron). Provided to the Terminal.Gui project and you under the terms of the MIT License.'
-
-# Description of the functionality provided by this module
-Description = 'Operations involving Terminal.Gui analyzer projects, fur use during development of Terminal.Gui'
-
-# Minimum version of the PowerShell engine required by this module
-PowerShellVersion = '7.4.0'
-
-# Name of the PowerShell host required by this module
-PowerShellHostName = 'ConsoleHost'
-
-# Minimum version of the PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-RequiredModules = @('Microsoft.PowerShell.Management','Microsoft.PowerShell.Utility','./Terminal.Gui.PowerShell.Core.psd1')
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = @()
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
-# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
-
-# Modules to import as nested modules.
-NestedModules = @('./Terminal.Gui.PowerShell.Analyzers.psm1')
-
-# Functions to export from this module.
-FunctionsToExport = @('Build-Analyzers')
-
-# Cmdlets to export from this module.
-CmdletsToExport = @()
-
-# Variables to export from this module
-VariablesToExport = @()
-
-# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
-AliasesToExport = @()
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
-PrivateData = @{
-
-    PSData = @{
-
-        # Tags applied to this module. These help with module discovery in online galleries.
-        # Tags = @()
-
-        # A URL to the license for this module.
-        LicenseUri = 'https://github.com/gui-cs/Terminal.Gui/Scripts/COPYRIGHT'
-
-        # A URL to the main website for this project.
-        ProjectUri = 'https://github.com/gui-cs/Terminal.Gui'
-
-        # A URL to an icon representing this module.
-        # IconUri = ''
-
-        # ReleaseNotes of this module
-        # ReleaseNotes = ''
-
-        # Prerelease string of this module
-        # Prerelease = ''
-
-        # Flag to indicate whether the module requires explicit user acceptance for install/update/save
-        # RequireLicenseAcceptance = $false
-
-        # External dependent modules of this module
-        # ExternalModuleDependencies = @()
-
-    } # End of PSData hashtable
-
-} # End of PrivateData hashtable
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
-
-}
-

+ 0 - 96
Scripts/Terminal.Gui.PowerShell.Analyzers.psm1

@@ -1,96 +0,0 @@
-<#
-  .SYNOPSIS
-  Builds all analyzer projects in Debug and Release configurations.
-  .DESCRIPTION
-  Uses dotnet build to build all analyzer projects, with optional behavior changes via switch parameters.
-  .PARAMETER AutoClose
-  Automatically close running Visual Studio processes which have the Terminal.sln solution loaded, before taking any other actions.
-  .PARAMETER AutoLaunch
-  Automatically start a new Visual Studio process and load the solution after completion.
-  .PARAMETER Force
-  Carry out operations unconditionally and do not prompt for confirmation.
-  .PARAMETER NoClean
-  Do not delete the bin and obj folders before building the analyzers. Usually best not to use this, but can speed up the builds slightly.
-  .PARAMETER Quiet
-  Write less text output to the terminal.
-  .INPUTS
-  None
-  .OUTPUTS
-  None
-#>
-Function Build-Analyzers {
-  [CmdletBinding()]
-  param(
-    [Parameter(Mandatory=$false, HelpMessage="Automatically close running Visual Studio processes which have the Terminal.sln solution loaded, before taking any other actions.")]
-    [switch]$AutoClose,
-    [Parameter(Mandatory=$false, HelpMessage="Automatically start a new Visual Studio process and load the solution after completion.")]
-    [switch]$AutoLaunch,
-    [Parameter(Mandatory=$false, HelpMessage="Carry out operations unconditionally and do not prompt for confirmation.")]
-    [switch]$Force,
-    [Parameter(Mandatory=$false, HelpMessage="Do not delete the bin and obj folders before building the analyzers.")]
-    [switch]$NoClean,
-    [Parameter(Mandatory=$false, HelpMessage="Write less text output to the terminal.")]
-    [switch]$Quiet
-  )
-  
-  if($AutoClose) {
-    if(!$Quiet) {
-      Write-Host Closing Visual Studio processes
-    }
-    Close-Solution
-  }
-
-  if($Force){
-    $response = 'Y'
-  }
-  elseif(!$Force && $NoClean){
-    $response = ($r = Read-Host "Pre-build Terminal.Gui.InternalAnalyzers without removing old build artifacts? [Y/n]") ? $r : 'Y'
-  }
-  else{
-    $response = ($r = Read-Host "Delete bin and obj folders for Terminal.Gui and Terminal.Gui.InternalAnalyzers and pre-build Terminal.Gui.InternalAnalyzers? [Y/n]") ? $r : 'Y'
-  }
-
-  if (($response -ne 'Y')) {
-    Write-Host Took no action
-    return
-  }
-  
-  Push-Location $InternalAnalyzersProjectDirectory
-  
-  if(!$NoClean) {
-    if(!$Quiet) {
-      Write-Host Deleting bin and obj folders for Terminal.Gui
-    }
-    Remove-Item -Recurse -Force $TerminalGuiProjectDirectory/bin -ErrorAction SilentlyContinue
-    Remove-Item -Recurse -Force $TerminalGuiProjectDirectory/obj -ErrorAction SilentlyContinue
-
-    if(!$Quiet) {
-      Write-Host Deleting bin and obj folders for Terminal.Gui.InternalAnalyzers
-    }
-    Remove-Item -Recurse -Force $InternalAnalyzersProjectDirectory/bin -ErrorAction SilentlyContinue
-    Remove-Item -Recurse -Force $InternalAnalyzersProjectDirectory/obj -ErrorAction SilentlyContinue
-  }
-  
-  if(!$Quiet) {
-    Write-Host Building analyzers in Debug configuration
-  }
-  dotnet build $InternalAnalyzersProjectFilePath --no-incremental --nologo --force --configuration Debug
-
-  if(!$Quiet) {
-    Write-Host Building analyzers in Release configuration
-  }
-  dotnet build $InternalAnalyzersProjectFilePath --no-incremental --nologo --force --configuration Release
-
-  Pop-Location
-  
-  if(!$AutoLaunch) {
-    Write-Host -ForegroundColor Green Finished. Restart Visual Studio for changes to take effect.
-  } else {
-    if(!$Quiet) {
-      Write-Host -ForegroundColor Green Finished. Re-loading Terminal.sln.
-    }
-    Open-Solution
-  }
-
-  return
-}

+ 0 - 6
Scripts/Terminal.Gui.PowerShell.Core.psm1

@@ -69,9 +69,6 @@ Function Set-PowerShellEnvironment {
   New-Variable -Name SolutionFilePath -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.sln") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name SolutionFilePath -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.sln") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectDirectory -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.Gui") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectDirectory -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.Gui") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectFilePath -Value (Join-Path -Resolve $TerminalGuiProjectDirectory "Terminal.Gui.csproj") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectFilePath -Value (Join-Path -Resolve $TerminalGuiProjectDirectory "Terminal.Gui.csproj") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name AnalyzersDirectory -Value (Join-Path -Resolve $RepositoryRootDirectory "Analyzers") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name InternalAnalyzersProjectDirectory -Value (Join-Path -Resolve $AnalyzersDirectory "Terminal.Gui.Analyzers.Internal") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name InternalAnalyzersProjectFilePath -Value (Join-Path -Resolve $InternalAnalyzersProjectDirectory "Terminal.Gui.Analyzers.Internal.csproj") -Option ReadOnly -Scope Global -Visibility Public
 
 
   # Save existing PSModulePath for optional reset later.
   # Save existing PSModulePath for optional reset later.
   # If it is already saved, do not overwrite, but continue anyway.
   # If it is already saved, do not overwrite, but continue anyway.
@@ -137,9 +134,6 @@ Function Reset-PowerShellEnvironment {
   Remove-Variable -Name TerminalGuiProjectDirectory -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name TerminalGuiProjectDirectory -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name TerminalGuiProjectFilePath -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name TerminalGuiProjectFilePath -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name ScriptsDirectory -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name ScriptsDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name AnalyzersDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name InternalAnalyzersProjectDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name InternalAnalyzersProjectFilePath -Scope Global -Force -ErrorAction SilentlyContinue
 }
 }
 
 
 # This ensures the environment is reset when unloading the module.
 # This ensures the environment is reset when unloading the module.

+ 1 - 1
Scripts/Terminal.Gui.PowerShell.psd1

@@ -81,7 +81,7 @@ RequiredModules = @(
 
 
 # Modules to import as nested modules of this module.
 # Modules to import as nested modules of this module.
 # This module is just a shortcut that loads all of our modules.
 # This module is just a shortcut that loads all of our modules.
-NestedModules = @('./Terminal.Gui.PowerShell.Core.psd1', './Terminal.Gui.PowerShell.Analyzers.psd1', './Terminal.Gui.PowerShell.Git.psd1', './Terminal.Gui.PowerShell.Build.psd1')
+NestedModules = @('./Terminal.Gui.PowerShell.Core.psd1', './Terminal.Gui.PowerShell.Git.psd1', './Terminal.Gui.PowerShell.Build.psd1')
 
 
 # Functions to export from this module.
 # Functions to export from this module.
 # Not filtered, so exports all functions exported by all nested modules.
 # Not filtered, so exports all functions exported by all nested modules.

+ 112 - 0
SelfContained/Program.cs

@@ -0,0 +1,112 @@
+// This is a test application for a self-contained single file.
+
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using Terminal.Gui;
+
+namespace SelfContained;
+
+public static class Program
+{
+    [RequiresUnreferencedCode ("Calls Terminal.Gui.Application.Run<T>(Func<Exception, Boolean>, ConsoleDriver)")]
+    private static void Main (string [] args)
+    {
+        Application.Init ();
+
+        #region The code in this region is not intended for use in a self-contained single-file. It's just here to make sure there is no functionality break with localization in Terminal.Gui using single-file
+
+        if (Equals (Thread.CurrentThread.CurrentUICulture, CultureInfo.InvariantCulture) && Application.SupportedCultures?.Count == 0)
+        {
+            // Only happens if the project has <InvariantGlobalization>true</InvariantGlobalization>
+            Debug.Assert (Application.SupportedCultures.Count == 0);
+        }
+        else
+        {
+            Debug.Assert (Application.SupportedCultures?.Count > 0);
+            Debug.Assert (Equals (CultureInfo.CurrentCulture, Thread.CurrentThread.CurrentUICulture));
+        }
+
+        #endregion
+
+        ExampleWindow app = new ();
+        Application.Run (app);
+
+        // Dispose the app object before shutdown
+        app.Dispose ();
+
+        // Before the application exits, reset Terminal.Gui for clean shutdown
+        Application.Shutdown ();
+
+        // To see this output on the screen it must be done after shutdown,
+        // which restores the previous screen.
+        Console.WriteLine ($@"Username: {ExampleWindow.UserName}");
+    }
+}
+
+// Defines a top-level window with border and title
+public class ExampleWindow : Window
+{
+    public static string? UserName;
+
+    public ExampleWindow ()
+    {
+        Title = $"Example App ({Application.QuitKey} to quit)";
+
+        // Create input components and labels
+        var usernameLabel = new Label { Text = "Username:" };
+
+        var userNameText = new TextField
+        {
+            // Position text field adjacent to the label
+            X = Pos.Right (usernameLabel) + 1,
+
+            // Fill remaining horizontal space
+            Width = Dim.Fill ()
+        };
+
+        var passwordLabel = new Label
+        {
+            Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1
+        };
+
+        var passwordText = new TextField
+        {
+            Secret = true,
+
+            // align with the text box above
+            X = Pos.Left (userNameText),
+            Y = Pos.Top (passwordLabel),
+            Width = Dim.Fill ()
+        };
+
+        // Create login button
+        var btnLogin = new Button
+        {
+            Text = "Login",
+            Y = Pos.Bottom (passwordLabel) + 1,
+
+            // center the login button horizontally
+            X = Pos.Center (),
+            IsDefault = true
+        };
+
+        // When login button is clicked display a message popup
+        btnLogin.Accept += (s, e) =>
+                           {
+                               if (userNameText.Text == "admin" && passwordText.Text == "password")
+                               {
+                                   MessageBox.Query ("Logging In", "Login Successful", "Ok");
+                                   UserName = userNameText.Text;
+                                   Application.RequestStop ();
+                               }
+                               else
+                               {
+                                   MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
+                               }
+                           };
+
+        // Add the views to the Window
+        Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin);
+    }
+}

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Debug.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\linux-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_linux-x64_Release.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\linux-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Debug.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\osx-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 16 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_osx-x64_Release.pubxml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\osx-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 17 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Debug.pubxml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Debug</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Debug\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 17 - 0
SelfContained/Properties/PublishProfiles/FolderProfile_net8.0_win-x64_Release.pubxml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <PublishDir>bin\Release\net8.0\publish\win-x64\</PublishDir>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <_TargetId>Folder</_TargetId>
+    <TargetFramework>net8.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <SelfContained>true</SelfContained>
+    <PublishReadyToRun>false</PublishReadyToRun>
+  </PropertyGroup>
+</Project>

+ 9 - 0
SelfContained/README.md

@@ -0,0 +1,9 @@
+# Terminal.Gui C# SelfContained
+
+This project aims to test the `Terminal.Gui` library to create a simple `self-contained` `single-file` GUI application in C#, ensuring that all its features are available.
+
+With `Debug` the `.csproj` is used and with `Release` the latest `nuget package` is used, either in `Solution Configurations` or in `Profile Publish`.
+
+To publish the self-contained single file in `Debug` or `Release` mode, it is not necessary to select it in the `Solution Configurations`, just choose the `Debug` or `Release` configuration in the `Publish Profile`.
+
+When executing the file directly from the self-contained single file and needing to debug it, it will be necessary to attach it to the debugger, just like any other standalone application. However, when trying to attach the file running on `Linux` or `macOS` to the debugger, it will issue the error "`Failed to attach to process: Unknown Error: 0x80131c3c`". This issue has already been reported on [Developer Community](https://developercommunity.visualstudio.com/t/Failed-to-attach-to-process:-Unknown-Err/10694351). Maybe it would be a good idea to vote in favor of this fix because I think `Visual Studio for macOS` is going to be discontinued and we need this fix to remotely attach a process running on `Linux` or `macOS` to `Windows 11`.

+ 25 - 0
SelfContained/SelfContained.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+    <PublishTrimmed>true</PublishTrimmed>
+    <TrimMode>Link</TrimMode>
+    <PublishSingleFile>true</PublishSingleFile>
+    <InvariantGlobalization>false</InvariantGlobalization>
+    <DebugType>embedded</DebugType>
+  </PropertyGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <PackageReference Include="Terminal.Gui" Version="[2.0.0-pre.1788,3)" />
+    <TrimmerRootAssembly Include="Terminal.Gui" />
+  </ItemGroup>
+
+</Project>

+ 31 - 0
Showcase.md

@@ -0,0 +1,31 @@
+# Showcase #
+
+* **[UI Catalog](https://github.com/gui-cs/Terminal.Gui/tree/master/UICatalog)** - The UI Catalog project provides an easy to use and extend sample illustrating the capabilities of **Terminal.Gui**. Run `dotnet run --project UICatalog` to run the UI Catalog.
+  ![Sample app](docfx/images/sample.gif)  
+  ⠀
+* **[PowerShell's `Out-ConsoleGridView`](https://github.com/PowerShell/GraphicalTools)** - `OCGV` sends the output from a command to an interactive table.
+  ![OutConsoleGridView.png](docfx/images/OutConsoleGridView.png)  
+  ⠀
+* **[F7History](https://github.com/gui-cs/F7History)** - Graphical Command History for PowerShell (built on PowerShell's `Out-ConsoleGridView`).
+  ![F7History.gif](docfx/images/F7History.gif)  
+  ⠀
+* **[PoshRedisViewer](https://github.com/En3Tho/PoshRedisViewer)** - A compact Redis viewer module for PowerShell written in F#.
+  ![PoshRedisViewer.png](docfx/images/PoshRedisViewer.png)  
+  ⠀
+* **[PoshDotnetDumpAnalyzeViewer](https://github.com/En3Tho/PoshDotnetDumpAnalyzeViewer)** - dotnet-dump UI module for PowerShell.
+  ![PoshDotnetDumpAnalyzerViewer.png](docfx/images/PoshDotnetDumpAnalyzerViewer.png)  
+  ⠀
+* **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
+  ![TerminalGuiDesigner.gif](docfx/images/TerminalGuiDesigner.gif)
+
+* **[Capital and Cargo](https://github.com/dhorions/Capital-and-Cargo)** - A retro console game where you buy, sell, produce and transport goods built with Terminal.Gui
+ ![image](https://github.com/gui-cs/Terminal.Gui/assets/1682004/ed89f3d6-020f-4a8a-ae18-e057514f4c43)
+
+  
+# Examples #
+
+* **[C# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
+
+* **[F# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
+
+* **[Reactive Example](https://github.com/gui-cs/Terminal.Gui/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers. 

+ 29 - 0
Terminal.Gui/Application/Application.Driver.cs

@@ -0,0 +1,29 @@
+#nullable enable
+namespace Terminal.Gui;
+
+public static partial class Application // Driver abstractions
+{
+    internal static bool _forceFakeConsole;
+
+    /// <summary>Gets the <see cref="ConsoleDriver"/> that has been selected. See also <see cref="ForceDriver"/>.</summary>
+    public static ConsoleDriver? Driver { get; internal set; }
+
+    /// <summary>
+    ///     Gets or sets whether <see cref="Application.Driver"/> will be forced to output only the 16 colors defined in
+    ///     <see cref="ColorName"/>. The default is <see langword="false"/>, meaning 24-bit (TrueColor) colors will be output
+    ///     as long as the selected <see cref="ConsoleDriver"/> supports TrueColor.
+    /// </summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static bool Force16Colors { get; set; }
+
+    /// <summary>
+    ///     Forces the use of the specified driver (one of "fake", "ansi", "curses", "net", or "windows"). If not
+    ///     specified, the driver is selected based on the platform.
+    /// </summary>
+    /// <remarks>
+    ///     Note, <see cref="Application.Init(ConsoleDriver, string)"/> will override this configuration setting if called
+    ///     with either `driver` or `driverName` specified.
+    /// </remarks>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static string ForceDriver { get; set; } = string.Empty;
+}

+ 214 - 0
Terminal.Gui/Application/Application.Initialization.cs

@@ -0,0 +1,214 @@
+#nullable enable
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+
+namespace Terminal.Gui;
+
+public static partial class Application // Initialization (Init/Shutdown)
+{
+    /// <summary>Initializes a new instance of <see cref="Terminal.Gui"/> Application.</summary>
+    /// <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
+    /// <para>
+    ///     This function loads the right <see cref="ConsoleDriver"/> for the platform, Creates a <see cref="Toplevel"/>. and
+    ///     assigns it to <see cref="Top"/>
+    /// </para>
+    /// <para>
+    ///     <see cref="Shutdown"/> must be called when the application is closing (typically after
+    ///     <see cref="Run{T}"/> has returned) to ensure resources are cleaned up and
+    ///     terminal settings
+    ///     restored.
+    /// </para>
+    /// <para>
+    ///     The <see cref="Run{T}"/> function combines
+    ///     <see cref="Init(Terminal.Gui.ConsoleDriver,string)"/> and <see cref="Run(Toplevel, Func{Exception, bool})"/>
+    ///     into a single
+    ///     call. An application cam use <see cref="Run{T}"/> without explicitly calling
+    ///     <see cref="Init(Terminal.Gui.ConsoleDriver,string)"/>.
+    /// </para>
+    /// <param name="driver">
+    ///     The <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or
+    ///     <paramref name="driverName"/> are specified the default driver for the platform will be used.
+    /// </param>
+    /// <param name="driverName">
+    ///     The short name (e.g. "net", "windows", "ansi", "fake", or "curses") of the
+    ///     <see cref="ConsoleDriver"/> to use. If neither <paramref name="driver"/> or <paramref name="driverName"/> are
+    ///     specified the default driver for the platform will be used.
+    /// </param>
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+    public static void Init (ConsoleDriver? driver = null, string? driverName = null) { InternalInit (driver, driverName); }
+
+    internal static bool IsInitialized { get; set; }
+    internal static int MainThreadId { get; set; } = -1;
+
+    // INTERNAL function for initializing an app with a Toplevel factory object, driver, and mainloop.
+    //
+    // Called from:
+    //
+    // Init() - When the user wants to use the default Toplevel. calledViaRunT will be false, causing all state to be reset.
+    // Run<T>() - When the user wants to use a custom Toplevel. calledViaRunT will be true, enabling Run<T>() to be called without calling Init first.
+    // Unit Tests - To initialize the app with a custom Toplevel, using the FakeDriver. calledViaRunT will be false, causing all state to be reset.
+    //
+    // calledViaRunT: If false (default) all state will be reset. If true the state will not be reset.
+    [RequiresUnreferencedCode ("AOT")]
+    [RequiresDynamicCode ("AOT")]
+    internal static void InternalInit (
+        ConsoleDriver? driver = null,
+        string? driverName = null,
+        bool calledViaRunT = false
+    )
+    {
+        if (IsInitialized && driver is null)
+        {
+            return;
+        }
+
+        if (IsInitialized)
+        {
+            throw new InvalidOperationException ("Init has already been called and must be bracketed by Shutdown.");
+        }
+
+        if (!calledViaRunT)
+        {
+            // Reset all class variables (Application is a singleton).
+            ResetState ();
+        }
+
+        Navigation = new ();
+
+        // For UnitTests
+        if (driver is { })
+        {
+            Driver = driver;
+        }
+
+        // Start the process of configuration management.
+        // Note that we end up calling LoadConfigurationFromAllSources
+        // multiple times. We need to do this because some settings are only
+        // valid after a Driver is loaded. In this case we need just
+        // `Settings` so we can determine which driver to use.
+        // Don't reset, so we can inherit the theme from the previous run.
+        Load ();
+        Apply ();
+
+        AddApplicationKeyBindings ();
+
+        // Ignore Configuration for ForceDriver if driverName is specified
+        if (!string.IsNullOrEmpty (driverName))
+        {
+            ForceDriver = driverName;
+        }
+
+        if (Driver is null)
+        {
+            PlatformID p = Environment.OSVersion.Platform;
+
+            if (string.IsNullOrEmpty (ForceDriver))
+            {
+                if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows)
+                {
+                    Driver = new WindowsDriver ();
+                }
+                else
+                {
+                    Driver = new CursesDriver ();
+                }
+            }
+            else
+            {
+                List<Type?> drivers = GetDriverTypes ();
+                Type? driverType = drivers.FirstOrDefault (t => t!.Name.Equals (ForceDriver, StringComparison.InvariantCultureIgnoreCase));
+
+                if (driverType is { })
+                {
+                    Driver = (ConsoleDriver)Activator.CreateInstance (driverType)!;
+                }
+                else
+                {
+                    throw new ArgumentException (
+                                                 $"Invalid driver name: {ForceDriver}. Valid names are {string.Join (", ", drivers.Select (t => t!.Name))}"
+                                                );
+                }
+            }
+        }
+
+        try
+        {
+            MainLoop = Driver!.Init ();
+        }
+        catch (InvalidOperationException ex)
+        {
+            // This is a case where the driver is unable to initialize the console.
+            // This can happen if the console is already in use by another process or
+            // if running in unit tests.
+            // In this case, we want to throw a more specific exception.
+            throw new InvalidOperationException (
+                                                 "Unable to initialize the console. This can happen if the console is already in use by another process or in unit tests.",
+                                                 ex
+                                                );
+        }
+
+        Driver.SizeChanged += Driver_SizeChanged;
+        Driver.KeyDown += Driver_KeyDown;
+        Driver.KeyUp += Driver_KeyUp;
+        Driver.MouseEvent += Driver_MouseEvent;
+
+        SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ());
+
+        SupportedCultures = GetSupportedCultures ();
+        MainThreadId = Thread.CurrentThread.ManagedThreadId;
+        bool init = IsInitialized = true;
+        InitializedChanged?.Invoke (null, new (init));
+    }
+
+    private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
+    private static void Driver_KeyDown (object? sender, Key e) { OnKeyDown (e); }
+    private static void Driver_KeyUp (object? sender, Key e) { OnKeyUp (e); }
+    private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); }
+
+    /// <summary>Gets of list of <see cref="ConsoleDriver"/> types that are available.</summary>
+    /// <returns></returns>
+    [RequiresUnreferencedCode ("AOT")]
+    public static List<Type?> GetDriverTypes ()
+    {
+        // use reflection to get the list of drivers
+        List<Type?> driverTypes = new ();
+
+        foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ())
+        {
+            foreach (Type? type in asm.GetTypes ())
+            {
+                if (type.IsSubclassOf (typeof (ConsoleDriver)) && !type.IsAbstract)
+                {
+                    driverTypes.Add (type);
+                }
+            }
+        }
+
+        return driverTypes;
+    }
+
+    /// <summary>Shutdown an application initialized with <see cref="Init"/>.</summary>
+    /// <remarks>
+    ///     Shutdown must be called for every call to <see cref="Init"/> or
+    ///     <see cref="Application.Run(Toplevel, Func{Exception, bool})"/> to ensure all resources are cleaned
+    ///     up (Disposed)
+    ///     and terminal settings are restored.
+    /// </remarks>
+    public static void Shutdown ()
+    {
+        // TODO: Throw an exception if Init hasn't been called.
+        ResetState ();
+        PrintJsonErrors ();
+        bool init = IsInitialized;
+        InitializedChanged?.Invoke (null, new (in init));
+    }
+
+    /// <summary>
+    ///     This event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
+    /// </summary>
+    /// <remarks>
+    ///     Intended to support unit tests that need to know when the application has been initialized.
+    /// </remarks>
+    public static event EventHandler<EventArgs<bool>>? InitializedChanged;
+}

+ 434 - 0
Terminal.Gui/Application/Application.Keyboard.cs

@@ -0,0 +1,434 @@
+#nullable enable
+namespace Terminal.Gui;
+
+public static partial class Application // Keyboard handling
+{
+    private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrrides
+    private static Key _nextTabKey = Key.Tab; // Resources/config.json overrrides
+
+    private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrrides
+
+    private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrrides
+
+    private static Key _quitKey = Key.Esc; // Resources/config.json overrrides
+
+    static Application () { AddApplicationKeyBindings (); }
+
+    /// <summary>Gets the key bindings for this view.</summary>
+    public static KeyBindings KeyBindings { get; internal set; } = new ();
+
+    /// <summary>
+    ///     Event fired when the user presses a key. Fired by <see cref="OnKeyDown"/>.
+    ///     <para>
+    ///         Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
+    ///         additional processing.
+    ///     </para>
+    /// </summary>
+    /// <remarks>
+    ///     All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
+    ///     <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
+    ///     <para>Fired after <see cref="KeyDown"/> and before <see cref="KeyUp"/>.</para>
+    /// </remarks>
+    public static event EventHandler<Key>? KeyDown;
+
+    /// <summary>
+    ///     Event fired when the user releases a key. Fired by <see cref="OnKeyUp"/>.
+    ///     <para>
+    ///         Set <see cref="Key.Handled"/> to <see langword="true"/> to indicate the key was handled and to prevent
+    ///         additional processing.
+    ///     </para>
+    /// </summary>
+    /// <remarks>
+    ///     All drivers support firing the <see cref="KeyDown"/> event. Some drivers (Curses) do not support firing the
+    ///     <see cref="KeyDown"/> and <see cref="KeyUp"/> events.
+    ///     <para>Fired after <see cref="KeyDown"/>.</para>
+    /// </remarks>
+    public static event EventHandler<Key>? KeyUp;
+
+    /// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static Key NextTabGroupKey
+    {
+        get => _nextTabGroupKey;
+        set
+        {
+            if (_nextTabGroupKey != value)
+            {
+                ReplaceKey (_nextTabGroupKey, value);
+                _nextTabGroupKey = value;
+            }
+        }
+    }
+
+    /// <summary>Alternative key to navigate forwards through views. Ctrl+Tab is the primary key.</summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static Key NextTabKey
+    {
+        get => _nextTabKey;
+        set
+        {
+            if (_nextTabKey != value)
+            {
+                ReplaceKey (_nextTabKey, value);
+                _nextTabKey = value;
+            }
+        }
+    }
+
+    /// <summary>
+    ///     Called by the <see cref="ConsoleDriver"/> when the user presses a key. Fires the <see cref="KeyDown"/> event
+    ///     then calls <see cref="View.NewKeyDownEvent"/> on all top level views. Called after <see cref="OnKeyDown"/> and
+    ///     before <see cref="OnKeyUp"/>.
+    /// </summary>
+    /// <remarks>Can be used to simulate key press events.</remarks>
+    /// <param name="keyEvent"></param>
+    /// <returns><see langword="true"/> if the key was handled.</returns>
+    public static bool OnKeyDown (Key keyEvent)
+    {
+        //if (!IsInitialized)
+        //{
+        //    return true;
+        //}
+
+        KeyDown?.Invoke (null, keyEvent);
+
+        if (keyEvent.Handled)
+        {
+            return true;
+        }
+
+        if (Current is null)
+        {
+            foreach (Toplevel topLevel in TopLevels.ToList ())
+            {
+                if (topLevel.NewKeyDownEvent (keyEvent))
+                {
+                    return true;
+                }
+
+                if (topLevel.Modal)
+                {
+                    break;
+                }
+            }
+        }
+        else
+        {
+            if (Current.NewKeyDownEvent (keyEvent))
+            {
+                return true;
+            }
+        }
+
+        // Invoke any Application-scoped KeyBindings.
+        // The first view that handles the key will stop the loop.
+        foreach (KeyValuePair<Key, KeyBinding> binding in KeyBindings.Bindings.Where (b => b.Key == keyEvent.KeyCode))
+        {
+            if (binding.Value.BoundView is { })
+            {
+                bool? handled = binding.Value.BoundView?.InvokeCommands (binding.Value.Commands, binding.Key, binding.Value);
+
+                if (handled != null && (bool)handled)
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if (!KeyBindings.TryGet (keyEvent, KeyBindingScope.Application, out KeyBinding appBinding))
+                {
+                    continue;
+                }
+
+                bool? toReturn = null;
+
+                foreach (Command command in appBinding.Commands)
+                {
+                    toReturn = InvokeCommand (command, keyEvent, appBinding);
+                }
+
+                return toReturn ?? true;
+            }
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    /// INTENRAL method to invoke one of the commands in <see cref="CommandImplementations"/>
+    /// </summary>
+    /// <param name="command"></param>
+    /// <param name="keyEvent"></param>
+    /// <param name="appBinding"></param>
+    /// <returns></returns>
+    /// <exception cref="NotSupportedException"></exception>
+    private static bool? InvokeCommand (Command command, Key keyEvent, KeyBinding appBinding)
+    {
+        if (!CommandImplementations!.ContainsKey (command))
+        {
+            throw new NotSupportedException (
+                                             @$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application."
+                                            );
+        }
+
+        if (CommandImplementations.TryGetValue (command, out Func<CommandContext, bool?>? implementation))
+        {
+            var context = new CommandContext (command, keyEvent, appBinding); // Create the context here
+            return implementation (context);
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    ///     Called by the <see cref="ConsoleDriver"/> when the user releases a key. Fires the <see cref="KeyUp"/> event
+    ///     then calls <see cref="View.NewKeyUpEvent"/> on all top level views. Called after <see cref="OnKeyDown"/>.
+    /// </summary>
+    /// <remarks>Can be used to simulate key press events.</remarks>
+    /// <param name="a"></param>
+    /// <returns><see langword="true"/> if the key was handled.</returns>
+    public static bool OnKeyUp (Key a)
+    {
+        if (!IsInitialized)
+        {
+            return true;
+        }
+
+        KeyUp?.Invoke (null, a);
+
+        if (a.Handled)
+        {
+            return true;
+        }
+
+        foreach (Toplevel topLevel in TopLevels.ToList ())
+        {
+            if (topLevel.NewKeyUpEvent (a))
+            {
+                return true;
+            }
+
+            if (topLevel.Modal)
+            {
+                break;
+            }
+        }
+
+        return false;
+    }
+
+    /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static Key PrevTabGroupKey
+    {
+        get => _prevTabGroupKey;
+        set
+        {
+            if (_prevTabGroupKey != value)
+            {
+                ReplaceKey (_prevTabGroupKey, value);
+                _prevTabGroupKey = value;
+            }
+        }
+    }
+
+    /// <summary>Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key.</summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static Key PrevTabKey
+    {
+        get => _prevTabKey;
+        set
+        {
+            if (_prevTabKey != value)
+            {
+                ReplaceKey (_prevTabKey, value);
+                _prevTabKey = value;
+            }
+        }
+    }
+
+    /// <summary>Gets or sets the key to quit the application.</summary>
+    [SerializableConfigurationProperty (Scope = typeof (SettingsScope))]
+    public static Key QuitKey
+    {
+        get => _quitKey;
+        set
+        {
+            if (_quitKey != value)
+            {
+                ReplaceKey (_quitKey, value);
+                _quitKey = value;
+            }
+        }
+    }
+
+    internal static void AddApplicationKeyBindings ()
+    {
+        CommandImplementations = new ();
+
+        // Things this view knows how to do
+        AddCommand (
+                    Command.QuitToplevel, // TODO: IRunnable: Rename to Command.Quit to make more generic.
+                    static () =>
+                    {
+                        if (ApplicationOverlapped.OverlappedTop is { })
+                        {
+                            RequestStop (Current!);
+                        }
+                        else
+                        {
+                            RequestStop ();
+                        }
+
+                        return true;
+                    }
+                   );
+
+        AddCommand (
+                    Command.Suspend,
+                    static () =>
+                    {
+                        Driver?.Suspend ();
+
+                        return true;
+                    }
+                   );
+
+        AddCommand (
+                    Command.NextView,
+                    static () => Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop));
+
+        AddCommand (
+                    Command.PreviousView,
+                    static () => Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop));
+
+        AddCommand (
+                    Command.NextViewOrTop,
+                    static () =>
+                    {
+                        // TODO: This OverlapppedTop tomfoolery goes away in addressing #2491
+                        if (ApplicationOverlapped.OverlappedTop is { })
+                        {
+                            ApplicationOverlapped.OverlappedMoveNext ();
+
+                            return true;
+                        }
+
+                        return Navigation?.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
+                    }
+                   );
+
+        AddCommand (
+                    Command.PreviousViewOrTop,
+                    static () =>
+                    {
+                        // TODO: This OverlapppedTop tomfoolery goes away in addressing #2491
+                        if (ApplicationOverlapped.OverlappedTop is { })
+                        {
+                            ApplicationOverlapped.OverlappedMovePrevious ();
+
+                            return true;
+                        }
+
+                        return Navigation?.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
+                    }
+                   );
+
+        AddCommand (
+                    Command.Refresh,
+                    static () =>
+                    {
+                        Refresh ();
+
+                        return true;
+                    }
+                   );
+
+        KeyBindings.Clear ();
+
+        // Resources/config.json overrrides
+        NextTabKey = Key.Tab;
+        PrevTabKey = Key.Tab.WithShift;
+        NextTabGroupKey = Key.F6;
+        PrevTabGroupKey = Key.F6.WithShift;
+        QuitKey = Key.Esc;
+
+        KeyBindings.Add (QuitKey, KeyBindingScope.Application, Command.QuitToplevel);
+
+        KeyBindings.Add (Key.CursorRight, KeyBindingScope.Application, Command.NextView);
+        KeyBindings.Add (Key.CursorDown, KeyBindingScope.Application, Command.NextView);
+        KeyBindings.Add (Key.CursorLeft, KeyBindingScope.Application, Command.PreviousView);
+        KeyBindings.Add (Key.CursorUp, KeyBindingScope.Application, Command.PreviousView);
+        KeyBindings.Add (NextTabKey, KeyBindingScope.Application, Command.NextView);
+        KeyBindings.Add (PrevTabKey, KeyBindingScope.Application, Command.PreviousView);
+
+        KeyBindings.Add (NextTabGroupKey, KeyBindingScope.Application, Command.NextViewOrTop);
+        KeyBindings.Add (PrevTabGroupKey, KeyBindingScope.Application, Command.PreviousViewOrTop);
+
+        // TODO: Refresh Key should be configurable
+        KeyBindings.Add (Key.F5, KeyBindingScope.Application, Command.Refresh);
+
+        // TODO: Suspend Key should be configurable
+        if (Environment.OSVersion.Platform == PlatformID.Unix)
+        {
+            KeyBindings.Add (Key.Z.WithCtrl, KeyBindingScope.Application, Command.Suspend);
+        }
+    }
+
+    /// <summary>
+    ///     Gets the list of Views that have <see cref="KeyBindingScope.Application"/> key bindings.
+    /// </summary>
+    /// <remarks>
+    ///     This is an internal method used by the <see cref="View"/> class to add Application key bindings.
+    /// </remarks>
+    /// <returns>The list of Views that have Application-scoped key bindings.</returns>
+    internal static List<KeyBinding> GetViewKeyBindings ()
+    {
+        // Get the list of views that do not have Application-scoped key bindings
+        return KeyBindings.Bindings
+                          .Where (kv => kv.Value.Scope != KeyBindingScope.Application)
+                          .Select (kv => kv.Value)
+                          .Distinct ()
+                          .ToList ();
+    }
+
+    /// <summary>
+    ///     <para>
+    ///         Sets the function that will be invoked for a <see cref="Command"/>.
+    ///     </para>
+    ///     <para>
+    ///         If AddCommand has already been called for <paramref name="command"/> <paramref name="f"/> will
+    ///         replace the old one.
+    ///     </para>
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This version of AddCommand is for commands that do not require a <see cref="CommandContext"/>.
+    ///     </para>
+    /// </remarks>
+    /// <param name="command">The command.</param>
+    /// <param name="f">The function.</param>
+    private static void AddCommand (Command command, Func<bool?> f) { CommandImplementations! [command] = ctx => f (); }
+
+    /// <summary>
+    ///     Commands for Application.
+    /// </summary>
+    private static Dictionary<Command, Func<CommandContext, bool?>>? CommandImplementations { get; set; }
+
+    private static void ReplaceKey (Key oldKey, Key newKey)
+    {
+        if (KeyBindings.Bindings.Count == 0)
+        {
+            return;
+        }
+
+        if (newKey == Key.Empty)
+        {
+            KeyBindings.Remove (oldKey);
+        }
+        else
+        {
+            KeyBindings.ReplaceKey (oldKey, newKey);
+        }
+    }
+}

Some files were not shown because too many files changed in this diff