NeoMutt  2021-02-05-329-g9e03b7
Teaching an old dog new tricks
DOXYGEN
status.c File Reference

GUI display a user-configurable status line. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "status.h"
#include "index/lib.h"
#include "menu/lib.h"
#include "context.h"
#include "format_flags.h"
#include "mutt_globals.h"
#include "mutt_mailbox.h"
#include "muttlib.h"
#include "options.h"
#include "protos.h"
+ Include dependency graph for status.c:

Go to the source code of this file.

Data Structures

struct  MenuStatusLineData
 Data for creating a Menu line. More...
 

Functions

static char * get_sort_str (char *buf, size_t buflen, enum SortType method)
 Get the sort method as a string. More...
 
static const char * status_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Create the status bar string - Implements format_t. More...
 
void menu_status_line (char *buf, size_t buflen, struct IndexSharedData *shared, struct Menu *menu, int cols, const char *fmt)
 Create the status line. More...
 

Detailed Description

GUI display a user-configurable status line.

Authors
  • Michael R. Elkins

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file status.c.

Function Documentation

◆ get_sort_str()

static char* get_sort_str ( char *  buf,
size_t  buflen,
enum SortType  method 
)
static

Get the sort method as a string.

Parameters
bufBuffer for the sort string
buflenLength of the buffer
methodSort method, see SortType
Return values
ptrBuffer pointer

Definition at line 55 of file status.c.

