From aeb957a2852555b2fce037aac4c3cb2b9d2f5c39 Mon Sep 17 00:00:00 2001
From: Junegunn Choi <junegunn.c@gmail.com>
Date: Tue, 4 Oct 2016 02:09:03 +0900
Subject: [PATCH] Use exact match by default for inverse search term

This is a breaking change, but I believe it makes much more sense. It is
almost impossible to predict which entries will be filtered out due to
a fuzzy inverse term. You can still perform inverse-fuzzy-match by
prepending `!'` to the term.

| Token    | Match type                 | Description                       |
| -------- | -------------------------- | --------------------------------- |
| `sbtrkt` | fuzzy-match                | Items that match `sbtrkt`         |
| `^music` | prefix-exact-match         | Items that start with `music`     |
| `.mp3$`  | suffix-exact-match         | Items that end with `.mp3`        |
| `'wild`  | exact-match (quoted)       | Items that include `wild`         |
| `!fire`  | inverse-exact-match        | Items that do not include `fire`  |
| `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` |
---
 src/pattern.go      | 3 ++-
 src/pattern_test.go | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/pattern.go b/src/pattern.go
index 7e5f4289..82272af6 100644
--- a/src/pattern.go
+++ b/src/pattern.go
@@ -163,12 +163,13 @@ func parseTerms(fuzzy bool, caseMode Case, str string) []termSet {
 
 		if strings.HasPrefix(text, "!") {
 			inv = true
+			typ = termExact
 			text = text[1:]
 		}
 
 		if strings.HasPrefix(text, "'") {
 			// Flip exactness
-			if fuzzy {
+			if fuzzy && !inv {
 				typ = termExact
 				text = text[1:]
 			} else {
diff --git a/src/pattern_test.go b/src/pattern_test.go
index a3aa5969..9b6d394e 100644
--- a/src/pattern_test.go
+++ b/src/pattern_test.go
@@ -22,15 +22,15 @@ func TestParseTermsExtended(t *testing.T) {
 		terms[1][0].typ != termExact || terms[1][0].inv ||
 		terms[2][0].typ != termPrefix || terms[2][0].inv ||
 		terms[3][0].typ != termSuffix || terms[3][0].inv ||
-		terms[4][0].typ != termFuzzy || !terms[4][0].inv ||
-		terms[5][0].typ != termExact || !terms[5][0].inv ||
+		terms[4][0].typ != termExact || !terms[4][0].inv ||
+		terms[5][0].typ != termFuzzy || !terms[5][0].inv ||
 		terms[6][0].typ != termPrefix || !terms[6][0].inv ||
 		terms[7][0].typ != termSuffix || !terms[7][0].inv ||
 		terms[7][1].typ != termEqual || terms[7][1].inv ||
 		terms[8][0].typ != termPrefix || terms[8][0].inv ||
 		terms[8][1].typ != termExact || terms[8][1].inv ||
 		terms[8][2].typ != termSuffix || terms[8][2].inv ||
-		terms[8][3].typ != termFuzzy || !terms[8][3].inv {
+		terms[8][3].typ != termExact || !terms[8][3].inv {
 		t.Errorf("%s", terms)
 	}
 	for idx, termSet := range terms[:8] {
-- 
GitLab