xaizek / pipedial (License: GPLv3 only) (since 2019-01-08)
One more tool for selecting something in console.
Commit e2ed8fdac868d082e8ff0fb1552b864af8f9ff61

Do case-insensitive filtering on empty results
Author: xaizek
Author date (UTC): 2020-07-29 16:46
Committer name: xaizek
Committer date (UTC): 2020-07-29 16:49
Parent(s): 64cf2b4c79978b086366c68e3453ede6b9d15e8c
Signing key: 99DC5E4DB05F6BE2
Tree: d14b2204ad8a3f80a95d4f3bd2101da4f635c2cf
File Lines added Lines deleted
ChangeLog 4 1
docs/04-shortcuts.md 2 1
docs/pipedial.1 2 1
src/PipeDial.cpp 50 14
File ChangeLog changed (mode: 100644) (index 3b1c846..7ea1f87)
1 1 Unreleased changes since 0.2 Unreleased changes since 0.2
2 2
3 (none)
3 Filtering:
4
5 * Do case-sensitive search by default, but if there are no results look up
6 the pattern ignoring case
4 7
5 8 0.1 to 0.2 (2019-09-21) 0.1 to 0.2 (2019-09-21)
6 9
File docs/04-shortcuts.md changed (mode: 100644) (index 9124d39..405fd12)
... ... Normal Mode
14 14
15 15 **e** -- edit current item and accept the result. **e** -- edit current item and accept the result.
16 16
17 **/** -- start interactive filtering.
17 **/** -- start interactive filtering. Case is respected unless no matches are
18 found.
18 19
19 20 **[count]gg** -- put cursor on the first or **[count]**-th element. **[count]gg** -- put cursor on the first or **[count]**-th element.
20 21
File docs/pipedial.1 changed (mode: 100644) (index 1abc8d0..115f2f6)
1 1 .\" Automatically generated by Pandoc 1.17.0.3 .\" Automatically generated by Pandoc 1.17.0.3
2 2 .\" .\"
3 .TH "pipedial" "1" "May 21, 2019" "" ""
3 .TH "pipedial" "1" "July 29, 2020" "" ""
4 4 .hy .hy
5 5 .SH NAME .SH NAME
6 6 .PP .PP
 
... ... Display version information.
37 37 \f[B]e\f[] \-\- edit current item and accept the result. \f[B]e\f[] \-\- edit current item and accept the result.
38 38 .PP .PP
39 39 \f[B]/\f[] \-\- start interactive filtering. \f[B]/\f[] \-\- start interactive filtering.
40 Case is respected unless no matches are found.
40 41 .PP .PP
41 42 \f[B][count]gg\f[] \-\- put cursor on the first or \f[B][count]\f[]\-th \f[B][count]gg\f[] \-\- put cursor on the first or \f[B][count]\f[]\-th
42 43 element. element.
File src/PipeDial.cpp changed (mode: 100644) (index 398b706..a63c790)
17 17
18 18 #include "PipeDial.hpp" #include "PipeDial.hpp"
19 19
20 #include <algorithm>
21 #include <locale>
20 22 #include <string> #include <string>
21 23 #include <utility> #include <utility>
22 24 #include <vector> #include <vector>
 
32 34 #include "vle/Modes.hpp" #include "vle/Modes.hpp"
33 35 #include "vle/keys.hpp" #include "vle/keys.hpp"
34 36
37 static std::wstring::size_type find(const std::wstring &str,
38 const std::wstring &what,
39 bool caseSensitive,
40 std::wstring::size_type from = 0U);
41
35 42 PipeDial::PipeDial(std::wstring titleText, std::vector<std::wstring> initLines) PipeDial::PipeDial(std::wstring titleText, std::vector<std::wstring> initLines)
36 43 : lines(std::move(initLines)), input(cursed::Keypad::Disabled), : lines(std::move(initLines)), input(cursed::Keypad::Disabled),
37 44 title(std::move(titleText)), quit(false) title(std::move(titleText)), quit(false)
 
... ... PipeDial::buildNormalMode()
236 243 } }
237 244
238 245 filtered.clear(); filtered.clear();
239 for (const std::wstring &line : lines) {
240 auto pos = line.find(filter);
241 if (pos == std::wstring::npos) {
242 continue;
246 for (int tries = 0; tries < 2; ++tries) {
247 bool caseSensitive = (tries == 0);
248 for (const std::wstring &line : lines) {
249 auto pos = find(line, filter, caseSensitive);
250 if (pos == std::wstring::npos) {
251 continue;
252 }
253
254 cursed::ColorTree item;
255 decltype(pos) from = 0U;
256 while (pos != std::wstring::npos) {
257 item += line.substr(from, pos - from);
258 item += matchHi(line.substr(pos, filter.size()));
259
260 from = pos + filter.size();
261 pos = find(line, filter, caseSensitive, from);
262 }
263 item += line.substr(from);
264 filtered.emplace_back(std::move(item));
243 265 } }
244 266
245 cursed::ColorTree item;
246 decltype(pos) from = 0U;
247 while (pos != std::wstring::npos) {
248 item += line.substr(from, pos - from);
249 item += matchHi(line.substr(pos, filter.size()));
250
251 from = pos + filter.size();
252 pos = line.find(filter, from);
267 if (!filtered.empty()) {
268 break;
253 269 } }
254 item += line.substr(from);
255 filtered.emplace_back(std::move(item));
256 270 } }
257 271 filterList.setItems(filtered); filterList.setItems(filtered);
258 272 }; };
 
... ... PipeDial::buildNormalMode()
269 283 return normalMode; return normalMode;
270 284 } }
271 285
286 // A `std::string::find()`-like function that can do case-insensitive searches.
287 static std::wstring::size_type
288 find(const std::wstring &where, const std::wstring &what, bool caseSensitive,
289 std::wstring::size_type from)
290 {
291 if (caseSensitive) {
292 return where.find(what, from);
293 }
294
295 std::locale loc;
296 auto it = std::search(where.cbegin() + from, where.cend(),
297 what.cbegin(), what.cend(),
298 [&loc](wchar_t a, wchar_t b) {
299 return std::toupper(a, loc)
300 == std::toupper(b, loc);
301 });
302 if (it == where.cend()) {
303 return std::wstring::npos;
304 }
305 return it - where.cbegin();
306 }
307
272 308 vle::Mode vle::Mode
273 309 PipeDial::buildHelpMode() PipeDial::buildHelpMode()
274 310 { {
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/pipedial

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/pipedial

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master