{"id":15764597,"url":"https://github.com/pavkam/sharpie","last_synced_at":"2025-04-15T16:17:29.174Z","repository":{"id":62329893,"uuid":"554128101","full_name":"pavkam/sharpie","owner":"pavkam","description":"Terminal manipulation library based on Curses (ncurses, pdcurses and pdcurses-mod) for modern .NET applications.","archived":false,"fork":false,"pushed_at":"2024-10-01T09:34:45.000Z","size":20987,"stargazers_count":25,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T16:17:13.602Z","etag":null,"topics":["c-sharp","csharp","curses","curses-library","curses-ui","dotnet","dotnet-core","gui","pdcurses","pdcursesmod","terminal","tui"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pavkam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T09:45:48.000Z","updated_at":"2025-01-20T06:46:09.000Z","dependencies_parsed_at":"2024-03-01T10:26:47.668Z","dependency_job_id":"f02e0b4e-7577-4272-a57d-90622ddb6c9d","html_url":"https://github.com/pavkam/sharpie","commit_stats":{"total_commits":529,"total_committers":3,"mean_commits":"176.33333333333334","dds":"0.10964083175803407","last_synced_commit":"534b60673527941da11387a30039fcee7b515a53"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fsharpie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fsharpie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fsharpie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fsharpie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pavkam","download_url":"https://codeload.github.com/pavkam/sharpie/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249105474,"owners_count":21213536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","csharp","curses","curses-library","curses-ui","dotnet","dotnet-core","gui","pdcurses","pdcursesmod","terminal","tui"],"created_at":"2024-10-04T12:04:11.063Z","updated_at":"2025-04-15T16:17:29.143Z","avatar_url":"https://github.com/pavkam.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build, Test and Release](https://github.com/pavkam/sharpie/actions/workflows/sharpie-build-test-and-deploy.yml/badge.svg)](https://github.com/pavkam/sharpie/actions/workflows/sharpie-build-test-and-deploy.yml)\n[![codecov](https://codecov.io/gh/pavkam/sharpie/branch/main/graph/badge.svg?token=QI3EVFGHUZ)](https://codecov.io/gh/pavkam/sharpie)\n[![Issues](https://img.shields.io/github/issues/pavkam/sharpie)](https://github.com/pavkam/sharpie/issues)\n[![License](https://img.shields.io/github/license/pavkam/sharpie)](https://raw.githubusercontent.com/pavkam/sharpie/main/LICENSE)\n![.NET 6](https://img.shields.io/badge/.NET-6.0-orange)\n[![NuGet](https://img.shields.io/nuget/v/Sharpie-Curses)](https://www.nuget.org/packages/Sharpie-Curses)\n![Downloads](https://img.shields.io/nuget/dt/Sharpie-Curses)\n\n# Sharpie\n**Sharpie** is a terminal manipulation library based on NCurses and targeting .NET 6 (dotnet core) and above.\n\n![Demo](media/demo-3.gif)\n\n**Or, if you prefer the Snake game...**\n\n![Demo](media/demo-2.gif)\n\n# Platforms\n**Sharpie** supports any platform that **.NET 6.0+**, **[ncurses](https://github.com/mirror/ncurses)**, **[pdcurses](https://github.com/wmcbrine/PDCurses)** and **[pdcurses-mod](https://github.com/Bill-Gray/PDCursesMod)** support. This essentially means that `Linux`, `Macos` and `Windows` are supported on both `x64` and `ARM64` architectures.\n\nFor more information on supported platforms visit [.NET Supported Platforms Page](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md) and [NCurses Packages Page](https://invisible-island.net/ncurses/#packages).\n\n**Sharpie** provides unofficial builds for all the supported libraries located in [the lib directory](https://github.com/pavkam/sharpie/tree/main/lib)\n\n# Installation\nInstall the main library by adding the NuGet package:\n```sh\ndotnet add package Sharpie-Curses\n```\n\nAdditionally, one can install packages containing prebuilt native libraries. These packages are useful when targeting platforms that do not bundle a supported curses library by default (e.g. Windows).\n```sh\ndotnet add package Sharpie-Libs-PdCurses\ndotnet add package Sharpie-Libs-PdCursesMod\ndotnet add package Sharpie-Libs-NCurses\n```\n\n# Features\nAlmost all of Curses functionality is exposed through **Sharpie**. What follows is a list of suppoerted features:\n1. `Terminal` allows interfacing with terminal functionality exposed by Curses,\n2. `Screen` abstracts away the screen handling,\n3. `Pad` abstracts away the off-screen windows (known as pads),\n4. `SubPad` and `SubWindow` carves out areas of their respective parents for easy management,\n5. `EventPump` allows developers to listen for Curses events such as key presses, mouse moves and resizes,\n6. `ColorManager` abstracts away the management of colors,\n7. Even `SoftLabelKeys` are supported (though antiquated),\n\nIn addition to wrapping NCurses, this library also adds numerous quality-of-life improvements such as:\n1. Management of overlapping `Window`s within a `Screen`,\n2. Proper `Window` resizing and placement during terminal resizing events,\n3. Automatic `Screen` refresh management and support for _atomic_ refreshes,\n4. Supports `SynchronizationContext`-type execution,\n5. Supports protected/synchronized or raw access to all classes,\n6. And other small additions here and there...\n\n# Reasons\nThere are a number of libraries out there that already offer bindings to *NCurses*. One of the more popular one is [Terminal.Gui](https://github.com/gui-cs/Terminal.Gui); and others such as [dotnet-curses](https://github.com/MV10/dotnet-curses) also exist.\n\nSo why another one? The are many reasons, but the most important ones are:\n1. There is no .NET, object-oriented version of NCurses bindings,\n2. Existing versions are old, or are targeting old versions of .NET which do not benefit from numerous advances in the .NET platform,\n3. No other library exposes most of Curses functionality,\n4. Testing is either very limited or completely non-existent.\n5. And finally -- **because I wanted to dabble in Curses**.\n\n# How To\nWhat follows is a small example of how to use the library:\n![Demo](media/demo-1.gif)\n```csharp\n\n// Create the terminal instance without any non-standard settings.\nusing var terminal = new Terminal(CursesBackend.Load(), new(ManagedWindows: true));\n\n// Set the main screen attributes for text and drawings.\nterminal.Screen.ColorMixture = terminal.Colors.MixColors(StandardColor.Green, StandardColor.Blue);\n\n// Draw a border on the screen.\nterminal.Screen.DrawBorder();\n\n// Force a refresh so that all drawings will be actually pushed to teh screen.\nterminal.Screen.Refresh();\n\n// Create a child window within the terminal to operate within.\n// The other cells contain the border so we don't want to overwrite those.\nvar subWindow = terminal.Screen.SubWindow(\n    new(1, 1, terminal.Screen.Size.Width - 2, terminal.Screen.Size.Height - 2));\n\n// Process all events coming from the terminal.\nforeach (var @event in terminal.Events.Listen(subWindow))\n{\n    // Write the  event that occured.\n    subWindow.WriteText($\"{@event}\\n\");\n    \n    // If the event is a resize, change the size of the child window\n    // to allow for the screen to maintain its border.\n    // And then redraw the border of the main screen.\n    if (@event is TerminalResizeEvent re)\n    {\n        subWindow.Size = new(re.Size.Width - 2, re.Size.Height - 2);\n        terminal.Screen.DrawBorder();\n    }\n    \n    // If the user pressed CTRL+C, break the loop.\n    if (@event is KeyEvent { Key: Key.Character, Char.IsAscii: true, Char.Value: 'C', Modifiers: ModifierKey.Ctrl })\n    {\n        break;\n    }\n}\n```\nAs you can imagine, there are numerous other uses built into the library. Start out by reading [Setting Up The Terminal](https://github.com/pavkam/sharpie/wiki/Setting-Up-the-Terminal) wiki page.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavkam%2Fsharpie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavkam%2Fsharpie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavkam%2Fsharpie/lists"}