Compare commits

..

1 Commits

Author SHA1 Message Date
24dbd3a2e2 fix(editor): follow live terminal size in external editor
All checks were successful
CI Code / Linux (arch) (pull_request) Successful in 7m9s
CI Code / Check spelling (pull_request) Successful in 14s
CI Code / Check coding style (pull_request) Successful in 28s
CI Code / Linux (debian) (pull_request) Successful in 4m34s
CI Code / Code Coverage (pull_request) Successful in 3m35s
CI Code / Linux (ubuntu) (pull_request) Successful in 7m30s
The compose editor is spawned via fork+execvp and inherits profanity's
environment, including LINES/COLUMNS. Those hold the terminal size
captured when profanity started (set by readline/ncurses at init) and
are never refreshed on resize. A curses-based editor (nano, vim, ...)
honors LINES/COLUMNS over the real window, so it renders at the
launch-time dimensions and leaves the rest of the window unused after
the terminal has been resized.

Build a copy of the environment without LINES/COLUMNS before forking and
point the child's environ at it, so the editor's curses falls back to
ioctl(TIOCGWINSZ) and tracks the current window. The env is assembled in
the parent so the child only swaps the environ pointer, which is
async-signal-safe -- unlike unsetenv() -- in the multithreaded
fork->exec window. profanity itself is unaffected: it already reads the
live size via ioctl in ui_resize(), and its own environment is intact.
2026-07-04 11:36:59 +00:00

View File

@@ -143,8 +143,8 @@ launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* dat
g_source_unref(sigchld_warmup);
// Build the editor's env without LINES/COLUMNS pre-fork, so the child only
// reassigns environ instead of calling unsetenv() between fork and exec.
// The editor's (n)curses then reads the live window via ioctl(TIOCGWINSZ).
// swaps environ (async-signal-safe) instead of calling unsetenv(). The
// editor's (n)curses then reads the live window via ioctl(TIOCGWINSZ).
gsize env_len = 0;
while (environ[env_len]) {
env_len++;
@@ -191,7 +191,7 @@ launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* dat
editor_pid = pid;
g_child_watch_add((GPid)pid, _editor_exit_cb, ctx);
g_strfreev(editor_argv);
g_free(editor_env); // frees the parent's array only; the child keeps its own COW copy until execvp
g_free(editor_env); // array only; strings are borrowed from environ
return FALSE;
}