/** \file builtin_complete.c Functions defining the complete builtin Functions used for implementing the complete builtin. */ #include "config.h" #include #include #include #include #include #include #include #include "fallback.h" #include "util.h" #include "wutil.h" #include "builtin.h" #include "common.h" #include "complete.h" #include "wgetopt.h" #include "parser.h" #include "reader.h" /** Internal storage for the builtin_complete_get_temporary_buffer() function. */ static const wchar_t *temporary_buffer; /* builtin_complete_* are a set of rather silly looping functions that make sure that all the proper combinations of complete_add or complete_remove get called. This is needed since complete allows you to specify multiple switches on a single commandline, like 'complete -s a -s b -s c', but the complete_add function only accepts one short switch and one long switch. */ /** Silly function */ static void builtin_complete_add2( const wchar_t *cmd, int cmd_type, const wchar_t *short_opt, array_list_t *gnu_opt, array_list_t *old_opt, int result_mode, const wchar_t *condition, const wchar_t *comp, const wchar_t *desc, int flags ) { int i; const wchar_t *s; for( s=short_opt; *s; s++ ) { complete_add( cmd, cmd_type, *s, 0, 0, result_mode, condition, comp, desc, flags ); } for( i=0; i comp; const wchar_t *prev_temporary_buffer = temporary_buffer; wchar_t *token; parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 ); temporary_buffer = do_complete; if( recursion_level < 1 ) { recursion_level++; // comp = al_halloc( 0 ); complete( do_complete, comp ); for( size_t i=0; i< comp.size() ; i++ ) { const completion_t &next = comp.at( i ); const wchar_t *prepend; if( next.flags & COMPLETE_NO_CASE ) { prepend = L""; } else { prepend = token; } if( !(next.description).empty() ) { sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next.completion.c_str(), next.description.c_str() ); } else { sb_printf( sb_out, L"%ls%ls\n", prepend, next.completion.c_str() ); } } // halloc_free( comp ); recursion_level--; } temporary_buffer = prev_temporary_buffer; } else if( woptind != argc ) { sb_printf( sb_err, _( L"%ls: Too many arguments\n" ), argv[0] ); builtin_print_help( parser, argv[0], sb_err ); res = 1; } else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) ) { /* No arguments specified, meaning we print the definitions of * all specified completions to stdout.*/ complete_print( sb_out ); } else { if( remove ) { builtin_complete_remove( &cmd, &path, (wchar_t *)short_opt.buff, &gnu_opt, &old_opt ); } else { builtin_complete_add( &cmd, &path, (wchar_t *)short_opt.buff, &gnu_opt, &old_opt, result_mode, authoritative, condition, comp, desc, flags ); } } } al_foreach( &cmd, &free ); al_foreach( &path, &free ); al_destroy( &cmd ); al_destroy( &path ); sb_destroy( &short_opt ); al_destroy( &gnu_opt ); al_destroy( &old_opt ); return res; }