commit
c6c885345e
5 changed files with 104 additions and 19 deletions
10
README.md
10
README.md
|
@ -85,10 +85,18 @@ To adjust the search engine default and add/remove search engines, see the [sear
|
|||
|
||||
Open a URL or search keywords by search engine in new tab.
|
||||
|
||||
#### `:q` command
|
||||
#### `:quit` command
|
||||
|
||||
Close the current tab.
|
||||
|
||||
#### `:bdelete` command
|
||||
|
||||
Close a certain tab.
|
||||
|
||||
#### `:bdeletes` command
|
||||
|
||||
Close tabs matches with keywords.
|
||||
|
||||
#### `:winopen` command
|
||||
|
||||
Open a URL or search keywords by search engine in new window.
|
||||
|
|
|
@ -68,6 +68,7 @@ const setCommand = (args) => {
|
|||
};
|
||||
};
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
const exec = (tab, line, settings) => {
|
||||
let [name, args] = parsers.parseCommandLine(line);
|
||||
|
||||
|
@ -84,6 +85,18 @@ const exec = (tab, line, settings) => {
|
|||
case 'b':
|
||||
case 'buffer':
|
||||
return bufferCommand(args);
|
||||
case 'bd':
|
||||
case 'bdel':
|
||||
case 'bdelete':
|
||||
return tabs.closeTabByKeywords(args.join(' '));
|
||||
case 'bd!':
|
||||
case 'bdel!':
|
||||
case 'bdelete!':
|
||||
return tabs.closeTabByKeywordsForce(args.join(' '));
|
||||
case 'bdeletes':
|
||||
return tabs.closeTabsByKeywords(args.join(' '));
|
||||
case 'bdeletes!':
|
||||
return tabs.closeTabsByKeywordsForce(args.join(' '));
|
||||
case 'addbookmark':
|
||||
return addBookmarkCommand(tab, args).then((item) => {
|
||||
if (!item) {
|
||||
|
|
|
@ -65,6 +65,25 @@ const getOpenCompletions = (command, keywords, searchConfig) => {
|
|||
});
|
||||
};
|
||||
|
||||
const getBufferCompletions = (command, keywords, excludePinned) => {
|
||||
return tabs.getCompletions(keywords, excludePinned).then((got) => {
|
||||
let items = got.map((tab) => {
|
||||
return {
|
||||
caption: tab.title,
|
||||
content: command + ' ' + tab.title,
|
||||
url: tab.url,
|
||||
icon: tab.favIconUrl
|
||||
};
|
||||
});
|
||||
return [
|
||||
{
|
||||
name: 'Buffers',
|
||||
items: items
|
||||
}
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
const getCompletions = (line, settings) => {
|
||||
let typedWords = line.trim().split(/ +/);
|
||||
let typing = '';
|
||||
|
@ -88,22 +107,17 @@ const getCompletions = (line, settings) => {
|
|||
return getOpenCompletions(name, keywords, settings.search);
|
||||
case 'b':
|
||||
case 'buffer':
|
||||
return tabs.getCompletions(keywords).then((gotTabs) => {
|
||||
let items = gotTabs.map((tab) => {
|
||||
return {
|
||||
caption: tab.title,
|
||||
content: name + ' ' + tab.title,
|
||||
url: tab.url,
|
||||
icon: tab.favIconUrl
|
||||
};
|
||||
});
|
||||
return [
|
||||
{
|
||||
name: 'Buffers',
|
||||
items: items
|
||||
}
|
||||
];
|
||||
});
|
||||
return getBufferCompletions(name, keywords, false);
|
||||
case 'bd!':
|
||||
case 'bdel!':
|
||||
case 'bdelete!':
|
||||
case 'bdeletes!':
|
||||
return getBufferCompletions(name, keywords, false);
|
||||
case 'bd':
|
||||
case 'bdel':
|
||||
case 'bdelete':
|
||||
case 'bdeletes':
|
||||
return getBufferCompletions(name, keywords, true);
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const getCompletions = (keyword) => {
|
||||
const getCompletions = (keyword, excludePinned) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title && t.title.includes(keyword);
|
||||
}).filter((t) => {
|
||||
return !(excludePinned && t.pinned);
|
||||
});
|
||||
return matched;
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import * as tabCompletions from './completions/tabs';
|
||||
|
||||
const closeTab = (id) => {
|
||||
return browser.tabs.get(id).then((tab) => {
|
||||
if (!tab.pinned) {
|
||||
|
@ -10,6 +12,50 @@ const closeTabForce = (id) => {
|
|||
return browser.tabs.remove(id);
|
||||
};
|
||||
|
||||
const closeTabByKeywords = (keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title.includes(keyword);
|
||||
}).filter(t => !t.pinned);
|
||||
|
||||
if (matched.length === 0) {
|
||||
throw new Error('No matching buffer for ' + keyword);
|
||||
} else if (matched.length > 1) {
|
||||
throw new Error('More than one match for ' + keyword);
|
||||
}
|
||||
browser.tabs.remove(matched[0].id);
|
||||
});
|
||||
};
|
||||
|
||||
const closeTabByKeywordsForce = (keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title.includes(keyword);
|
||||
});
|
||||
|
||||
if (matched.length === 0) {
|
||||
throw new Error('No matching buffer for ' + keyword);
|
||||
} else if (matched.length > 1) {
|
||||
throw new Error('More than one match for ' + keyword);
|
||||
}
|
||||
browser.tabs.remove(matched[0].id);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const closeTabsByKeywords = (keyword) => {
|
||||
tabCompletions.getCompletions(keyword).then((tabs) => {
|
||||
let tabs2 = tabs.filter(tab => !tab.pinned);
|
||||
browser.tabs.remove(tabs2.map(tab => tab.id));
|
||||
});
|
||||
};
|
||||
|
||||
const closeTabsByKeywordsForce = (keyword) => {
|
||||
tabCompletions.getCompletions(keyword).then((tabs) => {
|
||||
browser.tabs.remove(tabs.map(tab => tab.id));
|
||||
});
|
||||
};
|
||||
|
||||
const reopenTab = () => {
|
||||
return browser.sessions.getRecentlyClosed({
|
||||
maxResults: 1
|
||||
|
@ -119,7 +165,9 @@ const duplicate = (id) => {
|
|||
};
|
||||
|
||||
export {
|
||||
closeTab, closeTabForce, reopenTab, selectAt, selectByKeyword,
|
||||
closeTab, closeTabForce, closeTabByKeywords, closeTabByKeywordsForce,
|
||||
closeTabsByKeywords, closeTabsByKeywordsForce,
|
||||
reopenTab, selectAt, selectByKeyword,
|
||||
selectPrevTab, selectNextTab, selectFirstTab,
|
||||
selectLastTab, selectTab, reload, updateTabPinned,
|
||||
toggleTabPinned, duplicate
|
||||
|
|
Reference in a new issue