import CompletionItem from '../domains/completion-item'; import CompletionGroup from '../domains/completion-group'; import Completions from '../domains/completions'; import CommandDocs from '../domains/command-docs'; import CompletionRepository from '../repositories/completions'; import * as filters from './filters'; import SettingRepository from '../repositories/setting'; import TabPresenter from '../presenters/tab'; import * as properties from '../../shared/settings/properties'; const COMPLETION_ITEM_LIMIT = 10; export default class CompletionsInteractor { constructor() { this.tabPresenter = new TabPresenter(); this.completionRepository = new CompletionRepository(); this.settingRepository = new SettingRepository(); } queryConsoleCommand(prefix) { let keys = Object.keys(CommandDocs); let items = keys .filter(name => name.startsWith(prefix)) .map(name => ({ caption: name, content: name, url: CommandDocs[name], })); if (items.length === 0) { return Promise.resolve(Completions.empty()); } return Promise.resolve( new Completions([new CompletionGroup('Console Command', items)]) ); } async queryOpen(name, keywords) { let settings = await this.settingRepository.get(); let groups = []; let complete = settings.properties.complete || properties.defaults.complete; for (let c of complete) { if (c === 's') { // eslint-disable-next-line no-await-in-loop let engines = await this.querySearchEngineItems(name, keywords); if (engines.length > 0) { groups.push(new CompletionGroup('Search Engines', engines)); } } else if (c === 'h') { // eslint-disable-next-line no-await-in-loop let histories = await this.queryHistoryItems(name, keywords); if (histories.length > 0) { groups.push(new CompletionGroup('History', histories)); } } else if (c === 'b') { // eslint-disable-next-line no-await-in-loop let bookmarks = await this.queryBookmarkItems(name, keywords); if (bookmarks.length > 0) { groups.push(new CompletionGroup('Bookmarks', bookmarks)); } } } return new Completions(groups); } // eslint-disable-next-line max-statements async queryBuffer(name, keywords) { let lastId = await this.tabPresenter.getLastSelectedId(); let trimmed = keywords.trim(); let tabs = []; if (trimmed.length > 0 && !isNaN(trimmed)) { let all = await this.tabPresenter.getAll(); let index = parseInt(trimmed, 10) - 1; if (index >= 0 && index < all.length) { tabs = [all[index]]; } } else if (trimmed === '%') { let all = await this.tabPresenter.getAll(); let tab = all.find(t => t.active); tabs = [tab]; } else if (trimmed === '#') { if (typeof lastId !== 'undefined' && lastId !== null) { let all = await this.tabPresenter.getAll(); let tab = all.find(t => t.id === lastId); tabs = [tab]; } } else { tabs = await this.completionRepository.queryTabs(keywords, false); } const flag = (tab) => { if (tab.active) { return '%'; } else if (tab.id === lastId) { return '#'; } return ' '; }; let items = tabs.map(tab => new CompletionItem({ caption: tab.index + 1 + ': ' + flag(tab) + ' ' + tab.title, content: name + ' ' + tab.title, url: tab.url, icon: tab.favIconUrl })); if (items.length === 0) { return Promise.resolve(Completions.empty()); } return new Completions([new CompletionGroup('Buffers', items)]); } queryBdelete(name, keywords) { return this.queryTabs(name, true, keywords); } queryBdeleteForce(name, keywords) { return this.queryTabs(name, false, keywords); } querySet(name, keywords) { let items = Object.keys(properties.docs).map((key) => { if (properties.types[key] === 'boolean') { return [ new CompletionItem({ caption: key, content: name + ' ' + key, url: 'Enable ' + properties.docs[key], }), new CompletionItem({ caption: 'no' + key, content: name + ' no' + key, url: 'Disable ' + properties.docs[key], }), ]; } return [ new CompletionItem({ caption: key, content: name + ' ' + key, url: 'Set ' + properties.docs[key], }) ]; }); items = items.reduce((acc, val) => acc.concat(val), []); items = items.filter((item) => { return item.caption.startsWith(keywords); }); if (items.length === 0) { return Promise.resolve(Completions.empty()); } return Promise.resolve( new Completions([new CompletionGroup('Properties', items)]) ); } async queryTabs(name, excludePinned, args) { let tabs = await this.completionRepository.queryTabs(args, excludePinned); let items = tabs.map(tab => new CompletionItem({ caption: tab.title, content: name + ' ' + tab.title, url: tab.url, icon: tab.favIconUrl })); if (items.length === 0) { return Promise.resolve(Completions.empty()); } return new Completions([new CompletionGroup('Buffers', items)]); } async querySearchEngineItems(name, keywords) { let settings = await this.settingRepository.get(); let engines = Object.keys(settings.search.engines) .filter(key => key.startsWith(keywords)); return engines.map(key => new CompletionItem({ caption: key, content: name + ' ' + key, })); } async queryHistoryItems(name, keywords) { let histories = await this.completionRepository.queryHistories(keywords); histories = [histories] .map(filters.filterBlankTitle) .map(filters.filterHttp) .map(filters.filterByTailingSlash) .map(pages => filters.filterByPathname(pages, COMPLETION_ITEM_LIMIT)) .map(pages => filters.filterByOrigin(pages, COMPLETION_ITEM_LIMIT))[0] .sort((x, y) => x.visitCount < y.visitCount) .slice(0, COMPLETION_ITEM_LIMIT); return histories.map(page => new CompletionItem({ caption: page.title, content: name + ' ' + page.url, url: page.url })); } async queryBookmarkItems(name, keywords) { let bookmarks = await this.completionRepository.queryBookmarks(keywords); return bookmarks.slice(0, COMPLETION_ITEM_LIMIT) .map(page => new CompletionItem({ caption: page.title, content: name + ' ' + page.url, url: page.url })); } }