Icicles - File-Name Input

iciclesimage
Previous: Icicles - Buffer-Name InputIciclesIciclesIndexNext: Icicles - Persistent Completions

File-Name Input and Locating Files Anywhere

Emacs offers two main functions for reading minibuffer input with completion: ‘completing-read’ and ‘read-file-name’. Icicles uses both of these, and it enhances each of them in various ways for use in your own EmacsLisp code. These two functions can each be used to read file-name input, but they do so in very different ways.

This section provides a reminder description of these two functions, and then it describes the main Icicles commands that read file names.

You do not need to use these Icicles commands to get the general benefits of Icicles enhancements to ‘completing-read’ and ‘read-file-name’. What these commands offer are additional benefits.

Remapping Vanilla File Commands to Icicles File Commands

By default, that is, if you do not change the value of user option `icicle-top-level-key-bindings’, some commonly used Emacs commands for accessing files are remapped to Icicles commands. For example, command ‘find-file’, is by default remapped in Icicle mode to multi-command ‘icicle-file’. Remapping means that any keys, such as ‘C-x C-f’, that would normally be bound to ‘find-file’ are instead bound to ‘icicle-file’ when you are in Icicle mode.

Consult ‘icicle-top-level-key-bindings’ to see how this works. In particular, note that if you normally bind a different command to one of the keys mentioned here then the corresponding remapping in ‘icicle-top-level-key-bindings’ will not have the advertised effect.

For example, if you normally use the key bindings provided by library ffap.el (FindFileAtPoint), meaning that you invoke command ‘ffap-bindings’, then for you ‘C-x C-f’ is bound to ‘find-file-at-point’, not ‘find-file’. By default, option ‘icicle-top-level-key-bindings’ does not remap ‘find-file-at-point’ to ‘icicle-file’, so even in Icicle mode ‘C-x C-f’ remains bound to ‘find-file-at-point’. If you want ‘C-x C-f’ to be bound to ‘icicle-file’, then change the ‘find-file’ entry in ‘icicle-top-level-key-bindings’ (or add another entry for ‘find-file-at-point’).

What has just been pointed out for Icicles file commands applies more generally to all Icicle-mode command remapping provided by option ‘icicle-top-level-key-bindings’.

Action Keys Bound Dynamically During File-Name Input

In addition to the usual Icicles key bindings, during file-name completion the Icicles commands that read file names bind the following keys dynamically in the minibuffer keymaps, so you can use them while to perform various operations on the fly when you input a file name. These minibuffer bindings are also available for autofile bookmark commands.

In many cases for Icicles multi-commands that read a file name, you can use ‘M-n’ to pick up the file name at point, or if none then the name of the file you are currently visiting.

Note: Whether a command supports file-name globbing wildcards such as ‘*’ is independent of whether it uses ‘read-file-name’ or ‘completing-read’. It is the command itself that offers such support or not. Globbing takes place only after the file name (with wildcards) is read. All Icicles commands that visit files (all of the commands mentioned in this section) let you use globbing wildcards. Remember also that file-name globbing, with its special wildcards, has nothing to do with regexp completion matching. See Icicles - Special Characters in Input Patterns for more information about file-name globbing.

Function `read-file-name'

Function ‘read-file-name’ uses relative file-name completion.

It is specialized for file-name input with completion. It knows about files and file names for your current platform. It knows about Emacs remote file name syntax (Tramp, Ange FTP). And starting with Emacs 23, ‘TAB’ also completes environment variables during ‘read-file-name’ completion.

Using ‘read-file-name’ is the most flexible way to read a file name in Emacs, and it is the traditional way. Unless stated otherwise, “file-name completion”, even in the Icicles doc, refers to ‘read-file-name’ completion.

