Skip to content

Conversation

@oxelf
Copy link

@oxelf oxelf commented Oct 17, 2025

As the title says, I exported the paste encoding function using the same pattern as with the key encoder. The GhosttyPasteEncoder is just a wrapper around the paste.Options and the allocator to keep track of.
Here is an example how it can be used:

 #include <ghostty/vt.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

int main() {
// Create a paste encoder
GhosttyPasteEncoder encoder;
if (ghostty_paste_encoder_new(NULL, &encoder) != GHOSTTY_SUCCESS) {
  printf("Failed to create paste encoder\n");
  return 1;
}

// Enable bracketed paste mode
ghostty_paste_encoder_set_bracketed(encoder, true);

// we could use this to find out the required size, or just use a large
// enough buffer
size_t required;
char simple_paste[] = "pasted content";
char encoded[128];

if (ghostty_paste_encoder_encode(simple_paste, strlen(simple_paste), encoder,
                                 encoded, sizeof(encoded),
                                 &required) != GHOSTTY_SUCCESS) {
  printf("Failed to encode paste data\n");
  return 1;
}

printf("Encoded paste data: ");
for (size_t i = 0; i < strlen(encoded); i++) {
  if (encoded[i] == 0x1b) {
    printf("\\x1b");
  } else {
    printf("%c", encoded[i]);
  }
}

 // free resources
 ghostty_paste_encoder_free(encoder);
} 

(Mitchellh said in the discord that he would be interested in some help and wants small PRs so I didnt open an issue just for this).

@oxelf oxelf requested a review from a team as a code owner October 17, 2025 07:41
Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

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

Thank you! A couple points.

*
* @ingroup paste
*/
GhosttyResult ghostty_paste_encoder_new(const GhosttyAllocator* allocator,
Copy link
Contributor

Choose a reason for hiding this comment

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

The main design thing I ran into here is whether we want an object like this or if we just want to do a single flat ghostty_paste_encode that takes an option structure. For ABI compatibility, the option structure may want to be a pointer with opaque setopt-style functions but then I struggle with whether that complexity should just back into what you did here anyways...

That's my main hesitation on this API.

Copy link
Author

Choose a reason for hiding this comment

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

When taking an option struct directly, we would either need to make it C ABI compatible or do it with opaque pointers like in this implementation. The problem with the opaque pointers is that we have to allocate. When we have just an extern struct for the options, we could let users of the api decide if they want to alloc the options or use a local reference. Complexity wise, I dont think that the current way is really that complicated. It also sounds logical that you create a PasteEnocder and set the bracketed mode on the encoder.

Copy link
Member

Choose a reason for hiding this comment

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

If we want to be really complicated we could copy Vulkan and use essentially type-erased, stack-allocated linked lists for extensions, but that is honestly quite cursed and over the top for what we're doing here

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah the reason I'm even sweating these details is because the patterns we pick here are likely to extend to what we do with other APIs. Does it really matter for the paste encoding API? No. But for being consistent with the terminal API? Probably. But we can always break ABI for now because we aren't even released.

Copy link
Author

@oxelf oxelf Oct 20, 2025

Choose a reason for hiding this comment

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

Just to compare a little bit:

setopt pros:

  • smaller API surface

setopt cons:

  • weaker typing(can that even be considered typed?)
  • user has to first look at the docs to find out what type to use per opt.

setters pros:

  • Type safe
  • People are used to setters
  • More easy to document what each opt does

setters cons:

  • A lot of ghostty_* functions.

Do you guys have something to add?

@mitchellh
Copy link
Contributor

Note this is just blocked on some test changes. I'm fine with the API itself.

@oxelf
Copy link
Author

oxelf commented Oct 22, 2025

Everything should be correct now. One thing I found quite weird is that in the build.zig:

        // Normal tests always test our libghostty modules
        //test_step.dependOn(test_lib_vt_step);

// Normal tests always test our libghostty modules

why is this commented out when it says that normal tests should always test the libghostty modules?

@oxelf oxelf requested a review from mitchellh October 22, 2025 11:29
@mitchellh mitchellh force-pushed the lib_vt_paste_encode branch from 6625c5c to fb044f0 Compare October 23, 2025 19:53
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.

3 participants