Skip to content

plugins: add QuickCalc - #203

Open
klopster wants to merge 7 commits into
Ryoku-dev:mainfrom
klopster:plugin/quickcalc
Open

klopster wants to merge 7 commits into
Ryoku-dev:mainfrom
klopster:plugin/quickcalc

Conversation

@klopster

@klopster klopster commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

What is this?

QuickCalc (plugins/quickcalc), a community plugin: a fast, keyboard-driven calculator with Basic, Scientific and Programmer modes, live preview, variables, memory and a persistent history. It runs as a bar panel (topbarGlyph) or as a floating window (framePopout), and one IPC keybind toggles either: qs -c shell ipc call quickcalc toggle.

  • No window-manager code: the floating window is a Quickshell layer-shell surface, and its corners follow the shell frame rounding through PluginKit Config.frameRadius.
  • Imports only QtQuick, Quickshell and Ryoku.PluginKit. Settings go through pluginApi.saveSetting; it writes only state.json in its own state folder.
  • The arithmetic engine is pure JS with no eval, and has its own tests (node tests/engine.test.cjs, 101 pass). The tests are for development; the plugin never runs them.
  • External commands: wl-copy (copy the result) and mkdir (create the state folder), both declared in the manifest.
  • Maintained by me (Klopster), not the Ryoku team. MIT licensed.

Checklist

  • One folder under its catalogue with a manifest and a real preview image.
  • One entry added to that catalogue's registry.json
  • Tested live in Ryoku, it renders and behaves correctly.
  • tests/validate-catalogue.sh passes from the repo root.
  • I own or have permission to submit this content, and it is licensed for redistribution.
  • It does not overwrite user configuration or run privileged commands without clear consent.

@neur0map

neur0map commented Nov 8, 2026

Copy link
Copy Markdown
Member

Slop score: 25/100 (no significant slop signals)

  • large change adds over 60% of lines outside tests

🔍 mika-agent · self-hosted review for the Ryoku org · @mika-agent help for commands

@neur0map

neur0map commented Nov 8, 2026

Copy link
Copy Markdown
Member

@mika-agent review

@neur0map

neur0map commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

🦊 mika's review

Incremental review: new commits since the last checkpoint.

Summary

  • Add QuickCalc with basic, scientific, and programmer modes.
  • Support bar panels and positioned floating windows with IPC toggling.
  • Persist history, variables, memory, and calculator view choices.
  • Add arithmetic engine tests and installation documentation.

Estimated review effort: 1/5 · risk: low

📁 Walkthrough details

plugins/quickcalc/service/Engine.js

  • Adds a tokenizer and recursive-descent evaluator without eval.
  • Supports scientific functions, variables, programmer bases, bitwise operations, and result formatting.
    • Bounds expression length and nesting for live preview.
    • Preserves full-precision results when chaining calculations.

plugins/quickcalc/service/Main.qml

  • Manages shared calculator state, evaluation, clipboard actions, and IPC toggling.
  • Persists history, variables, memory, and view overrides in the plugin state directory.
    • Merges startup state with changes made before loading finishes.
    • Routes the toggle to the bar panel or floating window.

plugins/quickcalc/content/CalculatorView.qml

  • Adds the shared keyboard-driven calculator interface with live preview and history.
  • Provides mode controls, base readouts, shortcuts, and optional keypad access.
    • Restores the service expression when a view opens.
    • Requires confirmation before clearing history.

plugins/quickcalc/content/FloatingWindow.qml

  • Adds a positioned layer-shell calculator window with exclusive keyboard focus.
  • Closes on outside clicks and follows shell frame rounding.
    • Positions the view using the reported popout placement.

plugins/quickcalc/content/Widget.qml

  • Adds the bar glyph and frame-popout window opener.
  • Reports popout placement to the shared service, with a manifest-default fallback.
    • Uses the host panel toggle for bar placement.

plugins/quickcalc/content/Panel.qml

  • Hosts the shared calculator view in the shell-managed bar panel.
    • Reports the calculator's implicit dimensions to the host.

plugins/quickcalc/content/Keypad.qml

  • Adds optional on-screen keypads for all three calculator modes.
    • Disables programmer digits unavailable in the selected base.

plugins/quickcalc/manifest.json

  • Declares plugin entry points, supported hosts, defaults, settings, and command dependencies.
    • Defaults to a right-edge frame popout in basic mode.

plugins/quickcalc/product-manifest.json

  • Defines the versioned catalogue payload, file hashes, and installation flags.
    • Lists runtime files, tests, documentation, and preview assets.

plugins/registry.json

  • Registers QuickCalc for catalogue discovery with its manifest hash and gallery references.
    • Marks the plugin as community-maintained.

plugins/quickcalc/tests/engine.test.cjs

  • Adds development-only tests for parsing, arithmetic, formatting, and programmer mode.
    • Covers precision carry, invalid input, and parser limits.

