-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.php
108 lines (91 loc) · 2.92 KB
/
search.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
include 'vendor/autoload.php';
use Alfred\Workflows\Workflow;
use Alfred\Workflows\ParamBuilder\Mod;
$workflow = new Workflow();
$workflow->logger()->info('PHP version: '.phpversion());
if (empty($workflow->env('SEARCH_PATHS'))) {
return;
}
// Expand ignored file setting into an array
$ignore = array_map(
'trim',
explode(',', $workflow->env('IGNORE_PATTERNS', '.,..,.DS_Store'))
);
// Normalize comma-separated setting value into a glob-friendly pattern
$searchPathString = buildSearchPathString(
$workflow->env('SEARCH_PATHS'),
$workflow->env('HOME'),
);
// Match directories
$matches = glob($searchPathString, GLOB_ONLYDIR | GLOB_BRACE);
$workflow->logger()->info('Search glob: '.$searchPathString);
// Build a keyed list of directory folder names and full paths
$list = [];
foreach ($matches as $match) {
$folder = basename($match);
if (!in_array($folder, $ignore, true)) {
$list[] = [
'folder' => $folder,
'path' => $match,
];
}
}
// Prepare Fuse to search folder names and be slightly picky about it
$fuse = new \Fuse\Fuse($list, [
'keys' => ['folder'],
'minMatchCharLength' => 1,
'threshold' => 0.3,
]);
$keyword = trim($workflow->argument() ?? '');
if (empty($keyword)) {
$results = [];
foreach ($fuse->getCollection() as $item) {
$results[] = [
'item' => $item,
];
}
} else {
// Rock and roll
$results = $fuse->search($keyword);
$workflow->logger()->info('Matching results: '.count($results));
}
foreach ($results as $result) {
$workflow->item()
->title($result['item']['folder'])
->subtitle($result['item']['path'])
->arg($result['item']['path'])
->iconForFilePath('/Applications/Visual Studio Code.app')
->mod(Mod::cmd()->iconForFilePath('/Applications/PhpStorm.app'))
->mod(Mod::shift()->iconForFilePath('/Applications/iTerm.app'))
->mod(Mod::ctrl()->iconForFilePath('/System/Library/CoreServices/Finder.app'));
}
$workflow->output();
/**
* Takes the comma-separated setting value of paths, cleans any leading
* or trailing space, expands relative home references (`~/`) into
* absolute paths, and joins them back together into a glob search string
* using braces (`{/path/one,/path/two}/*`).
*
* @param string $settingValue
* @param string $homePath
* @return string
*/
function buildSearchPathString(string $settingValue, string $homePath): string
{
$searchPaths = array_map(static function($path) use ($homePath) {
$path = trim($path);
if (str_starts_with($path, '~/')) {
// Expand `~/` to full path
$fullHomePath = $homePath.'/';
return substr_replace(
$path,
$fullHomePath,
0,
strlen('~/')
);
}
return $path;
}, explode(',', $settingValue));
return '{'.implode(',', $searchPaths).'}/*';
}