mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/embedded: support asking for selection text, existence
This commit is contained in:
@ -489,6 +489,8 @@ void ghostty_surface_split_equalize(ghostty_surface_t);
|
||||
bool ghostty_surface_binding_action(ghostty_surface_t, const char *, uintptr_t);
|
||||
void ghostty_surface_complete_clipboard_request(ghostty_surface_t, const char *, void *, bool);
|
||||
uintptr_t ghostty_surface_pwd(ghostty_surface_t, char *, uintptr_t);
|
||||
bool ghostty_surface_has_selection(ghostty_surface_t);
|
||||
uintptr_t ghostty_surface_selection(ghostty_surface_t, char *, uintptr_t);
|
||||
|
||||
ghostty_inspector_t ghostty_surface_inspector(ghostty_surface_t);
|
||||
void ghostty_inspector_free(ghostty_surface_t);
|
||||
|
@ -971,8 +971,9 @@ extension Ghostty.SurfaceView: NSServicesMenuRequestor {
|
||||
}
|
||||
|
||||
// If we have a selection we can send the accepted types too
|
||||
// TODO selection
|
||||
if (sendType == nil || accepted.contains(sendType!)) {
|
||||
if ((self.surface != nil && ghostty_surface_has_selection(self.surface)) &&
|
||||
(sendType == nil || accepted.contains(sendType!))
|
||||
) {
|
||||
return self
|
||||
}
|
||||
|
||||
@ -983,8 +984,17 @@ extension Ghostty.SurfaceView: NSServicesMenuRequestor {
|
||||
to pboard: NSPasteboard,
|
||||
types: [NSPasteboard.PasteboardType]
|
||||
) -> Bool {
|
||||
// TODO
|
||||
return false
|
||||
guard let surface = self.surface else { return false }
|
||||
|
||||
// We currently cap the maximum copy size to 1MB. iTerm2 I believe
|
||||
// caps theirs at 0.1MB (configurable) so this is probably reasonable.
|
||||
let v = String(unsafeUninitializedCapacity: 1000000) {
|
||||
Int(ghostty_surface_selection(surface, $0.baseAddress, UInt($0.count)))
|
||||
}
|
||||
|
||||
pboard.declareTypes([.string], owner: nil)
|
||||
pboard.setString(v, forType: .string)
|
||||
return true
|
||||
}
|
||||
|
||||
func readSelection(from pboard: NSPasteboard) -> Bool {
|
||||
|
@ -865,6 +865,21 @@ fn changeConfig(self: *Surface, config: *const configpkg.Config) !void {
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns true if the terminal has a selection.
|
||||
pub fn hasSelection(self: *const Surface) bool {
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
return self.io.terminal.screen.selection != null;
|
||||
}
|
||||
|
||||
/// Returns the selected text. This is allocated.
|
||||
pub fn selectionString(self: *Surface, alloc: Allocator) !?[]const u8 {
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
const sel = self.io.terminal.screen.selection orelse return null;
|
||||
return try self.io.terminal.screen.selectionString(alloc, sel, false);
|
||||
}
|
||||
|
||||
/// Returns the pwd of the terminal, if any. This is always copied because
|
||||
/// the pwd can change at any point from termio. If we are calling from the IO
|
||||
/// thread you should just check the terminal directly.
|
||||
|
@ -1438,6 +1438,30 @@ pub const CAPI = struct {
|
||||
return surface.core_surface.needsConfirmQuit();
|
||||
}
|
||||
|
||||
/// Returns true if the surface has a selection.
|
||||
export fn ghostty_surface_has_selection(surface: *Surface) bool {
|
||||
return surface.core_surface.hasSelection();
|
||||
}
|
||||
|
||||
/// Copies the surface selection text into the provided buffer and
|
||||
/// returns the copied size. If the buffer is too small, there is no
|
||||
/// selection, or there is an error, then 0 is returned.
|
||||
export fn ghostty_surface_selection(surface: *Surface, buf: [*]u8, cap: usize) usize {
|
||||
const selection_ = surface.core_surface.selectionString(global.alloc) catch |err| {
|
||||
log.warn("error getting selection err={}", .{err});
|
||||
return 0;
|
||||
};
|
||||
const selection = selection_ orelse return 0;
|
||||
defer global.alloc.free(selection);
|
||||
|
||||
// If the buffer is too small, return no selection.
|
||||
if (selection.len > cap) return 0;
|
||||
|
||||
// Copy into the buffer and return the length
|
||||
@memcpy(buf[0..selection.len], selection);
|
||||
return selection.len;
|
||||
}
|
||||
|
||||
/// Copies the surface working directory into the provided buffer and
|
||||
/// returns the copied size. If the buffer is too small, there is no pwd,
|
||||
/// or there is an error, then 0 is returned.
|
||||
|
Reference in New Issue
Block a user