diff --git a/CHANGES b/CHANGES index 22b72791..4a002a8e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +11 January 2009 + +* save-buffer command, from Tiago Cunha. + 10 January 2009 * New option, lock-after-time. If there is no activity in the period specified @@ -855,7 +859,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.191 2009-01-11 01:01:05 nicm Exp $ +$Id: CHANGES,v 1.192 2009-01-11 23:14:57 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/GNUmakefile b/GNUmakefile index bb8144c8..93c96151 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.49 2009-01-11 00:48:42 nicm Exp $ +# $Id: GNUmakefile,v 1.50 2009-01-11 23:14:57 nicm Exp $ .PHONY: clean @@ -33,6 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \ cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \ cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \ + cmd-save-buffer.c \ window-clock.c window-scroll.c window-more.c window-copy.c \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \ tty.c tty-term.c tty-keys.c tty-write.c diff --git a/Makefile b/Makefile index ac0ae27b..87b0b02c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.86 2009-01-11 00:48:42 nicm Exp $ +# $Id: Makefile,v 1.87 2009-01-11 23:14:57 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -37,6 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \ cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \ cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \ + cmd-save-buffer.c \ window-clock.c window-scroll.c window-more.c window-copy.c \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \ tty.c tty-term.c tty-keys.c tty-write.c diff --git a/TODO b/TODO index 7e875bef..ba766d91 100644 --- a/TODO +++ b/TODO @@ -34,8 +34,7 @@ - better terminal emulation (identify, insert mode, some other bits) - when resizing, use history - audit for leftover/unused code -- commands: save-buffer -b number filename - load-buffer -b number filename +- commands: load-buffer -b number filename copy-buffer -s src-session -t dst-session -a src-index -b dst-index (copy from other session) diff --git a/cmd-generic.c b/cmd-generic.c index 50b11599..b92ee520 100644 --- a/cmd-generic.c +++ b/cmd-generic.c @@ -1,4 +1,4 @@ -/* $Id: cmd-generic.c,v 1.18 2009-01-11 23:05:36 nicm Exp $ */ +/* $Id: cmd-generic.c,v 1.19 2009-01-11 23:14:57 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -22,7 +22,7 @@ #include "tmux.h" -#define CMD_FLAGS "dgku" +#define CMD_FLAGS "adgku" int cmd_do_flags(int, int, int *); size_t cmd_print_flags(char *, size_t, size_t, int); @@ -32,6 +32,12 @@ int cmd_do_flags(int opt, int iflags, int *oflags) { switch (opt) { + case 'a': + if (iflags & CMD_AFLAG) { + (*oflags) |= CMD_AFLAG; + return (0); + } + return (-1); case 'd': if (iflags & CMD_DFLAG) { (*oflags) |= CMD_DFLAG; diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c new file mode 100644 index 00000000..0c545df6 --- /dev/null +++ b/cmd-save-buffer.c @@ -0,0 +1,90 @@ +/* $Id: cmd-save-buffer.c,v 1.1 2009-01-11 23:14:57 nicm Exp $ */ + +/* + * Copyright (c) 2009 Tiago Cunha + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "tmux.h" + +/* + * Saves a session paste buffer to a file. + */ + +void cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *); + +const struct cmd_entry cmd_save_buffer_entry = { + "save-buffer", "saveb", + "[-a] " CMD_BUFFER_SESSION_USAGE " path", + CMD_AFLAG|CMD_ONEARG, + cmd_buffer_init, + cmd_buffer_parse, + cmd_save_buffer_exec, + cmd_buffer_send, + cmd_buffer_recv, + cmd_buffer_free, + cmd_buffer_print +}; + +void +cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) +{ + struct cmd_buffer_data *data = self->data; + struct session *s; + struct paste_buffer *pb; + mode_t mask; + FILE *f; + + if ((s = cmd_find_session(ctx, data->target)) == NULL) + return; + + if (data->buffer == -1) { + if ((pb = paste_get_top(&s->buffers)) == NULL) + ctx->error(ctx, "no buffers"); + } else { + if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) + ctx->error(ctx, "no buffer %d", data->buffer); + } + + if (pb == NULL) + return; + + mask = umask(S_IRWXG | S_IRWXO); + if (data->flags & CMD_AFLAG) + f = fopen(data->arg, "a"); + else + f = fopen(data->arg, "w"); + if (f == NULL) { + ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); + return; + } + + if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) { + ctx->error(ctx, "%s: fwrite error", data->arg); + fclose(f); + return; + } + + fclose(f); + umask(mask); + + if (ctx->cmdclient != NULL) + server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); +} diff --git a/cmd.c b/cmd.c index 7fc213f7..5b1ce895 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.72 2009-01-11 00:48:42 nicm Exp $ */ +/* $Id: cmd.c,v 1.73 2009-01-11 23:14:57 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -56,6 +56,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_rename_session_entry, &cmd_rename_window_entry, &cmd_respawn_window_entry, + &cmd_save_buffer_entry, &cmd_scroll_mode_entry, &cmd_select_prompt_entry, &cmd_select_window_entry, diff --git a/tmux.1 b/tmux.1 index 7df71f09..3ce1b18f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.56 2009-01-10 01:51:22 nicm Exp $ +.\" $Id: tmux.1,v 1.57 2009-01-11 23:14:57 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -576,6 +576,18 @@ is not given, the command used when the window was created is executed. The window must be already inactive, unless .Fl k is given, in which case any existing command is killed. +.It Xo Ic save-buffer +.Op Fl a +.Op Fl b Ar buffer-index +.Op Fl t Ar target-session +.Ar path +.Xc +.D1 (alias: Ic saveb ) +Save the contents of the specified paste buffer to +.Ar path . +The +.Fl a +option appends to rather than overwriting the file. .It Xo Ic scroll-mode .Op Fl t Ar target-window .Xc diff --git a/tmux.h b/tmux.h index c280845b..6725ddab 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.221 2009-01-11 00:48:42 nicm Exp $ */ +/* $Id: tmux.h,v 1.222 2009-01-11 23:14:57 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -807,6 +807,7 @@ struct cmd_entry { #define CMD_ZEROONEARG 0x20 #define CMD_GFLAG 0x40 #define CMD_UFLAG 0x80 +#define CMD_AFLAG 0x100 int flags; void (*init)(struct cmd *, int); @@ -1086,6 +1087,7 @@ extern const struct cmd_entry cmd_refresh_client_entry; extern const struct cmd_entry cmd_rename_session_entry; extern const struct cmd_entry cmd_rename_window_entry; extern const struct cmd_entry cmd_respawn_window_entry; +extern const struct cmd_entry cmd_save_buffer_entry; extern const struct cmd_entry cmd_scroll_mode_entry; extern const struct cmd_entry cmd_select_prompt_entry; extern const struct cmd_entry cmd_select_window_entry;