mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Merge pull request #1485 from StefanKropp/feature/editor-command
Add basic functionality to launch external editor Regards https://github.com/profanity-im/profanity/issues/1521
This commit is contained in:
commit
2f4289bb3e
@ -2586,6 +2586,20 @@ static struct cmd_t command_defs[] = {
|
|||||||
CMD_NOEXAMPLES
|
CMD_NOEXAMPLES
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "/editor",
|
||||||
|
parse_args, 0, 0, NULL,
|
||||||
|
CMD_NOSUBFUNCS
|
||||||
|
CMD_MAINFUNC(cmd_editor)
|
||||||
|
CMD_TAGS(
|
||||||
|
CMD_TAG_CHAT)
|
||||||
|
CMD_SYN(
|
||||||
|
"/editor")
|
||||||
|
CMD_DESC(
|
||||||
|
"Call editor")
|
||||||
|
CMD_NOARGS
|
||||||
|
CMD_NOEXAMPLES
|
||||||
|
},
|
||||||
|
|
||||||
// NEXT-COMMAND (search helper)
|
// NEXT-COMMAND (search helper)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,6 +52,12 @@
|
|||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// fork / execl
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <readline/readline.h>
|
||||||
|
|
||||||
#include "profanity.h"
|
#include "profanity.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -9304,3 +9310,84 @@ cmd_change_password(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cmd_editor(ProfWin* window, const char* const command, gchar** args)
|
||||||
|
{
|
||||||
|
xmpp_ctx_t* const ctx = connection_get_ctx();
|
||||||
|
if (!ctx) {
|
||||||
|
log_debug("Editor: no connection");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build temp file name. Example: /tmp/profanity-f2f271dd-98c8-4118-8d47-3bd49c8e2e63.txt
|
||||||
|
char* uuid = xmpp_uuid_gen(ctx);
|
||||||
|
char* filename = g_strdup_printf("%s%s%s.txt", g_get_tmp_dir(), "/profanity-", uuid);
|
||||||
|
if (uuid) {
|
||||||
|
xmpp_free(ctx, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file exists and create file
|
||||||
|
if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
|
||||||
|
cons_show("Editor: temp file exists already");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GError* creation_error = NULL;
|
||||||
|
GFile* file = g_file_new_for_path(filename);
|
||||||
|
GFileOutputStream* fos = g_file_create(file,
|
||||||
|
G_FILE_CREATE_PRIVATE, NULL,
|
||||||
|
&creation_error);
|
||||||
|
if (creation_error) {
|
||||||
|
cons_show_error("Editor: could not create temp file");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
g_object_unref(fos);
|
||||||
|
|
||||||
|
char* editor = prefs_get_string(PREF_COMPOSE_EDITOR);
|
||||||
|
if (!g_file_test(editor, G_FILE_TEST_EXISTS)) {
|
||||||
|
cons_show_error("Editor: binary %s not exist", editor);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fork / exec
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
int x = execl(editor, editor, g_file_get_path(file), (char*)NULL);
|
||||||
|
if (x == -1) {
|
||||||
|
cons_show_error("Editor:Failed to exec %s", editor);
|
||||||
|
}
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
if (pid == -1) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
int status = 0;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
int fd_input_file = open(g_file_get_path(file), O_RDONLY);
|
||||||
|
const size_t COUNT = 8192;
|
||||||
|
char buf[COUNT];
|
||||||
|
ssize_t size_read = read(fd_input_file, buf, COUNT);
|
||||||
|
if (size_read > 0 && size_read <= COUNT) {
|
||||||
|
buf[size_read - 1] = '\0';
|
||||||
|
GString* text = g_string_new(buf);
|
||||||
|
ProfWin* win = wins_get_current();
|
||||||
|
win_println(win, THEME_DEFAULT, "!", "EDITOR PREVIEW: %s", text->str);
|
||||||
|
rl_insert_text(text->str);
|
||||||
|
g_string_free(text, TRUE);
|
||||||
|
}
|
||||||
|
close(fd_input_file);
|
||||||
|
|
||||||
|
GError* deletion_error = NULL;
|
||||||
|
g_file_delete(file, NULL, &deletion_error);
|
||||||
|
if (deletion_error) {
|
||||||
|
cons_show("Editor: error during file deletion");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
g_object_unref(file);
|
||||||
|
ui_resize();
|
||||||
|
rl_point = rl_end;
|
||||||
|
rl_forced_update_display();
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@ -242,5 +242,6 @@ gboolean cmd_executable_avatar(ProfWin* window, const char* const command, gchar
|
|||||||
gboolean cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args);
|
gboolean cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args);
|
||||||
gboolean cmd_executable_urlsave(ProfWin* window, const char* const command, gchar** args);
|
gboolean cmd_executable_urlsave(ProfWin* window, const char* const command, gchar** args);
|
||||||
gboolean cmd_mam(ProfWin* window, const char* const command, gchar** args);
|
gboolean cmd_mam(ProfWin* window, const char* const command, gchar** args);
|
||||||
|
gboolean cmd_editor(ProfWin* window, const char* const command, gchar** args);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1868,6 +1868,7 @@ _get_group(preference_t pref)
|
|||||||
case PREF_TITLEBAR_MUC_TITLE_JID:
|
case PREF_TITLEBAR_MUC_TITLE_JID:
|
||||||
case PREF_TITLEBAR_MUC_TITLE_NAME:
|
case PREF_TITLEBAR_MUC_TITLE_NAME:
|
||||||
case PREF_SLASH_GUARD:
|
case PREF_SLASH_GUARD:
|
||||||
|
case PREF_COMPOSE_EDITOR:
|
||||||
return PREF_GROUP_UI;
|
return PREF_GROUP_UI;
|
||||||
case PREF_STATES:
|
case PREF_STATES:
|
||||||
case PREF_OUTTYPE:
|
case PREF_OUTTYPE:
|
||||||
@ -2189,6 +2190,8 @@ _get_key(preference_t pref)
|
|||||||
return "url.open.cmd";
|
return "url.open.cmd";
|
||||||
case PREF_URL_SAVE_CMD:
|
case PREF_URL_SAVE_CMD:
|
||||||
return "url.save.cmd";
|
return "url.save.cmd";
|
||||||
|
case PREF_COMPOSE_EDITOR:
|
||||||
|
return "compose.editor";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2326,6 +2329,8 @@ _get_default_string(preference_t pref)
|
|||||||
return "xdg-open";
|
return "xdg-open";
|
||||||
case PREF_URL_OPEN_CMD:
|
case PREF_URL_OPEN_CMD:
|
||||||
return "xdg-open %u";
|
return "xdg-open %u";
|
||||||
|
case PREF_COMPOSE_EDITOR:
|
||||||
|
return "/usr/bin/vim";
|
||||||
case PREF_URL_SAVE_CMD:
|
case PREF_URL_SAVE_CMD:
|
||||||
return NULL; // Default to built-in method.
|
return NULL; // Default to built-in method.
|
||||||
default:
|
default:
|
||||||
|
@ -173,6 +173,7 @@ typedef enum {
|
|||||||
PREF_MAM,
|
PREF_MAM,
|
||||||
PREF_URL_OPEN_CMD,
|
PREF_URL_OPEN_CMD,
|
||||||
PREF_URL_SAVE_CMD,
|
PREF_URL_SAVE_CMD,
|
||||||
|
PREF_COMPOSE_EDITOR,
|
||||||
} preference_t;
|
} preference_t;
|
||||||
|
|
||||||
typedef struct prof_alias_t
|
typedef struct prof_alias_t
|
||||||
|
Loading…
Reference in New Issue
Block a user