Skip to content

Instantly share code, notes, and snippets.

@vivaxy vivaxy/alfred-search.js
Last active Aug 21, 2019

Embed
What would you like to do?
/**
* @since 2019-08-14 02:43
* @author vivaxy
*/
const path = require('path');
const alfy = require('alfy');
const glob = require('fast-glob');
const wds = process.env.wds.split(',');
async function updateProjectsCache() {
const projects = (await Promise.all(
wds.map(async function(wd) {
const names = await glob('*', { cwd: wd, onlyDirectories: true });
return {
wd,
names
};
})
)).reduce(function(all, wdProject) {
return [
...all,
...wdProject.names.map(function(name) {
return {
name,
wd: wdProject.wd
};
})
];
}, []);
alfy.cache.set('projects', JSON.stringify(projects));
}
function getProjects() {
const projectsCache = alfy.cache.get('projects');
if (projectsCache) {
return JSON.parse(projectsCache);
}
return [];
}
const searchStrategies = {
matchFromStart(value, input) {
function format(v) {
return v.toLowerCase().replace(/[^a-z0-9]/g, '');
}
return format(value).startsWith(format(input));
},
matchIncludes(value, input) {
function format(v) {
return v.toLowerCase().replace(/[^a-z0-9]/g, '');
}
return format(value).includes(format(input));
},
keywordIncludes(value, input) {
const keywords = input
.replace(/[^a-z0-9]/g, ' ')
.split(' ')
.filter(function(v) {
return !!v;
});
return keywords.every(keyword => {
return searchStrategies.matchIncludes(value, keyword);
});
}
};
updateProjectsCache();
const projects = getProjects();
const searchResultsByStrategy = [];
const searchStrategyNames = [
'matchFromStart',
'matchIncludes',
'keywordIncludes'
];
projects.forEach(function(project) {
searchStrategyNames.forEach(function(searchStrategyName, searchStrategyIndex) {
const searchStrategy = searchStrategies[searchStrategyName];
if (searchStrategy(project.name, alfy.input)) {
searchResultsByStrategy[searchStrategyIndex] = searchResultsByStrategy[searchStrategyIndex] || [];
searchResultsByStrategy[searchStrategyIndex].push(project);
}
});
});
const items = searchResultsByStrategy.reduce(function(all, searchResults) {
return [...all, ...searchResults];
}, []);
const output = items.map(function(project) {
const absolutePath = path.join(project.wd, project.name);
return {
title: project.name,
uid: absolutePath,
subtitle: absolutePath,
arg: absolutePath,
autocomplete: project.name,
type: 'file'
};
});
alfy.output(output);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.