: [[image:iciclesimage]]

|| *Previous:*  [[Icicles - Emacs Tags Enhancements]] || '''[[Icicles]]''' || IciclesIndex || *Next:* [[Icicles - Dired Enhancements]] ||

----

== Icicles Shell-Command Enhancements ==


'''Icicles''' provides [[completion]] support for shell commands in these
ways:

* In ShellMode and related modes, it enhances completion of
  commands, previous inputs (commands plus their switches and
  arguments), file names, and environment variables.
This is the
main shell-related completion enhancement that Icicles offers.
It is documented not here but in section [[Icicles - Completion in Other Buffers#ShellCommandCompletion|Comint Mode Completion]].

* In any [[buffer]], it provides completion for '''`##M-!##'''' and '''`##M-|##''''.  This is an optional feature that is ''not enabled by
default''.

* In [[Dired]] mode, it provides '''Icicles''' completion for '''`##!##'''', and '''`##&##''''.  See [[Icicles - Dired Enhancements#CompleteShellCommands|Shell Commands on Marked Files]].  This is an optional feature that is ''not enabled by
default''.



This section describes the optional '''Icicles''' completion available for `##M-!##' and
`##M-|##'.  It applies also to completion for `##!##', and `##&##' in Dired
(but those have additional enhancements).

In vanilla Emacs, when you enter a shell command at the prompt for
`##M-!##' or `##M-|##', no completion is available for empty
input, and non-empty input is completed only to an environment variable or to a shell command that is in your
search path.  For Emacs releases
prior to Emacs 23, vanilla Emacs offers no completion at all.

In ''Icicle'' mode, `##M-!##' and `##M-|##' can, like vanilla Emacs (23 and later),
complete using commands in your search path.  This depends on the
the value of [[option]] `icicle-guess-commands-in-path' (see below).









[:ShellCommandCompletionAsFileNameCompletion]
=== Shell Command Completion as File-Name Completion ===

The most significant thing about '''Icicles''' completion
for reading a shell command is that it is in fact ''file-name''
completion.  Reading a shell command means, first, reading a
file name.  This is unexpected, to say the least.

Because of this unusual behavior, this feature is optional and is
''not enabled by default''.  To enable it, customize [[option]]
'''`<tt>[[Icicles - Customization and General Tips#icicle-functions-to-redefine|icicle-functions-to-redefine]]</tt>''''
to add the shell-related functions
`dired-read-shell-command' and `read-shell-command'.  If you do
that, then ''Icicle'' mode will substitute '''Icicles''' functions for these
standard functions and you will get the Icicles completion
described here.

A shell command is itself an executable file, either a binary
program or a script.  That's not so shocking.  But since '''Icicles'''
uses file-name completion for your entire shell-command input,
including any switches (options) and command arguments, all of
that input is interpreted by `read-file-name' as a file name,
before it gets passed on to the shell.

The reason for optionally providing file-name completion for a shell command
is to let you easily invoke a program no matter where it resides,
whether or not its directory is in your search path.  You can use
completion to navigate to the command's location.

'''Icicles''' shell-command completion is [[lax]], so you can enter any command you
want, not just a file-name completion candidate.  And you can edit the completed
input before hitting `RET', to add command switches (options) and arguments.  The overall input
string is taken as a (pseudo) file name, but it is then passed to
the shell for execution.

One drawback to this approach of using file-name completion is
that the history list is the file-name history, not the history of previous shell commands.








[:GotchaDollarInShellCommands]
=== Gotcha: `$' in Shell Commands ===

There is a gotcha, however, regarding `##$##' and file-name input:

When you hit `RET' to accept the input, `read-file-name' finishes
its job, as always, by trying to expand any environment variables
in the string.  Usually this is what you want, and it presents no
problem.  But in the context of a shell another `##$##' syntax is also
used.  For example, `##$1##' typically means the first argument or
first field; it does not mean a variable named `1'.

`read-file-name' knows nothing about this different `##$##' syntax,
and it systematically calls `substitute-in-file-name' to expand
any environment variables in the file name you enter (when you hit
`RET').  It interprets `##$1##' the same way it inteprets `##$PATH##',
treating `1' as an (unknown) environment variable.  This is not
what you want it to do.  If you input `##awk '{print $1}##' Emacs
raises this error:

  Substituting nonexistent environment variable "1"

What can you do about this?  Three possible approaches:

* Do not use this '''Icicles''' feature at all.  The feature is turned
off, by default.

* You can escape a dollar sign by doubling it: use `##$$##' instead of `##$##' when
you want to pass a `##$##' to the shell and not let `read-file-name'
try to interpret it in terms of an environment variable.

* You can turn off ''Icicle'' mode temporarily whenever you use a complex command
that involves `##$##': `M-x icy-mode'.









[:icicle-guess-commands-in-path]
[:KnownShellCommandsAsProxyCandidates]
=== Known Shell Commands as Proxy Candidates ===

If you do turn on '''Icicles''' file-name completion for reading shell commands, then extra, known shell commands are also made available as ''proxy'' completion candidates, provided that option '''`<tt>[[Icicles - Customization and General Tips#icicle-guess-commands-in-path|icicle-guess-commands-in-path]]</tt>'''' is non-`nil' (it is `nil' by default).  These extra candidates are the names of all executable
files (or of all files, if `shell-completion-execonly' is `nil') in
your ''search path''.

The fact that these are '''Icicles''' proxy candidates means that they
are available regardless of the current default-directory -- they
are not in fact treated as file-name candidates, even though they
are available during file-name completion.  You can easily
recognize '''Icicles''' proxy candidates in buffer `*Completions*': they
have face `icicle-proxy-candidates'.  See [[Icicles - Completions Display#ProxyCandidates|Proxy Candidates]].

[:icicle-shell-command-candidates-cache]
If `icicle-guess-commands-in-path' is non-`nil', the list of
search-path candidate commands is computed once and cached as the
value of '''`<tt>[[Icicles - Customization and General Tips#icicle-shell-command-candidates-cache|icicle-shell-command-candidates-cache]]</tt>''''.  The
particular non-`nil' value of `icicle-guess-commands-in-path'
determines when the cache is filled.
If the value of `icicle-guess-commands-in-path' is '''`first-use'''', the cache is filled the first time you use it, and each time you turn on ''Icicle''
mode it is updated.  If the value of `icicle-guess-commands-in-path' to is '''`load'''', then the cache is instead filled each time you
load '''Icicles'''.

Regardless of the non-`nil' value of
`icicle-guess-commands-in-path', if you ''save''
`icicle-shell-command-candidates-cache', then that value is used
in future sessions (no delay for searching your path).

[:icicle-recompute-shell-command-candidates]
If your environment changes, you can use command
'''`icicle-recompute-shell-command-candidates'''' to update the cached
list at any time.  With a [[prefix argument]], the updated value is
saved persistently.

In addition to the extra candidates computed by searching your
search path, in contexts such as [[DiredMode|Dired]] where target (e.g. marked)
files for the shell command are known, the extra candidates
include additional commands (possibly including switches) that '''Icicles''' can
guess might be appropriate for the target files.
See [[Icicles - Dired Enhancements#CompleteShellCommands|Shell Commands on Marked Files]].

During '''Icicles''' shell-command completion, help is available for individual
candidates, using `C-M-RET', `C-M-mouse-2', and so on.  For an
extra candidate, help is
provided for the command by the `apropos' shell command (if available).  For a
file-name candidate, help shows the file's properties.  See [[Icicles - Help on Candidates]].








[:UsingOnDemandCompletionWithShellCommandInput]
=== Using On-Demand Completion with Shell-Command Input ===

Even if you do not choose to turn on the file-name completion
feature described above, you can still get file-name completion
when you input a shell command.  Just do it on the fly, using
'''`C-M-S-f'''' (aka '''`C-M-F'''').

After you have typed or completed the shell command per se (e.g. a
file name or a search-path command), you can use `C-M-F' to
complete (relative) file names to insert as shell-command
arguments as part of the command line to submit to the shell.  See [[Icicles - Completion On Demand]].

In addition, remember that you can use '''`M-o'''' anytime in the
minibuffer to complete against a previous input.  This means that
if you have previously entered some complex shell command
(e.g. with various switches or arguments), then you can use `M-o'
to retrieve it for reuse (possibly editing it).  See [[Icicles - History Enhancements#InsertPreviousInputs|Using Completion to Insert Previous Inputs: `M-o']].


In addition, you can use '''`C-M-pause'''' to switch to another history,
then use `M-o' to complete against that history.  And you can do
this as many times as you like during the same overall
shell-command input.  You can thus use different histories to
compose different parts of the overall command.  See [[Icicles - History Enhancements#UsingOtherHistories|Using Other Histories; Commands Any Which Way]].

None of this is special to shell-command input.  `C-M-F',
`C-M-pause', and `M-o' are all available in Icicle mode for any
minibuffer input.





----


|| *Previous:*  [[Icicles - Emacs Tags Enhancements]] || '''[[Icicles]]''' || IciclesIndex || *Next:* [[Icicles - Dired Enhancements]] ||




DrewsElispLibraries referenced here: Lisp:icicles.el


CategoryCommands 
CategoryCompletion
CategoryRegexp
CategoryModes
CategoryProgrammerUtils
CategoryCode
CategorySearchAndReplace
CategoryShell
CategoryRegion

