Skip to content

feat(case-convert): add Case Convert launcher plugin - #510

Merged
ItsLemmy merged 1 commit into
noctalia-dev:mainfrom
kjvdven:add-case-convert
Aug 30, 2026
Merged

feat(case-convert): add Case Convert launcher plugin#510
ItsLemmy merged 1 commit into
noctalia-dev:mainfrom
kjvdven:add-case-convert

Conversation

@kjvdven

@kjvdven kjvdven commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Plugin

  • Id: kjvdven/case-convert
  • New plugin
  • Update to an existing plugin (version bumped in plugin.toml)

What it does

Converts text between naming conventions from the launcher: 18 of them, across
camelCase, PascalCase, kebab-case, snake_case, CONSTANT_CASE,
dot.case, path/case, Pascal_Snake_Case, KEBAB-UPPER-CASE,
Header-Case, Title Case, Capital Case, Sentence case, no case,
lower case, UPPER CASE, sWAP cASE and AlTeRnAtInG cAsE. Every row shows
the converted text with its convention as the subtitle; Enter copies it.

Type the text after the prefix (/case parse http response), or leave the query
empty and it converts the current primary selection, falling back to the
clipboard — select text anywhere, open the launcher, /case, Enter. A query
starting with > filters the conversion list by name while still using the
selection as input.

The three manifest categories (Programming, Text, Fun) drive the launcher's
filter bar. It scratches the itch of having a label in one shape and needing it
in another: a heading that has to become a file name, a database column that has
to become a JSON key.

External dependencies

wl-paste (wl-clipboard), and only to read the primary selection when the query
is empty. It is invoked as wl-paste --primary --no-newline. The plugin checks
noctalia.commandExists("wl-paste") first and falls back to
noctalia.clipboardText(), so it degrades gracefully when it is absent. Listed
in dependencies in plugin.toml and under Requirements in the README.

No other process is spawned, no file is written or read outside the plugin
directory, and there is no network access at all. The only clipboard write is
the copy the user asks for by activating a row.

Testing

Ran it from the launcher against typed queries, the primary selection and the
clipboard; walked the category filter bar; toggled all three settings
(input_source across its three values, preserve_casing, notify_on_copy);
exercised the > name filter; and checked edge cases: multi-line input,
accented text (café-au-lait), acronyms (HTTPServerURL), an empty selection
and a separators-only input.

The conversion logic lives in cases.luau and touches no noctalia API, so it
also runs standalone under the luau CLI; the repository linked below carries 52
unit checks over it, including the tokenizer equivalence between parse HTTP response, parse-http-response and parseHttpResponse.

noctalia plugins lint case-convert reports 0 errors, 0 warnings, and
.github/workflows/scripts/validate-plugins.py passes locally.

  • Tested on Niri
  • Tested on Hyprland
  • Tested on Sway
  • Tested on another compositor:
  • Noctalia version tested against: 5.0.0
  • Plugin API level: 3

Screenshots / Videos

Case Convert in the launcher

Notes

Rows carry a blank badge on purpose. Leaving glyph unset falls back to
app-window, and a text badge renders at icon size, so a blank badge is what
keeps the rows about the converted text while staying aligned with the rest of
the launcher.

Casing is UTF-8 aware for ASCII and the Latin-1 Supplement block (café
CAFÉ). Letters past that block pass through uncased rather than corrupted, and
the decoder walks bytes instead of calling the utf8 library, so the invalid
UTF-8 a raw selection can contain cannot throw.

Development happens at https://github.com/kjvdven/noctalia-case-convert.

Checklist

  • The directory name matches the part of id after the / in plugin.toml exactly.
  • It ships plugin.toml, README.md, thumbnail.webp, and translations/en.json.
  • README.md follows the
    README template, documents
    every entry id and dependency, and includes exact panel IPC commands and launcher prefixes where applicable.
  • I created thumbnail.webp with the thumbnail generator.
  • version follows semver and is bumped in this PR; plugin_api is the oldest API level this plugin requires.
  • Every non-English translation in this PR uses a locale supported by Noctalia core, and I can read, write, and
    understand that language well enough to review and maintain it (no unreviewed machine/LLM translations).
  • I did not edit catalog.toml; CI generates it.
  • This PR touches exactly one plugin directory.

Code review attestation

  • The code is readable and not obfuscated, minified, or generated.
  • It does not download and execute remote code.
  • Every network call, filesystem write, and spawned process is something the description above accounts for.
  • I have the right to publish this code under the license declared in plugin.toml.

@ItsLemmy
ItsLemmy merged commit 475ab29 into noctalia-dev:main Aug 30, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants