mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-10-26 11:08:40 +03:00
feat: Filter ignored files if query begins with !
This commit is contained in:
parent
3ed35741b0
commit
980aae5cbb
@ -12,6 +12,7 @@ When opening a file, you can control the behavior.
|
||||
* <kbd>shift-enter</kbd> defaults to switching to another pane if the file is already open there
|
||||
* <kbd>cmd-k</kbd> <kbd>right</kbd> *(macOS)* or <kbd>ctrl-k</kbd> <kbd>right</kbd> *(Linux/Windows)* (or any other directional arrow) will open the highlighted file in a new pane on the side indicated by the arrow
|
||||
* Adding `:<line number>` to the end of your search will go directly to the line number you specify, or the last line if the number is larger
|
||||
* Beginning your search with `!` will search for VCS ignored files (only if using ripgrep indexing)
|
||||
|
||||
Turning on the "Search All Panes" setting reverses the behavior of <kbd>enter</kbd> and <kbd>shift-enter</kbd> so <kbd>enter</kbd> opens the file in any pane and <kbd>shift-enter</kbd> creates a new tab in the current pane.
|
||||
|
||||
|
@ -12,7 +12,9 @@ const MAX_RESULTS = 10
|
||||
module.exports = class FuzzyFinderView {
|
||||
constructor () {
|
||||
this.previousQueryWasLineJump = false
|
||||
this.previousQueryOverrodeIgnore = false
|
||||
this.items = []
|
||||
this.ignoredItems = []
|
||||
this.filterFn = this.filterFn.bind(this)
|
||||
|
||||
this.selectListView = new SelectListView({
|
||||
@ -25,6 +27,11 @@ module.exports = class FuzzyFinderView {
|
||||
if (colon !== -1) {
|
||||
query = query.slice(0, colon)
|
||||
}
|
||||
|
||||
if (query.indexOf('!') === 0 ) {
|
||||
query = query.slice(1)
|
||||
}
|
||||
|
||||
// Normalize to backslashes on Windows
|
||||
if (process.platform === 'win32') {
|
||||
query = query.replace(/\//g, '\\')
|
||||
@ -45,7 +52,11 @@ module.exports = class FuzzyFinderView {
|
||||
this.iconDisposables = null
|
||||
}
|
||||
const isLineJump = this.isQueryALineJump()
|
||||
const overridesIgnore = this.queryOverridesIgnore()
|
||||
|
||||
// if last query was not line jump and this one is, clear the list of items
|
||||
if (isLineJump) {
|
||||
|
||||
this.previousQueryWasLineJump = true
|
||||
const query = this.selectListView.getQuery()
|
||||
let emptyMessage = null
|
||||
@ -65,8 +76,24 @@ module.exports = class FuzzyFinderView {
|
||||
emptyMessage: emptyMessage,
|
||||
errorMessage: errorMessage
|
||||
})
|
||||
} else if (this.previousQueryWasLineJump) {
|
||||
|
||||
// if last query did not override ignored paths and this one does,
|
||||
// set the filter items to the ignored paths
|
||||
} else if (!this.previousQueryOverrodeIgnore && overridesIgnore) {
|
||||
this.previousQueryOverrodeIgnore = true
|
||||
this.selectListView.update({
|
||||
items: this.ignoredItems,
|
||||
emptyMessage: this.getEmptyMessage(),
|
||||
errorMessage: null
|
||||
})
|
||||
|
||||
// if last query was line jump and this one is not,
|
||||
// OR if last query overrode ignored paths and this one doesn't
|
||||
// reset the filter items to the regular items
|
||||
} else if ((this.previousQueryWasLineJump && !isLineJump) ||
|
||||
(this.previousQueryOverrodeIgnore && !overridesIgnore)) {
|
||||
this.previousQueryWasLineJump = false
|
||||
this.previousQueryOverrodeIgnore = false
|
||||
this.selectListView.update({
|
||||
items: this.items,
|
||||
emptyMessage: this.getEmptyMessage(),
|
||||
@ -124,10 +151,13 @@ module.exports = class FuzzyFinderView {
|
||||
}
|
||||
})
|
||||
|
||||
if (!this.nativeFuzzy) {
|
||||
this.nativeFuzzy = atom.ui.fuzzyMatcher.setCandidates(
|
||||
if (!this.nativeFuzzyTracked) {
|
||||
this.nativeFuzzyTracked = atom.ui.fuzzyMatcher.setCandidates(
|
||||
this.items.map(el => el.label)
|
||||
);
|
||||
this.nativeFuzzyIgnored = atom.ui.fuzzyMatcher.setCandidates(
|
||||
this.ignoredItems.map(el => el.label)
|
||||
)
|
||||
// We need a separate instance of the fuzzy finder to calculate the
|
||||
// matched paths only for the returned results. This speeds up considerably
|
||||
// the filtering of items.
|
||||
@ -268,6 +298,10 @@ module.exports = class FuzzyFinderView {
|
||||
)
|
||||
}
|
||||
|
||||
queryOverridesIgnore () {
|
||||
return this.selectListView.getQuery().indexOf('!') === 0
|
||||
}
|
||||
|
||||
getCaretPosition () {
|
||||
const query = this.selectListView.getQuery()
|
||||
const firstColon = query.indexOf(':')
|
||||
@ -287,12 +321,18 @@ module.exports = class FuzzyFinderView {
|
||||
return position
|
||||
}
|
||||
|
||||
setItems (items) {
|
||||
setItems (items, ignoredItems = []) {
|
||||
this.items = items
|
||||
this.ignoredItems = ignoredItems
|
||||
|
||||
atom.ui.fuzzyMatcher.setCandidates(
|
||||
this.nativeFuzzy,
|
||||
this.nativeFuzzyTracked,
|
||||
this.items.map(item => item.label)
|
||||
);
|
||||
atom.ui.fuzzyMatcher.setCandidates(
|
||||
this.nativeFuzzyIgnored,
|
||||
this.ignoredItems.map(item => item.label)
|
||||
);
|
||||
|
||||
if (this.isQueryALineJump()) {
|
||||
this.selectListView.update({
|
||||
@ -303,7 +343,9 @@ module.exports = class FuzzyFinderView {
|
||||
})
|
||||
} else {
|
||||
this.selectListView.update({
|
||||
items: this.items,
|
||||
items: this.queryOverridesIgnore()
|
||||
? this.ignoredItems
|
||||
: this.items,
|
||||
infoMessage: null,
|
||||
loadingMessage: null,
|
||||
loadingBadge: null
|
||||
@ -337,7 +379,15 @@ module.exports = class FuzzyFinderView {
|
||||
|
||||
filterFn(items, query) {
|
||||
if (!query) return items
|
||||
return this.nativeFuzzy.match(query, {maxResults: MAX_RESULTS, algorithm: 'command-t'})
|
||||
|
||||
if (this.queryOverridesIgnore()) {
|
||||
return this.nativeFuzzyIgnored
|
||||
.match(query, {maxResults: MAX_RESULTS, algorithm: 'command-t'})
|
||||
.map(({id}) => this.ignoredItems[id])
|
||||
}
|
||||
|
||||
return this.nativeFuzzyTracked
|
||||
.match(query, {maxResults: MAX_RESULTS, algorithm: 'command-t'})
|
||||
.map(({id}) => this.items[id])
|
||||
}
|
||||
}
|
||||
|
@ -1644,7 +1644,7 @@ describe('FuzzyFinder', () => {
|
||||
})
|
||||
|
||||
if (useRipGrep) {
|
||||
it('does excludes paths that are git ignored', async () => {
|
||||
it('excludes paths that are git ignored', async () => {
|
||||
fs.writeFileSync(path.join(projectPath, 'dir', 'a.txt'), 'something')
|
||||
|
||||
await projectView.toggle()
|
||||
@ -1693,6 +1693,81 @@ describe('FuzzyFinder', () => {
|
||||
a.textContent.includes('HEAD'))).not.toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the query starts with an exclamation point', () => {
|
||||
beforeEach(() => {
|
||||
const ignoreFile = path.join(projectPath, '.gitignore')
|
||||
fs.writeFileSync(ignoreFile, "ignored.txt\nanother.txt")
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(projectPath, 'ignored.txt'),
|
||||
'this text is not important'
|
||||
)
|
||||
fs.writeFileSync(
|
||||
path.join(projectPath, 'another.txt'),
|
||||
'this text is not important'
|
||||
)
|
||||
})
|
||||
|
||||
it('excludes paths that are tracked when indexIgnoredPaths is true', async () => {
|
||||
atom.config.set('fuzzy-finder.indexIgnoredPaths', true)
|
||||
projectView.selectListView.refs.queryEditor.insertText('!')
|
||||
|
||||
await projectView.toggle()
|
||||
await waitForPathsToDisplay(projectView)
|
||||
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('a.txt'))
|
||||
).not.toBeDefined()
|
||||
})
|
||||
|
||||
it('includes paths that are git ignored when indexIgnoredPaths is true', async () => {
|
||||
atom.config.set('fuzzy-finder.indexIgnoredPaths', true)
|
||||
projectView.selectListView.refs.queryEditor.insertText('!')
|
||||
|
||||
await projectView.toggle()
|
||||
await waitForPathsToDisplay(projectView)
|
||||
|
||||
expect(projectView.queryOverridesIgnore()).toBe(true)
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('ignored.txt'))
|
||||
).toBeDefined()
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('another.txt'))
|
||||
).toBeDefined()
|
||||
})
|
||||
|
||||
it('matches paths that are git ignored when indexIgnoredPaths is true', async () => {
|
||||
atom.config.set('fuzzy-finder.indexIgnoredPaths', true)
|
||||
projectView.selectListView.refs.queryEditor.insertText('!anoth')
|
||||
|
||||
await projectView.toggle()
|
||||
await waitForPathsToDisplay(projectView)
|
||||
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('ignored.txt'))
|
||||
).not.toBeDefined()
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('another.txt'))
|
||||
).toBeDefined()
|
||||
})
|
||||
|
||||
it('excludes paths that are git ignored when indexIgnoredPaths is false', async () => {
|
||||
atom.config.set('fuzzy-finder.indexIgnoredPaths', false)
|
||||
projectView.selectListView.refs.queryEditor.insertText('!ig')
|
||||
|
||||
await projectView.toggle()
|
||||
await waitForReCrawlerToFinish(projectView)
|
||||
|
||||
expect(projectView.queryOverridesIgnore()).toBe(true)
|
||||
expect(projectView.element.querySelectorAll('li').length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when core.excludeVcsIgnoredPaths is set to false', () => {
|
||||
@ -1715,6 +1790,29 @@ describe('FuzzyFinder', () => {
|
||||
expect(Array.from(projectView.element.querySelectorAll('li')).find(a => a.textContent.includes('ignored.txt'))).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the query starts with an exclamation point', () => {
|
||||
beforeEach(() => {
|
||||
const ignoreFile = path.join(projectPath, '.gitignore')
|
||||
fs.writeFileSync(ignoreFile, 'ignored.txt')
|
||||
|
||||
const ignoredFile = path.join(projectPath, 'ignored.txt')
|
||||
fs.writeFileSync(ignoredFile, 'ignored text')
|
||||
})
|
||||
|
||||
it('excludes paths that are git ignored when indexIgnoredPaths is true', async () => {
|
||||
atom.config.set('fuzzy-finder.indexIgnoredPaths', false)
|
||||
projectView.selectListView.refs.queryEditor.insertText('!ig')
|
||||
|
||||
await projectView.toggle()
|
||||
await waitForReCrawlerToFinish(projectView)
|
||||
|
||||
expect(
|
||||
Array.from(projectView.element.querySelectorAll('li'))
|
||||
.find(a => a.textContent.includes('ignored.txt'))
|
||||
).not.toBeDefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user