When ‘read-file-name’ reads input, only the file name itself, not the directory portion, is used for matching. The directory is understood to be the directory that is present in the minibuffer, or the value of variable `default-directory’ (which you can change using command ‘cd’, for instance) if there is no directory there.

Whether the value of ‘default-directory’ is automatically inserted in the minibuffer is controlled by user option ‘insert-default-directory’. But if you do not change the directory seen in the minibuffer then the behavior is the same whether or not the ‘default-directory’ name is present in the minibuffer: it is the assumed directory. If you prefer, you can delete the directory name first, using ‘M-k’.

With ‘read-file-name’, you can thus use apropos completion to match a file-name substring, without needing to prefix the substring with `.*’ in the minibuffer. For example, to match the file named `favorite-foo-file.bar’ in directory ‘/some/path/to/my/’, you need not use `/some/path/to/my/.*foo’; it is sufficient to use either ‘foo’ or ‘/some/path/to/my/foo’.

Function `completing-read'

Function ‘completing-read’ is a general function for reading input with completion. It is not specially designed for reading file names. It knows nothing about files and file names. It knows nothing about remote file-name syntax. When ‘completing-read’ reads input, it makes no use of ‘default-directory’. The completion candidates are treated as simple strings; they are not really treated as file names.

Icicles commands that use ‘completing-read’ to read a file name typically read an absolute name, that is, a name that includes the directory portion. This means that you can match against any part of the full name, including any directory components. The directory portions of the candidate file names need not be the same – you can thus complete against a set of files in multiple directories.

Icicles Commands that Read File Names

Icicles commands that use ‘read-file-name’ include all multi-commands, such as ‘icicle-find-file’, that are defined using ‘icicle-define-file-command’. Vanilla Emacs command ‘find-file’ is another example of a command that uses ‘read-file-name’.

Icicles commands that use ‘completing-read’ to read file names include the multi-commands ‘icicle-find-file-absolute’, ‘icicle-find-file-in-tags-table’, ‘icicle-recent-file’, ‘icicle-locate’, ‘icicle-locate-file’, and ‘icicle-locate-file-no-symlinks’. These are defined using ‘icicle-define-command’, not ‘icicle-define’-file-command’.

There are also ‘-other-window’ versions of all of the Icicles commands that read file names.

The Icicles commands that use ‘completing-read’ to read file names have an additional feature: you can use a prefix argument to tell them to combine the last modification date with the file name, as a multi-completion. This means that you can easily look up files whose modification time or date matches some (regexp) criterion, such as being sometime in July 2008.

When using a command that reads an absolute file name, remember that, to save space, you can use `C-x .’ to toggle hiding of the common match portions of the candidates in ‘*Completions*’. This portion is often a long directory substring.

Because this generally facilitates the use of absolute file-name commands, by default Icicles automatically does this for you. You can unhide the common-match portion by hitting the toggle `C-x .’.

You can control which commands automatically turn on hiding of the expanded common match, by adding/removing property ‘icicle-hide-common-match’ to/from the command symbol. For example, if you do not want ‘icicle-locate-file’ to hide the common match then add this to your init file (~/.emacs):

    (put 'icicle-locate-file 'icicle-hide-common-match nil)

On the other hand, you can make any command hide the common match by putting a non-‘nil’ value on its symbol.

`icicle-file', `icicle-find-file', `icicle-find-file-absolute'

Multi-command ‘icicle-file’ is bound, by default, to ‘C-x C-f’ in Icicle mode, thus taking the place of ‘find-file’. It combines multi-commands ‘icicle-find-file’ and ‘icicle-find-file-absolute’. With no prefix argument, it matches relative file names; with a prefix argument, it matches absolute names (as ordinary strings). With a negative prefix argument, you can match also the last modification date.

An additional feature of these commands is that candidates that are directory names are highlighted in buffer ‘*Completions*’ using face ‘icicle-special-candidate’.

Another feature is that if you use a prefix argument when acting on an individual file-name candidate then the file is visited in read-only mode. The same invocation of ‘C-x C-f’ can thus open multiple files, some in read-only mode, some not.

(There are also multi-commands ‘icicle-find-file-read-only’ and ‘icicle-find-file-abs-read-only’, unbound by default, which are the same as ‘icicle-find-file’ and ‘icicle-find-file-absolute’, except that they visit files in read-only mode. For ‘icicle-find-file-read-only’, the prefix-argument behavior is flipped: with a prefix argument when you act on a candidate file it is not visited read-only.)

Match File Names and File Content Too

Starting with Emacs 23, the Icicles commands that read file names let you optionally provide a regexp pattern to match against file content

. In this they are similar to the buffer-switching multi-command ‘icicle-buffer’.

Versions of the file-finding commands are also available that do not let you search file contents. Their file names contain ‘-no-search’. Prior to Emacs 23, these are all that are available, so commands such as ‘icicle-file’ are aliased to them.

(For Emacs 23 and later, commands such as ‘icicle-file’ are actually aliased to commands that let you search content, and which have ‘-of-content’ in their name.)

If you provide a pattern to match file content then all files whose names match the file-name part of your input are searched for the content pattern. Icicles looks only for a single content-match within each file it tests. Choosing a candidate file just visits it normally — it does not move to that tested match or to any other content-match position. Matching is used only to filter candidate files.

However, if your input includes a content-matching part that matches, that part is automatically added to the Isearch regexp history, ‘regexp-search-ring’, whenever you hit ‘S-TAB’ to complete your input. This means that when you visit the file you can immediately search for matches using ‘C-M-s’ or ‘C-M-r’.

(You can also work in the other direction, reusing an Isearch regexp as a content-matching regexp. See Using Completion to Insert Previous Inputs: `M-o'.)

