Skip to content

feat(config): per-platform shell and keyboard layout - #1856

Merged
y3owk1n merged 2 commits into
mainfrom
feat/per-platform-shell-and-layout
Oct 24, 2026
Merged

y3owk1n merged 2 commits into
mainfrom
feat/per-platform-shell-and-layout

Conversation

@y3owk1n

@y3owk1n y3owk1n commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Description

This PR makes the shell that exec steps run, and general.kb_layout_to_use, configurable per platform, using the same table shape general.primary_modifier introduced in #1854.

[general]
kb_layout_to_use = { darwin = "com.apple.keylayout.Dvorak", linux = "English (Dvorak)" }

[general.shell]
darwin = ["/bin/zsh", "-lc"]
linux = ["/bin/bash", "-lc"]
windows = ['C:\Windows\System32\cmd.exe', "/c"]

What changed for users.

  • general.shell is new. It is the full command line (shell plus arguments) an exec step runs, with the step's command string appended last. Every entry must start with a path that is absolute on its own platform and have at least one argument. Neru checks all three entries on every machine.
  • general.kb_layout_to_use takes the same per-platform table.
  • All three per-platform options (shell, kb_layout_to_use, primary_modifier) accept a table keyed by darwin, linux and windows, or one value for all three. A table only changes the platforms it names. A misspelled platform key such as macos refuses the file with "macos" is not a platform. Use darwin, linux or windows.
  • neru config set general.shell.linux '["/bin/zsh", "-c"]' and neru config set general.kb_layout_to_use.darwin <id> change one entry at runtime.

Existing configs keep working.

  • A kb_layout_to_use = "..." line loads as one value for every platform, with no warning.
  • exec_shell and exec_shell_args are deprecated and are removed in v2. Until then each one that is set replaces its part of general.shell on every platform, so a config written for one machine runs the same shell as before. Loading and neru config validate warn general.exec_shell is deprecated and is removed in v2. Move it to general.shell (same for exec_shell_args). neru config set does not print it, as with every config warning today.
  • The Windows default is now the literal C:\Windows\System32\cmd.exe instead of %SystemRoot%\System32\cmd.exe, because a table cannot read environment variables. A Windows install on another drive sets the windows entry.

Related Issues

Follows #1854.

Target Platform

  • Platform-agnostic (shared logic, no OS-specific code)
  • macOS
  • Linux
  • Windows

Type of Change

  • feat — New feature
  • fix — Bug fix
  • refactor — Code restructuring (no behavior change)
  • perf — Performance improvement
  • docs — Documentation only
  • test — Adding or updating tests
  • chore — Build, CI, dependencies, tooling

Cross-Platform Checklist

  • OS-specific files use correct build tags (e.g., //go:build darwin)
  • No darwin imports from untagged (shared) code — The One Rule
  • Stub implementations added for other platforms (returning CodeNotSupported)
  • N/A — This PR does not touch platform-specific code

The only platform-specific change is config_windows.go, whose shell override is removed. It is type-checked by check-cross and lint-cross. The Windows default is not run locally.

General Checklist

  • Code formatted (just fmt)
  • just ci passes — the same checks CI runs, on your host only (format
    check, lint, vet, build, a CGO-off type-check of the Linux and Windows
    builds, tests including a unit -race pass, vulnerability scan); CI
    runs them on macOS, Linux and Windows
  • Tests added/updated for new or changed functionality
  • Documentation updated (if applicable)
  • PR title is a conventional commit
    subject written for users — this PR squash-merges, so the title is what
    Release Please ships in the changelog, not the commits on the branch

Additional Context

N/A

One config file shared across machines could not say which shell each
of them runs, and Windows got its shell from a per-build override plus
a text rewrite in config init. kb_layout_to_use had the same problem,
since its values are platform-specific names.

general.shell is a new per-platform command line for exec steps:

  [general.shell]
  darwin = ["/bin/zsh", "-lc"]
  linux = ["/bin/bash", "-lc"]
  windows = ['C:\Windows\System32\cmd.exe', "/c"]

kb_layout_to_use now takes the same table. Both, and primary_modifier,
share one PerPlatform type. Each takes a table keyed by darwin, linux
and windows, or one value for all three, so every existing
kb_layout_to_use line loads unchanged. A table only changes the
platforms it names, and a key that names no platform refuses the file.

exec_shell and exec_shell_args are deprecated and are removed in v2.
Until then each one that is set replaces its part of general.shell on
every platform, and loading warns about it. The Windows default is now
the literal C:\Windows\System32\cmd.exe rather than %SystemRoot%, so an
install on another drive sets the windows entry.

The explicit-defaults guardrail now reads generic literal types, which
it skipped before.
@greptile-apps

greptile-apps Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all three previous findings are fixed and no new actionable issues remain.

Summary

This PR adds per-platform shell commands and keyboard layouts while keeping the deprecated shell settings available until v2.

  • Exec steps run through the shell command chosen for their platform.
  • Keyboard layouts and primary modifiers can use a value for each platform.

Reviews (2) · Last reviewed commit: "fix(config): accept one shell value and ..." · Reviewed by Greptile

Comment thread internal/config/shell.go Outdated
Comment thread internal/config/loader/per_platform_test.go Outdated
Comment thread internal/config/config.go
One value for general.shell could never load. It applies to every
platform, and the windows entry was checked as a Windows path on every
machine, so no single path passed. Only the entry for the running
platform now needs an absolute path. Every entry still needs an
argument.

neru config set general.kb_layout_to_use <id> stopped working once the
option became a table. Naming a per-platform option without a platform
now sets every platform, as the single-value form in a file does.

The loader tests use a path that is absolute on the host, so they pass
on Windows.
@y3owk1n y3owk1n mentioned this pull request Oct 24, 2026
@y3owk1n
y3owk1n merged commit 8067a80 into main Oct 24, 2026
45 of 46 checks passed
@y3owk1n
y3owk1n deleted the feat/per-platform-shell-and-layout branch October 24, 2026 17:38
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.

1 participant