aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc_src/fish_indent.txt4
-rw-r--r--src/fish_indent.cpp74
2 files changed, 60 insertions, 18 deletions
diff --git a/doc_src/fish_indent.txt b/doc_src/fish_indent.txt
index b4cf13c0..5f38449b 100644
--- a/doc_src/fish_indent.txt
+++ b/doc_src/fish_indent.txt
@@ -7,12 +7,14 @@ fish_indent [OPTIONS]
\subsection fish_indent-description Description
-`fish_indent` is used to indent a piece of fish code. `fish_indent` reads commands from standard input and outputs them to standard output.
+`fish_indent` is used to indent a piece of fish code. `fish_indent` reads commands from standard input and outputs them to standard output or a specified file.
The following options are available:
- `-d` or `--dump` dumps information about the parsed fish commands to stderr
+- `-w` or `--write` indents a specified file and immediately writes to that file
+
- `-i` or `--no-indent` do not indent commands; only reformat to one job per line
- `-v` or `--version` displays the current fish version and then exits
diff --git a/src/fish_indent.cpp b/src/fish_indent.cpp
index 7e68e310..a1479f47 100644
--- a/src/fish_indent.cpp
+++ b/src/fish_indent.cpp
@@ -18,12 +18,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "config.h" // IWYU pragma: keep
#include <assert.h>
+#include <errno.h>
#include <getopt.h>
#include <locale.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <memory>
@@ -164,10 +166,9 @@ static void prettify_node_recursive(const wcstring &source, const parse_node_tre
// Entry point for prettification.
static wcstring prettify(const wcstring &src, bool do_indent) {
parse_node_tree_t tree;
- if (!parse_tree_from_string(src,
- parse_flag_continue_after_error | parse_flag_include_comments |
- parse_flag_leave_unterminated | parse_flag_show_blank_lines,
- &tree, NULL /* errors */)) {
+ int parse_flags = (parse_flag_continue_after_error | parse_flag_include_comments |
+ parse_flag_leave_unterminated | parse_flag_show_blank_lines);
+ if (!parse_tree_from_string(src, parse_flags, &tree, NULL)) {
// We return the initial string on failure.
return src;
}
@@ -339,26 +340,27 @@ int main(int argc, char *argv[]) {
// Types of output we support.
enum {
output_type_plain_text,
+ output_type_file,
output_type_ansi,
output_type_html
} output_type = output_type_plain_text;
+ const char *output_location;
bool do_indent = true;
- const char *short_opts = "+dhvi";
- const struct option long_opts[] = {{"dump", no_argument, NULL, 'd'},
- {"no-indent", no_argument, NULL, 'i'},
- {"help", no_argument, NULL, 'h'},
- {"version", no_argument, NULL, 'v'},
- {"html", no_argument, NULL, 1},
- {"ansi", no_argument, NULL, 2},
- {NULL, 0, NULL, 0}};
+ const char *short_opts = "+dhvwi";
+ const struct option long_opts[] = {
+ {"dump", no_argument, NULL, 'd'}, {"no-indent", no_argument, NULL, 'i'},
+ {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'},
+ {"write", no_argument, NULL, 'w'}, {"html", no_argument, NULL, 1},
+ {"ansi", no_argument, NULL, 2}, {NULL, 0, NULL, 0}};
int opt;
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (opt) {
case 0: {
fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n"));
- exit_without_destructors(127);
+ exit(127);
+ break;
}
case 'd': {
dump_parse_tree = true;
@@ -366,12 +368,16 @@ int main(int argc, char *argv[]) {
}
case 'h': {
print_help("fish_indent", 1);
- exit_without_destructors(0);
+ exit(0);
+ break;
}
case 'v': {
fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
exit(0);
- assert(0 && "Unreachable code reached");
+ break;
+ }
+ case 'w': {
+ output_type = output_type_file;
break;
}
case 'i': {
@@ -388,12 +394,33 @@ int main(int argc, char *argv[]) {
}
default: {
// We assume getopt_long() has already emitted a diagnostic msg.
- exit_without_destructors(1);
+ exit(1);
+ break;
}
}
}
- const wcstring src = read_file(stdin);
+ argc -= optind;
+ argv += optind;
+
+ wcstring src;
+ if (argc == 0) {
+ src = read_file(stdin);
+ } else if (argc == 1) {
+ FILE *fh = fopen(*argv, "r");
+ if (fh) {
+ src = read_file(fh);
+ fclose(fh);
+ output_location = *argv;
+ } else {
+ fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), *argv, strerror(errno));
+ exit(1);
+ }
+ } else {
+ fwprintf(stderr, _(L"Too many arguments\n"));
+ exit(1);
+ }
+
const wcstring output_wtext = prettify(src, do_indent);
// Maybe colorize.
@@ -409,6 +436,19 @@ int main(int argc, char *argv[]) {
colored_output = no_colorize(output_wtext);
break;
}
+ case output_type_file: {
+ FILE *fh = fopen(output_location, "w");
+ if (fh) {
+ fputs(wcs2str(output_wtext), fh);
+ fclose(fh);
+ exit(0);
+ } else {
+ fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), output_location,
+ strerror(errno));
+ exit(1);
+ }
+ break;
+ }
case output_type_ansi: {
colored_output = ansi_colorize(output_wtext, colors);
break;