More work towards autosuggesting completions

This commit is contained in:
ridiculousfish 2012-02-25 18:54:49 -08:00
parent 5ea78f55f2
commit 38e40862fe
14 changed files with 184 additions and 140 deletions

View file

@ -261,7 +261,7 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, wcstring &
screen_height = common_get_height();
lines = count_char( str, L'\n' );
if( !is_interactive || (lines > 2*screen_height/3) )
if( !get_is_interactive() || (lines > 2*screen_height/3) )
{
wchar_t *pos;
int cut=0;
@ -2569,7 +2569,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv )
}
if( !is_interactive )
if( !get_is_interactive() )
{
stderr_buffer.append(parser.current_line());
}
@ -2599,7 +2599,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv )
dir );
}
if( !is_interactive )
if( !get_is_interactive() )
{
stderr_buffer.append(parser.current_line());
}

View file

@ -2062,6 +2062,7 @@ void assert_is_main_thread(const char *who)
if (! is_main_thread()) {
fprintf(stderr, "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n", who);
debug_thread_error();
sleep(1000);
}
}

View file

@ -143,7 +143,7 @@ typedef struct complete_entry_opt
/** True if old style long options are used */
int old_mode;
/** Completion flags */
int flags;
complete_flags_t flags;
const wchar_t *localized_desc() const
{
@ -198,6 +198,9 @@ class completer_t {
{
}
bool empty() const { return completions.empty(); }
const std::vector<completion_t> &get_completions(void) { return completions; }
bool try_complete_variable( const wcstring &str );
bool try_complete_user( const wcstring &str );
@ -206,15 +209,14 @@ class completer_t {
const wcstring &str,
bool use_switches);
void complete_param_expand( const wcstring &str, bool do_file);
void complete_param_expand(const wcstring &str, bool do_file);
void complete_cmd( const wcstring &str,
bool use_function,
bool use_builtin,
bool use_command);
bool use_function,
bool use_builtin,
bool use_command);
bool empty() const { return completions.empty(); }
const std::vector<completion_t> &get_completions(void) { return completions; }
bool complete_variable(const wcstring &str, int start_offset);
};
@ -244,7 +246,7 @@ void completion_autoload_t::command_removed(const wcstring &cmd) {
Create a new completion entry
*/
void completion_allocate(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc, int flags)
void completion_allocate(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc, complete_flags_t flags)
{
completions.push_back(completion_t(comp, desc, flags));
}
@ -362,7 +364,7 @@ void complete_add( const wchar_t *cmd,
const wchar_t *condition,
const wchar_t *comp,
const wchar_t *desc,
int flags )
complete_flags_t flags )
{
CHECK( cmd, );
@ -757,7 +759,7 @@ static void complete_strings( std::vector<completion_t> &comp_out,
const wchar_t *desc,
const wchar_t *(*desc_func)(const wcstring &),
std::vector<completion_t> &possible_comp,
int flags )
complete_flags_t flags )
{
wcstring tmp = wc_escaped;
if (! expand_one(tmp, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_WILDCARDS))
@ -1090,21 +1092,24 @@ static void complete_from_args( const wcstring &str,
const wcstring &args,
const wcstring &desc,
std::vector<completion_t> &comp_out,
int flags )
complete_type_t type,
complete_flags_t flags )
{
/* If type is COMPLETE_AUTOSUGGEST, it means we're on a background thread, so don't call proc_push_interactive */
std::vector<completion_t> possible_comp;
parser_t parser(PARSER_TYPE_COMPLETIONS_ONLY);
proc_push_interactive(0);
if (type != COMPLETE_AUTOSUGGEST)
proc_push_interactive(0);
parser.eval_args( args.c_str(), possible_comp );
proc_pop_interactive();
if (type != COMPLETE_AUTOSUGGEST)
proc_pop_interactive();
complete_strings( comp_out, str.c_str(), desc.c_str(), 0, possible_comp, flags );
// al_foreach( &possible_comp, &free );
// al_destroy( &possible_comp );
}
/**
@ -1249,7 +1254,7 @@ static int complete_param( const wchar_t *cmd_orig,
{
use_common &= ((o->result_mode & NO_COMMON )==0);
use_files &= ((o->result_mode & NO_FILES )==0);
complete_from_args( arg, o->comp, o->localized_desc(), comp_out, o->flags );
complete_from_args( arg, o->comp, o->localized_desc(), comp_out, type, o->flags );
}
}
@ -1273,7 +1278,7 @@ static int complete_param( const wchar_t *cmd_orig,
old_style_match = 1;
use_common &= ((o->result_mode & NO_COMMON )==0);
use_files &= ((o->result_mode & NO_FILES )==0);
complete_from_args( str, o->comp, o->localized_desc(), comp_out, o->flags );
complete_from_args( str, o->comp, o->localized_desc(), comp_out, type, o->flags );
}
}
}
@ -1300,7 +1305,7 @@ static int complete_param( const wchar_t *cmd_orig,
{
use_common &= ((o->result_mode & NO_COMMON )==0);
use_files &= ((o->result_mode & NO_FILES )==0);
complete_from_args( str, o->comp.c_str(), o->localized_desc(), comp_out, o->flags );
complete_from_args( str, o->comp.c_str(), o->localized_desc(), comp_out, type, o->flags );
}
}
@ -1326,7 +1331,7 @@ static int complete_param( const wchar_t *cmd_orig,
if( (o->short_opt == L'\0' ) && (o->long_opt[0]==L'\0'))
{
use_files &= ((o->result_mode & NO_FILES )==0);
complete_from_args( str, o->comp, o->localized_desc(), comp_out, o->flags );
complete_from_args( str, o->comp, o->localized_desc(), comp_out, type, o->flags );
}
if( wcslen(str) > 0 && use_switches )
@ -1370,7 +1375,7 @@ static int complete_param( const wchar_t *cmd_orig,
int req_arg=0; /* Does this switch _require_ an argument */
int offset = 0;
int flags = 0;
complete_flags_t flags = 0;
if( match )
@ -1426,7 +1431,6 @@ bool completer_t::complete_param( const wcstring &cmd_orig, const wcstring &popt
static void complete_param_expand( const wchar_t *str, std::vector<completion_t> &comp_out, int do_file, complete_type_t type )
{
const wchar_t *comp_str;
int flags;
if( (wcsncmp( str, L"--", 2 )) == 0 && (comp_str = wcschr(str, L'=' ) ) )
{
@ -1437,7 +1441,7 @@ static void complete_param_expand( const wchar_t *str, std::vector<completion_t>
comp_str = str;
}
flags = EXPAND_SKIP_CMDSUBST | ACCEPT_INCOMPLETE;
expand_flags_t flags = EXPAND_SKIP_CMDSUBST | ACCEPT_INCOMPLETE;
if (! do_file)
flags |= EXPAND_SKIP_WILDCARDS;
@ -1464,11 +1468,13 @@ void completer_t::complete_param_expand( const wcstring &str, bool do_file)
*/
static int complete_variable( const wchar_t *whole_var,
int start_offset,
std::vector<completion_t> &comp_list )
std::vector<completion_t> &comp_list,
complete_type_t type)
{
const wchar_t *var = &whole_var[start_offset];
int varlen = wcslen( var );
int res = 0;
bool wants_description = (type != COMPLETE_AUTOSUGGEST);
const wcstring_list_t names = env_get_names(0);
for( size_t i=0; i<names.size(); i++ )
@ -1489,34 +1495,39 @@ static int complete_variable( const wchar_t *whole_var,
if( match || match_no_case )
{
const env_var_t value_unescaped = env_get_string( env_name );
if( !value_unescaped.missing() )
{
wcstring comp;
int flags = 0;
int offset = 0;
if( match )
{
comp.append(env_name.c_str() + varlen);
offset = varlen;
}
else
{
comp.append(whole_var, start_offset);
comp.append(env_name);
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
}
wcstring value = expand_escape_variable( value_unescaped );
wcstring comp;
int flags = 0;
int offset = 0;
if( match )
{
comp.append(env_name.c_str() + varlen);
offset = varlen;
}
else
{
comp.append(whole_var, start_offset);
comp.append(env_name);
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
}
wcstring desc;
if (wants_description)
{
env_var_t value_unescaped = env_get_string( env_name );
if (value_unescaped.missing())
continue;
wcstring desc = format_string(COMPLETE_VAR_DESC_VAL, value.c_str());
completion_allocate( comp_list,
comp.c_str(),
desc.c_str(),
flags );
res =1;
}
wcstring value = expand_escape_variable( value_unescaped );
if (type != COMPLETE_AUTOSUGGEST)
desc = format_string(COMPLETE_VAR_DESC_VAL, value.c_str());
}
completion_allocate( comp_list,
comp.c_str(),
desc.c_str(),
flags );
res =1;
}
}
@ -1524,13 +1535,18 @@ static int complete_variable( const wchar_t *whole_var,
return res;
}
bool completer_t::complete_variable(const wcstring &str, int start_offset)
{
return ::complete_variable(str.c_str(), start_offset, this->completions, this->type);
}
/**
Search the specified string for the \$ sign. If found, try to
complete as an environment variable.
\return 0 if unable to complete, 1 otherwise
*/
static int try_complete_variable( const wchar_t *cmd, std::vector<completion_t> &comp )
static int try_complete_variable( const wchar_t *cmd, std::vector<completion_t> &comp, complete_type_t type )
{
int len = wcslen( cmd );
int i;
@ -1540,7 +1556,7 @@ static int try_complete_variable( const wchar_t *cmd, std::vector<completion_t>
if( cmd[i] == L'$' )
{
/* wprintf( L"Var prefix \'%ls\'\n", &cmd[i+1] );*/
return complete_variable( cmd, i+1, comp );
return complete_variable( cmd, i+1, comp, type);
}
if( !isalnum(cmd[i]) && cmd[i]!=L'_' )
{
@ -1552,7 +1568,7 @@ static int try_complete_variable( const wchar_t *cmd, std::vector<completion_t>
bool completer_t::try_complete_variable( const wcstring &str )
{
return ::try_complete_variable(str.c_str(), this->completions) > 0;
return ::try_complete_variable(str.c_str(), this->completions, this->type) > 0;
}
/**
@ -1910,7 +1926,7 @@ void complete( const wchar_t *cmd, std::vector<completion_t> &comp, complete_typ
if( !done )
{
if( try_complete_variable( tok_begin, comp ) || try_complete_user( tok_begin, comp ))
if( try_complete_variable( tok_begin, comp, type ) || try_complete_user( tok_begin, comp ))
{
done=1;
}

View file

@ -67,39 +67,41 @@
*/
#define PROG_COMPLETE_SEP L'\t'
/**
Do not insert space afterwards if this is the only completion. (The
default is to try insert a space)
*/
#define COMPLETE_NO_SPACE 1
enum {
/**
Do not insert space afterwards if this is the only completion. (The
default is to try insert a space)
*/
COMPLETE_NO_SPACE = 1 << 0,
/**
This compeltion is case insensitive.
/**
This compeltion is case insensitive.
Warning: The contents of the completion_t structure is actually
different if this flag is set! Specifically, the completion string
contains the _entire_ completion token, not only the current
*/
#define COMPLETE_NO_CASE 2
Warning: The contents of the completion_t structure is actually
different if this flag is set! Specifically, the completion string
contains the _entire_ completion token, not only the current
*/
COMPLETE_NO_CASE = 1 << 1,
/**
This compeltion is the whole argument, not just the remainder. This
flag must never be set on completions returned from the complete()
function. It is strictly for internal use in the completion code.
*/
#define COMPLETE_WHOLE_ARGUMENT 4
/**
This compeltion is the whole argument, not just the remainder. This
flag must never be set on completions returned from the complete()
function. It is strictly for internal use in the completion code.
*/
COMPLETE_WHOLE_ARGUMENT = 1 << 2,
/**
This completion may or may not want a space at the end - guess by
checking the last character of the completion.
*/
#define COMPLETE_AUTO_SPACE 8
/**
This completion should be inserted as-is, without escaping.
*/
#define COMPLETE_DONT_ESCAPE 16
/**
This completion may or may not want a space at the end - guess by
checking the last character of the completion.
*/
COMPLETE_AUTO_SPACE = 1 << 3,
/**
This completion should be inserted as-is, without escaping.
*/
COMPLETE_DONT_ESCAPE = 1 << 4
};
typedef int complete_flags_t;
class completion_t

17
env.cpp
View file

@ -97,7 +97,7 @@ struct var_entry_t
/**
Struct representing one level in the function variable stack
*/
typedef struct env_node
struct env_node_t
{
/**
Variable table
@ -118,12 +118,11 @@ typedef struct env_node
/**
Pointer to next level
*/
struct env_node *next;
struct env_node_t *next;
env_node() : new_scope(0), exportv(0), next(NULL) { }
}
env_node_t;
env_node_t() : new_scope(0), exportv(0), next(NULL) { }
};
class variable_entry_t {
bool exportv; /**< Whether the variable should be exported */
@ -337,7 +336,7 @@ static void handle_locale()
dcgettext( "fish", "Changing language to English", LC_MESSAGES );
if( is_interactive )
if( get_is_interactive() )
{
debug( 0, _(L"Changing language to English") );
}
@ -1479,6 +1478,8 @@ static void add_key_to_string_set(const std::map<wcstring, var_entry_t*> &envs,
wcstring_list_t env_get_names( int flags )
{
scoped_lock lock(env_lock);
wcstring_list_t result;
std::set<wcstring> names;
int show_local = flags & ENV_LOCAL;
@ -1489,9 +1490,9 @@ wcstring_list_t env_get_names( int flags )
get_names_show_exported =
flags & ENV_EXPORT|| (!(flags & ENV_UNEXPORT));
(flags & ENV_EXPORT) || !(flags & ENV_UNEXPORT);
get_names_show_unexported =
flags & ENV_UNEXPORT|| (!(flags & ENV_EXPORT));
(flags & ENV_UNEXPORT) || !(flags & ENV_EXPORT);
if( !show_local && !show_global && !show_universal )
{

4
env.h
View file

@ -93,7 +93,7 @@ int env_set( const wchar_t *key,
valid until the next call to env_get(), env_set(), env_push() or
env_pop() takes place.
*/
const wchar_t *env_get( const wchar_t *key );
//const wchar_t *env_get( const wchar_t *key );
class env_var_t : public wcstring {
private:
@ -153,7 +153,7 @@ void env_pop();
char **env_export_arr( int recalc );
/**
Insert all variable names into l. These are not copies of the strings and should not be freed after use.
Returns all variable names.
*/
wcstring_list_t env_get_names( int flags );

View file

@ -145,11 +145,11 @@ int expand_is_clean( const wchar_t *in )
/**
Return the environment variable value for the string starting at \c in.
*/
static const wchar_t* expand_var(const wchar_t *in)
static env_var_t expand_var(const wchar_t *in)
{
if( !in )
return 0;
return env_get( in );
return env_var_t::missing_var();
return env_get_string( in );
}
/**
@ -818,7 +818,6 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std:
int start_pos = i+1;
int stop_pos;
int var_len;
const wchar_t * var_val;
int is_single = (c==VARIABLE_EXPAND_SINGLE);
int var_name_stop_pos;
@ -849,9 +848,9 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std:
}
var_tmp.append(in + start_pos, var_len);
var_val = expand_var(var_tmp.c_str() );
env_var_t var_val = expand_var(var_tmp.c_str() );
if( var_val )
if( ! var_val.missing() )
{
int all_vars=1;
wcstring_list_t var_item_list;
@ -873,7 +872,7 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std:
if( is_ok )
{
tokenize_variable_array( var_val, var_item_list );
tokenize_variable_array( var_val.c_str(), var_item_list );
if( !all_vars )
{

View file

@ -266,7 +266,7 @@ const wchar_t *kill_yank()
void kill_sanity_check()
{
int i;
if( is_interactive )
if( get_is_interactive() )
{
/* Test that the kill-ring is consistent */
if( kill_current != 0 )

View file

@ -762,6 +762,8 @@ void parser_t::print_errors_stderr()
int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
{
tokenizer tok;
const bool show_errors = (this->parser_type == PARSER_TYPE_GENERAL || this->parser_type == PARSER_TYPE_ERRORS_ONLY);
/*
eval_args may be called while evaulating another command, so we
save the previous tokenizer and restore it on exit
@ -772,12 +774,15 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
CHECK( line, 1 );
// CHECK( args, 1 );
proc_push_interactive(0);
// PCA we need to suppress calling proc_push_interactive off of the main thread. I'm not sure exactly what it does.
if (this->parser_type == PARSER_TYPE_GENERAL)
proc_push_interactive(0);
current_tokenizer = &tok;
current_tokenizer_pos = 0;
tok_init( &tok, line, 0 );
tok_init( &tok, line, (show_errors ? 0 : TOK_SQUASH_ERRORS) );
error_code=0;
for(;do_loop && tok_has_next( &tok) ; tok_next( &tok ) )
@ -794,7 +799,7 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
DIE_MEM();
}
if( expand_string( tmp, args, 0 ) == EXPAND_ERROR )
if( expand_string( tmp, args, (show_errors ? 0 : EXPAND_NO_DESCRIPTIONS) ) == EXPAND_ERROR )
{
err_pos=tok_get_pos( &tok );
do_loop=0;
@ -809,10 +814,11 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
case TOK_ERROR:
{
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
TOK_ERR_MSG,
tok_last(&tok) );
if (show_errors)
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
TOK_ERR_MSG,
tok_last(&tok) );
do_loop=0;
break;
@ -820,10 +826,11 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
default:
{
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
UNEXPECTED_TOKEN_ERR_MSG,
tok_get_desc( tok_last_type(&tok)) );
if (show_errors)
error( SYNTAX_ERROR,
tok_get_pos( &tok ),
UNEXPECTED_TOKEN_ERR_MSG,
tok_get_desc( tok_last_type(&tok)) );
do_loop=0;
break;
@ -831,14 +838,17 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
}
}
this->print_errors_stderr();
if (show_errors)
this->print_errors_stderr();
tok_destroy( &tok );
current_tokenizer=previous_tokenizer;
current_tokenizer_pos = previous_pos;
proc_pop_interactive();
if (this->parser_type == PARSER_TYPE_GENERAL)
proc_pop_interactive();
return 1;
}
@ -1114,7 +1124,7 @@ const wchar_t *parser_t::current_line()
/**
If we are not going to print a stack trace, at least print the line number and filename
*/
if( !is_interactive || is_function() )
if( !get_is_interactive() || is_function() )
{
int prev_width = my_wcswidth( lineinfo.c_str() );
if( file )
@ -1139,7 +1149,7 @@ const wchar_t *parser_t::current_line()
Skip printing character position if we are in interactive mode
and the error was on the first character of the line.
*/
if( !is_interactive || is_function() || (current_line_width!=0) )
if( !get_is_interactive() || is_function() || (current_line_width!=0) )
{
// Workaround since it seems impossible to print 0 copies of a character using %*lc
if( offset+current_line_width )
@ -1559,7 +1569,7 @@ void parser_t::parse_job_argument_list( process_t *p,
{
job_set_flag( j, JOB_WILDCARD_ERROR, 1 );
proc_set_last_status( STATUS_UNMATCHED_WILDCARD );
if( is_interactive && !is_block )
if( get_is_interactive() && !is_block )
{
int tmp;
@ -2210,11 +2220,11 @@ void parser_t::eval_job( tokenizer *tok )
job_set_flag( j, JOB_SKIP_NOTIFICATION, is_subshell \
|| is_block \
|| is_event \
|| (!is_interactive));
|| (!get_is_interactive()));
current_block->job = j;
if( is_interactive )
if( get_is_interactive() )
{
if( tcgetattr (0, &j->tmodes) )
{

View file

@ -101,7 +101,6 @@ job_list_t &job_list(void) {
return s_job_list;
}
int is_interactive=-1;
int is_interactive_session=0;
int is_subshell=0;
int is_block=0;
@ -112,6 +111,12 @@ pid_t proc_last_bg_pid = 0;
int job_control_mode = JOB_CONTROL_INTERACTIVE;
int no_exec=0;
static int is_interactive = -1;
int get_is_interactive(void) {
ASSERT_IS_MAIN_THREAD();
return is_interactive;
}
/**
The event variable used to send all process event
@ -1236,6 +1241,7 @@ void proc_sanity_check()
void proc_push_interactive( int value )
{
ASSERT_IS_MAIN_THREAD();
int old = is_interactive;
interactive_stack.push_back(is_interactive);
is_interactive = value;
@ -1245,6 +1251,7 @@ void proc_push_interactive( int value )
void proc_pop_interactive()
{
ASSERT_IS_MAIN_THREAD();
int old = is_interactive;
is_interactive= interactive_stack.back();
interactive_stack.pop_back();

2
proc.h
View file

@ -366,7 +366,7 @@ extern int is_block;
/**
Whether we are reading from the keyboard right now
*/
extern int is_interactive;
int get_is_interactive(void);
/**
Whether this shell is attached to the keyboard at all

View file

@ -1049,6 +1049,9 @@ static void completion_insert( const wchar_t *val, int flags )
}
insert_char( L' ' );
}
/* Since we just inserted a completion, don't immediately do a new autosuggestion */
data->suppress_autosuggestion = true;
}
free(replaced);
@ -1234,10 +1237,7 @@ struct autosuggestion_context_t {
int threaded_autosuggest(void) {
ASSERT_IS_BACKGROUND_THREAD();
std::vector<completion_t> completions;
complete(search_string.c_str(), completions, COMPLETE_AUTOSUGGEST);
while (searcher.go_backwards()) {
history_item_t item = searcher.current_item();
bool item_ok = false;
@ -1259,6 +1259,15 @@ struct autosuggestion_context_t {
}
}
/* Try normal completions */
std::vector<completion_t> completions;
complete2(search_string, completions, COMPLETE_AUTOSUGGEST);
if (! completions.empty()) {
this->autosuggestion = this->search_string;
this->autosuggestion.append(completions.at(0).completion);
return 1;
}
/* Since we didn't find a suggestion from history, try other means */
wcstring special_suggestion;
if (autosuggest_suggest_special(search_string, working_directory, special_suggestion)) {
@ -1436,8 +1445,7 @@ static int handle_completions( std::vector<completion_t> &comp )
*/
if( !(c.flags & COMPLETE_NO_CASE) || reader_can_replace( tok, c.flags ) )
{
completion_insert( c.completion.c_str(),
c.flags );
completion_insert( c.completion.c_str(), c.flags );
}
done = 1;
len = 1;
@ -1732,7 +1740,7 @@ static void reader_interactive_destroy()
void reader_sanity_check()
{
if( is_interactive)
if( get_is_interactive())
{
if( !data )
sanity_lose();
@ -2440,7 +2448,7 @@ static void reader_super_highlight_me_plenty( int match_highlight_pos )
/* Here's a hack. Check to see if our autosuggestion still applies; if so, don't recompute it. Since the autosuggestion computation is asynchronous, this avoids "flashing" as you type into the autosuggestion. */
const wcstring &cmd = data->command_line, &suggest = data->autosuggestion;
if (! suggest.empty() && ! cmd.empty() && string_prefixes_string(cmd, suggest)) {
if (can_autosuggest() && ! suggest.empty() && string_prefixes_string(cmd, suggest)) {
/* The autosuggestion is still reasonable, so do nothing */
} else {
update_autosuggestion();
@ -2450,7 +2458,7 @@ static void reader_super_highlight_me_plenty( int match_highlight_pos )
int exit_status()
{
if( is_interactive )
if( get_is_interactive() )
return job_list().empty() && data->end_loop;
else
return end_loop;
@ -3444,7 +3452,7 @@ int reader_read( int fd, io_data_t *io )
int inter = ((fd == STDIN_FILENO) && isatty(STDIN_FILENO));
proc_push_interactive( inter );
res= is_interactive?read_i():read_ni( fd, io );
res= get_is_interactive() ? read_i():read_ni( fd, io );
/*
If the exit command was called in a script, only exit the

View file

@ -41,7 +41,7 @@ void sanity_lose()
int sanity_check()
{
if( !insane )
if( is_interactive )
if( get_is_interactive() )
history_sanity_check();
if( !insane )
reader_sanity_check();

View file

@ -503,7 +503,7 @@ void signal_set_handlers()
{
struct sigaction act;
if( is_interactive == -1 )
if( get_is_interactive() == -1 )
return;
sigemptyset( & act.sa_mask );
@ -527,7 +527,7 @@ void signal_set_handlers()
*/
sigaction( SIGPIPE, &act, 0);
if( is_interactive )
if( get_is_interactive() )
{
/*
Interactive mode. Ignore interactive signals. We are a