From 0ca138cba46408388ee46eab16f46cec25cac41a Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 29 Jul 2018 11:17:01 +0900 Subject: [PATCH 1/2] Select last tab on presenter --- src/background/presenters/tab.js | 25 +++++++++++++++++++++++++ src/background/usecases/operation.js | 18 +----------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/background/presenters/tab.js b/src/background/presenters/tab.js index 2a06a5a..6ad9736 100644 --- a/src/background/presenters/tab.js +++ b/src/background/presenters/tab.js @@ -1,3 +1,8 @@ +import MemoryStorage from '../infrastructures/memory-storage'; + +const CURRENT_SELECTED_KEY = 'tabs.current.selected'; +const LAST_SELECTED_KEY = 'tabs.last.selected'; + export default class TabPresenter { open(url, tabId) { return browser.tabs.update(tabId, { url }); @@ -18,6 +23,15 @@ export default class TabPresenter { return browser.tabs.query({ currentWindow: true }); } + async getLastSelectedId() { + let cache = new MemoryStorage(); + let tabId = await cache.get(LAST_SELECTED_KEY); + if (tabId === null || typeof tabId === 'undefined') { + return; + } + return tabId; + } + async getByKeyword(keyword, excludePinned = false) { let tabs = await browser.tabs.query({ currentWindow: true }); return tabs.filter((t) => { @@ -99,3 +113,14 @@ export default class TabPresenter { browser.tabs.onActivated.addListener(listener); } } + +let tabPresenter = new TabPresenter(); +tabPresenter.onSelected((tab) => { + let cache = new MemoryStorage(); + + let lastId = cache.get(CURRENT_SELECTED_KEY); + if (lastId) { + cache.set(LAST_SELECTED_KEY, lastId); + } + cache.set(CURRENT_SELECTED_KEY, tab.tabId); +}); diff --git a/src/background/usecases/operation.js b/src/background/usecases/operation.js index 7bf93e4..74ea830 100644 --- a/src/background/usecases/operation.js +++ b/src/background/usecases/operation.js @@ -1,10 +1,6 @@ -import MemoryStorage from '../infrastructures/memory-storage'; import TabPresenter from '../presenters/tab'; import ConsolePresenter from '../presenters/console'; -const CURRENT_SELECTED_KEY = 'tabs.current.selected'; -const LAST_SELECTED_KEY = 'tabs.last.selected'; - const ZOOM_SETTINGS = [ 0.33, 0.50, 0.66, 0.75, 0.80, 0.90, 1.00, 1.10, 1.25, 1.50, 1.75, 2.00, 2.50, 3.00 @@ -13,11 +9,7 @@ const ZOOM_SETTINGS = [ export default class OperationInteractor { constructor() { this.tabPresenter = new TabPresenter(); - this.tabPresenter.onSelected(info => this.onTabSelected(info.tabId)); - this.consolePresenter = new ConsolePresenter(); - - this.cache = new MemoryStorage(); } async close(force) { @@ -69,7 +61,7 @@ export default class OperationInteractor { } async selectPrevSelected() { - let tabId = await this.cache.get(LAST_SELECTED_KEY); + let tabId = await this.tabPresenter.getLastSelectedId(); if (tabId === null || typeof tabId === 'undefined') { return; } @@ -180,13 +172,5 @@ export default class OperationInteractor { let tab = await this.tabPresenter.getCurrent(); return this.consolePresenter.hide(tab.id); } - - onTabSelected(tabId) { - let lastId = this.cache.get(CURRENT_SELECTED_KEY); - if (lastId) { - this.cache.set(LAST_SELECTED_KEY, lastId); - } - this.cache.set(CURRENT_SELECTED_KEY, tabId); - } } From b3672f0ffd82148716b38d133f35a5f9d2706ba8 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sun, 29 Jul 2018 13:13:11 +0900 Subject: [PATCH 2/2] Add buffer flags on buffer command and completion --- src/background/presenters/tab.js | 12 ------- src/background/usecases/command.js | 18 +++++++++- src/background/usecases/completions.js | 46 ++++++++++++++++++++++++-- src/console/site.scss | 2 +- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/background/presenters/tab.js b/src/background/presenters/tab.js index 6ad9736..bacb644 100644 --- a/src/background/presenters/tab.js +++ b/src/background/presenters/tab.js @@ -46,18 +46,6 @@ export default class TabPresenter { return browser.tabs.update(tabId, { active: true }); } - async selectAt(index) { - let tabs = await browser.tabs.query({ currentWindow: true }); - if (tabs.length < 2) { - return; - } - if (index < 0 || tabs.length <= index) { - throw new RangeError(`tab ${index + 1} does not exist`); - } - let id = tabs[index].id; - return browser.tabs.update(id, { active: true }); - } - remove(ids) { return browser.tabs.remove(ids); } diff --git a/src/background/usecases/command.js b/src/background/usecases/command.js index 7fd2e57..f6ade43 100644 --- a/src/background/usecases/command.js +++ b/src/background/usecases/command.js @@ -34,13 +34,29 @@ export default class CommandIndicator { return this.windowPresenter.create(url); } + // eslint-disable-next-line max-statements async buffer(keywords) { if (keywords.length === 0) { return; } + if (!isNaN(keywords)) { + let tabs = await this.tabPresenter.getAll(); let index = parseInt(keywords, 10) - 1; - return tabs.selectAt(index); + if (index < 0 || tabs.length <= index) { + throw new RangeError(`tab ${index + 1} does not exist`); + } + return this.tabPresenter.select(tabs[index].id); + } else if (keywords.trim() === '%') { + // Select current window + return; + } else if (keywords.trim() === '#') { + // Select last selected window + let lastId = await this.tabPresenter.getLastSelectedId(); + if (typeof lastId === 'undefined' || lastId === null) { + throw new Error('No last selected tab'); + } + return this.tabPresenter.select(lastId); } let current = await this.tabPresenter.getCurrent(); diff --git a/src/background/usecases/completions.js b/src/background/usecases/completions.js index 2bf5b3b..af7aaf2 100644 --- a/src/background/usecases/completions.js +++ b/src/background/usecases/completions.js @@ -5,12 +5,14 @@ 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(); } @@ -50,8 +52,48 @@ export default class CompletionsInteractor { return new Completions(groups); } - queryBuffer(name, keywords) { - return this.queryTabs(name, false, keywords); + // 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) { diff --git a/src/console/site.scss b/src/console/site.scss index cb89e50..b9b1016 100644 --- a/src/console/site.scss +++ b/src/console/site.scss @@ -44,7 +44,7 @@ body { background-position: 0 center; background-size: contain; background-repeat: no-repeat; - white-space: nowrap; + white-space: pre; &.vimvixen-completion-selected { background-color: yellow;