From f35d2629d40908bb4a516e9801a42bb47e501012 Mon Sep 17 00:00:00 2001
From: ridiculousfish <corydoras@ridiculousfish.com>
Date: Mon, 5 Mar 2012 14:18:16 -0800
Subject: [PATCH] Notice when fish_term256 changes and react to it

---
 env.cpp   | 60 +++++++++++++++++++++++++------------------------------
 env.h     |  6 ++----
 event.cpp |  8 +++++---
 input.cpp | 25 +++++++++++++----------
 input.h   | 15 ++++++--------
 5 files changed, 55 insertions(+), 59 deletions(-)

diff --git a/env.cpp b/env.cpp
index 389b04508..db7ddfd94 100644
--- a/env.cpp
+++ b/env.cpp
@@ -54,7 +54,7 @@
 #include "reader.h"
 #include "parser.h"
 #include "env_universal.h"
-#include "input_common.h"
+#include "input.h"
 #include "event.h"
 #include "path.h"
 
@@ -200,7 +200,7 @@ static int get_names_show_unexported;
 /**
    List of all locale variable names
 */
-static const wchar_t *locale_variable[] =
+static const wchar_t * const locale_variable[] =
 {
 	L"LANG",
 	L"LC_ALL",
@@ -211,8 +211,7 @@ static const wchar_t *locale_variable[] =
 	L"LC_NUMERIC",
 	L"LC_TIME",
 	NULL
-}
-	;
+};
 
 
 /**
@@ -250,20 +249,14 @@ static mode_t get_umask()
 	return res;
 }
 
-/**
-   Checks if the specified variable is a locale variable
-*/
-static int is_locale( const wchar_t *key )
-{
-	int i;
-	for( i=0; locale_variable[i]; i++ )
-	{
-		if( wcscmp(locale_variable[i], key ) == 0 )
-		{
-			return 1;
+/** Checks if the specified variable is a locale variable */
+static bool var_is_locale(const wcstring &key) {
+	for (size_t i=0; locale_variable[i]; i++) {
+		if (key == locale_variable[i]) {
+			return true;
 		}
 	}
-	return 0;
+	return false;
 }
 
 /**
@@ -339,6 +332,16 @@ static void handle_locale()
 }
 
 
+/** React to modifying hte given variable */
+static void react_to_variable_change(const wcstring &key) {
+    if(var_is_locale(key)){
+        handle_locale();
+    } else if (key == L"fish_term256") {
+        update_fish_term256();
+        reader_repaint_needed();
+    }
+}
+
 /**
    Universal variable callback function. This function makes sure the
    proper events are triggered when an event occurs.
@@ -349,7 +352,7 @@ static void universal_callback( int type,
 {
 	const wchar_t *str=0;
 	
-	if( is_locale( name ) )
+	if( var_is_locale( name ) )
 	{
 		handle_locale();
 	}
@@ -720,9 +723,7 @@ static env_node_t *env_get_node( const wcstring &key )
 	return 0;
 }
 
-int env_set( const wchar_t *key, 
-			 const wchar_t *val, 
-			 int var_mode )
+int env_set(const wchar_t *key,  const wchar_t *val, int var_mode)
 {
 	env_node_t *node = NULL;
 	bool has_changed_old = has_changed;
@@ -947,10 +948,7 @@ int env_set( const wchar_t *key,
         ev.arguments.reset(NULL);
     }
     
-    if( is_locale( key ) )
-    {
-        handle_locale();
-    }
+    react_to_variable_change(key);
     
     return 0;
 }
@@ -1002,12 +1000,11 @@ static int try_remove( env_node_t *n,
 }
 
 
-int env_remove( const wchar_t *key, int var_mode )
+int env_remove( const wcstring &key, int var_mode )
 {
+    ASSERT_IS_MAIN_THREAD();
 	env_node_t *first_node;
 	int erased = 0;
-	
-	CHECK( key, 1 );
 		
 	if( (var_mode & ENV_USER ) && is_read_only(key) )
 	{
@@ -1024,7 +1021,7 @@ int env_remove( const wchar_t *key, int var_mode )
 			first_node = global_env;
 		}
 		
-		if( try_remove( first_node, key, var_mode ) )
+		if( try_remove( first_node, key.c_str(), var_mode ) )
 		{		
 			event_t ev = event_t::variable_event(key);
             ev.arguments.reset(new wcstring_list_t);
@@ -1043,13 +1040,10 @@ int env_remove( const wchar_t *key, int var_mode )
 		!(var_mode & ENV_GLOBAL) &&
 		!(var_mode & ENV_LOCAL) ) 
 	{
-		erased = !env_universal_remove( key );
+		erased = ! env_universal_remove( key.c_str() );
 	}
 
-	if( is_locale( key ) )
-	{
-		handle_locale();
-	}
+    react_to_variable_change(key);
 	
 	return !erased;	
 }
diff --git a/env.h b/env.h
index a286df6d8..c43efba10 100644
--- a/env.h
+++ b/env.h
@@ -81,9 +81,7 @@ void env_destroy();
    * ENV_INVALID, the variable name or mode was invalid
 */
 
-int env_set( const wchar_t *key, 
-			 const wchar_t *val,
-			 int mode );
+int env_set(const wchar_t *key,  const wchar_t *val, int mode);
 
 
 /**
@@ -145,7 +143,7 @@ int env_exist( const wchar_t *key, int mode );
 
    \return zero if the variable existed, and non-zero if the variable did not exist
 */
-int env_remove( const wchar_t *key, int mode );
+int env_remove( const wcstring &key, int mode );
 
 /**
   Push the variable stack. Used for implementing local variables for functions and for-loops.
diff --git a/event.cpp b/event.cpp
index 0f87bc39b..4a9f9222b 100644
--- a/event.cpp
+++ b/event.cpp
@@ -88,10 +88,12 @@ static event_list_t blocked;
 static int event_match( const event_t *classv, const event_t *instance )
 {
 
-	if( ! classv->function_name.empty() && ! instance->function_name.empty() )
+    /* If the function names are both non-empty and different, then it's not a match */
+	if( ! classv->function_name.empty() &&
+        ! instance->function_name.empty() &&
+          classv->function_name != instance->function_name)
 	{
-		if( classv->function_name != instance->function_name )
-			return 0;
+        return 0;
 	}
 
 	if( classv->type == EVENT_ANY )
diff --git a/input.cpp b/input.cpp
index 26138cfe0..8562cd762 100644
--- a/input.cpp
+++ b/input.cpp
@@ -305,6 +305,20 @@ static int interrupt_handler()
 	return R_NULL;	
 }
 
+void update_fish_term256(void)
+{
+    /* Infer term256 support */
+    env_var_t fish_term256 = env_get_string(L"fish_term256");
+    bool support_term256;
+    if (! fish_term256.missing_or_empty()) {
+        support_term256 = from_string<bool>(fish_term256);
+    } else {
+        env_var_t term = env_get_string(L"TERM");
+        support_term256 = ! term.missing() && term.find(L"256color") != wcstring::npos;
+    }
+    output_set_supports_term256(support_term256);
+}
+
 int input_init()
 {
 	if( is_init )
@@ -325,16 +339,7 @@ int input_init()
 	
 	input_terminfo_init();
     
-    /* Infer term256 support. Consider using t_Co */
-    env_var_t fish_term256 = env_get_string(L"fish_term256");
-    bool support_term256;
-    if (! fish_term256.missing_or_empty()) {
-        support_term256 = from_string<bool>(fish_term256);
-    } else {
-        env_var_t term = env_get_string(L"TERM");
-        support_term256 = ! term.missing() && term.find(L"256color") != wcstring::npos;
-    }
-    output_set_supports_term256(support_term256);
+    update_fish_term256();
 
 	/* If we have no keybindings, add a few simple defaults */
 	if( mapping_list.size() )
diff --git a/input.h b/input.h
index 5669db3fd..fbb4d7fd7 100644
--- a/input.h
+++ b/input.h
@@ -119,24 +119,21 @@ bool input_mapping_get( const wcstring &sequence, wcstring &cmd );
  */
 const wchar_t *input_terminfo_get_sequence( const wchar_t *name );
 
-/**
-   Return the name of the terminfo variable with the specified sequence
- */
+/** Return the name of the terminfo variable with the specified sequence */
 bool input_terminfo_get_name( const wcstring &seq, wcstring &name );
 
 /** Return a list of all known terminfo names */
 wcstring_list_t input_terminfo_get_names( bool skip_null );
 
 
-/**
-   Returns the input function code for the given input function name.
-*/
+/** Returns the input function code for the given input function name. */
 wchar_t input_function_get_code( const wcstring &name );
 
-/**
-   Returns a list of all existing input function names
- */
+/** Returns a list of all existing input function names */
 wcstring_list_t input_function_get_names( void );
 
+/** Updates our idea of whether we support term256 */
+void update_fish_term256();
+
 
 #endif