This rule is generally trying to be helpful, but it doesn't like a few
places in our code base where we're intentionally listing out all of the
well-known cases. Given that, just disable it.
https://realm.github.io/SwiftLint/no_fallthrough_only.html
In order to support running from both the repository root and from
within Xcode project, and to keep things generally organized, our
primary .swiftlint.yml configuration file lives under macos/.
This change introduces a root-level .swiftlint.yml which limits the file
scope to macos/ and then includes macos/.swiftlint.yml for the rest of
the directives.
This unlocks a few benefits:
- We no longer need to pass an explicit `macos` path argument in any of
our invocations. SwiftLint will do the right thing when run either from
the repository root or from within the macos/ directory.
- It lets us easily exclude the macos/build/ directory (and re-enable
the 'deployment_target' rule). In the previous setup, this was more
challenging than you'd expect due to SwiftLint's path resolution rules
and required passing even more arguments like `--working-directory`.
The only downside is adding a new file to the repository root, but that
feels like the right trade-off given the benefits and conveniences.
In order to support running from both the repository root and from
within Xcode project, and to keep things generally organized, our
primary .swiftlint.yml configuration file lives under macos/.
This change introduces a root-level .swiftlint.yml which limits the file
scope to macos/ and then includes macos/.swiftlint.yml for the rest of
the directives.
This unlocks a few benefits:
- We no longer need to pass an explicit `macos` path argument in any of
our invocations. SwiftLint will do the right thing when run either
from the repository root or from within the macos/ directory.
- It lets us easily exclude the macos/build/ directory (and re-enable
the 'deployment_target' rule). In the previous setup, this was more
challenging than you'd expect due to SwiftLint's path resolution rules
and required passing even more arguments like `--working-directory`.
The only downside is adding a new file to the repository root, but that
feels like the right trade-off given the benefits and conveniences.
SwiftLint <https://realm.github.io/SwiftLint/> is both a linter and
formatting. It's a popular way to spot issues and enforce a consistent
style.
Our SwiftLint configuration lives in macos/.swiftlint.yml, where is is
automatically discovered. It's very configurable, and I made an initial
pass as some basic, weakly-opinionated rules. The "TODO" section lists
rules that currently have violations but can be easily (auto)fixed in
follow-up commits.
Our integration is CLI-based. Similar to our other support tools, we
expect developers to install `swiftlint` via nix or e.g. Homebrew.
This is documented in HACKING.md.
We also have an optional Xcode integration, for in-editor feedback. When
`swiftlint` is available, it's run as a script-based Build Phase.
SwiftLint supports an auto-fix mode (--fix). Agents are aware of this
via AGENTS.md.
The rules are enforced using a (nix-based) CI job.
Switch to using the existing UTType.unixExecutable constant for this
operator, which also lets us remove a failure path. Also, use the
completion-based setDefaultApplication() variant to handle errors.
This simplifies the code enough that we don't need the additional
NSWorkspace+Ghostty extension functions.
This PR enables iTerm2-like one button "Set Ghostty as Default Terminal
App" functionality on macOS, making it easier to open a directory in
Ghostty, run shell scripts when mouse clicking, etc.
We already had an established Ghostty.Shell namespace (previously a
struct; now a more idiomatic enum), and locating these functions next to
each other makes it clearer how they relate to one another.
We already had an established Ghostty.Shell namespace (previously a
struct; now a more idiomatic enum), and locating these functions next to
each other makes it clearer how they relate to one another.
Xcode wants these to be sorted and will update this list when the
project file is saved so proactively make this change before it gets
mixed up in other work.
## Summary
- Fixes#10345 — `copy_title_to_clipboard` now copies the user-set
custom title instead of the raw terminal title
- Adds a new `copy_title` apprt action as [suggested by
@mitchellh](https://github.com/ghostty-org/ghostty/issues/10345#issuecomment-2601002974)
- Each platform (GTK + macOS) resolves the effective title (user
override → terminal title fallback) before copying to clipboard
## Changes
- **`src/apprt/action.zig`** — New `copy_title` void action
- **`include/ghostty.h`** — C ABI enum entry
- **`src/Surface.zig`** — Binding handler now dispatches apprt action
instead of inline logic
- **`src/apprt/gtk/class/surface.zig`** — `getEffectiveTitle()` helper
(returns `title_override orelse title`)
- **`src/apprt/gtk/class/application.zig`** — GTK action handler
- **`macos/.../Ghostty.App.swift`** — macOS handler using
`surfaceView.title` + `NSPasteboard`
*Note*: This PR was *AI* assisted.
When a user renames a surface via "Change Terminal Title" and then
uses copy_title_to_clipboard, the raw terminal title was copied
instead of the custom name.
This adds a new `copy_title` apprt action so each platform resolves
the effective title (user override or terminal-set) before copying
to clipboard.
Fixes#10345
When we're building an input string that's explicitly meant to be used
as a shell command, quote it using the same logic as Python's
`shlex.quote` function.
This specifically addresses issues we've seen when open(1)'ing Ghostty
with filename arguments that contain spaces.
See #2633, #3030
When we're building an input string that's explicitly meant to be used
as a shell command, quote (escape) it using the same logic as Python's
shlex.quote function.
This specifically addresses issues we've seen when open(1)'ing Ghostty
with filename arguments that contain spaces.
[Reference](https://github.com/insidegui/AudioCap). This is Apple's latest system for allowing apps to access loopback audio streams eg: Desktop-Audio, Window-Audio, etc...