From fbade198b942a666d3fc1110804a7da2c47918f1 Mon Sep 17 00:00:00 2001
From: ridiculousfish <corydoras@ridiculousfish.com>
Date: Sat, 11 Oct 2014 16:50:16 -0700
Subject: [PATCH] Support space separators for abbreviations as part of #731

---
 expand.cpp     | 12 +++++++-----
 fish_tests.cpp |  8 +++++++-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/expand.cpp b/expand.cpp
index 351a84f16..dca54f706 100644
--- a/expand.cpp
+++ b/expand.cpp
@@ -2107,13 +2107,15 @@ bool expand_abbreviation(const wcstring &src, wcstring *output)
     wcstokenizer tokenizer(var, ARRAY_SEP_STR);
     while (tokenizer.next(line))
     {
-        /* Line is expected to be of the form 'foo=bar'. Parse out the first =. Be forgiving about spaces, but silently skip on failure (no equals, or equals at the end or beginning). Try to avoid copying any strings until we are sure this is a match. */
-        size_t equals = line.find(L'=');
-        if (equals == wcstring::npos || equals == 0 || equals + 1 == line.size())
+        /* Line is expected to be of the form 'foo=bar' or 'foo bar'. Parse out the first = or space. Silently skip on failure (no equals, or equals at the end or beginning). Try to avoid copying any strings until we are sure this is a match. */
+        size_t equals_pos = line.find(L'=');
+        size_t space_pos = line.find(L' ');
+        size_t separator = mini(equals_pos, space_pos);
+        if (separator == wcstring::npos || separator == 0 || separator + 1 == line.size())
             continue;
 
         /* Find the character just past the end of the command. Walk backwards, skipping spaces. */
-        size_t cmd_end = equals;
+        size_t cmd_end = separator;
         while (cmd_end > 0 && iswspace(line.at(cmd_end - 1)))
             cmd_end--;
 
@@ -2122,7 +2124,7 @@ bool expand_abbreviation(const wcstring &src, wcstring *output)
         {
             /* Success. Set output to everythign past the end of the string. */
             if (output != NULL)
-                output->assign(line, equals + 1, wcstring::npos);
+                output->assign(line, separator + 1, wcstring::npos);
 
             result = true;
             break;
diff --git a/fish_tests.cpp b/fish_tests.cpp
index c46dcf7a7..34d505c96 100644
--- a/fish_tests.cpp
+++ b/fish_tests.cpp
@@ -1466,7 +1466,8 @@ static void test_abbreviations(void)
         L"=" ARRAY_SEP_STR
         L"=foo" ARRAY_SEP_STR
         L"foo" ARRAY_SEP_STR
-        L"foo=bar";
+        L"foo=bar" ARRAY_SEP_STR
+        L"gx git checkout";
 
     env_push(true);
 
@@ -1493,6 +1494,11 @@ static void test_abbreviations(void)
     expanded = reader_expand_abbreviation_in_command(L"gc somebranch", wcslen(L"gc"), &result);
     if (! expanded) err(L"gc not expanded");
     if (result != L"git checkout somebranch") err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
+    
+    /* space separation */
+    expanded = reader_expand_abbreviation_in_command(L"gx somebranch", wcslen(L"gc"), &result);
+    if (! expanded) err(L"gx not expanded");
+    if (result != L"git checkout somebranch") err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
 
     expanded = reader_expand_abbreviation_in_command(L"echo hi ; gc somebranch", wcslen(L"echo hi ; g"), &result);
     if (! expanded) err(L"gc not expanded on line %ld", (long)__LINE__);