Content-searching is obviously much more costly than file-name matching, so clearly if you can provide some information about the file name, that improves performance. IOW, the more you can limit the number of files to search, the better.

To search file content, the candidate files are visited, that is, buffers are created for them and searched. By default, after the command is finished these buffers are killed, except for those you actually chose as completion candidate(s) and any that existed prior to invoking the command.

This automatic extra-buffers cleanup is controlled by option `icicle-kill-visited-buffers-flag’. But providing a prefix argument to ‘icicle-file’ flips the behavior specified by that option for the command duration. (This is not true for the commands that read absolute file names. For them, a prefix argument has a different meaning.)

You can use option `icicle-file-skip-functions’ to specify patterns for file names to exclude from content-searching when you provide a content-matching pattern. By default, image files and byte-compiled Emacs-Lisp files are ignored for content-searching.

If your input contains a content-matching part then, by default, it is ignored for completion of a directory-name candidate. The behavior is governed by options ‘find-file-run-dired’ and `icicle-file-search-dir-as-dired-flag’. If both of these options are non-‘nil’ then the directory is visited in Dired mode during completion, and the Dired listing is searched as the content.

In a Dired buffer, there are related content-matching multi-commands that you can use to visit marked files and subdirectories whose content matches a regexp.

The latter visit not only the files that are marked in the current directory, but also those that are marked in any marked subdirectories, and sub-subdirectories etc., recursively. They are available only if you also use library Dired+.

File content-matching is available for all Icicles commands that read file names, including ‘icicle-recent-file’, ‘icicle-locate-file’, and ‘icicle-locate’.

Using a negative prefix argument when you invoke ‘icicle-file’ (‘C-x C-f’), or any prefix argument when you invoke a command that reads absolute file names, means that the completion candidates have up to three parts: the file name, followed by the last modification date, followed by the file content.

For example, these each match files with names matching ‘ici’, last modification dates matching ‘2013’, and contents matching ‘define-file’:

    C-- C-x C-f ici C-M-j 2013 C-M-j define-file
    M-x icicle-locate-file ici C-M-j 2013 C-M-j define-file

The parts of your input pattern that match any of the candidate parts can be empty. For example, this matches files with any name, whose last modification date matches ‘2013 07’, and whose contents match ‘recent file’:

    C-- C-x C-f C-M-j 2013 07 C-M-j recent file

See Also:

Cycling into Subdirectories

The Icicles commands that use ‘read-file-name’ to read a file or directory name visit the files or directories you choose. If you act on a directory-name completion candidate (e.g. using ‘RET’ or ‘C-RET’) it is visited using Dired. And cycling moves past a directory candidate to the next candidate, the name of a sibling file or directory.

But sometimes you want not to visit a candidate directory but to descend into it, to access its own files or subdirectories using completion. To do that, you can do either of the following to expand a directory candidate:

If you prefer, you can have Icicles cycle into subdirectories whenever you choose them using ‘RET’ (or ‘mouse-2’ in ‘*Completions*’), by setting option `icicle-find-file-expand-directory-flag to non-‘nil’.