plugins/quickcalc/README.md

  • Documents installation, manual IPC keybinding, calculator features, and settings.
  • Describes state storage, external commands, development checks, and maintenance.
    • Explains bar and floating-window placement behavior.

plugins/quickcalc/LICENSE

  • Adds the MIT license and author copyright notice.
    • Specifies redistribution terms.

No actionable findings. Mika looked for bugs, security issues, and risks in the diff and came up empty on clear defects.

🚦 Merge recommendation: no_concerns_found


🦊 Generated by Mika — the Ryoku org's self-hosted AI code reviewer. Machine findings: verify before merging.

@neur0map neur0map left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 mika reviewed this change; details in the walkthrough comment.

Comment thread plugins/quickcalc/product-manifest.json Resolved
Comment thread plugins/quickcalc/service/Engine.js Resolved
Comment thread plugins/quickcalc/service/Engine.js Resolved
Comment thread plugins/quickcalc/service/Engine.js Resolved
Comment thread plugins/quickcalc/service/Main.qml Resolved
…xpression when the floating window reopens; Floating window: exclusive keyboard, click outside to close (Ask bar pattern); Default to the manifest placement when none is stored; Negative carried result keeps unary precedence; HistorySize 0 keeps no history-document HEX a-f vs e; Remove the root-level duplicate CalculatorView.qml

@neur0map neur0map left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Changes requested — 0 critical and 2 major issue(s): see the inline comments and the walkthrough for fixes and an agent-ready prompt.

Comment on lines +84 to +99
readonly property var hints: {
var h = [
{ keys: ["Enter"], label: "Evaluate", action: "evaluate" },
{ keys: ["\u2191", "\u2193"], label: "History", action: "historyUp" },
{ keys: ["Del"], label: "Clear", action: "clearEntry" },
{ keys: ["\u21e7", "Del"], label: "Clear all", action: "clearAll" },
{ keys: ["Ctrl", "C"], label: "Copy result", action: "copyResult" },
{ keys: ["Ctrl", "\u21e7", "C"], label: "Copy all", action: "copyCalculation" },
{ keys: ["Ctrl", "M"], label: "Next mode", action: "cycleLayout" }
];
if (root.layout === "scientific") h.push({ keys: ["Ctrl", "B"], label: "Deg / Rad", action: "toggleAngleMode" });
if (root.layout === "programmer") h.push({ keys: ["Ctrl", "B"], label: "Next base", action: "cycleBase" });
h.push({ keys: ["Ctrl", "L"], label: root.clearArmed ? "Again to clear" : "Clear history", action: "clearHistory" });
h.push({ keys: ["Ctrl", "K"], label: "Keypad", action: "toggleKeypad" });
h.push({ keys: ["Ctrl", "H"], label: "Shortcuts", action: "toggleHints" });
h.push({ keys: ["Esc"], label: "Close", action: "close" });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 minor · Possible Bug · fix: high effort

The new calculator labels and prompts are hard-coded English, so they remain untranslated in non-English shell sessions. Route these strings through the shell's I18n catalog.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugins can't use the shell's I18n catalog: the plugin rules (R4) only allow QtQuick*, Quickshell* and Ryoku.PluginKit* imports, and PluginKit has no translation API. Of the 45 store plugins only power-button ships a plugin-local catalog; ten use qsTr() with no translations behind it. Happy to add a plugin-local catalog like power-button's, but there's no shell catalog to route through.

Comment thread plugins/quickcalc/product-manifest.json Resolved
Comment thread plugins/quickcalc/service/Main.qml Resolved
Comment thread plugins/quickcalc/service/Main.qml Resolved
@klopster

klopster commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor Author

@neur0map
Pushed the fixes for mika's second round; summary so it's quick to review:

Fixed:

  • State saves made before the state dir/first read are no longer dropped; a late load merges instead of overwriting (Main.qml)
  • HEX: face=5 assigns; FF= still evaluates (Engine.js, +5 tests)
  • History results re-render in the active base (10 → 0xA in HEX)
  • Floating window: exclusive keyboard on open, click outside to close (same pattern as the Ask bar)
  • Mode, base, angle unit, keypad and shortcuts panel now persist across reloads; Hub settings remain the defaults and override the saved state when changed (two new settings: Number base, Show shortcuts panel)
  • Version 0.3.0

Tests:

  • 112/112 engine tests, ryoku plugin validate clean, tests/validate-catalogue.sh passes.

Resolved:

  • LICENSE install: false is packer policy for plugins (confirmed by mika).

Needs your call (details in the inline threads)

  • i18n. Plugins can't import the shell's I18n (rule R4), so the open thread is the only remaining finding. I can add a plugin-local catalogue like power-button's if you want one.

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