Skip to content

Commit dfa8722

Browse files
committed
finders/fs: add filesystem finder
1 parent 6d3d687 commit dfa8722

9 files changed

Lines changed: 170 additions & 13 deletions

File tree

src/config/ConfigManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ CConfigManager::CConfigManager() : m_inotifyFd(inotify_init()) {
2121
m_config->addConfigValue("finders:unicode_prefix", Hyprlang::STRING{"."});
2222
m_config->addConfigValue("finders:math_prefix", Hyprlang::STRING{"="});
2323
m_config->addConfigValue("finders:font_prefix", Hyprlang::STRING{"'"});
24+
m_config->addConfigValue("finders:fs_prefix", Hyprlang::STRING{"/"});
2425

2526
m_config->addConfigValue("finders:desktop_launch_prefix", Hyprlang::STRING{""});
2627
m_config->addConfigValue("finders:desktop_icons", Hyprlang::INT{1});

src/finders/FinderTypes.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ enum eFinderTypes : uint8_t {
88
FINDER_MATH = 2,
99
FINDER_IPC = 3,
1010
FINDER_FONT = 4,
11+
FINDER_FS = 5,
1112
};

src/finders/Fuzzy.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ static float tokenBestMatch(std::string_view qt, std::string_view lastQ, const s
8787
return (best - MIN_FUZZY_TO_COUNT) / (1.F - MIN_FUZZY_TO_COUNT);
8888
}
8989

90-
static float scoreCandidate(std::string_view query, std::string_view cand, float freq) {
91-
CVarList2 qTokens(std::string{query}, 0, 's', true, false);
92-
CVarList2 cTokens(std::string{cand}, 0, 's', true, false);
90+
static float scoreCandidate(std::string_view query, std::string_view cand, float freq, char tokenBreak) {
91+
CVarList2 qTokens(std::string{query}, 0, tokenBreak == ' ' ? 's' : tokenBreak, true, false);
92+
CVarList2 cTokens(std::string{cand}, 0, tokenBreak == ' ' ? 's' : tokenBreak, true, false);
9393

9494
std::vector<std::string_view> qTok, cTok;
9595
qTok.reserve(qTokens.size());
@@ -145,11 +145,11 @@ struct SScoreData {
145145
size_t idx = 0;
146146
};
147147

148-
static void workerFn(std::vector<SScoreData>& scores, const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t start, size_t end) {
148+
static void workerFn(std::vector<SScoreData>& scores, const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t start, size_t end, char tokenBreak) {
149149
for (size_t i = start; i < end; ++i) {
150150
auto& ref = scores[i];
151151

152-
ref.score = scoreCandidate(query, in[i]->fuzzable(), in[i]->frequency());
152+
ref.score = scoreCandidate(query, in[i]->fuzzable(), in[i]->frequency(), tokenBreak);
153153

154154
ref.result = in[i];
155155
ref.idx = i;
@@ -185,7 +185,7 @@ static std::vector<SP<IFinderResult>> getBestResultsStable(std::vector<SScoreDat
185185
static constexpr const decltype(sysconf(0)) MAX_THREADS = 10;
186186

187187
//
188-
std::vector<SP<IFinderResult>> Fuzzy::getNResults(const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t results) {
188+
std::vector<SP<IFinderResult>> Fuzzy::getNResults(const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t results, char tokenBreak) {
189189
std::vector<SScoreData> scores;
190190
scores.resize(in.size());
191191

@@ -203,10 +203,10 @@ std::vector<SP<IFinderResult>> Fuzzy::getNResults(const std::vector<SP<IFinderRe
203203
size_t workElDone = 0, workElPerThread = in.size() / THREADS;
204204
for (long i = 0; i < THREADS; ++i) {
205205
if (i == THREADS - 1) {
206-
workerThreads[i] = std::thread([&, begin = workElDone] { workerFn(scores, in, query, begin, in.size()); });
206+
workerThreads[i] = std::thread([&, begin = workElDone] { workerFn(scores, in, query, begin, in.size(), tokenBreak); });
207207
break;
208208
}
209-
workerThreads[i] = std::thread([&, begin = workElDone, end = workElDone + workElPerThread] { workerFn(scores, in, query, begin, end); });
209+
workerThreads[i] = std::thread([&, begin = workElDone, end = workElDone + workElPerThread] { workerFn(scores, in, query, begin, end, tokenBreak); });
210210

211211
workElDone += workElPerThread;
212212
}
@@ -218,7 +218,7 @@ std::vector<SP<IFinderResult>> Fuzzy::getNResults(const std::vector<SP<IFinderRe
218218

219219
workerThreads.clear();
220220
} else
221-
workerFn(scores, in, query, 0, in.size());
221+
workerFn(scores, in, query, 0, in.size(), tokenBreak);
222222

223223
return getBestResultsStable(scores, results);
224224
}

src/finders/Fuzzy.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
#include "../helpers/Memory.hpp"
88

99
namespace Fuzzy {
10-
std::vector<SP<IFinderResult>> getNResults(const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t results);
10+
std::vector<SP<IFinderResult>> getNResults(const std::vector<SP<IFinderResult>>& in, const std::string& query, size_t results, char tokenBreak = ' ');
1111
};

src/finders/desktop/DesktopFinder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,9 @@ std::vector<SFinderResult> CDesktopFinder::getResultsForQuery(const std::string&
280280
if (!p)
281281
continue;
282282
results.emplace_back(SFinderResult{
283-
.label = p->m_name,
284-
.icon = *PICONSENABLED ? p->m_icon : "",
285-
.result = p,
283+
.label = p->m_name,
284+
.icon = *PICONSENABLED ? p->m_icon : "",
285+
.result = p,
286286
.hasIcon = true,
287287
});
288288
}

src/finders/fs/FsFinder.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include "FsFinder.hpp"
2+
3+
#include "../Fuzzy.hpp"
4+
5+
#include <hyprutils/string/String.hpp>
6+
#include <hyprutils/os/Process.hpp>
7+
#include <hyprutils/string/ConstVarList.hpp>
8+
9+
#include <unordered_set>
10+
#include <algorithm>
11+
12+
using namespace Hyprutils::String;
13+
using namespace Hyprutils::OS;
14+
15+
class CFsEntry : public IFinderResult {
16+
public:
17+
CFsEntry() = default;
18+
virtual ~CFsEntry() = default;
19+
20+
virtual const std::string& fuzzable() {
21+
return m_fuzzable;
22+
}
23+
24+
virtual eFinderTypes type() {
25+
return FINDER_FS;
26+
}
27+
28+
virtual uint32_t frequency() {
29+
return m_frequency;
30+
}
31+
32+
virtual const std::string& name() {
33+
return m_name;
34+
}
35+
36+
virtual void run() {
37+
CProcess proc("xdg-open", {m_name});
38+
proc.runAsync();
39+
}
40+
41+
std::string m_name, m_fuzzable;
42+
43+
uint32_t m_frequency = 0;
44+
};
45+
46+
CFsFinder::CFsFinder() = default;
47+
48+
void CFsFinder::cacheEntry(const std::filesystem::path& path) {
49+
auto x = m_fsEntryCache.emplace_back(makeShared<CFsEntry>());
50+
x->m_name = path.string();
51+
x->m_fuzzable = x->m_name;
52+
std::ranges::transform(x->m_fuzzable, x->m_fuzzable.begin(), ::tolower);
53+
m_fsEntryCacheGeneric.emplace_back(std::move(x));
54+
}
55+
56+
void CFsFinder::init() {
57+
// walk the fs from a config'd path
58+
// FIXME: config!!!
59+
const auto BASE_PATH = getenv("HOME");
60+
std::unordered_set<std::filesystem::path> visitedDirs;
61+
62+
//
63+
std::function<void(const std::filesystem::path&)> walk = [&](const std::filesystem::path& p) -> void {
64+
if (visitedDirs.contains(p))
65+
return;
66+
67+
std::error_code ec;
68+
const auto CAN = std::filesystem::canonical(p, ec);
69+
70+
if (ec)
71+
return;
72+
73+
// cache dir
74+
visitedDirs.emplace(CAN);
75+
cacheEntry(CAN);
76+
77+
for (const auto& e : std::filesystem::directory_iterator(CAN, ec)) {
78+
if (ec)
79+
break;
80+
81+
if (e.is_regular_file()) {
82+
// cache file and continue
83+
cacheEntry(e);
84+
continue;
85+
}
86+
87+
if (e.is_directory()) {
88+
// enter directory
89+
walk(e);
90+
continue;
91+
}
92+
93+
// invalid... thing?
94+
}
95+
};
96+
97+
walk(BASE_PATH);
98+
}
99+
100+
std::vector<SFinderResult> CFsFinder::getResultsForQuery(const std::string& query) {
101+
std::vector<SFinderResult> results;
102+
103+
auto fuzzed = Fuzzy::getNResults(m_fsEntryCacheGeneric, query, MAX_RESULTS_PER_FINDER, '/');
104+
105+
results.reserve(fuzzed.size());
106+
107+
for (const auto& f : fuzzed) {
108+
const auto p = reinterpretPointerCast<CFsEntry>(f);
109+
if (!p)
110+
continue;
111+
results.emplace_back(SFinderResult{
112+
.label = p->m_name,
113+
.icon = "",
114+
.result = p,
115+
.hasIcon = false,
116+
});
117+
}
118+
119+
return results;
120+
}

src/finders/fs/FsFinder.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include "../IFinder.hpp"
4+
5+
#include <filesystem>
6+
7+
class CFsEntry;
8+
9+
class CFsFinder : public IFinder {
10+
public:
11+
CFsFinder();
12+
virtual ~CFsFinder() = default;
13+
14+
virtual std::vector<SFinderResult> getResultsForQuery(const std::string& query);
15+
virtual void init();
16+
17+
private:
18+
std::vector<SP<CFsEntry>> m_fsEntryCache;
19+
std::vector<SP<IFinderResult>> m_fsEntryCacheGeneric;
20+
21+
void cacheEntry(const std::filesystem::path& path);
22+
23+
friend class CFsEntry;
24+
};
25+
26+
inline UP<CFsFinder> g_fsFinder;

src/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "finders/math/MathFinder.hpp"
66
#include "finders/ipc/IPCFinder.hpp"
77
#include "finders/font/FontFinder.hpp"
8+
#include "finders/fs/FsFinder.hpp"
89
#include "socket/ClientSocket.hpp"
910
#include "socket/ServerSocket.hpp"
1011
#include "query/QueryProcessor.hpp"
@@ -107,12 +108,14 @@ int main(int argc, char** argv, char** envp) {
107108
g_mathFinder = makeUnique<CMathFinder>();
108109
g_ipcFinder = makeUnique<CIPCFinder>();
109110
g_fontFinder = makeUnique<CFontFinder>();
111+
g_fsFinder = makeUnique<CFsFinder>();
110112

111113
g_desktopFinder->init();
112114
g_unicodeFinder->init();
113115
g_mathFinder->init();
114116
g_ipcFinder->init();
115117
g_fontFinder->init();
118+
g_fsFinder->init();
116119

117120
socket.reset();
118121

src/query/QueryProcessor.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "../finders/unicode/UnicodeFinder.hpp"
77
#include "../finders/math/MathFinder.hpp"
88
#include "../finders/font/FontFinder.hpp"
9+
#include "../finders/fs/FsFinder.hpp"
910

1011
#include <hyprutils/utils/ScopeGuard.hpp>
1112

@@ -18,6 +19,8 @@ static WP<IFinder> finderForName(const std::string& x) {
1819
return g_unicodeFinder;
1920
if (x == "math")
2021
return g_mathFinder;
22+
if (x == "fs")
23+
return g_fsFinder;
2124
return WP<IFinder>{};
2225
}
2326

@@ -28,6 +31,7 @@ static std::pair<WP<IFinder>, bool> finderForPrefix(const char x) {
2831
static auto PUNICODEPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:unicode_prefix");
2932
static auto PMATHPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:math_prefix");
3033
static auto PFONTPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:font_prefix");
34+
static auto PFSPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:fs_prefix");
3135

3236
if (x == (*PDESKTOPPREFIX)[0])
3337
return {g_desktopFinder, true};
@@ -37,6 +41,8 @@ static std::pair<WP<IFinder>, bool> finderForPrefix(const char x) {
3741
return {g_mathFinder, true};
3842
if (x == (*PFONTPREFIX)[0])
3943
return {g_fontFinder, true};
44+
if (x == (*PFSPREFIX)[0])
45+
return {g_fsFinder, true};
4046
return {finderForName(*PDEFAULTFINDER), false};
4147
}
4248

0 commit comments

Comments
 (0)