diff --git a/Makefile.in b/Makefile.in
index d25f4ce3e..5f5a6d4bc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -64,6 +64,7 @@ CFLAGS = @CFLAGS@ $(MACROS)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LIBS@ @LDFLAGS@
LDFLAGS_FISH = ${LDFLAGS} @LIBS_FISH@ @LDFLAGS_FISH@
+LDFLAGS_FISH_INDENT = ${LDFLAGS} @LIBS_FISH_INDENT@
LDFLAGS_FISH_PAGER = ${LDFLAGS} @LIBS_FISH_PAGER@
LDFLAGS_FISHD = ${LDFLAGS} @LIBS_FISHD@
LDFLAGS_MIMEDB = ${LDFLAGS} @LIBS_MIMEDB@
@@ -95,6 +96,8 @@ FISH_OBJS := function.o builtin.o complete.o env.o exec.o expand.o \
signal.o io.o parse_util.o common.o screen.o path.o \
parser_keywords.o
+FISH_INDENT_OBJS := fish_indent.o print_help.o common.o \
+parser_keywords.o wutil.o tokenizer.o
#
# Additional files used by builtin.o
@@ -190,7 +193,7 @@ MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help.in \
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
fish.spec.in INSTALL README user_doc.head.html xsel-0.9.6.tar \
ChangeLog config.sub config.guess fish_tests.c main.c fish_pager.c \
- fishd.c seq.in make_vcs_completions.fish
+ fishd.c seq.in make_vcs_completions.fish $(FISH_INDENT_OBJS:.o=.c)
#
# The sorting is not meaningful in itself, but it has the side effect
@@ -241,7 +244,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
# Programs to install
#
-SIMPLE_PROGRAMS := fish set_color mimedb count fish_pager fishd
+SIMPLE_PROGRAMS := fish set_color mimedb count fish_pager fishd fish_indent
PROGRAMS := $(SIMPLE_PROGRAMS) @XSEL@ @SEQ_FALLBACK@
@@ -745,6 +748,14 @@ tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
$(CC) $(CFLAGS) tokenizer.c wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -o $@
+#
+# Build the fish_indent program.
+#
+
+fish_indent: $(FISH_INDENT_OBJS)
+ $(CC) $(FISH_INDENT_OBJS) $(LDFLAGS_FISH_INDENT) -o $@
+
+
#
# Neat little program to show output from terminal
#
@@ -869,8 +880,7 @@ distclean: clean
clean:
rm -f *.o doc.h doc.tmp doc_src/*.doxygen doc_src/*.c doc_src/*.o doc_src/commands.hdr
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
- rm -f tokenizer_test fish key_reader set_color mimedb
- rm -f fishd fish_pager count fish_tests
+ rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
rm -f fish-@PACKAGE_VERSION@.tar
rm -f fish-@PACKAGE_VERSION@.tar.gz
rm -f fish-@PACKAGE_VERSION@.tar.bz2
diff --git a/configure.ac b/configure.ac
index 0d044bc15..d410f2d5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ AC_SUBST( docdir )
AC_SUBST( HAVE_GETTEXT )
AC_SUBST( LDFLAGS_FISH )
AC_SUBST( LIBS_FISH )
+AC_SUBST( LIBS_FISH_INDENT )
AC_SUBST( LIBS_FISH_PAGER )
AC_SUBST( LIBS_FISHD )
AC_SUBST( LIBS_MIMEDB )
@@ -481,6 +482,31 @@ AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv impl
LIBS_FISH=$LIBS
LIBS=$LIBS_COMMON
+#
+# Check for libraries needed by fish_indent.
+#
+
+LIBS_COMMON=$LIBS
+LIBS=""
+if test x$local_gettext != xno; then
+ AC_SEARCH_LIBS( gettext, intl,,)
+fi
+LIBS_FISH_INDENT=$LIBS
+LIBS=$LIBS_COMMON
+
+#
+# Check for libraries needed by fish_pager.
+#
+
+LIBS_COMMON=$LIBS
+LIBS=""
+if test x$local_gettext != xno; then
+ AC_SEARCH_LIBS( gettext, intl,,)
+fi
+AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
+AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
+LIBS_FISH_PAGER=$LIBS
+LIBS=$LIBS_COMMON
#
# Check for libraries needed by fishd.
@@ -495,7 +521,6 @@ AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library
LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
-
#
# Check for libraries needed by mimedb.
#
@@ -509,21 +534,6 @@ LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
-#
-# Check for libraries needed by fish_pager.
-#
-
-LIBS_COMMON=$LIBS
-LIBS=""
-if test x$local_gettext != xno; then
- AC_SEARCH_LIBS( gettext, intl,,)
-fi
-AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
-AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
-LIBS_FISH_PAGER=$LIBS
-LIBS=$LIBS_COMMON
-
-
#
# Check for libraries needed by set_color
#
diff --git a/doc_src/fish_indent.txt b/doc_src/fish_indent.txt
new file mode 100644
index 000000000..b05a40daf
--- /dev/null
+++ b/doc_src/fish_indent.txt
@@ -0,0 +1,17 @@
+\section fish_indent fish_indent - indenter and prettyfier
+
+\subsection fish_indent-synopsis Synopsis
+ fish_indent [options]
+
+\subsection fish_indent-description Description
+
+\c fish_indent is used to indent or otherwise prettyfy a piece of fish
+code. \c fish_indent reads commands from standard input and outputs
+them to standard output.
+
+\c fish_indent underatands the following options:
+
+- -h or --help displays this help message and then exits
+- -i or --no-indent do not indent commands
+- -v or --version displays the current fish version and then exits
+
diff --git a/fish.spec.in b/fish.spec.in
index 31be307dc..ee47dfcd8 100644
--- a/fish.spec.in
+++ b/fish.spec.in
@@ -115,22 +115,24 @@ fi
%doc %_datadir/doc/%{name}-%{version}
# man files
+%_mandir/man1/count.1*
%_mandir/man1/fish.1*
-%_mandir/man1/xsel.1x*
+%_mandir/man1/fish_pager.1*
+%_mandir/man1/fish_indent.1*
+%_mandir/man1/fishd.1*
%_mandir/man1/mimedb.1*
%_mandir/man1/set_color.1*
-%_mandir/man1/count.1*
-%_mandir/man1/fishd.1*
-%_mandir/man1/fish_pager.1*
+%_mandir/man1/xsel.1x*
# The program binaries
-%attr(0755,root,root) %_bindir/fish
-%attr(0755,root,root) %_bindir/fishd
-%attr(0755,root,root) %_bindir/fish_pager
-%attr(0755,root,root) %_bindir/xsel
-%attr(0755,root,root) %_bindir/set_color
-%attr(0755,root,root) %_bindir/mimedb
%attr(0755,root,root) %_bindir/count
+%attr(0755,root,root) %_bindir/fish
+%attr(0755,root,root) %_bindir/fish_indent
+%attr(0755,root,root) %_bindir/fish_pager
+%attr(0755,root,root) %_bindir/fishd
+%attr(0755,root,root) %_bindir/mimedb
+%attr(0755,root,root) %_bindir/set_color
+%attr(0755,root,root) %_bindir/xsel
# Configuration files
%config %_sysconfdir/fish/config.fish
@@ -156,9 +158,10 @@ fi
-
-
%changelog
+* Sat Apr 21 2007 Axel Liljencrantz 1.23.0-0
+- Add fish_indent command
+
* Thu Feb 8 2007 Axel Liljencrantz 1.22.3-0
- Tell rpm about the help pages in %_datadir/fish/man/
diff --git a/fish_indent.c b/fish_indent.c
new file mode 100644
index 000000000..edf8cd423
--- /dev/null
+++ b/fish_indent.c
@@ -0,0 +1,328 @@
+/*
+Copyright (C) 2005-2006 Axel Liljencrantz
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+/** \file main.c
+ The main loop of fish.
+*/
+
+#include "config.h"
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_GETOPT_H
+#include
+#endif
+
+#include
+#include
+
+#include "fallback.h"
+#include "util.h"
+
+#include "common.h"
+#include "wutil.h"
+#include "halloc.h"
+#include "halloc_util.h"
+#include "tokenizer.h"
+#include "print_help.h"
+#include "parser_keywords.h"
+
+/**
+ The string describing the single-character options accepted by the main fish binary
+*/
+#define GETOPT_STRING "hvi"
+
+void read_file( FILE *f, string_buffer_t *b )
+{
+ while( 1 )
+ {
+ wint_t c = fgetwc( f );
+ if( c == WEOF )
+ {
+ break;
+ }
+
+ sb_append_char( b, c );
+ }
+}
+
+static void insert_tabs( string_buffer_t *out, int indent )
+{
+ int i;
+
+ for( i=0; i " );
+ break;
+
+ case TOK_REDIRECT_APPEND:
+ sb_append( out, L">> " );
+ break;
+
+ case TOK_REDIRECT_IN:
+ sb_append( out, L"< " );
+ break;
+
+ case TOK_REDIRECT_FD:
+ sb_append( out, L">& " );
+ break;
+
+ }
+ break;
+ }
+
+
+ case TOK_BACKGROUND:
+ {
+ sb_append( out, L"&\n" );
+ do_indent = 1;
+ is_command = 1;
+ break;
+ }
+
+
+ case TOK_COMMENT:
+ {
+ sb_printf( out, L"%ls", last );
+ do_indent = 1;
+ break;
+ }
+
+ default:
+ {
+ debug( 0, L"Unknown wha? %ls", last );
+ exit(1);
+ }
+ }
+
+ }
+
+ tok_destroy( &tok );
+
+ return res;
+}
+
+
+int main( int argc, char **argv )
+{
+ string_buffer_t sb_in;
+ string_buffer_t sb_out;
+
+ int do_indent=1;
+
+ wsetlocale( LC_ALL, L"" );
+ program_name=L"fish_indent";
+
+ while( 1 )
+ {
+ static struct option
+ long_options[] =
+ {
+ {
+ "no-indent", no_argument, 0, 'i'
+ }
+ ,
+ {
+ "help", no_argument, 0, 'h'
+ }
+ ,
+ {
+ "version", no_argument, 0, 'v'
+ }
+ ,
+ {
+ 0, 0, 0, 0
+ }
+ }
+ ;
+
+ int opt_index = 0;
+
+ int opt = getopt_long( argc,
+ argv,
+ GETOPT_STRING,
+ long_options,
+ &opt_index );
+
+ if( opt == -1 )
+ break;
+
+ switch( opt )
+ {
+ case 0:
+ {
+ break;
+ }
+
+ case 'h':
+ {
+ print_help( "fish_indent", 1 );
+ exit( 0 );
+ break;
+ }
+
+ case 'v':
+ {
+ fwprintf( stderr,
+ _(L"%ls, version %s\n"),
+ program_name,
+ PACKAGE_VERSION );
+ exit( 0 );
+ }
+
+ case 'i':
+ {
+ do_indent = 0;
+ break;
+ }
+
+
+ case '?':
+ {
+ exit( 1 );
+ }
+
+ }
+ }
+
+ halloc_util_init();
+
+ sb_init( &sb_in );
+ sb_init( &sb_out );
+
+ read_file( stdin, &sb_in );
+
+ wutil_init();
+
+ if( !indent( &sb_out, (wchar_t *)sb_in.buff, do_indent ) )
+ {
+
+ fwprintf( stdout, L"%ls", sb_out.buff );
+ }
+ else
+ {
+ /*
+ Indenting failed - print original input
+ */
+ fwprintf( stdout, L"%ls", sb_in.buff );
+ }
+
+
+ wutil_destroy();
+
+ halloc_util_destroy();
+
+ return 0;
+}