Skip to content

Commit b38dd9e

Browse files
dschogitster
authored andcommitted
strbuf: add a helper function to call the editor "on an strbuf"
This helper supports the scenario where Git has a populated `strbuf` and wants to let the user edit it interactively. In `git add -p`, we will use this to allow interactive hunk editing: the diff hunks are already in memory, but we need to write them out to a file so that an editor can be launched, then read everything back once the user is done editing. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 11f2c0d commit b38dd9e

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

strbuf.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,3 +1125,31 @@ int strbuf_normalize_path(struct strbuf *src)
11251125
strbuf_release(&dst);
11261126
return 0;
11271127
}
1128+
1129+
int strbuf_edit_interactively(struct strbuf *buffer, const char *path,
1130+
const char *const *env)
1131+
{
1132+
char *path2 = NULL;
1133+
int fd, res = 0;
1134+
1135+
if (!is_absolute_path(path))
1136+
path = path2 = xstrdup(git_path("%s", path));
1137+
1138+
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1139+
if (fd < 0)
1140+
res = error_errno(_("could not open '%s' for writing"), path);
1141+
else if (write_in_full(fd, buffer->buf, buffer->len) < 0) {
1142+
res = error_errno(_("could not write to '%s'"), path);
1143+
close(fd);
1144+
} else if (close(fd) < 0)
1145+
res = error_errno(_("could not close '%s'"), path);
1146+
else {
1147+
strbuf_reset(buffer);
1148+
if (launch_editor(path, buffer, env) < 0)
1149+
res = error_errno(_("could not edit '%s'"), path);
1150+
unlink(path);
1151+
}
1152+
1153+
free(path2);
1154+
return res;
1155+
}

strbuf.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,17 @@ int launch_editor(const char *path, struct strbuf *buffer,
621621
int launch_sequence_editor(const char *path, struct strbuf *buffer,
622622
const char *const *env);
623623

624+
/*
625+
* In contrast to `launch_editor()`, this function writes out the contents
626+
* of the specified file first, then clears the `buffer`, then launches
627+
* the editor and reads back in the file contents into the `buffer`.
628+
* Finally, it deletes the temporary file.
629+
*
630+
* If `path` is relative, it refers to a file in the `.git` directory.
631+
*/
632+
int strbuf_edit_interactively(struct strbuf *buffer, const char *path,
633+
const char *const *env);
634+
624635
void strbuf_add_lines(struct strbuf *sb,
625636
const char *prefix,
626637
const char *buf,

0 commit comments

Comments
 (0)