File src/PipeDial.cpp changed (mode: 100644) (index a63c790..517ed1c) |
... |
... |
PipeDial::buildNormalMode() |
224 |
224 |
normalMode.addShortcut({ vle::Key(L'y').ctrl(), [&]() { |
normalMode.addShortcut({ vle::Key(L'y').ctrl(), [&]() { |
225 |
225 |
list.scrollUp(); |
list.scrollUp(); |
226 |
226 |
}, "scroll one line up" }); |
}, "scroll one line up" }); |
227 |
|
normalMode.addShortcut({ L"/", [&]() { |
|
228 |
|
cursed::List filterList; |
|
229 |
|
filterList.setItems({ lines.cbegin(), lines.cend() }); |
|
|
227 |
|
normalMode.addShortcut({ L"/", [this]() { filter(); }, |
|
228 |
|
"start interactive filtering" }); |
230 |
229 |
|
|
231 |
|
cursed::Prompt prompt; |
|
232 |
|
cursed::Track tmpTrack; |
|
233 |
|
tmpTrack.addItem(&title); |
|
234 |
|
tmpTrack.addItem(&filterList); |
|
235 |
|
tmpTrack.addItem(&prompt); |
|
|
230 |
|
return normalMode; |
|
231 |
|
} |
236 |
232 |
|
|
237 |
|
std::vector<cursed::ColorTree> filtered(lines.cbegin(), lines.cend()); |
|
238 |
|
auto update = [&](const std::wstring &filter) { |
|
239 |
|
if (filter.empty()) { |
|
240 |
|
filtered.assign(lines.cbegin(), lines.cend()); |
|
241 |
|
filterList.setItems(filtered); |
|
242 |
|
return; |
|
243 |
|
} |
|
|
233 |
|
void |
|
234 |
|
PipeDial::filter() |
|
235 |
|
{ |
|
236 |
|
cursed::List filterList; |
|
237 |
|
filterList.setItems({ lines.cbegin(), lines.cend() }); |
|
238 |
|
|
|
239 |
|
cursed::Prompt prompt; |
|
240 |
|
cursed::Track tmpTrack; |
|
241 |
|
tmpTrack.addItem(&title); |
|
242 |
|
tmpTrack.addItem(&filterList); |
|
243 |
|
tmpTrack.addItem(&prompt); |
|
244 |
|
|
|
245 |
|
std::vector<cursed::ColorTree> filtered(lines.cbegin(), lines.cend()); |
|
246 |
|
auto update = [&](const std::wstring &filter) { |
|
247 |
|
if (filter.empty()) { |
|
248 |
|
filtered.assign(lines.cbegin(), lines.cend()); |
|
249 |
|
filterList.setItems(filtered); |
|
250 |
|
return; |
|
251 |
|
} |
244 |
252 |
|
|
245 |
|
filtered.clear(); |
|
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)); |
|
|
253 |
|
filtered.clear(); |
|
254 |
|
for (int tries = 0; tries < 2; ++tries) { |
|
255 |
|
bool caseSensitive = (tries == 0); |
|
256 |
|
for (const std::wstring &line : lines) { |
|
257 |
|
auto pos = find(line, filter, caseSensitive); |
|
258 |
|
if (pos == std::wstring::npos) { |
|
259 |
|
continue; |
265 |
260 |
} |
} |
266 |
261 |
|
|
267 |
|
if (!filtered.empty()) { |
|
268 |
|
break; |
|
|
262 |
|
cursed::ColorTree item; |
|
263 |
|
decltype(pos) from = 0U; |
|
264 |
|
while (pos != std::wstring::npos) { |
|
265 |
|
item += line.substr(from, pos - from); |
|
266 |
|
item += matchHi(line.substr(pos, filter.size())); |
|
267 |
|
|
|
268 |
|
from = pos + filter.size(); |
|
269 |
|
pos = find(line, filter, caseSensitive, from); |
269 |
270 |
} |
} |
|
271 |
|
item += line.substr(from); |
|
272 |
|
filtered.emplace_back(std::move(item)); |
270 |
273 |
} |
} |
271 |
|
filterList.setItems(filtered); |
|
272 |
|
}; |
|
273 |
274 |
|
|
274 |
|
cursedrl::PromptRequest request(screen, prompt); |
|
275 |
|
request.setOnInputChanged(update); |
|
276 |
|
screen.replaceTopWidget(&tmpTrack); |
|
277 |
|
if (request.prompt(L"&/", L"")) { |
|
278 |
|
list.setItems(std::move(filtered)); |
|
|
275 |
|
if (!filtered.empty()) { |
|
276 |
|
break; |
|
277 |
|
} |
279 |
278 |
} |
} |
280 |
|
screen.replaceTopWidget(&track); |
|
281 |
|
}, "start interactive filtering" }); |
|
282 |
|
|
|
283 |
|
return normalMode; |
|
|
279 |
|
filterList.setItems(filtered); |
|
280 |
|
}; |
|
281 |
|
|
|
282 |
|
cursedrl::PromptRequest request(screen, prompt); |
|
283 |
|
request.setOnInputChanged(update); |
|
284 |
|
screen.replaceTopWidget(&tmpTrack); |
|
285 |
|
if (request.prompt(L"&/", L"")) { |
|
286 |
|
list.setItems(std::move(filtered)); |
|
287 |
|
} |
|
288 |
|
screen.replaceTopWidget(&track); |
284 |
289 |
} |
} |
285 |
290 |
|
|
286 |
291 |
// A `std::string::find()`-like function that can do case-insensitive searches. |
// A `std::string::find()`-like function that can do case-insensitive searches. |