summaryrefslogtreecommitdiff
path: root/include/term/term.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/term/term.h')
-rw-r--r--include/term/term.h77
1 files changed, 45 insertions, 32 deletions
diff --git a/include/term/term.h b/include/term/term.h
index 9c6281b..dc41114 100644
--- a/include/term/term.h
+++ b/include/term/term.h
@@ -11,8 +11,9 @@
* paints from that copy.
*
* All functions take the terminal as the first argument. Functions that take
- * a const struct term do not change what it shows. A function that returns
- * text copies it into a buffer that the caller owns.
+ * a const struct term do not change what it shows. Selection, history, link,
+ * directory, and pointer-shape queries return owned strings; release them
+ * with term_text_free().
*
* Threads. Any thread can call any function. Each call that reads or changes
* a terminal enters its writer section, so calls on one terminal run one at a
@@ -262,11 +263,13 @@ TERM_API struct term_input_result term_input_encode_paste(
);
/* The cursor in screen coordinates (not the viewport). */
TERM_API struct term_cursor term_cursor(const struct term *t);
-/* Copy the directory from OSC 7 into buf, with the rules of
- * term_selection_text(). Return 0 when there is none. */
-TERM_API size_t term_cwd(const struct term *t, char *buf, size_t cap);
-/* Copy the pointer shape name from OSC 22 the same way. */
-TERM_API size_t term_pointer_shape(const struct term *t, char *buf, size_t cap);
+/* Owned, NUL-terminated text from OSC 7 and OSC 22. NULL when unavailable
+ * or allocation fails. The strings stay valid after the terminal changes
+ * or is freed. Release them with term_text_free(). */
+TERM_API char *term_cwd(const struct term *t);
+TERM_API char *term_pointer_shape(const struct term *t);
+/* Release any owned text returned by the library. NULL is safe. */
+TERM_API void term_text_free(char *text);
/*
* Viewport. The viewport shows as many rows as the screen. Offset 0 shows
@@ -302,30 +305,36 @@ TERM_API void term_select_start(struct term *t, struct term_vector2i cell, bool
TERM_API void term_select_extend(struct term *t, struct term_vector2i cell, bool right_half);
TERM_API void term_select_clear(struct term *t);
TERM_API bool term_has_selection(const struct term *t);
-/* Copy the selected text as UTF-8 into buf. Return its length without the NUL.
- * With a NULL buf or a zero cap, only the length is returned. Otherwise the
- * copy is cut to cap - 1 bytes and NUL-terminated. Return 0 when nothing is
- * selected. Hold term_lock across the length query and the copy to keep the
- * length stable. */
-TERM_API size_t term_selection_text(const struct term *t, char *buf, size_t cap);
-/* The OSC 8 link or the detected URL at a viewport cell. Copies it with the
- * same rules as term_selection_text(). Return 0 when there is no link. */
-TERM_API size_t term_link_at(const struct term *t, struct term_vector2i cell, char *buf, size_t cap);
-
-/* Cell attributes. */
+/* Owned, NUL-terminated UTF-8 of the selection. NULL when nothing is
+ * selected or allocation fails; a selection of blanks may produce an empty
+ * string. Capture is atomic with respect to other calls on t. Release the
+ * result with term_text_free(). */
+TERM_API char *term_selection_text(const struct term *t);
+/* Owned OSC 8 link or detected URL at a viewport cell. NULL when there is
+ * no link or allocation fails. Release the result with term_text_free(). */
+TERM_API char *term_link_at(const struct term *t, struct term_vector2i cell);
+
+/* Cell attributes share the write core's bit layout. Underline styles are
+ * mutually exclusive flags, not a shifted enum; use term_attr_underline(). */
enum term_attr {
TERM_ATTR_BOLD = 1u << 0,
TERM_ATTR_ITALIC = 1u << 1,
- TERM_ATTR_FAINT = 1u << 2,
+ TERM_ATTR_UNDERLINE = 1u << 2,
TERM_ATTR_STRIKE = 1u << 3,
TERM_ATTR_OVERLINE = 1u << 4,
- TERM_ATTR_LINK = 1u << 5,
- TERM_ATTR_EMOJI = 1u << 6, /* the text requested emoji presentation */
- TERM_ATTR_TEXT = 1u << 7, /* the text requested text presentation */
+ TERM_ATTR_EMOJI = 1u << 5, /* the text requested emoji presentation */
+ TERM_ATTR_TEXT = 1u << 6, /* the text requested text presentation */
+ TERM_ATTR_FAINT = 1u << 10,
+ TERM_ATTR_DOUBLE_UNDERLINE = 1u << 11,
+ TERM_ATTR_CURLY_UNDERLINE = 1u << 12,
+ TERM_ATTR_DOTTED_UNDERLINE = 1u << 13,
+ TERM_ATTR_DASHED_UNDERLINE = 1u << 14,
+ TERM_ATTR_LINK = 1u << 15,
};
-#define TERM_ATTR_UNDERLINE_SHIFT 8
-#define TERM_ATTR_UNDERLINE_MASK (7u << TERM_ATTR_UNDERLINE_SHIFT)
+#define TERM_ATTR_UNDERLINE_MASK \
+ (TERM_ATTR_UNDERLINE | TERM_ATTR_DOUBLE_UNDERLINE | TERM_ATTR_CURLY_UNDERLINE | \
+ TERM_ATTR_DOTTED_UNDERLINE | TERM_ATTR_DASHED_UNDERLINE)
enum term_underline {
TERM_UNDERLINE_NONE,
@@ -338,7 +347,11 @@ enum term_underline {
static inline enum term_underline term_attr_underline(uint16_t attrs)
{
- return (enum term_underline)((attrs & TERM_ATTR_UNDERLINE_MASK) >> TERM_ATTR_UNDERLINE_SHIFT);
+ if (attrs & TERM_ATTR_DOUBLE_UNDERLINE) return TERM_UNDERLINE_DOUBLE;
+ if (attrs & TERM_ATTR_CURLY_UNDERLINE) return TERM_UNDERLINE_CURLY;
+ if (attrs & TERM_ATTR_DOTTED_UNDERLINE) return TERM_UNDERLINE_DOTTED;
+ if (attrs & TERM_ATTR_DASHED_UNDERLINE) return TERM_UNDERLINE_DASHED;
+ return attrs & TERM_ATTR_UNDERLINE ? TERM_UNDERLINE_SINGLE : TERM_UNDERLINE_NONE;
}
/* text refers to a grapheme cluster in the snapshot; see term_snapshot_cluster(). */
@@ -348,7 +361,7 @@ static inline enum term_underline term_attr_underline(uint16_t attrs)
struct term_cell {
uint32_t text; /* a code point, TERM_TEXT_CLUSTER | n, or 0 for an empty cell */
term_color fg, bg;
- uint16_t attrs; /* enum term_attr and the underline style */
+ uint16_t attrs; /* enum term_attr flags; at most one underline flag */
uint8_t width; /* 1; 2 for a wide glyph; 0 for the right half of a wide glyph */
uint8_t reserved;
};
@@ -404,12 +417,12 @@ TERM_API uint64_t term_snapshot_row_key(const struct term_snapshot *s, int y);
/* Number of rows in history above the screen. 0 if alternate screen or no history. */
TERM_API int term_history_rows(const struct term *t);
-/* Copy up to max_rows history rows before the current viewport as UTF-8 into
- * buf, with the same rules as term_selection_text(). Join soft-wrapped rows.
- * End closed lines with a newline. This does not change the selection.
- * Return 0 when there is no history text, and also when the text cannot be
- * built. */
-TERM_API size_t term_history_text(struct term *t, int max_rows, char *buf, size_t cap);
+/* Owned, NUL-terminated UTF-8 of up to max_rows history rows before the
+ * current viewport. Join soft-wrapped rows and end closed lines with a
+ * newline. Does not change the selection. No history or max_rows <= 0 gives
+ * an empty string; NULL means allocation failed or t is NULL. Release the
+ * result with term_text_free(). */
+TERM_API char *term_history_text(struct term *t, int max_rows);
TERM_API struct term_span term_snapshot_row_selection(const struct term_snapshot *s, int y);
/* The code points of a cluster cell. Returns the number of code points and