diff --git a/ov.yaml b/ov.yaml index 5246b7b4..707f031b 100644 --- a/ov.yaml +++ b/ov.yaml @@ -2,6 +2,7 @@ # Copy it to `$XDG_CONFIG_HOME/ov/config.yaml` or start it with `ov --config ov.yaml`. # # CaseSensitive: false +# SmartCaseSensitive: false # RegexpSearch: false # Incsearch: true # BeforeWriteOriginal: 1000 diff --git a/oviewer/oviewer.go b/oviewer/oviewer.go index 6cacf149..04ce27d4 100644 --- a/oviewer/oviewer.go +++ b/oviewer/oviewer.go @@ -189,6 +189,7 @@ type Config struct { IsWriteOriginal bool QuitSmall bool CaseSensitive bool + SmartCaseSensitive bool RegexpSearch bool Incsearch bool Debug bool diff --git a/oviewer/search.go b/oviewer/search.go index ba836737..acb98aa8 100644 --- a/oviewer/search.go +++ b/oviewer/search.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "sync/atomic" + "unicode" "code.rocketnine.space/tslocum/cbind" "github.com/gdamore/tcell/v2" @@ -228,9 +229,20 @@ func (root *Root) setSearcher(word string, caseSensitive bool) Searcher { } root.input.value = word root.searchWord = word - root.searchReg = regexpCompile(root.searchWord, caseSensitive) - return NewSearcher(root.searchWord, root.searchReg, caseSensitive, root.Config.RegexpSearch) + smartCaseSensitive := caseSensitive + if root.Config.SmartCaseSensitive { + smartCaseSensitive = false + for _, ch := range word { + if unicode.IsUpper(ch) { + smartCaseSensitive = true + break + } + } + } + root.searchReg = regexpCompile(root.searchWord, smartCaseSensitive) + + return NewSearcher(root.searchWord, root.searchReg, smartCaseSensitive, root.Config.RegexpSearch) } // searchMove searches forward/backward and moves to the nearest matching line. diff --git a/oviewer/search_test.go b/oviewer/search_test.go index 051ddd98..44081020 100644 --- a/oviewer/search_test.go +++ b/oviewer/search_test.go @@ -474,6 +474,7 @@ func TestRoot_setSearch(t *testing.T) { fields fields args args want Searcher + config Config }{ { name: "testNil", @@ -499,11 +500,28 @@ func TestRoot_setSearch(t *testing.T) { word: strings.ToLower("test"), }, }, + { + name: "testSmartCaseSensitiveTrue", + config: Config{ + SmartCaseSensitive: true, + }, + fields: fields{ + input: &Input{}, + }, + args: args{ + word: "Test", + caseSensitive: false, + }, + want: sensitiveWord{ + word: "Test", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { root := &Root{ input: tt.fields.input, + Config: tt.config, } if got := root.setSearcher(tt.args.word, tt.args.caseSensitive); !reflect.DeepEqual(got, tt.want) { t.Errorf("Root.setSearch() = %v, want %v", got, tt.want)