56 {
57  snprintf(buf, buflen, "%s%s%s", (method & SORT_REVERSE) ? "reverse-" : "",
58  (method & SORT_LAST) ? "last-" : "",
60  return buf;
61 }
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
const struct Mapping SortMethods[]
Sort methods for &#39;$sort&#39; for the index.
Definition: mutt_config.c:77
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
#define SORT_LAST
Sort thread by last-X, e.g. received date.
Definition: sort2.h:80
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ status_format_str()

static const char* status_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Create the status bar string - Implements format_t.

Expando Description
%b Number of incoming folders with unread messages
%D Description of the mailbox
%d Number of deleted messages
%f Full mailbox path
%F Number of flagged messages
%h Hostname
%l Length of mailbox (in bytes)
%L Size (in bytes) of the messages shown (or limited)
%M Number of messages shown (virtual message count when limiting)
%m Total number of messages
%n Number of new messages
%o Number of old unread messages
%p Number of postponed messages
%P Percent of way through index
%R Number of read messages
%r Readonly/wontwrite/changed flag
%S Current aux sorting method ($sort_aux)
%s Current sorting method ($sort)
%t Number of tagged messages
%u Number of unread messages
%V Currently active limit pattern
%v NeoMutt version

Definition at line 100 of file status.c.

104 {
105  char fmt[128], tmp[128];
106  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
107  struct MenuStatusLineData *msld = (struct MenuStatusLineData *) data;
108  struct IndexSharedData *shared = msld->shared;
109  struct Context *ctx = shared->ctx;
110  struct Mailbox *m = shared->mailbox;
111  struct Menu *menu = msld->menu;
112 
113  *buf = '\0';
114  switch (op)
115  {
116  case 'b':
117  {
118  const int num = mutt_mailbox_check(m, 0);
119  if (!optional)
120  {
121  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
122  snprintf(buf, buflen, fmt, num);
123  }
124  else if (num == 0)
125  optional = false;
126  break;
127  }
128 
129  case 'd':
130  {
131  const int num = m ? m->msg_deleted : 0;
132  if (!optional)
133  {
134  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
135  snprintf(buf, buflen, fmt, num);
136  }
137  else if (num == 0)
138  optional = false;
139  break;
140  }
141 
142  case 'D':
143  // If there's a descriptive name, use it. Otherwise, fall-through
144  if (m && m->name)
145  {
146  mutt_str_copy(tmp, m->name, sizeof(tmp));
147  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
148  snprintf(buf, buflen, fmt, tmp);
149  break;
150  }
151  /* fallthrough */
152  case 'f':
153 #ifdef USE_COMP_MBOX
154  if (m && m->compress_info && (m->realpath[0] != '\0'))
155  {
156  mutt_str_copy(tmp, m->realpath, sizeof(tmp));
157  mutt_pretty_mailbox(tmp, sizeof(tmp));
158  }
159  else
160 #endif
161  if (m && (m->type == MUTT_NOTMUCH) && m->name)
162  {
163  mutt_str_copy(tmp, m->name, sizeof(tmp));
164  }
165  else if (m && !mutt_buffer_is_empty(&m->pathbuf))
166  {
167  mutt_str_copy(tmp, mailbox_path(m), sizeof(tmp));
168  mutt_pretty_mailbox(tmp, sizeof(tmp));
169  }
170  else
171  mutt_str_copy(tmp, _("(no mailbox)"), sizeof(tmp));
172 
173  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
174  snprintf(buf, buflen, fmt, tmp);
175  break;
176  case 'F':
177  {
178  const int num = m ? m->msg_flagged : 0;
179  if (!optional)
180  {
181  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
182  snprintf(buf, buflen, fmt, num);
183  }
184  else if (num == 0)
185  optional = false;
186  break;
187  }
188 
189  case 'h':
190  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
191  snprintf(buf, buflen, fmt, NONULL(ShortHostname));
192  break;
193 
194  case 'l':
195  {
196  const off_t num = m ? m->size : 0;
197  if (!optional)
198  {
199  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
200  mutt_str_pretty_size(tmp, sizeof(tmp), num);
201  snprintf(buf, buflen, fmt, tmp);
202  }
203  else if (num == 0)
204  optional = false;
205  break;
206  }
207 
208  case 'L':
209  if (!optional)
210  {
211  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
212  mutt_str_pretty_size(tmp, sizeof(tmp), ctx ? ctx->vsize : 0);
213  snprintf(buf, buflen, fmt, tmp);
214  }
215  else if (!ctx_has_limit(ctx))
216  optional = false;
217  break;
218 
219  case 'm':
220  {
221  const int num = m ? m->msg_count : 0;
222  if (!optional)
223  {
224  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
225  snprintf(buf, buflen, fmt, num);
226  }
227  else if (num == 0)
228  optional = false;
229  break;
230  }
231 
232  case 'M':
233  if (!optional)
234  {
235  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
236  snprintf(buf, buflen, fmt, m ? m->vcount : 0);
237  }
238  else if (!ctx_has_limit(ctx))
239  optional = false;
240  break;
241 
242  case 'n':
243  {
244  const int num = m ? m->msg_new : 0;
245  if (!optional)
246  {
247  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
248  snprintf(buf, buflen, fmt, num);
249  }
250  else if (num == 0)
251  optional = false;
252  break;
253  }
254 
255  case 'o':
256  {
257  const int num = m ? (m->msg_unread - m->msg_new) : 0;
258  if (!optional)
259  {
260  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
261  snprintf(buf, buflen, fmt, num);
262  }
263  else if (num == 0)
264  optional = false;
265  break;
266  }
267 
268  case 'p':
269  {
270  const int count = mutt_num_postponed(m, false);
271  if (!optional)
272  {
273  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
274  snprintf(buf, buflen, fmt, count);
275  }
276  else if (count == 0)
277  optional = false;
278  break;
279  }
280 
281  case 'P':
282  {
283  if (!menu)
284  break;
285  char *cp = NULL;
286  if (menu->top + menu->pagelen >= menu->max)
287  {
288  cp = menu->top ?
289  /* L10N: Status bar message: the end of the list emails is visible in the index */
290  _("end") :
291  /* L10N: Status bar message: all the emails are visible in the index */
292  _("all");
293  }
294  else
295  {
296  int count = (100 * (menu->top + menu->pagelen)) / menu->max;
297  snprintf(tmp, sizeof(tmp), "%d%%", count);
298  cp = tmp;
299  }
300  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
301  snprintf(buf, buflen, fmt, cp);
302  break;
303  }
304 
305  case 'r':
306  {
307  size_t i = 0;
308 
309  if (m)
310  {
311  i = OptAttachMsg ? 3 :
312  ((m->readonly || m->dontwrite) ? 2 :
313  (m->changed ||
314  /* deleted doesn't necessarily mean changed in IMAP */
315  (m->type != MUTT_IMAP && m->msg_deleted)) ?
316  1 :
317  0);
318  }
319 
320  const struct MbTable *c_status_chars =
321  cs_subset_mbtable(NeoMutt->sub, "status_chars");
322  if (!c_status_chars || !c_status_chars->len)
323  buf[0] = '\0';
324  else if (i >= c_status_chars->len)
325  snprintf(buf, buflen, "%s", c_status_chars->chars[0]);
326  else
327  snprintf(buf, buflen, "%s", c_status_chars->chars[i]);
328  break;
329  }
330 
331  case 'R':
332  {
333  const int read = m ? (m->msg_count - m->msg_unread) : 0;
334  if (!optional)
335  {
336  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
337  snprintf(buf, buflen, fmt, read);
338  }
339  else if (read == 0)
340  optional = false;
341  break;
342  }
343 
344  case 's':
345  {
346  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
347  const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
348  snprintf(buf, buflen, fmt, get_sort_str(tmp, sizeof(tmp), c_sort));
349  break;
350  }
351 
352  case 'S':
353  {
354  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
355  const short c_sort_aux = cs_subset_sort(NeoMutt->sub, "sort_aux");
356  snprintf(buf, buflen, fmt, get_sort_str(tmp, sizeof(tmp), c_sort_aux));
357  break;
358  }
359 
360  case 't':
361  {
362  const int num = m ? m->msg_tagged : 0;
363  if (!optional)
364  {
365  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
366  snprintf(buf, buflen, fmt, num);
367  }
368  else if (num == 0)
369  optional = false;
370  break;
371  }
372 
373  case 'u':
374  if (!optional)
375  {
376  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
377  snprintf(buf, buflen, fmt, m ? m->msg_unread : 0);
378  }
379  else if (!m || (m->msg_unread == 0))
380  optional = false;
381  break;
382 
383  case 'v':
384  snprintf(buf, buflen, "%s", mutt_make_version());
385  break;
386 
387  case 'V':
388  if (!optional)
389  {
390  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
391  snprintf(buf, buflen, fmt, ctx_has_limit(ctx) ? ctx->pattern : "");
392  }
393  else if (!ctx_has_limit(ctx))
394  optional = false;
395  break;
396 
397  case 0:
398  *buf = '\0';
399  return src;
400 
401  default:
402  snprintf(buf, buflen, "%%%s%c", prec, op);
403  break;
404  }
405 
406  if (optional)
407  {
408  mutt_expando_format(buf, buflen, col, cols, if_str, status_format_str, data,
410  }
411  else if (flags & MUTT_FORMAT_OPTIONAL)
412  {
413  mutt_expando_format(buf, buflen, col, cols, else_str, status_format_str,
414  data, MUTT_FORMAT_NO_FLAGS);
415  }
416 
417  /* We return the format string, unchanged */
418  return src;
419 }
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:206
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:525
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:91
off_t size
Size of the Mailbox.
Definition: mailbox.h:87
char ** chars
The array of multibyte character strings.
Definition: mbtable.h:37
GUI selectable list of items.
Definition: lib.h:56
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
bool ctx_has_limit(const struct Context *ctx)
Is a limit active?
Definition: context.c:429
#define _(a)
Definition: message.h:28
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:36
multibyte character table
Definition: mbtable.h:33
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
int vcount
The number of virtual messages.
Definition: mailbox.h:102
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
static char * get_sort_str(char *buf, size_t buflen, enum SortType method)
Get the sort method as a string.
Definition: status.c:55
struct Context * ctx
Current Mailbox view.
Definition: shared_data.h:39
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:272
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:39
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
A mailbox.
Definition: mailbox.h:81
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:137
int top
Entry that is the top of the current page.
Definition: lib.h:78
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:46
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1679
bool dontwrite
Don&#39;t write the mailbox on close.
Definition: mailbox.h:115
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
int pagelen
Number of entries per screen.
Definition: lib.h:63
Data for creating a Menu line.
Definition: status.c:66
struct MbTable * cs_subset_mbtable(const struct ConfigSubset *sub, const char *name)
Get a Multibyte table config item by name.
Definition: helpers.c:137
int max
Number of entries in the menu.
Definition: lib.h:60
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
int mutt_num_postponed(struct Mailbox *m, bool force)
Return the number of postponed messages.
Definition: postpone.c:85
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
struct IndexSharedData * shared
Data shared between Index, Pager and Sidebar.
Definition: status.c:68
int msg_new
Number of new messages.
Definition: mailbox.h:95
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:779
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:124
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
struct Buffer pathbuf
Definition: mailbox.h:83
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
char * pattern
Limit pattern string.
Definition: context.h:40
struct Menu * menu
Current Menu.
Definition: status.c:69
int len
Number of characters.
Definition: mbtable.h:36
const char * mutt_make_version(void)
Generate the NeoMutt version string.
Definition: muttlib.c:1476
static const char * status_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Create the status bar string - Implements format_t.
Definition: status.c:100
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ menu_status_line()

void menu_status_line ( char *  buf,
size_t  buflen,
struct IndexSharedData shared,
struct Menu menu,
int  cols,
const char *  fmt 
)

Create the status line.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]sharedShared Index data
[in]menuCurrent menu
[in]colsMaximum number of columns to use
[in]fmtFormat string

Definition at line 430 of file status.c.

432 {
433  struct MenuStatusLineData data = { shared, menu };
434 
435  mutt_expando_format(buf, buflen, 0, cols, fmt, status_format_str,
436  (intptr_t) &data, MUTT_FORMAT_NO_FLAGS);
437 }
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
Data for creating a Menu line.
Definition: status.c:66
struct IndexSharedData * shared
Data shared between Index, Pager and Sidebar.
Definition: status.c:68
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:779
static const char * status_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Create the status bar string - Implements format_t.
Definition: status.c:100
+ Here is the call graph for this function:
+ Here is the caller graph for this function: