How to search for files faster in Sublime Text 3 - search

Right now I do ⌘t then scroll through autocomplete, or start typing the name (but half the time it doesn't find it).
Sublime doesn't find a file in many cases. For example, I typically have all my files called index.<ext> nested inside some folder. So I might have:
my/long/directory/structure/index.js
my/long/directory/structure2/index.js
my/long/directory/structure3/index.js
my/long/directory/structure.../index.js
my/long/directory/structuren/index.js
my/long/directory/index.js
my/long/directory2/index.js
my/long/directory.../index.js
my/long/directoryn/index.js
my/long/index.js
my/index.js
...
But in sublime you have to search for an exact path. I can't search this:
my directory index
And get results for directory, directory2, directory..., directoryn, I just get empty results because there is not my/directory. I can't remember the full folder path most of the time, so it takes a lot of effort to do so and I end up just navigating in the sidebar to find the file which takes some time.
Wondering if there is a better/faster way of doing this. Basically searching for a file by snippets/keywords of the complete path. So m dir would return my/long/directory, etc.

The first thing to note is that you do not have to search for an exact path; anywhere that Sublime provides you a list of items to select from and a text entry, fuzzy matching is in play. In your example searching just for idx will narrow down the list to all items that have those characters in that order, even if they're not adjacent to each other.
The entries show you visually how they're matching up, and there's a fairly sophisticated system behind the scenes that decides which characters make the best matches (relative to some hidden scoring algorithm):
In addition to this you can use multiple space separated terms to filter down the list. Each term is applied to the list of items resulting from the prior term, so they don't need to be provided in the same order as they appear in the file names.
This helps with searches where you know generally the name of the file, and from there can further drill down on segments of the path or other terms that will help narrow things down:
Something to note here is that as seen in these images, the folder structure is my/long/directory/structure, but the names of the files as seen in the panel don't include the my/ at the start.
In cases where your project contains only one top level folder, that folder isn't presented in the names of the files. Presumably this is because it's common to every file and thus not going to be a useful filter. As such trying to use my in the search field will return no matches unless one of the files has an m and a y somewhere in their filenames.
This isn't the case if there are multiple top level folders; in that case Sublime will include the root folder in the names of the files presented because now it's required to be able to distinguish between files in the different folders:
In addition to this, note that for any given filter text you enter in a panel, Sublime remembers the full text of the item that you selected while that filter text was being used, and uses that in it's scoring to prioritize the matches the next time you search in the same panel. The next time you search with the same term, Sublime will automatically pre-select the item that you picked last time under the theory that you probably want it again.
The search terms and their matches are saved in the session file and in your project's sublime-workspace files, so as you move from window to window and project to project you're essentially training Sublime how to find the files that you want.
My advice would be to try and flip your thinking a little bit. In my opinion the power of the fuzzy matching algorithm works best when you try to find files in a more organic way than trying to replicate the path entirely.
Instead, I would throw a few characters from the name of the file that I'm trying to find first, and then add another term that filters on some part of the path that will disambiguate things more; a term of idx s1 in this example immediately finds the two index.js files that are contained in structure1 folders, for example.
In a more real world example the names of the folders might contain the names of the components that they're a part of or something else that is providing a logical structure to the code, so you might do idx con to pull the index.js from the controller folder or idx mod to find the one in the model folder, and so on.
Regarding a better/faster way to do this I don't think there is one, at least in the general case. Sublime inherently knows every file that's in your project as a part of indexing all of the files to power other features such as Goto Symbol and it uses file watchers to detect changes to the structure of the open folders.
Anything else, including a third party plugin or package, would need to first do a redundant file scan to accumulate the list of files and would also have to replicate the file watching that Sublime is already doing in order to know when things change.

Related

Find a file with all given strings on Linux

Similar to this question How do I find all files containing specific text on Linux? but I want all the files that contain multiple given strings (these strings not necessarily next to each other or on the same line, just in the same file).
My use case is I am looking at a UI and want to modify the file which controls this particular screen. The codebase though is huge and it is difficult to locate this file. All I have to go on is some of the hardcoded strings on this screen which I would like to do the search on. The strings are quite generic though such as 'Done', 'Close', 'View Details'... Doing a search on any of these strings individually, using the answer from the linked question above, brings back too many results but I think doing the search on all of them together will filter it down enough to find the file.

Can I filter sidebar directories by name (in sublime text 3) to quickly find node module, for example?

Here is my example, where I could have some input to filter directory subfolders.
The direct answer to the question is that this is not possible; the list of files and folders in the side bar is controlled by what folders you add and the settings that you include/exclude files and folders from within those folders. In theory you could try to modify the settings to change what appears in the side bar, but every time those settings change the file catalog needs to be rebuilt, which is something that can take some time (particularly in something with a large node_modules folder). It also causes all of the folders in the side bar to fold up.
The expected workflow is more designed around working with files than with working with groups of folders and that workflow centers around the Goto Anything panel. Choosing Goto > Goto Anything in the menu will open a panel showing you a list of every file that is currently contained in the side bar (except binary files).
The panel can filter text via fuzzy matching using as many search terms as you want (in any order you want) and will move the most likely matches closer to the top of the list. It also learns over time what files you pick when you use certain filters.
For your use case here you can open the panel and use a filter like node_modules or nmod/ to filter to files in the node_modules/ directory, acorn/ to see only files that exist in folders that match acorn, or a combination. You can also include fragments of filenames like lodash/ indjs to bring the index.js of the `lodash/ package to the top of the list.
The best way to get a feel for how this works is to play with it a little bit. Note also that the context menu in open files has a Reveal in side bar command that will focus the side bar on that file, which can be a handy way to see the other siblings of files you have open.

what is the difference between binary_file_patterns and index_exclude_patterns in SublimeText3?

In SublimeText3 binary_file_patterns excludes files from being found in Files or fuzzy search (Goto Anything) while index_exclude_patterns prevents files from being indexed.
Since we know that not indexed files cannot be found and assuming that untraceable files do not need to be indexed, what are the differences and implications by the usage of one over another?
Sublime maintains a catalog of all known files based on the folders that are currently open in the window/project, and that catalog of files is used to populate the Goto Anything file list and also the list of files that are searched when you do Find in Files.
You can control what appears in the catalog by using the file_exclude_patterns and folder_exclude_patterns settings to stop files from appearing in the sidebar (and thus in the catalog). As you mentioned you can also use binary_file_patterns to indicate that files should still appear in the side bar, but should not be offered in the Goto Anything panel or searched by Find in Files.
In addition to the above, as long as index_files is turned on, then in addition to the file catalog Sublime also runs an indexing process against the files in the side bar as well.
The indexer runs in the background using some number of threads (controlled by index_workers) and essentially loads every file in the side bar, applies the appropriate syntax definition, and then gathers the list of symbols that are marked as ones that should appear in the index (this is a per-syntax setting). The index_exclude_patterns setting specifies files which should not be indexed, even if they appear in the sidebar.
The index is used to power the Goto Definition/Goto Reference/Goto Symbol in Project functionality; it's literally just a list of all of the indexed symbols, what files they appear in, and where in that file that they appear.
Your assumption that files that are not indexed are ones that can't be found is not correct; files that are not indexed can still appear in the side bar and be found by Goto Anything, they just don't contribute symbols to the index, which means the above functionality will not show any content from those files, but you can still open and search them.
So overall, the implications of the two are:
If you want a file to appear in the side bar but you don't want to search inside it or have it eligible for opening with Goto Anything, add it to the binary_file_patterns.
If you want a file to appear in the side bar but not contribute symbols to the index, then add it to the index_exclude_patterns setting.
Files can appear in both settings, in which case you can see them in the side bar but Sublime pretends that they're not there for purposes of all of the above functionality.

Delimiting quick-open path with fullstops in Sublime Text 3?

I'm making the move to ST3, and I'm having some trouble. I'd like to be able to delimit the quick-open filepath (⌘ + T) with periods instead of slashes or spaces. However, I can't find the setting to do that.
For example:
component.biz_site_promotions.presentation
should be able to open the file that
component biz_site_promotions presentation
would.
Any help would be greatly appreciated!
There is no setting in Sublime that changes the way this works; the search term is always used to directly match the text in the list items (except for space characters).
Note however that the Goto Anything panel uses fuzzy matching on the text that you're entering, so in many cases trying to enter an entire file name is more time consuming anyway.
As an example, to find the file you're mentioning, you could try entering the text cbspp, which in this case is the first letters of all of the parts of the file name in question.
As you add to the search term, the file list immediately filters down to text that matches what you entered; first only filenames that contain a C, then only filenames that contain a C that is followed somewhere after by a B, and so on.
Depending on the complexity and number of files that you have in your project, you may need to add in a few extra characters to dial in better (e.g. comb_s_pp). Usually this search method will either end you up at the exact file you want, or filter the list so much that the file that you want will be easier to find and select.
Additionally, when you select an item and there was more than one possible match, Sublime remembers which item you selected for that particular search term and brings it to the top of the search results next time you do it, under the assumption that you want the same thing again.
As you use Sublime more (and with different projects) you will quickly get a handle on what partial search terms work the best for you.
In addition to finding files, you can do other things with that panel as well, such as jumping to a specific line and/or column or searching inside the file for a search term and jumping directly to it. This applies not only to the current file but also the one that you're about to open.
For more complete details, there is a page in the Unofficial Documentation that covers File Navigation with Goto Anything
As an extra aside, starting with Sublime Text build 3154, the fuzzy searching algorithm handles spaces differently than previous builds.
Historically, spaces in the search term are essentially ignored and the entire input is treated as one search term to be matched character by character.
Starting in build 3154, spaces are handled by splitting up a single search term into multiple search terms, which are applied one after the other.
This allows multiple search terms to hit out of order. For example, index doc in build 3154 will find doc/index.html, but it won't find it in previous versions because the terms aren't in the right order.
As such, assuming you're not currently using such a build (as of right now it's a development build, so only licensed users have access to it), moving forward if you continue to search the way you're searching in your question, you might start getting more results than you expected.

Finding files using icicles in Emacs under Windows 7

The short version of the question: how can I get icicles to search usefully for files in directories and subdirectories, even if only given a partial match of the filename?
EDIT: The short answer is to use icicle-locate-file in the top level of your directory and use S-Tab (shift-tab) to begin completion rather than plain tab. More details in this answer.
Just as an addendum, I gave up on icicles after this as it took about 10 seconds to find files in the (large) directory tree in question each time I used icicle-locate-file. There may be a way round this delay, perhaps by creating and sets of files 'gathered' by icicles, but I began to feel that the potential benefits were being eroded by the up-front costs of working this out and by the costs of keeping the file sets updated. As the author of icicles points out below, access to *nix's locate command would allow me to use icicle-locate, which is quicker than icicle-locate-file. However, I run on Windows and the Everything utility doesn't work for me. So, back to copious use of IDO and bookmarks that expand to dired buffers.
==========
The longer version... As Emacs (24.3.1) is now my main development environment I have been exploring ways of improving my efficiency, particularly regarding filename completion for some time now. Several excellent answers to this question pointed me to ido-mode and dired-x, both of which I am now using.
Another great recommendation was Emacs' bookmarks. In particular, defining dired buffers as bookmarks and jumping to them using C-x r b mybook1 or even calling C-x r b from the C-x C-f minibuffer (this page was helpful) are two very useful strategies.
A couple of people mentioned anything and its successor helm. I have been unable to get the file location part of either package working on Windows 7. Apparently they depend on the command line version of Everything but this fails for me, as detailed in this question, to which there were some helpful responses but no definitive answers. It seems that it works smoothly on *nix but there's not much discussion of helm-locate etc on Windows. So that counts out helm and anything for filename completion.
Which brings me to icicles. In a question about making find-file search in subdirectories the asker commented that they had taken a look at "ido and icicles, but they seem to work shallowly, only within current directory".
In response to this came a comment on icicles: "you can search for any file on your system, if you want, matching any part of the file name and path" with a pointer to a page on Icicles file name input. While I appreciate the considerable effort that has gone the help pages for icicles, I didn't find this one very useful because it consisted largely of a list of descriptions of icicles functions. What would be useful to me is a tutorial that walks you through finding files.
Let's assume the following.
I am running a Windows 7 installation of Emacs 24.3.1.
I have a top-level directory containing some files and folders. In this case it is c:/iciclestest/.
I know there's a file somewhere in this section of the tree that has "grob" as part of the filename.
I want to use icicles to find this file. I have put (require 'icicles) and (icy-mode 1) in my init file.
So, off we go. Start Emacs in the scratch buffer. Hit C-x C-f. I get a File or directory prompt, with a purple plus sign to the left that I think indicates that this is one of icicles' multi-commands.
Hitting tab gets me this mini-frame, showing me the contents of the current directory.
I hit tab on the folder1 subdirectory and icicles shows me the contents of that, as one would expect.
You can see a couple of files with "grob" in the name.
Right, C-g to clear everything then C-x C-f again. Enter 'grob'. I get a "no prefix completions" message. This surprised me a little because I expected icicles to have some kind of whizzy fuzzy matching like ido-mode.
Okay, maybe I need a different command. Let's try M-x icicle-locate-file, which gives me this prompt:
If I enter 'grob' and hit confirm I just get a new file, as per below.
To recap: what I'd like to be able to do is enter a string and have icicles go and look for files or folders containing that string. My main dev folder has many dozens of directories and thousands of files so a quick find within Emacs would be a godsend.
I realise that the locate command doesn't exist on Windows so functionality will be in some ways limited, but I would have thought a recursive search of files and subdirs from the current dir based on a user-entered string would be straightforward. What am I missing? Am I going about this the right way? Can this be done in icicles?
You need to read the Icicles doc a bit more: use S-TAB instead of TAB for apropos (regexp or substring) completion. That is apparently all you want here: match grob as a substring. (No need for any fuzzy matching for that.)
Since you want files matching grob anywhere under that directory, use icicle-locate-file. Give it that directory as the starting point. (And since you want to match grob anywhere in the file name, use S-TAB for completion.)
Icicles does provide "whizzy fuzzy matching like ido-mode" (in fact a lot whizzier). Ido's "flex" matching is the same as Icicles's "scatter" matching.
You can set the kind of completion you want to be one of the fuzzy-matching types. In the minibuffer, C-( cycles among the prefix-completion methods. M-( cycles among the apropos-completion methods. True fuzzy matching is a prefix completion method. Flex/scatter matching is a poor man's fuzzy matching, and it is an apropos completion method (so use M-( to cycle to it). To change the default matching, so you need not cycle to get the ones you prefer, customize option icicle-S-TAB-completion-methods-alist or icicle-TAB-completion-methods.
In addition to the answer about icicle-locate-file, you can find files that are in marked Dired subdirectories, and their marked subdirectories, etc. recursively, using M-+ C-F (command icicle-visit-marked-file-of-content-recursive), if you use both Icicles and Dired+.
This answer provides the details.

Resources