├── .foundryrc ├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── Commands.sublime-commands ├── Default.sublime-keymap ├── DirectoryPanel.py ├── FindPlusPlus.py ├── FindPlusPlus.sublime-settings ├── LICENSE-MIT ├── README.md ├── messages.json ├── messages ├── 0.2.0.md ├── 0.3.0.md └── install.md ├── release.sh └── symlink.sh /.foundryrc: -------------------------------------------------------------------------------- 1 | { 2 | "releaseCommands": [ 3 | "foundry-release-git" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://twolfson.com/support-me 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # FindPlusPlus changelog 2 | 0.4.3 - Replaced Gittip with support me page 3 | 4 | 0.4.2 - Fixed up lint errors 5 | 6 | 0.4.1 - Added foundry for release 7 | 8 | 0.4.0 - Added "Find: In Current Folder" via @davidlesieur in #14 9 | 10 | 0.3.3 - Updated messages.json to point to semver over date based semver 11 | 12 | 0.3.2 - Removed version specific text and corrected installation script 13 | 14 | 0.3.1 - Removed `package.json` to avoid confusion 15 | 16 | 0.3.0 - Added Sublime Text 3 support 17 | 18 | 0.2.5 - Corrected broken README link 19 | 20 | 0.2.4 - Updated donations section 21 | 22 | 0.2.3 - Updated README with new images and more developer relevant info 23 | 24 | 0.2.2 - Patched bug with "Find: In..." that would not open on panels with no open views 25 | 26 | 0.2.1 - Added Gittip to README 27 | 28 | 0.2.0 - Added "Show Results Panel" command 29 | 30 | 0.1.0 - Initial release 31 | -------------------------------------------------------------------------------- /Commands.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Find: In Current File", 4 | "command": "fpp_find_in_current_file" 5 | }, 6 | { 7 | "caption": "Find: In Current Folder", 8 | "command": "fpp_find_in_current_folder" 9 | }, 10 | { 11 | "caption": "Find: In Open Files", 12 | "command": "fpp_find_in_open_files" 13 | }, 14 | { 15 | "caption": "Find: In Project", 16 | "command": "fpp_find_in_project" 17 | }, 18 | { 19 | "caption": "Find: In...", 20 | "command": "fpp_find_in_panel" 21 | }, 22 | { 23 | "caption": "Find: Show Results Panel", 24 | "command": "fpp_show_results_panel" 25 | } 26 | ] -------------------------------------------------------------------------------- /Default.sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "keys": ["backspace"], 4 | "command": "fpp_delete_line", 5 | "context": [ 6 | { 7 | "key": "selector", 8 | "operator": "equal", 9 | "operand": "text.find-in-files" 10 | } 11 | ] 12 | }, 13 | { 14 | "keys": ["delete"], 15 | "command": "fpp_delete_line", 16 | "context": [ 17 | { 18 | "key": "selector", 19 | "operator": "equal", 20 | "operand": "text.find-in-files" 21 | } 22 | ] 23 | } 24 | ] -------------------------------------------------------------------------------- /DirectoryPanel.py: -------------------------------------------------------------------------------- 1 | """ 2 | Shamlessly copied/modified from SublimeQuickFileCreator 3 | https://github.com/noklesta/SublimeQuickFileCreator 4 | """ 5 | import os 6 | import re 7 | import sublime 8 | import sublime_plugin 9 | SETTINGS_KEY = 'FindPlusPlus' 10 | 11 | 12 | class DirectoryPanel(sublime_plugin.WindowCommand): 13 | relative_paths = [] 14 | full_torelative_paths = {} 15 | rel_path_start = 0 16 | 17 | def complete(self): 18 | # If there ia selected directory, callback with it 19 | selected_dir = self.selected_dir 20 | if selected_dir: 21 | self.cb(selected_dir) 22 | 23 | def open_panel(self, cb): 24 | # Build out exclude pattern, paths, and save cb 25 | self.construct_excluded_pattern() 26 | self.build_relative_paths() 27 | self.cb = cb 28 | 29 | # If there is only one directory, return early with it 30 | if len(self.relative_paths) == 1: 31 | self.selected_dir = self.relative_paths[0] 32 | self.selected_dir = self.full_torelative_paths[self.selected_dir] 33 | self.complete() 34 | 35 | # Otherwise, if there are multiple directories, open a panel to search on 36 | elif len(self.relative_paths) > 1: 37 | self.move_current_directory_to_top() 38 | self.window.show_quick_panel(self.relative_paths, self.dir_selected) 39 | 40 | # Otherwise, attempt to resolve the directory of the current file 41 | else: 42 | view = self.window.active_view() 43 | self.selected_dir = os.path.dirname(view.file_name()) 44 | self.complete() 45 | 46 | def construct_excluded_pattern(self): 47 | patterns = [pat.replace('|', '\\') for pat in self.get_setting('excluded_dir_patterns')] 48 | self.excluded = re.compile('|'.join(patterns)) 49 | 50 | def get_setting(self, key): 51 | settings = None 52 | view = self.window.active_view() 53 | 54 | if view: 55 | settings = self.window.active_view().settings() 56 | 57 | if settings and settings.has(SETTINGS_KEY) and key in settings.get(SETTINGS_KEY): 58 | # Get project-specific setting 59 | results = settings.get(SETTINGS_KEY)[key] 60 | else: 61 | # Get user-specific or default setting 62 | settings = sublime.load_settings('%s.sublime-settings' % SETTINGS_KEY) 63 | results = settings.get(key) 64 | return results 65 | 66 | def build_relative_paths(self): 67 | folders = self.window.folders() 68 | self.relative_paths = [] 69 | self.full_torelative_paths = {} 70 | for path in folders: 71 | rootfolders = os.path.split(path)[-1] 72 | self.rel_path_start = len(os.path.split(path)[0]) + 1 73 | if not self.excluded.search(rootfolders): 74 | self.full_torelative_paths[rootfolders] = path 75 | self.relative_paths.append(rootfolders) 76 | 77 | for base, dirs, files in os.walk(path): 78 | for dir in dirs: 79 | relative_path = os.path.join(base, dir)[self.rel_path_start:] 80 | if not self.excluded.search(relative_path): 81 | self.full_torelative_paths[relative_path] = os.path.join(base, dir) 82 | self.relative_paths.append(relative_path) 83 | 84 | def move_current_directory_to_top(self): 85 | view = self.window.active_view() 86 | if view and view.file_name(): 87 | cur_dir = os.path.dirname(view.file_name())[self.rel_path_start:] 88 | if cur_dir in self.full_torelative_paths: 89 | i = self.relative_paths.index(cur_dir) 90 | self.relative_paths.insert(0, self.relative_paths.pop(i)) 91 | else: 92 | self.relative_paths.insert(0, os.path.dirname(view.file_name())) 93 | return 94 | 95 | def dir_selected(self, selected_index): 96 | if selected_index != -1: 97 | self.selected_dir = self.relative_paths[selected_index] 98 | self.selected_dir = self.full_torelative_paths[self.selected_dir] 99 | self.complete() 100 | -------------------------------------------------------------------------------- /FindPlusPlus.py: -------------------------------------------------------------------------------- 1 | # Load in core dependencies 2 | import os 3 | import sublime 4 | import sublime_plugin 5 | 6 | # Attempt to load DirectoryPanel via Python 2 syntax, then Python 3 7 | try: 8 | from .DirectoryPanel import DirectoryPanel 9 | except ValueError: 10 | from DirectoryPanel import DirectoryPanel 11 | 12 | # TODO: Definitely use code from Default/Find in Files.sublime-menu 13 | # We are already using Default/Find Results.hidden-tmLanguage for Default.sublime-keymap insights 14 | 15 | 16 | # Command to delete a line (used by Find Results) 17 | class FppDeleteLineCommand(sublime_plugin.TextCommand): 18 | def run(self, edit): 19 | # DEV: This is blantantly ripped from Packages/Default/Delete Line.sublime-macro 20 | 21 | # Localize view 22 | view = self.view 23 | 24 | # TODO: If this is a file name we are deleting (e.g. start of a set of results), delete them all 25 | 26 | # Expand selection to line, include line feed, delete lines 27 | view.run_command("expand_selection", {"to": "line"}) 28 | view.run_command("add_to_kill_ring", {"forward": True}) 29 | view.run_command("left_delete") 30 | 31 | 32 | # Show results panel 33 | # Grabbed out of Packages/Default/Main.sublime-menu (ironically discovered via Find++) 34 | class FppShowResultsPanel(sublime_plugin.WindowCommand): 35 | def run(self): 36 | self.window.run_command("show_panel", {"panel": "output.find_results"}) 37 | 38 | # TODO: For full blown implementation, result stacking and double click to fold/unfold 39 | 40 | # TODO: Modify output from Find in Files (partial work on this in dev/exploration) 41 | 42 | 43 | # Use SideBarEnhancements' logic for find in current file 44 | # Menu -- https://github.com/titoBouzout/SideBarEnhancements/blob/875fa106af2f4204aecc8827e72edf81e9442e0d/Side%20Bar.sublime-menu#L27 # noqa 45 | # Command -- https://github.com/titoBouzout/SideBarEnhancements/blob/875fa106af2f4204aecc8827e72edf81e9442e0d/SideBar.py#L243-L255 # noqa 46 | # class FppFindInPathsCommand(sublime_plugin.WindowCommand): 47 | class FppFindInPathsCommand(DirectoryPanel): 48 | def open_path(self, path=None): 49 | if path: 50 | self.open_paths([path]) 51 | 52 | def open_paths(self, paths=[]): 53 | # Hide the search panel 54 | window = self.window 55 | window.run_command('hide_panel') 56 | 57 | # Set up options for the current version 58 | options = {"panel": "find_in_files", "where": ",".join(paths)} 59 | if int(sublime.version()) < 2134: 60 | options['location'] = options['where'] 61 | del options['where'] 62 | 63 | # Open the search path 64 | window.run_command("show_panel", options) 65 | 66 | 67 | class FppFindInCurrentFileCommand(FppFindInPathsCommand): 68 | def run(self): 69 | # Grab the file name 70 | window = self.window 71 | file_name = window.active_view().file_name() 72 | 73 | # If there is one, run FppFindInPathsCommand on it 74 | if file_name: 75 | self.open_paths(**{'paths': [file_name]}) 76 | 77 | 78 | class FppFindInCurrentFolderCommand(FppFindInPathsCommand): 79 | def run(self): 80 | window = self.window 81 | file_name = window.active_view().file_name() 82 | if file_name: 83 | self.open_paths(**{'paths': [os.path.dirname(file_name)]}) 84 | 85 | 86 | class FppFindInOpenFilesCommand(FppFindInPathsCommand): 87 | def run(self): 88 | self.open_paths(**{'paths': ['']}) 89 | 90 | 91 | class FppFindInProjectCommand(FppFindInPathsCommand): 92 | def run(self): 93 | self.open_paths(**{'paths': ['', '']}) 94 | 95 | 96 | class FppFindInPanelCommand(FppFindInPathsCommand): 97 | INPUT_PANEL_CAPTION = 'Find in:' 98 | 99 | def run(self): 100 | # Open a search panel which will open the respective path 101 | self.open_panel(lambda path: self.open_path(path)) 102 | 103 | # TODO: Make these settings rather than more commands -- people will only use one or the other (I think) 104 | # TODO: Find in project command (explicit) 105 | # TODO: Find in open files (explicit) 106 | # TODO: Find in pane files? 107 | 108 | # TODO: We can overkill it with additive/subtractive file searches -- leave those for another module 109 | # That is, include open file to search -- exclude open file from search 110 | -------------------------------------------------------------------------------- /FindPlusPlus.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "excluded_dir_patterns": [ 3 | "|.git", "|.svn" 4 | ] 5 | } -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Todd Wolfson 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Find++ 2 | 3 | Find code quickly in [Sublime Text][subl]. 4 | 5 | This was built to allow quick shuffling between search directories. It is useful for projects using multiple repositories to isolate noise in search results. 6 | 7 | [subl]: http://www.sublimetext.com/ 8 | 9 | - `Find: In Current File` - Opens `Find in Files` with `Where` as the current file 10 | - `Find: In Current Folder` - Opens `Find in Files` with `Where` as the folder of the current file 11 | - `Find: In Open Files` - Opens `Find in Files` with `Where` as `` 12 | - `Find: In Project` - Opens `Find in Files` with `Where` as `,` 13 | - `Find: In...` - Shows panel to pick directory to open `Find in Files` with as its `Where` 14 | - `Find: Show Results Panel` - Reveals the `Find Results` panel 15 | 16 | ![Find in Files example](https://f.cloud.github.com/assets/902488/860977/39331c12-f5c2-11e2-9de7-9769e885d111.png) 17 | 18 | ## Installation 19 | `Find++` is available via [Package Control][pkg-ctrl] and can be found as `Find++`. 20 | 21 | [pkg-ctrl]: http://wbond.net/sublime_packages/package_control 22 | 23 | For manual installation, run the following script in the Sublime Text terminal (``ctrl+` ``) which utilizes `git clone`. 24 | 25 | ```python 26 | import os; path=sublime.packages_path(); (os.makedirs(path) if not os.path.exists(path) else None); window.run_command('exec', {'cmd': ['git', 'clone', 'https://github.com/twolfson/FindPlusPlus', 'Find++'], 'working_dir': path}) 27 | ``` 28 | 29 | Packages can be uninstalled via `Package Control: Remove Package`, located in the Command Palette. 30 | 31 | ## Documentation 32 | All commands are accessible via the Command Palette, `Ctrl + Shift + P` on Windows/Linux, `Command + Shift + P` on Mac. 33 | 34 | ![Find Palette](https://f.cloud.github.com/assets/902488/279674/a552365a-9134-11e2-8c89-603fbb89b606.png) 35 | 36 | The `Find: In...` command opens a quick panel with relevant paths and the ability to filter. 37 | 38 | ![Find in current file panel](https://f.cloud.github.com/assets/902488/860987/ba97f2b4-f5c2-11e2-9b8d-c53060cd0f59.png) 39 | 40 | When you search, the normal `Find in Files` search will be executed with one modification. The `Delete` and `Backspace` key will delete an entire row rather than a single character. 41 | 42 | ![Find in files results](https://f.cloud.github.com/assets/902488/279676/acdae412-9134-11e2-9c3d-10cdaaa6daff.png) 43 | 44 | ## Donating 45 | Support this project and [others by twolfson][twolfson-projects] via [donations][twolfson-support-me]. 46 | 47 | 48 | 49 | [twolfson-projects]: http://twolfson.com/projects 50 | [twolfson-support-me]: http://twolfson.com/support-me 51 | 52 | ## Inspiration 53 | As the name of this project suggests, this plugin was started to gain the same `Find` functionality of [Notepad++][npp]. 54 | 55 | [npp]: http://notepad-plus-plus.org/ 56 | 57 | ## License 58 | Copyright (c) 2013 Todd Wolfson 59 | 60 | Licensed under the MIT license. 61 | -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "install": "messages/install.md", 3 | "0.2.0": "messages/0.2.0.md", 4 | "0.3.0": "messages/0.3.0.md" 5 | } -------------------------------------------------------------------------------- /messages/0.2.0.md: -------------------------------------------------------------------------------- 1 | # Find++ updates for 0.2.0 (2013-04-29) 2 | 3 | ## Functionality 4 | - Added `Find: Show Results Panel` to command palette 5 | - Reveals the Find Results panel 6 | 7 | ## Code 8 | - Renamed `find_plus_plus_delete_line` to `fpp_delete_line` for function consistency -------------------------------------------------------------------------------- /messages/0.3.0.md: -------------------------------------------------------------------------------- 1 | # Find++ updates for 0.3.0 (2013-08-20) 2 | 3 | ## Functionality 4 | - Added Sublime Text 3 support 5 | -------------------------------------------------------------------------------- /messages/install.md: -------------------------------------------------------------------------------- 1 | # Find++ 2 | 3 | Find functionality from Notepad++ for Sublime Text 2. 4 | 5 | ## Documentation 6 | All commands are accessible via the Command Palette, `Ctrl + Shift + P` on Windows/Linux, `Command + Shift + P` on Mac. 7 | 8 | The available commands are: 9 | 10 | - `Find: In Current File` - Open `Find in Files` prompt with current file as target 11 | - `Find: In Open Files` - Open `Find in Files` prompt with open files as targets 12 | - `Find: In Project` - Open `Find in Files` prompt with project files and folder as targets 13 | - `Find: In...` - Open panel to pick directory to open `Find in Files` with as its target 14 | - `Find: Show Results Panel` - Reveals the Find Results panel 15 | 16 | When you search, the normal `Find in Files` search will be executed with one modification. The `Delete` and `Backspace` key will delete an entire row rather than a single character. 17 | 18 | ## License 19 | Copyright (c) 2013 Todd Wolfson 20 | 21 | Licensed under the MIT license. 22 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Exit on first error 3 | set -e 4 | 5 | # Install our dependencies 6 | npm install foundry@~4.3.2 foundry-release-git@~2.0.2 7 | 8 | # Run foundry release with an adjusted PATH 9 | PATH="$PATH:$PWD/node_modules/.bin/" 10 | foundry release $* 11 | -------------------------------------------------------------------------------- /symlink.sh: -------------------------------------------------------------------------------- 1 | ln -s $PWD ~/.config/sublime-text-2/Packages/Find++ 2 | --------------------------------------------------------------------------------