The effect of ‘RET’ and ‘C-RET’ is then the same as ‘C-M-/’ — directory candidates are not visited using Dired. This behavior does not occur for multi-command candidate actions such as ‘C-RET’, ‘C-mouse-2’, and ‘C-down’ — those continue to open Dired on the candidate directory.

You can toggle this option using ‘C-x /’.

Visit Recent Files or Files for Emacs Tags

You can use ‘icicle-recent-file’ to open any file that you have visited recently, perhaps in a previous Emacs session.

Because Icicles lets you easily sort and filter candidates, consider customizing option ‘recentf-max-saved-items’ to a large number, such as 1000. The default number (20) is very small because it assumes that you will access the candidates using a menu.

Commands ‘icicle-find-file-in-tags-table’ and ‘icicle-find-file-in-tags-table-other-window’ let you visit files that are listed in the current Emacs tags table. You can think of these potential completion candidates as all of the files in a project defined by the tags table.

‘icicle-recent-file’ and ‘icicle-find-file-in-tags-table’ are like ‘icicle-find-file-absolute’: ‘completing-read’ is used, not ‘read-file-name’ (file names are treated as just strings), and (for Emacs 23 and later) you can match both file names and file contents.

Find Files Anywhere, Without Knowing Where

You can use ‘icicle-locate’ or ‘icicle-locate-file’ to find a file when you do not know precisely what directory it is in. The former requires GNU/Linux or UNIX command ‘locate’, to work. The latter does not require any external program.

Because it takes advantage of ‘locate’ having indexed files on your file system, ‘icicle-locate’ can be much faster than ‘icicle-locate-file’. Otherwise, these two Icicles commands work similarly.

‘icicle-locate’ and ‘icicle-locate-file’ are like ‘icicle-find-file-absolute’: file names are absolute, and (for Emacs 23 and later) you can match both file names and file contents. Of course, since these commands work with all of the files in and under a given directory, this can mean many, many files, so generally you will want to use an input pattern that also matches file names.

Since it does not use an index, ‘icicle-locate-file’ looks throughout a given directory, including throughout all of its subdirectories. Command ‘icicle-locate-file-no-symlinks’ is the same, except that it does not follow symbolic links. Both of these commands respect option `icicle-ignored-directories’, which is a list of directories to ignore – by default, version-control directories.

By default, the target directory for ‘icicle-locate-file’ is the current directory, but if you supply a non-negative numeric prefix argument (non-positive means include the date), then you are prompted for the directory to search.

If you use a plain prefix argument (‘C-u’) or a double plain prefix argument (‘C-u C-u’) then you are prompted to choose a set of directories to use. This choosing uses multi-command ‘icicle-directory-list’. Icicles searches for file-name matches under each of the directories you choose. For ‘C-u C-u’, the candidate multi-completions include the last file-modification date.

In addition, if you turn on the use of proxy candidates (`C-M-_’), ‘icicle-directory-list’ also offers proxy candidates that are variables, such as ‘load-path’, whose values are lists that include directories. Choosing a proxy candidate adds all of its directories to the set to be searched.

If you use the root of your file system as the search directory, then the Icicles file-locating commands will match completion candidates anywhere in your file system.

This can be quite useful. It gives you much of the power of the Unix ‘find’ command just for completing input. And with incremental completion (see Icicles - Icompletion), you can see what matches your input as you type.

Obviously, if you use your entire file system as the set of completion candidates and you use ‘icicle-locate-file’ (because you do not have available the external program ‘locate’), then gathering and matching such a large set of file names can take some time.

On my hard drive, for instance, there are 36 GB full of files, and it takes about 40 seconds to gather all of the file names. In spite of this inconvenience, this functionality can be useful. And of course searching a shallower directory tree presents less of a performance penalty – you pay for what you get.

However, even if you do not have command ‘locate’, there of having your cake and eating it too. You can gather all of the file names in your file system once, and save that list of completion candidates to a cache file on disk, as a snapshot. See Icicles - Persistent Completions for how to do this.

