├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── coffeelint.json ├── demo.gif ├── keymaps └── atom-fuzzy-grep.cson ├── lib ├── atom-fuzzy-grep-view.coffee ├── atom-fuzzy-grep.coffee └── runner.coffee ├── menus └── atom-fuzzy-grep.cson └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.17.2 2 | * Git project detection fails (fix #47) 3 | 4 | ## 0.17.1 5 | * use coffeescript equality check instead of === (#45) Thanks [@astephenb](https://github.com/astephenb) 6 | 7 | ## 0.17.0 8 | * add search for word under cursor (#44) Thanks [@astephenb](https://github.com/astephenb) 9 | 10 | ## 0.16.0 11 | * Removed support for environment package 12 | * Added highlight for matched words 13 | * Update ripgrep command to enable line-numbers 14 | 15 | ## 0.15.0 16 | * Add support for ripgrep (rg). (#36) Thanks [@jonboiser](https://github.com/jonboiser) 17 | 18 | ## 0.14.0 19 | * Fix git repository detection within a symlink directory. Thanks [@lemming](https://github.com/lemming) 20 | 21 | ## 0.13.0 22 | * Update Readme with PATH and environment package info 23 | * Fix path variable on OS X. Ref #16 24 | * Fix readme, missed target in ctrl-f command 25 | * Fix home dir detection. 26 | * Added command to escape pasted text. 27 | 28 | ## 0.12.0 29 | * Added inputThrottle settings. Thanks [@aki77](https://github.com/aki77) 30 | 31 | ## 0.11.0 32 | * Fix deprecated calls. Thanks [@aki77](https://github.com/aki77) 33 | * Use Workspace::open options. Thanks [@aki77](https://github.com/aki77) 34 | 35 | ## 0.10.0 36 | * Supports no result. Thanks [@aki77](https://github.com/aki77) 37 | 38 | ## 0.9.0 39 | * Fixed, atom-fuzzy-grep never finds anything on Windows. Thanks [@mykolav](https://github.com/mykolav) 40 | 41 | ## 0.8.0 42 | * Support the Platinum Searcher. Thanks [@xHN35RQ](https://github.com/xHN35RQ) 43 | 44 | ## 0.7.0 45 | * Added file filter mode for files found. 46 | * Add coffeelint config file. 47 | * Add option to display full path to file. 48 | 49 | ## 0.6.0 50 | * When opened file out of the project path use directory where it located. 51 | * Prevent exception when grep outisde of a project. Thanks [@khyo](https://github.com/khyo) 52 | * Add 'Escape Selected Text' config option. Thanks [@khyo](https://github.com/khyo) 53 | 54 | ## 0.5.0 55 | * Option to activate persisting of last search string. 56 | * Command to run grep dialog with last search string. 57 | 58 | ## 0.4.0 59 | * Git grep command can be set with custom value. Thanks [@wackywendell](https://github.com/wackywendell) 60 | * Default git grep command ignore case. Thanks [@wackywendell](https://github.com/wackywendell) 61 | * Fixed mess result showing for big stdout. 62 | * Absolute file path passed during file opening. 63 | 64 | ## 0.3.0 65 | * Display error output from command 66 | * Start time improvement. Thanks [@kankaristo](https://github.com/kankaristo) 67 | * Fixed following by symlinks. Thanks [@kankaristo](https://github.com/kankaristo) 68 | 69 | ## 0.2.0 70 | * Added --no-color option for ```git grep``` command. Thanks [@koba04](https://github.com/koba04) 71 | * Fixed error for non git projects. 72 | * Fixed error for running grep command with Untitled buffer. 73 | 74 | ## 0.1.0 - First Release 75 | * Every feature added 76 | * Every bug fixed 77 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Denys Buzhor 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # atom-fuzzy-grep package 2 | 3 | ### :warning: Looking for maintainers! :warning: 4 | 5 | ![demo](https://raw.githubusercontent.com/geksilla/atom-fuzzy-grep/master/demo.gif) 6 | 7 | ## Install 8 | 9 | apm install atom-fuzzy-grep 10 | 11 | Or search via __Settings View -> Install__ 12 | 13 | ## Usage 14 | 15 | Hit ```ctrl-alt-g``` or ```, f f``` in vim-mode to toggle panel. 16 | 17 | To open dialog with last searched string there is the command ```fuzzy-grep:toggleLastSearch```. You can map it in your ```keymap.cson```: 18 | 19 | ``` 20 | 'atom-workspace': 21 | 'ctrl-alt-shift-g': 'fuzzy-grep:toggleLastSearch' 22 | ``` 23 | 24 | To always open dialog with last search string check **Preserve Last Search** in package settings. 25 | 26 | You can filter files in opened dialog. Toggle between grep/file mode with ```ctrl-f```. 27 | To change this keybinding add following lines to your *keymaps.cson*: 28 | 29 | ``` 30 | 'atom-workspace .atom-fuzzy-grep': 31 | '': 'fuzzy-grep:toggleFileFilter' 32 | ``` 33 | 34 | ## Configuration 35 | 36 | You can specify any command you want by **Grep Command String** option in package settings, [ag](https://github.com/ggreer/the_silver_searcher) is used by default. 37 | 38 | If you want to setup another one instead of **ag** here few examples: 39 | 40 | ### [pt](https://github.com/monochromegane/the_platinum_searcher) 41 | 42 | pt -i --nocolor --nogroup --column 43 | 44 | ### [ack](https://github.com/petdance/ack2) 45 | 46 | ack -i --nocolor --nogroup --column 47 | 48 | ### grep 49 | 50 | grep -r -n --color=never 51 | 52 | ### [ripgrep](https://github.com/BurntSushi/ripgrep) 53 | 54 | rg -i -n -H --no-heading --column 55 | 56 | ### git grep 57 | 58 | git grep -n -E 59 | 60 | ```git grep``` used by default for git projects if you don't want to use it uncheck **Detect Git Project And Use Git Grep** option in package settings. 61 | 62 | Check package settings for more info. 63 | 64 | ## Caveats 65 | 66 | * Search folder detects on project path from active text editor. 67 | * When no editors opened or `Untitled` first project root path used. 68 | * When you have opened several projects and want to search through it you need to open any file from this project and start search dialog. 69 | * When active item not in project home directory used as root dir. 70 | * When no projects opened home directory used as root dir. 71 | 72 | ## Commands 73 | 74 | Name | Selector | Key Map | Description 75 | --------------------------------|------------------|-----------------------|---------------------------------------------------------------------- 76 | __fuzzy-grep:toggle__ | `atom-workspace` | 'ctrl-alt-g' | Open search dialog start typing and select item 77 | __fuzzy-grep:toggleLastSearch__ | `atom-workspace` | none | Open dialog with last search string 78 | __fuzzy-grep:toggleWordUnderCursor__ | `atom-workspace` | 'cmd-*' | Open dialog with word under cursor 79 | __fuzzy-grep:toggleFileFilter__ | `atom-workspace .atom-fuzzy-grep atom-text-editor` | 'ctrl-f' | When search dialog opened toggle file name filtering on found results 80 | __fuzzy-grep:pasteEscaped__ | `body.platform-linux atom-workspace .atom-fuzzy-grep atom-text-editor, body.platform-win32 atom-workspace .atom-fuzzy-grep atom-text-editor` | 'ctrl-v' | Paste text to dialog and escape it, you can disable this behavior with `atom-fuzzy-grep.escapeOnPaste` config 81 | __fuzzy-grep:pasteEscaped__ | `body.platform-darwin atom-workspace .atom-fuzzy-grep atom-text-editor` | 'cmd-v' | Paste text to dialog and escape it, you can disable this behavior with `atom-fuzzy-grep.escapeOnPaste` config 82 | 83 | 84 | ## Configs 85 | 86 | Name | Default | Type | Description 87 | --------------------------------------------------|--------------------------------------|-----------|----------------------------------------------------------------------------------- 88 | __atom-fuzzy-grep.minSymbolsToStartSearch__ | 3 | _number_ | Start search after N symbol 89 | __atom-fuzzy-grep.maxCandidates__ | 100 | _number_ | Maximum count of displayed items 90 | __atom-fuzzy-grep.grepCommandString__ | 'ag -i --nocolor --nogroup --column' | _string_ | Grep command 91 | __atom-fuzzy-grep.detectGitProjectAndUseGitGrep__ | false | _boolean_ | Always use `git grep` when opened project is a git repository 92 | __atom-fuzzy-grep.gitGrepCommandString__ | 'git grep -i --no-color -n -E' | _string_ | `git grep` command used when `detectGitProjectAndUseGitGrep` is true 93 | __atom-fuzzy-grep.preserveLastSearch__ | false | _boolean_ | Use last search string as input for search dialog 94 | __atom-fuzzy-grep.escapeSelectedText__ | true | _boolean_ | Escape special characters when dialog opened with selected text 95 | __atom-fuzzy-grep.showFullPath__ | false | _boolean_ | Show full file path instead of file name 96 | __atom-fuzzy-grep.inputThrottle__ | 50 | _integer_ | Input throttle 97 | __atom-fuzzy-grep.escapeOnPaste__ | true | _boolean_ | Escape pasted text 98 | __atom-fuzzy-grep.fixEnv__ | true | boolean | Will fix $PATH variable when running your favourite grep tool, environment package should be installed. 99 | 100 | 101 | ## Contributing 102 | 103 | Feel free to open issue or send pull request. 104 | -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrow_spacing": { 3 | "level": "ignore" 4 | }, 5 | "braces_spacing": { 6 | "level": "ignore", 7 | "spaces": 0, 8 | "empty_object_spaces": 0 9 | }, 10 | "camel_case_classes": { 11 | "level": "error" 12 | }, 13 | "coffeescript_error": { 14 | "level": "error" 15 | }, 16 | "colon_assignment_spacing": { 17 | "level": "ignore", 18 | "spacing": { 19 | "left": 0, 20 | "right": 0 21 | } 22 | }, 23 | "cyclomatic_complexity": { 24 | "value": 10, 25 | "level": "ignore" 26 | }, 27 | "duplicate_key": { 28 | "level": "error" 29 | }, 30 | "empty_constructor_needs_parens": { 31 | "level": "ignore" 32 | }, 33 | "ensure_comprehensions": { 34 | "level": "warn" 35 | }, 36 | "eol_last": { 37 | "level": "ignore" 38 | }, 39 | "indentation": { 40 | "value": 2, 41 | "level": "error" 42 | }, 43 | "line_endings": { 44 | "level": "ignore", 45 | "value": "unix" 46 | }, 47 | "max_line_length": { 48 | "value": 80, 49 | "level": "ignore", 50 | "limitComments": true 51 | }, 52 | "missing_fat_arrows": { 53 | "level": "ignore", 54 | "is_strict": false 55 | }, 56 | "newlines_after_classes": { 57 | "value": 3, 58 | "level": "ignore" 59 | }, 60 | "no_backticks": { 61 | "level": "error" 62 | }, 63 | "no_debugger": { 64 | "level": "warn", 65 | "console": false 66 | }, 67 | "no_empty_functions": { 68 | "level": "ignore" 69 | }, 70 | "no_empty_param_list": { 71 | "level": "ignore" 72 | }, 73 | "no_implicit_braces": { 74 | "level": "ignore", 75 | "strict": true 76 | }, 77 | "no_implicit_parens": { 78 | "strict": true, 79 | "level": "ignore" 80 | }, 81 | "no_interpolation_in_single_quotes": { 82 | "level": "ignore" 83 | }, 84 | "no_plusplus": { 85 | "level": "ignore" 86 | }, 87 | "no_stand_alone_at": { 88 | "level": "ignore" 89 | }, 90 | "no_tabs": { 91 | "level": "error" 92 | }, 93 | "no_this": { 94 | "level": "ignore" 95 | }, 96 | "no_throwing_strings": { 97 | "level": "error" 98 | }, 99 | "no_trailing_semicolons": { 100 | "level": "error" 101 | }, 102 | "no_trailing_whitespace": { 103 | "level": "error", 104 | "allowed_in_comments": false, 105 | "allowed_in_empty_lines": true 106 | }, 107 | "no_unnecessary_double_quotes": { 108 | "level": "ignore" 109 | }, 110 | "no_unnecessary_fat_arrows": { 111 | "level": "warn" 112 | }, 113 | "non_empty_constructor_needs_parens": { 114 | "level": "ignore" 115 | }, 116 | "prefer_english_operator": { 117 | "level": "ignore", 118 | "doubleNotLevel": "ignore" 119 | }, 120 | "space_operators": { 121 | "level": "ignore" 122 | }, 123 | "spacing_after_comma": { 124 | "level": "ignore" 125 | }, 126 | "transform_messes_up_line_numbers": { 127 | "level": "warn" 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geksilla/atom-fuzzy-grep/259507214ce9bf330053e2cdac348a61b8237a7d/demo.gif -------------------------------------------------------------------------------- /keymaps/atom-fuzzy-grep.cson: -------------------------------------------------------------------------------- 1 | # Keybindings require three things to be fully defined: A selector that is 2 | # matched against the focused element, the keystroke and the command to 3 | # execute. 4 | # 5 | # Below is a basic keybinding which registers on all platforms by applying to 6 | # the root workspace element. 7 | 8 | # For more detailed documentation see 9 | # https://atom.io/docs/latest/advanced/keymaps 10 | 11 | 'atom-workspace': 12 | 'ctrl-alt-g': 'fuzzy-grep:toggle' 13 | 'cmd-*': 'fuzzy-grep:toggleWordUnderCursor' 14 | 15 | 'body.platform-linux atom-workspace .atom-fuzzy-grep atom-text-editor, body.platform-win32 atom-workspace .atom-fuzzy-grep atom-text-editor': 16 | 'ctrl-v': 'fuzzy-grep:pasteEscaped' 17 | 18 | 'body.platform-darwin atom-workspace .atom-fuzzy-grep atom-text-editor': 19 | 'cmd-v': 'fuzzy-grep:pasteEscaped' 20 | 21 | 'atom-workspace .atom-fuzzy-grep atom-text-editor': 22 | 'ctrl-f': 'fuzzy-grep:toggleFileFilter' 23 | 24 | 'atom-text-editor.vim-mode:not(.insert-mode)': 25 | ', f f': 'fuzzy-grep:toggle' 26 | -------------------------------------------------------------------------------- /lib/atom-fuzzy-grep-view.coffee: -------------------------------------------------------------------------------- 1 | {$$, View} = require 'space-pen' 2 | {SelectListView} = require 'atom-space-pen-views' 3 | {BufferedProcess, CompositeDisposable} = require 'atom' 4 | path = require 'path' 5 | Runner = require './runner' 6 | escapeStringRegexp = require 'escape-string-regexp' 7 | fuzzyFilter = null 8 | 9 | module.exports = 10 | class GrepView extends SelectListView 11 | preserveLastSearch: false 12 | maxItems: 100 13 | minFilterLength: 3 14 | showFullPath: false 15 | runner: null 16 | lastSearch: '' 17 | isFileFiltering: false 18 | escapeOnPaste: true 19 | 20 | initialize: -> 21 | super 22 | @subscriptions = new CompositeDisposable 23 | @subscriptions.add atom.commands.add(@filterEditorView.element, 'fuzzy-grep:toggleFileFilter', @toggleFileFilter) 24 | @subscriptions.add atom.commands.add(@filterEditorView.element, 'fuzzy-grep:pasteEscaped', @pasteEscaped) 25 | @panel = atom.workspace.addModalPanel(item: this, visible: false) 26 | @addClass 'atom-fuzzy-grep' 27 | @runner = new Runner 28 | @setupConfigs() 29 | 30 | setupConfigs: -> 31 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.minSymbolsToStartSearch', (@minFilterLength) => 32 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.maxCandidates', (@maxItems) => 33 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.preserveLastSearch', (@preserveLastSearch) => 34 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.escapeSelectedText', (@escapeSelectedText) => 35 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.showFullPath', (@showFullPath) => 36 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.inputThrottle', (@inputThrottle) => 37 | @subscriptions.add atom.config.observe 'atom-fuzzy-grep.escapeOnPaste', (@escapeOnPaste) => 38 | 39 | getFilterKey: -> 40 | if @isFileFiltering then 'filePath' else '' 41 | 42 | getFilterQuery: -> 43 | if @isFileFiltering then @filterEditorView.getText() else '' 44 | 45 | getSearchValue: -> 46 | unless @isFileFiltering then @filterEditorView.getText() else @tmpSearchString 47 | 48 | foundRowItem: ($, rowContent) => 49 | try 50 | reg = new RegExp(@getSearchValue(), 'ig') 51 | matched = reg.exec rowContent 52 | if reg and matched 53 | $.span -> 54 | $.span rowContent.slice(0, matched.index) 55 | $.span matched[0], class: 'text-info matched-search' 56 | $.span rowContent.slice(reg.lastIndex) 57 | else 58 | $.span rowContent 59 | 60 | viewForItem: ({filePath, line, content, error}) -> 61 | that = @ 62 | if error 63 | @setError error 64 | return 65 | $$ -> 66 | @li class: 'two-lines', => 67 | displayedPath = if that.showFullPath then filePath else path.basename filePath 68 | @div "#{displayedPath}:#{line+1}", class: 'primary-line file icon icon-file-text', 'data-name': displayedPath 69 | @div class: 'secondary-line', => 70 | that.foundRowItem(@, content) 71 | 72 | confirmed: (item)-> 73 | @lastSearch = @filterEditorView.getText() 74 | @openFile item.fullPath, item.line, item.column 75 | @cancelled() 76 | 77 | openFile: (filePath, line, column)-> 78 | return unless filePath 79 | atom.workspace.open(filePath, {initialLine: line, initialColumn: column}).then((editor) -> 80 | editorElement = atom.views.getView(editor) 81 | {top} = editorElement.pixelPositionForBufferPosition(editor.getCursorBufferPosition()) 82 | editorElement.setScrollTop(top - editorElement.getHeight() / 2) 83 | ) 84 | 85 | cancelled: -> 86 | @items = [] 87 | @isFileFiltering = false 88 | @panel.hide() 89 | @killRunner() 90 | 91 | grepProject: -> 92 | return if @minFilterLength and @filterEditorView.getText().length < @minFilterLength 93 | @killRunner() 94 | @runner.run(@filterEditorView.getText(), @getProjectPath(), @setItems.bind(@)) 95 | 96 | killRunner: -> 97 | @runner?.destroy() 98 | 99 | getProjectPath: -> 100 | homeDir = require('os').homedir() 101 | editor = atom.workspace.getActiveTextEditor() 102 | return atom.project.getPaths()[0] || homeDir unless editor 103 | if editor.getPath() 104 | atom.project.relativizePath(editor.getPath())[0] || path.dirname(editor.getPath()) 105 | else 106 | atom.project.getPaths()[0] || homeDir 107 | 108 | setSelection: -> 109 | editor = atom.workspace.getActiveTextEditor() 110 | if editor?.getSelectedText() 111 | @filterEditorView.setText editor.getSelectedText() 112 | @escapeFieldText() if @escapeSelectedText 113 | 114 | escapeFieldText: => 115 | escapedString = escapeStringRegexp @filterEditorView.getText() 116 | @filterEditorView.setText escapedString 117 | 118 | destroy: -> 119 | @subscriptions?.dispose() 120 | @subscriptions = null 121 | @detach() 122 | 123 | toggle: -> 124 | if @panel?.isVisible() 125 | @panel?.show() 126 | else 127 | @storeFocusedElement() 128 | @filterEditorView.setText(@lastSearch || '') if @preserveLastSearch 129 | @panel.show() 130 | @focusFilterEditor() 131 | @setSelection() 132 | 133 | toggleLastSearch: -> 134 | @toggle() 135 | @filterEditorView.setText(@lastSearch || '') 136 | 137 | toggleWordUnderCursor: -> 138 | @toggle() 139 | editor = atom.workspace.getActivePaneItem() 140 | pattern = editor?.getSelectedText() 141 | pattern = editor?.getWordUnderCursor() if pattern is "" 142 | @filterEditorView.setText(pattern || "") 143 | 144 | toggleFileFilter: => 145 | @isFileFiltering = !@isFileFiltering 146 | if @isFileFiltering 147 | @tmpSearchString = @filterEditorView.getText() 148 | @filterEditorView.setText('') 149 | else 150 | @filterEditorView.setText(@tmpSearchString) 151 | @tmpSearchString = '' 152 | 153 | pasteEscaped: (e)=> 154 | {target} = e 155 | atom.commands.dispatch target, "core:paste" 156 | @escapeFieldText() if @escapeOnPaste 157 | 158 | schedulePopulateList: -> 159 | clearTimeout(@scheduleTimeout) 160 | filterMethod = if @isFileFiltering then @populateList else @grepProject 161 | populateCallback = => 162 | filterMethod.bind(@)() if @isOnDom() 163 | @scheduleTimeout = setTimeout(populateCallback, @inputThrottle) 164 | 165 | setEnv: (env)-> 166 | @runner?.setEnv env 167 | -------------------------------------------------------------------------------- /lib/atom-fuzzy-grep.coffee: -------------------------------------------------------------------------------- 1 | GrepView = null 2 | 3 | module.exports = 4 | 5 | activate: -> 6 | @commandSubscription = atom.commands.add 'atom-workspace', 7 | 'fuzzy-grep:toggle': => @createView().toggle(), 8 | 'fuzzy-grep:toggleLastSearch': => @createView().toggleLastSearch(), 9 | 'fuzzy-grep:toggleWordUnderCursor': => @createView().toggleWordUnderCursor() 10 | 11 | deactivate: -> 12 | @commandSubscription?.dispose() 13 | @commandSubscription = null 14 | @grepView?.destroy() 15 | @grepView = null 16 | 17 | createView: -> 18 | GrepView ?= require './atom-fuzzy-grep-view' 19 | @grepView ?= new GrepView() 20 | -------------------------------------------------------------------------------- /lib/runner.coffee: -------------------------------------------------------------------------------- 1 | {BufferedProcess} = require 'atom' 2 | 3 | module.exports = 4 | class Runner 5 | commandString: null 6 | process: null 7 | useGitGrep: false 8 | columnArg: false 9 | env: process.env 10 | 11 | constructor: ()-> 12 | atom.config.observe 'atom-fuzzy-grep.grepCommandString', => 13 | @commandString = atom.config.get 'atom-fuzzy-grep.grepCommandString' 14 | @columnArg = @detectColumnFlag() 15 | atom.config.observe 'atom-fuzzy-grep.detectGitProjectAndUseGitGrep', => 16 | @useGitGrep = atom.config.get 'atom-fuzzy-grep.detectGitProjectAndUseGitGrep' 17 | 18 | run: (@search, @rootPath, callback)-> 19 | listItems = [] 20 | if @useGitGrep and @isGitRepo() 21 | @commandString = atom.config.get 'atom-fuzzy-grep.gitGrepCommandString' 22 | @columnArg = false 23 | [command, args...] = @commandString.split(/\s/) 24 | args.push @search 25 | options = cwd: @rootPath, stdio: ['ignore', 'pipe', 'pipe'], env: @env 26 | 27 | stdout = (output)=> 28 | if listItems.length > atom.config.get('atom-fuzzy-grep.maxCandidates') 29 | @destroy() 30 | return 31 | listItems = listItems.concat(@parseOutput(output)) 32 | callback(listItems) 33 | stderr = (error)-> 34 | callback([error: error]) 35 | exit = (code)-> 36 | callback([]) if code == 1 37 | @process = new BufferedProcess({command, exit, args, stdout, stderr, options}) 38 | @process 39 | 40 | parseOutput: (output, callback)-> 41 | items = [] 42 | contentRegexp = if @columnArg then /^(\d+):\s*/ else /^\s+/ 43 | for item in output.split(/\n/) 44 | break unless item.length 45 | [path, line, content...] = item.split(':') 46 | content = content.join ':' 47 | items.push 48 | filePath: path 49 | fullPath: @rootPath + '/' + path 50 | line: line-1 51 | column: @getColumn content 52 | content: content.replace(contentRegexp, '') 53 | items 54 | 55 | getColumn: (content)-> 56 | if @columnArg 57 | return content.match(/^(\d+):/)?[1] - 1 58 | # escaped characters in regexp can cause error 59 | # skip it for a while 60 | try 61 | match = content.match(new RegExp(@search, 'gi'))?[0] 62 | catch error 63 | match = false 64 | if match then content.indexOf(match) else 0 65 | 66 | destroy: -> 67 | @process?.kill() 68 | 69 | isGitRepo: -> 70 | atom.project.getRepositories().some (repo)=> 71 | @rootPath?.startsWith(repo.getWorkingDirectory()) if repo 72 | 73 | detectColumnFlag: -> 74 | /(ag|pt|ack|rg)$/.test(@commandString.split(/\s/)[0]) and ~@commandString.indexOf('--column') 75 | 76 | setEnv: (@env)-> 77 | -------------------------------------------------------------------------------- /menus/atom-fuzzy-grep.cson: -------------------------------------------------------------------------------- 1 | # See https://atom.io/docs/latest/creating-a-package#menus for more details 2 | 'context-menu': 3 | 'atom-text-editor': [ 4 | { 5 | 'label': 'Fuzzy Grep Toggle' 6 | 'command': 'fuzzy-grep:toggle' 7 | }, 8 | { 9 | 'label': 'Fuzzy Grep Toggle Last Search' 10 | 'command': 'fuzzy-grep:toggleLastSearch' 11 | } 12 | ] 13 | 'menu': [ 14 | { 15 | 'label': 'Packages' 16 | 'submenu': [ 17 | 'label': 'Fuzzy Grep' 18 | 'submenu': [ 19 | { 20 | 'label': 'Toggle' 21 | 'command': 'fuzzy-grep:toggle' 22 | }, 23 | { 24 | 'label': 'Toggle Last Search' 25 | 'command': 'fuzzy-grep:toggleLastSearch' 26 | } 27 | ] 28 | ] 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "atom-fuzzy-grep", 3 | "main": "./lib/atom-fuzzy-grep", 4 | "version": "0.17.2", 5 | "description": "Fuzzy grep project using ag, pt, ack, grep, ripgrep, or git-grep", 6 | "keywords": [ 7 | "fuzzy", 8 | "grep", 9 | "ag", 10 | "pt", 11 | "productivity", 12 | "search", 13 | "find" 14 | ], 15 | "configSchema": { 16 | "minSymbolsToStartSearch": { 17 | "type": "number", 18 | "default": 3, 19 | "order": 0 20 | }, 21 | "maxCandidates": { 22 | "type": "number", 23 | "default": 100, 24 | "order": 1 25 | }, 26 | "grepCommandString": { 27 | "type": "string", 28 | "default": "ag -i --nocolor --nogroup --column", 29 | "order": 2 30 | }, 31 | "detectGitProjectAndUseGitGrep": { 32 | "type": "boolean", 33 | "default": true, 34 | "order": 3 35 | }, 36 | "gitGrepCommandString": { 37 | "type": "string", 38 | "default": "git grep -i --no-color -n -E", 39 | "order": 4 40 | }, 41 | "preserveLastSearch": { 42 | "type": "boolean", 43 | "default": false, 44 | "order": 5 45 | }, 46 | "escapeSelectedText": { 47 | "type": "boolean", 48 | "default": true, 49 | "order": 6 50 | }, 51 | "showFullPath": { 52 | "type": "boolean", 53 | "default": false, 54 | "order": 7 55 | }, 56 | "inputThrottle": { 57 | "type": "integer", 58 | "default": 50, 59 | "order": 8 60 | }, 61 | "escapeOnPaste": { 62 | "type": "boolean", 63 | "default": true, 64 | "order": 9 65 | }, 66 | "fixEnv": { 67 | "type": "boolean", 68 | "description": "Fix env on OS X when running not from terminal.", 69 | "default": true, 70 | "order": 10 71 | } 72 | }, 73 | "activationCommands": { 74 | "atom-workspace": [ 75 | "fuzzy-grep:toggle", 76 | "fuzzy-grep:toggleLastSearch", 77 | "fuzzy-grep:toggleWordUnderCursor" 78 | ] 79 | }, 80 | "repository": "https://github.com/geksilla/atom-fuzzy-grep", 81 | "license": "MIT", 82 | "engines": { 83 | "atom": ">=0.174.0 <2.0.0" 84 | }, 85 | "dependencies": { 86 | "space-pen": "^5.1.1", 87 | "atom-space-pen-views": "^2.0.0", 88 | "escape-string-regexp": "^1.0.3", 89 | "fuzzaldrin": "^2.1.0" 90 | } 91 | } 92 | --------------------------------------------------------------------------------