]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
interactive: Introduce i9e_print_status_bar().
authorAndre Noll <maan@systemlinux.org>
Thu, 12 Apr 2012 04:20:42 +0000 (06:20 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 18 Nov 2012 19:28:28 +0000 (20:28 +0100)
When operating in single key mode, the users of the i9e API
may write a single line, called status bar, to stderr.

This patch adds a new public function to the i9e subsystem for
this purpose. It honors the width of the terminal and shortens
the given status bar string to fit in one line if necessary.

interactive.c
interactive.h

index a18d82b717846d1deeec01c3dcaf88587837bc43..44db6c58fda6b4080c0874725c7a9bd4b9f6fbe4 100644 (file)
@@ -31,6 +31,7 @@ struct i9e_private {
        char empty_line[1000];
        struct task task;
        struct btr_node *stdout_btrn;
        char empty_line[1000];
        struct task task;
        struct btr_node *stdout_btrn;
+       bool last_write_was_status;
        bool line_handler_running;
        bool input_eof;
        bool caught_sigint;
        bool line_handler_running;
        bool input_eof;
        bool caught_sigint;
@@ -311,7 +312,7 @@ static void i9e_post_select(__a_unused struct sched *s, struct task *t)
        int ret;
        struct i9e_client_info *ici = i9ep->ici;
        char *buf;
        int ret;
        struct i9e_client_info *ici = i9ep->ici;
        char *buf;
-       size_t sz;
+       size_t sz, consumed = 0;
 
        ret = -E_I9E_EOF;
        if (i9ep->input_eof)
 
        ret = -E_I9E_EOF;
        if (i9ep->input_eof)
@@ -333,16 +334,24 @@ static void i9e_post_select(__a_unused struct sched *s, struct task *t)
        }
        if (ret == 0)
                goto out;
        }
        if (ret == 0)
                goto out;
+again:
        sz = btr_next_buffer(i9ep->stdout_btrn, &buf);
        if (sz == 0)
                goto out;
        sz = btr_next_buffer(i9ep->stdout_btrn, &buf);
        if (sz == 0)
                goto out;
+       if (i9ep->last_write_was_status)
+               fprintf(i9ep->stderr_stream, "\n");
+       i9ep->last_write_was_status = false;
        ret = xwrite(ici->fds[1], buf, sz);
        if (ret < 0)
                goto rm_btrn;
        btr_consume(i9ep->stdout_btrn, ret);
        ret = xwrite(ici->fds[1], buf, sz);
        if (ret < 0)
                goto rm_btrn;
        btr_consume(i9ep->stdout_btrn, ret);
+       consumed += ret;
+       if (ret == sz && consumed < 10000)
+               goto again;
        goto out;
 rm_btrn:
        if (i9ep->stdout_btrn) {
        goto out;
 rm_btrn:
        if (i9ep->stdout_btrn) {
+               wipe_bottom_line();
                btr_remove_node(&i9ep->stdout_btrn);
                rl_set_keymap(i9ep->standard_km);
                rl_set_prompt(i9ep->ici->prompt);
                btr_remove_node(&i9ep->stdout_btrn);
                rl_set_keymap(i9ep->standard_km);
                rl_set_prompt(i9ep->ici->prompt);
@@ -503,6 +512,41 @@ __printf_2_3 void i9e_log(int ll, const char* fmt,...)
        vfprintf(i9ep->stderr_stream, fmt, argp);
        va_end(argp);
        reset_line_state();
        vfprintf(i9ep->stderr_stream, fmt, argp);
        va_end(argp);
        reset_line_state();
+       i9ep->last_write_was_status = false;
+}
+
+/**
+ * Print the current status to stderr.
+ *
+ * \param buf The text to print.
+ * \param len The number of bytes in \a buf.
+ *
+ * This clears the bottom line, moves to the beginning of the line and prints
+ * the given text. If the length of this text exceeds the width of the
+ * terminal, the text is shortened by leaving out a part in the middle.
+ */
+void ie9_print_status_bar(char *buf, unsigned len)
+{
+       size_t x = i9ep->num_columns, y = (x - 4) / 2;
+
+       assert(x >= 6);
+       if (len > x) {
+               buf[y] = '\0';
+               fprintf(i9ep->stderr_stream, "\r%s", buf);
+               fprintf(i9ep->stderr_stream, " .. ");
+               fprintf(i9ep->stderr_stream, "%s", buf + len - y);
+       } else {
+               char scratch[1000];
+
+               y = x - len;
+               scratch[0] = '\r';
+               strcpy(scratch + 1, buf);
+               memset(scratch + 1 + len, ' ', y);
+               scratch[1 + len + y] = '\r';
+               scratch[2 + len + y] = '\0';
+               fprintf(i9ep->stderr_stream, "\r%s", scratch);
+       }
+       i9ep->last_write_was_status = true;
 }
 
 /**
 }
 
 /**
index fb39860541fef3c09c74b3bff9031c48e7b7a625..8e436755bef81d726a1ed1a71dcd2f4a0fea8231 100644 (file)
@@ -84,6 +84,7 @@ struct i9e_client_info {
 
 int i9e_open(struct i9e_client_info *ici, struct sched *s);
 void i9e_attach_to_stdout(struct btr_node *producer);
 
 int i9e_open(struct i9e_client_info *ici, struct sched *s);
 void i9e_attach_to_stdout(struct btr_node *producer);
+void ie9_print_status_bar(char *buf, unsigned len);
 void i9e_close(void);
 void i9e_signal_dispatch(int sig_num);
 __printf_2_3 void i9e_log(int ll, const char* fmt,...);
 void i9e_close(void);
 void i9e_signal_dispatch(int sig_num);
 __printf_2_3 void i9e_log(int ll, const char* fmt,...);