Coverage Report

Created: 2026-10-28 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/cmd-list-commands.c
Line
Count
Source
1
/* $OpenBSD: cmd-list-commands.c,v 1.16 2026/10/09 13:12:14 nicm Exp $ */
2
3
/*
4
 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
21
#include <stdlib.h>
22
#include <string.h>
23
24
#include "tmux.h"
25
26
/*
27
 * List all commands.
28
 */
29
30
#define LIST_COMMANDS_TEMPLATE          \
31
0
  "#{command_list_name}"          \
32
0
  "#{?command_list_alias, (#{command_list_alias}),} " \
33
0
  "#{command_list_usage}"
34
#define LIST_COMMANDS_HELP_TEMPLATE       \
35
0
  "#{p|#{command_list_name_width}:command_list_name} "  \
36
0
  "#{command_list_description}"
37
#define LIST_COMMANDS_VERBOSE_TEMPLATE        \
38
0
  LIST_COMMANDS_TEMPLATE "\n    #{command_list_description}"
39
40
static enum cmd_retval cmd_list_commands(struct cmd *, struct cmdq_item *);
41
42
const struct cmd_entry cmd_list_commands_entry = {
43
  .name = "list-commands",
44
  .description = "List commands or show command syntax.",
45
  .alias = "lscm",
46
47
  .args = { "F:h", 0, 1, NULL },
48
  .usage = "[-h] [-F format] [command]",
49
50
  .flags = CMD_STARTSERVER|CMD_AFTERHOOK,
51
  .exec = cmd_list_commands
52
};
53
54
static u_int
55
cmd_list_commands_get_width(const struct cmd_entry *only)
56
0
{
57
0
  const struct cmd_entry  **entryp;
58
0
  u_int       width, largest = 0;
59
60
0
  if (only != NULL)
61
0
    return (utf8_cstrwidth(only->name));
62
63
0
  for (entryp = cmd_table; *entryp != NULL; entryp++) {
64
0
    width = utf8_cstrwidth((*entryp)->name);
65
0
    if (width > largest)
66
0
      largest = width;
67
0
  }
68
0
  return (largest);
69
0
}
70
71
static void
72
cmd_list_single_command(const struct cmd_entry *entry, struct format_tree *ft,
73
    const char *template, struct cmdq_item *item)
74
0
{
75
0
  const char  *s;
76
0
  char    *line;
77
78
0
  format_add(ft, "command_list_name", "%s", entry->name);
79
0
  if (entry->alias != NULL)
80
0
    s = entry->alias;
81
0
  else
82
0
    s = "";
83
0
  format_add(ft, "command_list_alias", "%s", s);
84
0
  if (entry->usage != NULL)
85
0
    s = entry->usage;
86
0
  else
87
0
    s = "";
88
0
  format_add(ft, "command_list_usage", "%s", s);
89
0
  if (entry->description != NULL)
90
0
    s = entry->description;
91
0
  else
92
0
    s = "";
93
0
  format_add(ft, "command_list_description", "%s", s);
94
95
0
  line = format_expand(ft, template);
96
0
  if (*line != '\0')
97
0
    cmdq_print(item, "%s", line);
98
0
  free(line);
99
0
}
100
101
static enum cmd_retval
102
cmd_list_commands(struct cmd *self, struct cmdq_item *item)
103
0
{
104
0
  struct args    *args = cmd_get_args(self);
105
0
  const struct cmd_entry  **entryp;
106
0
  const struct cmd_entry   *entry = NULL;
107
0
  struct format_tree   *ft;
108
0
  const char     *template,  *command;
109
0
  char       *cause;
110
0
  int       help;
111
0
  u_int       width;
112
113
0
  if ((template = args_get(args, 'F')) == NULL) {
114
0
    help = args_has(args, 'h');
115
0
    if (help > 1)
116
0
      template = LIST_COMMANDS_VERBOSE_TEMPLATE;
117
0
    else if (help == 1)
118
0
      template = LIST_COMMANDS_HELP_TEMPLATE;
119
0
    else
120
0
      template = LIST_COMMANDS_TEMPLATE;
121
0
  }
122
123
0
  command = args_string(args, 0);
124
0
  if (command != NULL) {
125
0
    entry = cmd_find(command, &cause);
126
0
    if (entry == NULL) {
127
0
      cmdq_error(item, "%s", cause);
128
0
      free(cause);
129
0
      return (CMD_RETURN_ERROR);
130
0
    }
131
0
  }
132
133
0
  ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
134
0
  format_defaults(ft, NULL, NULL, NULL, NULL);
135
0
  width = cmd_list_commands_get_width(entry);
136
0
  format_add(ft, "command_list_name_width", "%u", width);
137
138
0
  if (entry == NULL) {
139
0
    for (entryp = cmd_table; *entryp != NULL; entryp++)
140
0
      cmd_list_single_command(*entryp, ft, template, item);
141
0
  } else
142
0
    cmd_list_single_command(entry, ft, template, item);
143
144
0
  format_free(ft);
145
0
  return (CMD_RETURN_NORMAL);
146
0
}