You can also do a few things to improve performance when using a command like ‘icicle-locate-file’ that involves a large set of completion candidates: Turn off Icomplete mode, Icicles incremental completion, and sorting. You can use keys `C-M-#’, `C-#’, and `C-,’, respectively, to do this. But because it is likely that you will want to do these things most, if not all, of the time, Icicles does this for you automatically, by default.

User options `icicle-icomplete-mode-max-candidates’ and `icicle-sorting-max-candidatesautomatically turn off Icomplete mode and sorting when there are more completion candidates than the option values, and then they turn these back on when there are fewer candidates. This is the case regardless of the current command.

In addition, Icicles multi-commands that typically have a large number of candidates turn off Icomplete mode and Icicles incremental completion, and do not turn them on again, regardless of the number of current candidates at any moment. When this happens, a message informs you. Just use `C-M-#’ and `C-#’ to turn these back on.

You can control which commands do this, by adding/removing properties ‘icicle-turn-off-icomplete-mode’ and ‘icicle-turn-off-incremental-completion’ to/from the command symbol. For example, if you do not want ‘icicle-locate-file’ to turn either of these off then add this to your init file (~/.emacs):

    (put 'icicle-locate-file 'icicle-turn-off-icomplete-mode nil)
    (put 'icicle-locate-file 'icicle-turn-off-incremental-completion nil)

On the other hand, you can make any command turn one of these off by putting a non-‘nil’ value on its symbol.

Absolute File Names and Different Directories

Since ‘completing-read’ has no understanding of file-name syntax, including remote file-name syntax, ‘icicle-find-file-absolute’ (‘C-u C-x C-f’) and similar commands are similarly ignorant. (You can nevertheless use `C-. with these Icicles commands, to toggle respect of ‘completion-ignored-extensions’.) In particular, these commands will not let you complete to a remote file name if the current directory is local. They also will not let you complete to a file name in a different local directory.

Because all Icicles commands that read file names use lax completion, you can nevertheless visit a file in a different directory (remote or local) from the current one, even though you cannot complete your input to such a name. That is, you can always use ‘RET’ with any file name as minibuffer input.

So how can you complete your input to an absolute file-name in a different directory? By retrieving a saved candidate set that has such absolute names and then completing against that set. For example, you can retrieve a set that represents files on a remote machine and complete to their names even from a local directory. All that counts for ‘completing-read’ is that your input can match candidates, where that matching is ordinary (apropos or prefix) string matching.

To create such a saved set of names, you can visit the directory (perhaps remote) that contains the files and then use ‘C-u C-x C-f’ and `C-}’ to save the candidates. You can later retrieve this saved set for completion, no matter what the current directory is. As another example, you can use ‘icicle-locate-file’ in a remote directory to create a saved set that includes remote files that are all somewhere under that remote directory.

In addition, you can add more file names to an existing saved set using `C->’, `C-)’, ‘M-mouse-3’, ‘insert’, or ‘M-S-mouse-2’ – see Add More Saved Candidates. The added names can come from a different directory than files already in the saved set. In this way, you can build up a saved set that includes files from any directories, some of which can be local and some remote, some remote from one host, some remote from another, and so on. You can create a saved set with any mix of absolute file names from any locations.

Remember this:

Finally, although the commands that read absolute file names are essentially ignorant of directory hierarchies and of file names as such, so that they treat their candidates only as simple strings, most of these commands nevertheless define their domain of possible file-name candidates relative to some starting directory.

This is the case for all commands that read absolute file names, except for the ‘icicle-locate*’ family. You can use ‘C-c C-d’ (think UNIX command ‘cd’) during completion to change the current working directory (‘default-directory’) on the fly. You are prompted for the directory. The domain of possible candidates is recomputed relative to the new ‘default-directory’.

Use ‘C-c C-d’ this way as many times as you like. You can use this feature to add file names from different directories to a saved set of candidates. When the command is finished, the original ‘default-directory’ is restored.

See also:


Previous: Icicles - Buffer-Name InputIciclesIciclesIndexNext: Icicles - Persistent Completions

DrewsElispLibraries referenced here: Lisp:icicles.el

CategoryCommands CategoryCompletion CategoryRegexp CategoryDirectories CategoryFiles CategoryProgrammerUtils CategoryCode