diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..b7fcd31 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2026 Ignacio Garbayo Fernández +# SPDX-License-Identifier: MIT + +# All files are owned by the project maintainer. +* @igarbayo diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..73ac70f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,37 @@ +--- +name: Bug report +about: Something is not working as documented +title: 'fix: ' +labels: bug +assignees: '' +--- + +## What happened? + + + +## What did you expect? + + + +## Steps to reproduce + + + +```java +TerminalBuffer buf = new TerminalBuffer(80, 24, 100); +// ... +``` + +## Environment + +- OS: +- Java version (`java -version`): +- Shell (PowerShell / bash / zsh / other): + +## Additional context + + + + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..4bc8785 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2026 Ignacio Garbayo Fernández +# SPDX-License-Identifier: MIT + +blank_issues_enabled: false + +contact_links: + - name: Security vulnerability + url: https://github.com/igarbayo/terminal-text-buffer/blob/master/SECURITY.md + about: > + Do NOT open a public issue for security vulnerabilities. + Please follow the responsible disclosure process described in SECURITY.md. + - name: General question or usage help + url: https://github.com/igarbayo/terminal-text-buffer/issues/new?template=question.md + about: > + Ask a question about how to use the library or understand its behaviour. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..5024732 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,37 @@ +--- +name: Feature request +about: Propose an improvement or new capability +title: 'feat: ' +labels: enhancement +assignees: '' +--- + +## What problem does this solve? + + + +## Proposed solution + + + +## Example usage + + + +```java +// Example of how the new feature would look +buf.newMethod(arg1, arg2); +``` + +## Alternatives considered + + + +## Additional context + + + + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..4cd9497 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,41 @@ +--- +name: Question +about: Ask a question about how to use the library or understand its behaviour +title: '[QUESTION] ' +labels: question +assignees: '' + +--- + + + + +## What are you trying to do? + + + +## What have you tried? + + + +## Environment + +- **OS:** +- **Java version:** +- **How are you running the library?** + +## Additional context + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6e99a10 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,27 @@ +## Description + + + +## Type of change + +- [ ] `feat` — new feature +- [ ] `fix` — bug fix +- [ ] `test` — tests only +- [ ] `docs` — documentation only +- [ ] `refactor` — code change, no feature or fix +- [ ] `chore` — tooling, dependencies, build + +## Checklist + +- [ ] I branched from `develop` (not from `master`) +- [ ] The PR title is a valid Conventional Commit message (e.g. `feat: add X`) +- [ ] `./gradlew test` passes locally +- [ ] New or changed files have SPDX license headers +- [ ] I have updated documentation if needed + +## Related issues + +Closes # + + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..4395d3e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2026 Ignacio Garbayo Fernández +# SPDX-License-Identifier: MIT + +version: 2 +updates: + # Keep Gradle dependencies up to date (e.g. JUnit 5) + - package-ecosystem: gradle + directory: / + schedule: + interval: weekly + day: monday + labels: + - dependencies + + # Keep GitHub Actions up to date + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + labels: + - dependencies + - github-actions diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a3506b1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: 2026 Ignacio Garbayo Fernández +# SPDX-License-Identifier: MIT + +name: CI + +on: + push: + branches: [ master, develop, 'feature/**', 'hotfix/**' ] + pull_request: + branches: [ master, develop ] + +# Minimum permissions by default. Jobs that need more declare it explicitly. +permissions: + contents: read + +jobs: + build: + name: Build and test (Java ${{ matrix.java }}, ${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, windows-latest ] + java: [ '11', '17', '21' ] + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Set up Java ${{ matrix.java }} + uses: actions/setup-java@v4 # TODO: pin to SHA + with: + java-version: ${{ matrix.java }} + distribution: temurin + + - name: Run tests + run: ./gradlew test + shell: bash + + - name: Upload test report + if: failure() + uses: actions/upload-artifact@v4 # TODO: pin to SHA + with: + name: test-report-java-${{ matrix.java }} + path: build/reports/tests/test/ + + reuse: + name: REUSE compliance + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Check REUSE compliance + uses: fsfe/reuse-action@v4 # TODO: pin to SHA diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000..458a943 --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,24 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: terminal-text-buffer +Upstream-Contact: Ignacio Garbayo Fernández +Source: https://github.com/igarbayo/terminal-text-buffer + +# Gradle wrapper — generated by Gradle, licensed under Apache-2.0 +Files: gradlew gradlew.bat gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.properties +Copyright: Gradle Inc. +License: Apache-2.0 + +# Project configuration files — authored by the project maintainer +Files: gradle.properties .gitignore settings.gradle +Copyright: 2026 Ignacio Garbayo Fernandez +License: MIT + +# Documentation and governance files — authored by the project maintainer +Files: README.md CODE_OF_CONDUCT.md GOVERNANCE.md SECURITY.md docs/MANUAL_TESTING_GUIDE.md docs/COMPONENTS_LICENSE.md docs/GPG_KEY.md docs/ARCHITECTURE_DECISIONS.md images/image.png images/image-1.png +Copyright: 2026 Ignacio Garbayo Fernandez +License: MIT + +# Root governance files — authored by the project maintainer +Files: DCO +Copyright: The Linux Foundation and its contributors +License: MIT diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..3adca20 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,143 @@ +# Code of Conduct + +## Our Pledge + +We as members, contributors, and maintainers pledge to make participation in +this project and community a harassment-free experience for everyone, regardless +of age, body size, visible or invisible disability, ethnicity, sex +characteristics, gender identity and expression, level of experience, education, +socio-economic status, nationality, personal appearance, race, caste, colour, +religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +--- + +## Our Standards + +Examples of behaviour that contributes to a positive environment: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologising to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behaviour: + +- The use of sexualised language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +--- + +## Enforcement Responsibilities + +The project maintainer is responsible for clarifying and enforcing these +standards and will take appropriate and fair corrective action in response to +any behaviour that is deemed inappropriate, threatening, offensive, or harmful. + +The maintainer has the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned with this Code of Conduct, and will communicate reasons for +moderation decisions when appropriate. + +--- + +## Scope + +This Code of Conduct applies within all project spaces — GitHub Issues, Pull +Requests, Discussions, and email — and also applies when an individual is +officially representing the project in public spaces. + +--- + +## Reporting + +Instances of abusive, harassing, or otherwise unacceptable behaviour may be +reported to the project maintainer at: + +**ignacio.garbayo@rai.usc.es** + +Please use the subject line `[COC] terminal-text-buffer — `. + +**Do not report conduct issues in public GitHub issues.** All reports will be +handled privately. + +The maintainer will acknowledge receipt of your report within **72 hours** and +will keep you informed of the outcome. + +All reports will be reviewed and investigated promptly and fairly. The +maintainer is obligated to maintain confidentiality with regard to the reporter +of an incident. + +--- + +## Enforcement Guidelines + +The maintainer will follow these guidelines to determine the consequences for +any action deemed in violation of this Code of Conduct: + +### 1. Correction + +**Community impact:** Use of inappropriate language or other behaviour deemed +unprofessional or unwelcome. + +**Consequence:** A private written warning explaining the nature of the +violation and why the behaviour was inappropriate. A public apology may be +requested. + +### 2. Warning + +**Community impact:** A violation through a single incident or series of +actions. + +**Consequence:** A warning with consequences for continued behaviour. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community impact:** A serious violation of community standards, including +sustained inappropriate behaviour. + +**Consequence:** A temporary ban from any sort of interaction or public +communication with the project for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community impact:** Demonstrating a pattern of violation of community +standards, including sustained inappropriate behaviour, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence:** A permanent ban from any sort of public interaction within the +project community. + +--- + +## Attribution + +This Code of Conduct is adapted from the +[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, +available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7b0d5b6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,222 @@ +# Contributing to Terminal Text Buffer + +Thank you so much for taking the time to read this. It genuinely means a lot. +Terminal Text Buffer is a small project born from a Jetbrains coding challenge, +and the fact that you are here considering contributing to it is something we do +not take for granted. + +--- + +## A note before you start + +This is an **academic project** maintained by a single student. Please set your +expectations accordingly: + +- Response times may be **weeks or months**. This is not negligence — it is + reality. Coursework, exams, and life happen. +- There is **no roadmap** and no commitment to implement any particular feature. +- The project may go quiet for extended periods. + +None of this means your contribution is not valued. It means you should not +block on a response from me. + +--- + +## How to report a bug + +1. Check that the bug has not already been reported in the + [issue tracker](https://github.com/igarbayo/terminal-text-buffer/issues). +2. Open a new issue using the **Bug Report** template. +3. Include: + - What you did (exact commands or code). + - What you expected to happen. + - What actually happened (paste the output or stack trace). + - Your environment: OS, Java version (`java -version`), shell. + +**Example of a useful bug report:** + +> **Steps to reproduce:** +> ```java +> TerminalBuffer buf = new TerminalBuffer(10, 5, 100); +> buf.setCursor(9, 0); +> buf.writeText("AB"); // A fits, B should wrap +> ``` +> **Expected:** cursor at (0, 1), 'B' written on row 1. +> **Got:** cursor at (9, 0), 'B' lost. + +--- + +## How to propose a feature or improvement + +Open an issue using the **Feature Request** template. Describe: + +- The problem you are trying to solve (not just the solution). +- Your proposed approach, if you have one. +- Any alternatives you considered. + +--- + +## How to contribute code + +### 1. Set up your development environment + +**Prerequisites:** + +- **JDK 11 or later.** Make sure `java -version` and `javac -version` both + report the same JDK (not a JRE). +- **Git** (any recent version). +- No other tools required — the Gradle wrapper (`gradlew`) is bundled. + +**Steps:** + +```bash +# 1. Fork the repository on GitHub, then clone your fork +git clone https://github.com//terminal-text-buffer.git +cd terminal-text-buffer + +# 2. Verify the build passes before making any changes +./gradlew test + +# The HTML test report is at build/reports/tests/test/index.html +``` + +> **Windows note:** if Gradle complains about `tools.jar`, set +> `org.gradle.java.home` in `gradle.properties` to your JDK directory +> (not a JRE). See [README — Troubleshooting](README.md#troubleshooting). + +### 2. Create a feature branch from `develop` + +```bash +git checkout develop +git checkout -b feature/your-descriptive-name +``` + +Never branch from `master`. Never commit directly to `master` or `develop`. + +### 3. Write your code + +#### Code style + +This project uses the **Allman brace style** with **4-space indentation** +(no tabs). + +```java +// Allman style — opening brace on its own line +if (condition) +{ + doSomething(); +} +else +{ + doSomethingElse(); +} +``` + +- Keep lines under 120 characters where possible. +- Prefer `final` for local variables and parameters that are not reassigned. +- Write tests first (this project was built with TDD — see the development + process in the README). +- Add SPDX license headers to any new source file you create: + +```java +// SPDX-FileCopyrightText: +// SPDX-License-Identifier: MIT +``` + +For non-source files (Markdown, YAML, etc.) use an HTML or `#`-style comment +as appropriate, or create a `.license` sidecar file. + +### 4. Commit with Conventional Commits + +All commit messages must follow the +[Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +(): + + + + +``` + +Valid types: + +| Type | Use it for | +|---|---| +| `feat` | A new feature or behaviour | +| `fix` | A bug fix | +| `refactor` | Code change with no feature or fix | +| `perf` | Performance improvement (special case of `refactor`) | +| `style` | Whitespace, formatting — no behaviour change | +| `test` | Adding or fixing tests | +| `docs` | Documentation only | +| `build` | Build tools, dependencies, project version | +| `ops` | CI/CD, infrastructure, deployment scripts | +| `chore` | Initial commit, `.gitignore`, other housekeeping | + +**Examples:** + +``` +feat: add SGR escape sequence parser +fix: correct cursor clamping when width is 1 +test: add scrollback eviction edge case +docs: clarify wide character limitations in README +perf: replace ArrayDeque with circular buffer for O(1) scrollback access +chore: bump JUnit to 5.11.0 +``` + +Breaking changes: add `!` after the type and a `BREAKING CHANGE:` footer. + +``` +feat!: change scrollback row indexing to 0-based + +BREAKING CHANGE: getLine() now uses 0 for the most recent scrollback row +instead of -1. +``` + +### 5. Open a Pull Request to `develop` + +- Fill in the PR template completely. +- The PR title must itself be a valid Conventional Commit message. +- CI must be green (build + tests + REUSE compliance). +- At least one maintainer approval is required before merging. + +--- + +## Definition of done + +A contribution is considered complete when all of the following are true: + +- [ ] `./gradlew test` passes locally with no failures or errors +- [ ] New or changed source files have SPDX license headers +- [ ] New public behaviour is covered by at least one test +- [ ] Documentation is updated if the change affects behaviour or the API +- [ ] The PR title and all commit messages follow the Conventional Commits format + +--- + +## PGP signed commits + +The maintainer signs all commits with a PGP key. You are not required to sign +your commits, but it is encouraged. If you do, please include your public key +fingerprint in the PR description. See [docs/GPG_KEY.md](docs/GPG_KEY.md) for +setup instructions. + +--- + +## Code of Conduct + +This project follows the +[Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). +By participating you agree to abide by its terms. + +--- + +## Contact + +If you have a question that does not fit an issue, you can reach the maintainer +at **ignacio.garbayo@rai.usc.es**. Please use the subject line +`[terminal-text-buffer] your topic` so it does not get lost. + + + diff --git a/DCO b/DCO new file mode 100644 index 0000000..49b8cb0 --- /dev/null +++ b/DCO @@ -0,0 +1,34 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..583cbf4 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,148 @@ +# Governance + +## Project status + +Terminal Text Buffer is an active academic project. There is no formal roadmap, +no release schedule, and no commitment to any particular feature or timeline. + +--- + +## Contact + +| Name | Email | GitHub | Role | +|---|---|---|---| +| Ignacio Garbayo Fernández | ignacio.garbayo@rai.usc.es | @igarbayo | Sole maintainer | + +For questions or discussions, open an issue or send an email with subject +`[terminal-text-buffer] your topic`. + +--- + +## Roles + +**Maintainer** — currently Ignacio Garbayo Fernández. The maintainer: + +- Reviews and merges pull requests +- Manages releases and version tags +- Enforces the Code of Conduct +- Makes final decisions on technical direction +- Signs commits and release tags with a PGP key + +There is no steering committee and no formal RFC process. + +--- + +## Decision making + +### Routine decisions + +The maintainer can act alone on routine matters without prior discussion: + +- Bug fixes and correctness improvements +- Documentation updates +- CI/CD configuration changes +- Dependency version bumps (within the same major version) +- Code style and refactoring + +### Significant decisions + +The following decisions require the maintainer to document the rationale in +[docs/ARCHITECTURE_DECISIONS.md](docs/ARCHITECTURE_DECISIONS.md) before or +alongside the change: + +- Adding a new external dependency +- Breaking changes to the public API +- Releasing a new major version +- Changing the license or REUSE compliance strategy +- Changing the branch protection rules or CI requirements + +This is a single-maintainer project, so there is no second-approval requirement. +The documentation requirement serves as a public record and forces deliberate +thinking before significant changes. + +### Adding new maintainers + +New maintainers are added at the current maintainer's discretion, when the +project genuinely needs it. Any new maintainer must agree to the Code of +Conduct and the governance rules in this document. + +### Response times + +Response times are **best-effort** — expect weeks or months. This is a student +project competing with coursework and exams. + +--- + +## Conflict resolution + +Community members are encouraged to raise concerns via issues. If a contributor +disagrees with a decision, they are welcome to discuss it openly in the issue +tracker. The maintainer commits to explaining decisions transparently. + +In the case of conduct violations, the process described in +[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) takes precedence. + +--- + +## Branch strategy (Git Flow) + +| Branch | Purpose | Direct commits allowed | +|---|---|---| +| `master` | Stable releases only | No — PR required | +| `develop` | Integration of finished features | No — PR required | +| `feature/*` | Individual features, branched from `develop` | Yes | +| `hotfix/*` | Urgent fixes on `master` | Yes | + +### Rules + +- **No direct commits to `master` or `develop`.** All changes go through a + pull request, even from the maintainer. +- Feature branches are created from `develop`: + ```bash + git checkout develop + git checkout -b feature/my-feature + ``` +- When a feature is ready, open a PR targeting `develop`. +- Releases are merged from `develop` to `master` and tagged with a semver tag. + +### Branch protection (configured in GitHub) + +- `master`: require PR, no direct push, CI must pass (build + REUSE). +- `develop`: require PR, no direct push, CI must pass. + +To configure: GitHub → Settings → Branches → Branch protection rules. + +--- + +## Release process + +1. All planned features for the release are merged into `develop`. +2. `develop` is merged into `master` via PR. +3. A tag is created on `master`: + ```bash + git tag -s v1.0.0 -m "Release v1.0.0" + git push origin v1.0.0 + ``` + Tags are signed with the maintainer's PGP key. +4. A GitHub Release is created from the tag with release notes. + +Versioning follows [Semantic Versioning](https://semver.org/): +`MAJOR.MINOR.PATCH`. + +--- + +## Commit signing + +All commits from the maintainer are signed with a PGP key. Contributors are +encouraged (but not required) to sign their commits. See +[docs/GPG_KEY.md](docs/GPG_KEY.md) for setup instructions. + +--- + +## Amendments + +This document may be updated by the maintainer at any time. Significant changes +to governance will be noted in the commit message. + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..233d1b7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ignacio Garbayo Fernández + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000..eeeb215 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,170 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship made available under + the License, as indicated by a copyright notice that is included in + or attached to the work (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean, as submitted to the Licensor for inclusion + in the Work by the copyright owner or by an individual or Legal Entity + authorized to submit on behalf of the copyright owner. For the purposes + of this definition, "submitted" means any form of electronic, verbal, + or written communication sent to the Licensor or its representatives, + including but not limited to communication on electronic mailing lists, + source code control systems, and issue tracking systems that are managed + by, or on behalf of, the Licensor for the purpose of discussing and + improving the Work, but excluding communication that is conspicuously + marked or designated in writing by the copyright owner as "Not a + Contribution." + + "Contributor" shall mean Licensor and any Legal Entity on behalf of + whom a Contribution has been received by the Licensor and included + within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by the combination of their Contributions + with the Work to which such Contributions were submitted. If You + institute patent litigation against any entity (including a cross-claim + or counterclaim in a lawsuit) alleging that the Work or any + Contribution embodied within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under + this License for that Work shall terminate as of the date such + litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative + Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, You must include a readable copy of the + attribution notices contained within such NOTICE file, in + at least one of the following places: within a NOTICE text + file distributed as part of the Derivative Works; within + the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the + Derivative Works, if and wherever such third-party notices + normally appear. The contents of the NOTICE file are for + informational purposes only and do not modify the License. + You may add Your own attribution notices within Derivative + Works that You distribute, alongside or in addition to the + NOTICE text from the Work, provided that such additional + attribution notices cannot be construed as modifying the License. + + You may add Your own license statement for Your modifications and + may provide additional grant of rights to use, reproduce, modify, + prepare Derivative Works of, convert to other media types, display, + perform, and distribute such Contributions under the terms of Your + license. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any conditions of TITLE, + NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR + PURPOSE. You are solely responsible for determining the + appropriateness of using or reproducing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or exemplary damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or all other + commercial damages or losses), even if such Contributor has been + advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may offer such + conditions only on Your own behalf and on Your sole responsibility, + not on behalf of any other Contributor, and only if You agree to + indemnify, defend, and hold each Contributor harmless for any + liability incurred by, or claims asserted against, such Contributor + by reason of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000..233d1b7 --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Ignacio Garbayo Fernández + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index ef06081..640d9c8 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,224 @@ # Terminal Text Buffer -A terminal text buffer implementation in Java — the core data structure used by terminal emulators to store and render text output. +[![CI](https://github.com/igarbayo/terminal-text-buffer/actions/workflows/ci.yml/badge.svg)](https://github.com/igarbayo/terminal-text-buffer/actions/workflows/ci.yml) +[![REUSE Compliant](https://api.reuse.software/badge/github.com/igarbayo/terminal-text-buffer)](https://api.reuse.software/info/github.com/igarbayo/terminal-text-buffer) -## Building and Running Tests +> A terminal text buffer implementation in Java — the core data structure used by +> terminal emulators to store, edit, and render text output. + +![alt text](images/image.png) +![alt text](images/image-1.png) + +--- + +## What is this? + +When a shell prints output, something has to keep track of what character is in +each cell of the screen, what colour it has, and where the cursor is. That +"something" is a terminal buffer. + +This library implements that data structure from scratch in Java, without any +external runtime dependencies. It is meant for developers who are: + +- building a terminal emulator or TUI framework, +- studying how terminal emulators work internally, or +- looking for a clean, tested reference implementation. + +It is **not** a terminal emulator itself — it does not parse escape sequences, +drive a display, or handle input events. It is the data layer only. + +--- + +## Known Limitations + +Be aware of these before you use it: + +- **Wide characters in Windows PowerShell / CMD:** PowerShell replaces CJK + ideographs and many emoji with `?` before they reach the JVM. Wide character + support works correctly in the library (verified by the automated test suite) + but cannot be tested interactively from those terminals. Use IntelliJ's + built-in terminal or Windows Terminal with `chcp 65001`. + +--- + +## Quick Start + +**Requirements:** Java 8+, no external runtime dependencies. ```bash +git clone https://github.com/igarbayo/terminal-text-buffer.git +cd terminal-text-buffer +./gradlew test +``` + +All 14 test classes run. The HTML report is at +`build/reports/tests/test/index.html`. + +> **Windows note:** if Gradle cannot find the compiler, set +> `org.gradle.java.home` in `gradle.properties` to point to your JDK (not JRE): +> ``` +> org.gradle.java.home=C:\\Program Files\\Java\\jdk1.8.0_261 +> ``` + +### Use the buffer in your code + +```java +// Create an 80x24 buffer with 500 lines of scrollback +TerminalBuffer buf = new TerminalBuffer(80, 24, 500); + +// Set attributes and write +buf.setForeground(TerminalColor.RED); +buf.addStyle(TextStyle.BOLD); +buf.writeText("Hello, terminal!"); + +// Move the cursor and write more +buf.setCursor(0, 1); +buf.resetAttributes(); +buf.writeText("Normal text on row 1"); + +// Read back +String line0 = buf.getLine(0); // "Hello, terminal!" +char ch = buf.getChar(0, 0); // 'H' +``` + +--- + +## Interactive REPL + +A command-line REPL lets you poke at the buffer manually: + +```bash +./gradlew run +``` + +Type `help` at the prompt to see all commands, or consult the +[manual testing guide](docs/MANUAL_TESTING_GUIDE.md) for a full walkthrough +with expected output. + +| Command | What it does | +|---|---| +| `write ` | Write text at cursor position (overwrite) | +| `insert ` | Insert text at cursor, shifting content right | +| `fill [char]` | Fill current line with character (space if omitted) | +| `newline` | Insert empty line at bottom, scroll top to scrollback | +| `clear` | Clear screen and reset cursor to (0, 0) | +| `clearall` | Clear screen, scrollback, and reset cursor | +| `cursor ` | Move cursor to position | +| `move up\|down\|left\|right [n]` | Move cursor N steps (default 1) | +| `fg ` | Set foreground color | +| `bg ` | Set background color | +| `bold` / `italic` / `underline` | Enable text style | +| `nostyle