Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55faab726a56fd9a344653603a56785cd24237b4)
+++ ChangeLog	(revision 486688f72eab04e743b3f5db70de0852cc6e488d)
@@ -1,7 +1,11 @@
 $Id$
+
 1.2.6
 	Started adding code for newmsgproc.  It doesn't fully work yet!
 	  Don't use it.
 	Added search, '/' and '?' to basic help.
+	Will attempt to keep the current message as close as possible
+	     to the previous current message after an expunge.
+	"set <variable>" and "unset <variable>" now work for boolean variables.
 	
 1.2.5
@@ -24,5 +28,5 @@
 	You can now use %me% in filters
 	The built-in personal filter is updated to do so
-	Fixed a bug in moving the poiner after an expunge
+	Fixed a bug in moving the pointer after an expunge
 	Fixed up the normal scrolling code.  Now it should always
 	  land on a message, but it's still not optimal.
Index: commands.c
===================================================================
--- commands.c	(revision bde7714af13f550f13c3d59c19b2dc4b95ffb62a)
+++ commands.c	(revision 486688f72eab04e743b3f5db70de0852cc6e488d)
@@ -114,8 +114,16 @@
   OWLCMD_ARGS("set", owl_command_set, OWL_CTX_ANY,
 	      "set a variable value",
-	      "set [-q] <variable> <value>\n"
+	      "set [-q] <variable> [<value>]\n"
 	      "set",
 	      "Set the named variable to the specified value.  If no\n"
 	      "arguments are used print the value of all variables.\n"
+	      "If value is unspecified and the variable is a boolean, will set it to 'on'.\n"
+	      "If -q is specified, is silent and doesn't print a message.\n"),
+
+  OWLCMD_ARGS("unset", owl_command_unset, OWL_CTX_ANY,
+	      "unset a boolean variable value",
+	      "set [-q] <variable>\n"
+	      "set",
+	      "Set the named boolean variable to off.\n"
 	      "If -q is specified, is silent and doesn't print a message.\n"),
 
@@ -946,12 +954,20 @@
   char *var, *val;
   int  silent=0;
+  int requirebool=0;
 
   if (argc == 1) {
     owl_function_printallvars();
     return NULL;
-  } else if (argc == 4 && !strcmp("-q",argv[1])) {
+  } 
+
+  if (argc > 1 && !strcmp("-q",argv[1])) {
     silent = 1;
-    var=argv[2];
-    val=argv[3];
+    argc--; argv++;
+  }
+
+  if (argc == 2) {
+    var=argv[1];
+    val="on";
+    requirebool=1;
   } else if (argc == 3) {
     var=argv[1];
@@ -961,6 +977,24 @@
     return NULL;
   }
-
-  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent);
+  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
+  return NULL;
+}
+
+char *owl_command_unset(int argc, char **argv, char *buff) {
+  char *var, *val;
+  int  silent=0;
+
+  if (argc > 1 && !strcmp("-q",argv[1])) {
+    silent = 1;
+    argc--; argv++;
+  }
+  if (argc == 2) {
+    var=argv[1];
+    val="off";
+  } else {
+    owl_function_makemsg("Wrong number of arguments for unset command");
+    return NULL;
+  }
+  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
   return NULL;
 }
Index: functions.c
===================================================================
--- functions.c	(revision 601a9e06d0bf114578e76e6fae7eed5d871c4a72)
+++ functions.c	(revision 486688f72eab04e743b3f5db70de0852cc6e488d)
@@ -397,5 +397,5 @@
   owl_messagelist *ml;
   owl_view *v;
-  int i, j;
+  int lastmsgid=0;
 
   curmsg=owl_global_get_curmsg(&g);
@@ -403,31 +403,6 @@
   ml=owl_global_get_msglist(&g);
 
-  /* just check to make sure we're in bounds... */
-  if (curmsg>owl_view_get_size(v)-1) curmsg=owl_view_get_size(v)-1;
-  if (curmsg<0) curmsg=0;
-
-  /* first try to move to an undeleted message in the view */
   m=owl_view_get_element(v, curmsg);
-  if (owl_message_is_delete(m)) {
-    /* try to find the next undeleted message */
-    j=owl_view_get_size(v);
-    for (i=curmsg+1; i<j; i++) {
-      if (!owl_message_is_delete(owl_view_get_element(v, i))) {
-	owl_global_set_curmsg(&g, i);
-	break;
-      }
-    }
-
-    /* if we weren't successful try to find one backwards */
-    curmsg=owl_global_get_curmsg(&g);
-    if (owl_message_is_delete(owl_view_get_element(v, curmsg))) {
-      for (i=curmsg; i>0; i--) {
-	if (!owl_message_is_delete(owl_view_get_element(v, i))) {
-	  owl_global_set_curmsg(&g, i);
-	  break;
-	}
-      }
-    }
-  }
+  if (m) lastmsgid = owl_message_get_id(m);
 
   /* expunge the message list */
@@ -437,12 +412,11 @@
   owl_view_recalculate(v);
 
-  if (curmsg>owl_view_get_size(v)-1) {
-    owl_global_set_curmsg(&g, owl_view_get_size(v)-1);
-    if (owl_global_get_curmsg(&g)<0) {
-      owl_global_set_curmsg(&g, 0);
-    }
-    owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
-  }
-
+  /* find where the new position should be
+     (as close as possible to where we last where) */
+  curmsg = owl_view_get_nearest_to_msgid(v, lastmsgid);
+  if (curmsg>owl_view_get_size(v)-1) curmsg = owl_view_get_size(v)-1;
+  if (curmsg<0) curmsg = 0;
+  owl_global_set_curmsg(&g, curmsg);
+  owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
   /* if there are no messages set the direction to down in case we
      delete everything upwards */
