Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
🎨 copy search result of project-find to clipboard
Browse files Browse the repository at this point in the history
- add parseSearchResult() in util.coffee with DOM api
- add copySearchResultFromPane() in project-find-view.js
- add spec in project-find-view-spec.js
- add context-menu item
  • Loading branch information
liuderchi committed May 3, 2017
1 parent 3ea44d7 commit 4841893
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
12 changes: 11 additions & 1 deletion lib/project-find-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ class ProjectFindView {
'find-and-replace:use-selection-as-find-pattern': () => this.setSelectionAsFindPattern()
}));

this.subscriptions.add(atom.commands.add('.preview-pane', {
'project-find:copy-search-results': this.copySearchResultFromPane
}));

this.subscriptions.add(atom.commands.add(this.element, {
'find-and-replace:focus-next': () => this.focusNextElement(1),
'find-and-replace:focus-previous': () => this.focusNextElement(-1),
Expand All @@ -188,7 +192,8 @@ class ProjectFindView {
'project-find:toggle-regex-option': () => this.toggleRegexOption(),
'project-find:toggle-case-option': () => this.toggleCaseOption(),
'project-find:toggle-whole-word-option': () => this.toggleWholeWordOption(),
'project-find:replace-all': () => this.replaceAll()
'project-find:replace-all': () => this.replaceAll(),
'project-find:copy-search-results': () => this.copySearchResultFromPane()
}));

let updateInterfaceForSearching = () => {
Expand Down Expand Up @@ -235,6 +240,11 @@ class ProjectFindView {
this.handleEventsForReplace();
}

copySearchResultFromPane() {
atom.clipboard.write(Util.parseSearchResult());
atom.notifications.addInfo('Search results have been copied to clipboard');
}

handleEventsForReplace() {
this.replaceEditor.getBuffer().onDidChange(() => this.model.clearReplacementState());
this.replaceEditor.onDidStopChanging(() => this.model.getFindOptions().set({replacePattern: this.replaceEditor.getText()}));
Expand Down
24 changes: 23 additions & 1 deletion lib/project/util.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,29 @@ showIf = (condition) ->
else
{display: 'none'}

parseSearchResult = ->
searchResult = []
summary = document.querySelector('span.preview-count').textContent
searchResult.push summary, ''

orderList = document.querySelectorAll('.results-view ol.list-tree.has-collapsable-children')
orderListArray = Array.prototype.slice.call(orderList) # only visible item shown in DOM, you cannot query all search results
resItems = orderListArray[1].querySelectorAll('div > li') # omit first element which is dummy

resItems.forEach (el) ->
path = el.querySelector('div > span.path-name').textContent
matches = el.querySelector('div > span.path-match-number').textContent
searchResult.push "#{path} #{matches}"

el.querySelectorAll('li.search-result').forEach (e) ->
return if e.offsetParent is null # skip invisible elements
lineNumber = e.querySelector('span.line-number').textContent
preview = e.querySelector('span.preview').textContent
searchResult.push "\t#{lineNumber}\t#{preview}"
searchResult.push ''
searchResult.join('\n')

module.exports = {
escapeHtml, escapeRegex, sanitizePattern, getReplacementResultsMessage,
getSearchResultsMessage, showIf
getSearchResultsMessage, showIf, parseSearchResult
}
3 changes: 3 additions & 0 deletions menus/find-and-replace.cson
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@
'.path-details.list-item': [
{ 'label': 'Copy Path', 'command': 'find-and-replace:copy-path' }
]
'div.preview-pane': [
{ 'label': 'Copy to Clipboard', 'command': 'project-find:copy-search-results' }
]
20 changes: 19 additions & 1 deletion spec/project-find-view-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,24 @@ describe('ProjectFindView', () => {
expect(projectFindView.errorMessages).not.toBeVisible();
});

it("can copy search results to clipboard", async () => {
oldClipboardText = atom.clipboard.read();

atom.commands.dispatch(projectFindView.element, 'core:confirm');
await searchPromise;

const resultsView = getResultsView();
await resultsView.heightInvalidationPromise;

atom.commands.dispatch(resultsView.element, 'project-find:copy-search-results');
searchResults = atom.clipboard.read().split('\n');
expect(searchResults[0]).toBe("13 results found in 2 files for items");
expect(searchResults[2]).toBe("sample.coffee (7 matches)");
expect(searchResults[3]).toBe("\t2\tsort: (items) ->");
expect(searchResults[4]).toBe("\t3\treturn items if items.length <= 1");
atom.clipboard.write(oldClipboardText);
});

it("only searches paths matching text in the path filter", async () => {
spyOn(atom.workspace, 'scan').andCallFake(async () => {});
projectFindView.pathsEditor.setText('*.js');
Expand Down Expand Up @@ -1508,4 +1526,4 @@ function simulateResizeEvent(element) {
child.dispatchEvent(new AnimationEvent('animationstart'));
});
advanceClock(1);
}
}

0 comments on commit 4841893

Please sign in to comment.