Index: util.c
===================================================================
--- util.c	(revision 5a6e6b99eff3959eba0f4eb07f02e0516dc28ae4)
+++ util.c	(revision 486688f72eab04e743b3f5db70de0852cc6e488d)
@@ -4,4 +4,5 @@
 #include <unistd.h>
 #include <malloc.h>
+#include <unistd.h>
 #include <ctype.h>
 
Index: variable.c
===================================================================
--- variable.c	(revision 700c712b49074dfa52e15939d250ca199c0096f8)
+++ variable.c	(revision 486688f72eab04e743b3f5db70de0852cc6e488d)
@@ -430,5 +430,5 @@
 
 /* returns 0 on success, prints a status msg if msg is true */
-int owl_variable_set_fromstring(owl_vardict *d, char *name, char *value, int msg) {
+int owl_variable_set_fromstring(owl_vardict *d, char *name, char *value, int msg, int requirebool) {
   owl_variable *v;
   char buff2[1024];
@@ -441,6 +441,9 @@
   if (!v->set_fromstring_fn) {
     if (msg) owl_function_makemsg("Variable %s is read-only", name);
-    return -1;
-    
+    return -1;   
+  }
+  if (requirebool && v->type!=OWL_VARIABLE_BOOL) {
+    if (msg) owl_function_makemsg("Variable %s is not a boolean", name);
+    return -1;   
   }
   if (0 != v->set_fromstring_fn(v, value)) {
@@ -801,7 +804,7 @@
   FAIL_UNLESS("set bool 1", 0==owl_variable_set_bool_on(&vd,"personalbell"));
   FAIL_UNLESS("get bool 2", 1==owl_variable_get_bool(&vd,"personalbell"));
-  FAIL_UNLESS("set bool 3", 0==owl_variable_set_fromstring(&vd,"personalbell","off",0));
+  FAIL_UNLESS("set bool 3", 0==owl_variable_set_fromstring(&vd,"personalbell","off",0,0));
   FAIL_UNLESS("get bool 4", 0==owl_variable_get_bool(&vd,"personalbell"));
-  FAIL_UNLESS("set bool 5", -1==owl_variable_set_fromstring(&vd,"personalbell","xxx",0));
+  FAIL_UNLESS("set bool 5", -1==owl_variable_set_fromstring(&vd,"personalbell","xxx",0,0));
   FAIL_UNLESS("get bool 6", 0==owl_variable_get_bool(&vd,"personalbell"));
 
@@ -819,8 +822,8 @@
   FAIL_UNLESS("set int 1b", -1==owl_variable_set_int(&vd,"typewinsize",-3));
   FAIL_UNLESS("get int 2b", 12==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("set int 3", 0==owl_variable_set_fromstring(&vd,"typewinsize","9",0));
+  FAIL_UNLESS("set int 3", 0==owl_variable_set_fromstring(&vd,"typewinsize","9",0,0));
   FAIL_UNLESS("get int 4", 9==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("set int 5", -1==owl_variable_set_fromstring(&vd,"typewinsize","xxx",0));
-  FAIL_UNLESS("set int 6", -1==owl_variable_set_fromstring(&vd,"typewinsize","",0));
+  FAIL_UNLESS("set int 5", -1==owl_variable_set_fromstring(&vd,"typewinsize","xxx",0,0));
+  FAIL_UNLESS("set int 6", -1==owl_variable_set_fromstring(&vd,"typewinsize","",0,0));
   FAIL_UNLESS("get int 7", 9==owl_variable_get_int(&vd,"typewinsize"));
 
@@ -833,11 +836,11 @@
   FAIL_UNLESS("set enum 1b", -1==owl_variable_set_int(&vd,"webbrowser",209));
   FAIL_UNLESS("get enum 2b", OWL_WEBBROWSER_GALEON==owl_variable_get_int(&vd,"webbrowser"));
-  FAIL_UNLESS("set enum 3", 0==owl_variable_set_fromstring(&vd,"webbrowser","none",0));
+  FAIL_UNLESS("set enum 3", 0==owl_variable_set_fromstring(&vd,"webbrowser","none",0,0));
   FAIL_UNLESS("get enum 4", OWL_WEBBROWSER_NONE==owl_variable_get_int(&vd,"webbrowser"));
-  FAIL_UNLESS("set enum 5", 0==owl_variable_set_fromstring(&vd,"webbrowser","netscape",0));
+  FAIL_UNLESS("set enum 5", 0==owl_variable_set_fromstring(&vd,"webbrowser","netscape",0,0));
   FAIL_UNLESS("get enum 6", OWL_WEBBROWSER_NETSCAPE==owl_variable_get_int(&vd,"webbrowser"));
-  FAIL_UNLESS("set enum 7", -1==owl_variable_set_fromstring(&vd,"webbrowser","xxx",0));
-  FAIL_UNLESS("set enum 8", -1==owl_variable_set_fromstring(&vd,"webbrowser","",0));
-  FAIL_UNLESS("set enum 9", -1==owl_variable_set_fromstring(&vd,"webbrowser","netscapey",0));
+  FAIL_UNLESS("set enum 7", -1==owl_variable_set_fromstring(&vd,"webbrowser","xxx",0,0));
+  FAIL_UNLESS("set enum 8", -1==owl_variable_set_fromstring(&vd,"webbrowser","",0,0));
+  FAIL_UNLESS("set enum 9", -1==owl_variable_set_fromstring(&vd,"webbrowser","netscapey",0,0));
   FAIL_UNLESS("get enum 10", OWL_WEBBROWSER_NETSCAPE==owl_variable_get_int(&vd,"webbrowser"));
 
