# Listings with color OR tilde, not both

Trying to get a listing block with a command prompt that has both color and a proper formatting. I can get the proper format with a simple black typeset, but not with color...the tilde (signifying home directory) is omitted.

Example:

\documentclass{article}
\usepackage{listings}
\usepackage{lmodern}
\usepackage[dvipsnames]{xcolor}

\lstset{
showstringspaces=false,
basicstyle=\ttfamily,
columns=flexible,
escapeinside={(*}{*)}
}

\begin{document}
%first prompt is colored but missing the tilde
%second prompt is b/w, but the tilde shows
%   - but the tilde is in the wrong position...
\begin{lstlisting}[caption={Command prompt}]
(*\color{red}root*)(*\color{ForestGreen}@hostname:~\#*)
root@hostname:~#
\end{lstlisting}

\end{document}


I recommend to not use escapeinside for this purpose, as it somewhat defeats the purpose to leave the verbatim environment and use special commands to still get them typeset verbatim. Instead use the features listings provides for styling your code. Here are two suggestions to get the desired result.

# Define keywords

listings allows you to define several sets of keywords where each set can be styled differently. So we can just define set 1 to consist of only the root keyword and apply the red color to this keyword. Green then becomes the default color for your listing. Note that @ has to be redefined as other character to allow listings' keyword parser to properly stop whenever an @ occurs in the input.

\lstset{
basicstyle   = {\ttfamily\color{ForestGreen}},
keywords     = [1]{root},
keywordstyle = [1]{\color{red}},
alsoother    = {@}
}


# Use the literate option

Keywords work quite well in many cases, but sometimes we need to consider a bit more context. In case you only want root to be displayed red when it occurs before an @, you can define a literate rule to replace each literal occurence of root@ by a properly styled replacement text, in that case a red root string and an @ that has the default style.

\lstset{
basicstyle = {\ttfamily\color{ForestGreen}},
literate   = {root@}{{\color{red}root}@}5
}


# EDIT: More pleasant tilde

As noted in one of the comments, the default tilde character is too high for the use in filepaths. The url package provides a more pleasant version that can be used throughout our listings by also using the literate option as mentioned above. We just add the following line to \lstset:

literate={~}{\urltilde}1


where \urltilde is defined as

\newcommand\urltilde{\url{~}}


Here's the (updated) full code for both versions:

\documentclass{article}
\usepackage{listings}
\usepackage{lmodern}
\usepackage[dvipsnames]{xcolor}
\usepackage{url}

\newcommand\urltilde{\url{~}}

\begin{document}

\lstset{
showstringspaces=false,
columns=flexible,
escapeinside={(*}{*)},
basicstyle={\ttfamily\color{ForestGreen}},
keywords=[1]{root},
keywordstyle=[1]{\color{red}},
alsoother={@},
literate={~}{\urltilde}1
}
\begin{lstlisting}[caption={Command prompt}]
(*\color{red}root*)(*\color{ForestGreen}@hostname:~\#*)
root@hostname:~#
\end{lstlisting}

\bigskip

\lstset{
showstringspaces=false,
columns=flexible,
escapeinside={(*}{*)},
basicstyle={\ttfamily\color{ForestGreen}},
literate={root@}{{\color{red}root}@}5 {~}{\urltilde}1
}
\begin{lstlisting}[caption={Command prompt}]
(*\color{red}root*)(*\color{ForestGreen}@hostname:~\#*)
root@hostname:~#
\end{lstlisting}

\end{document}


• This works well with the urltilde. Thanks. One thing I cannot figure out: If I comment out all your sample code below \bigskip (except \end{document}, and also remove the escaped color line from the listing - I still get two prompts. The first without a tilde and the second with. The only thing left in the \lstlisting is "root@hostname:~#" What am I missing? – bgrundy May 6 '19 at 21:18
• Could you edit your question and add the current version of your code? I can only guess that there is some other problem that prevents the old output file from being updated. – siracusa May 7 '19 at 7:51
• I'm not sure what you're asking...Edit the question to include what? And I'm not sure what you mean about 'old output file from being updated'. Thanks. – bgrundy May 12 '19 at 13:32
• You said you still get two lines of output in your listing even though only one is left in the source code. This seems to be a contradiction, which is why I want you to add your exact document to the question. The only situation I can think of in that this scenario can happen, is that your output PDF doesn't get updated due to an error on compilation and you're still looking at the old version. Without verifying that your code is correct I can't help on that issue. – siracusa May 12 '19 at 17:24

Try using \textasciitilde in place of the tilde symbol:

(*\color{red}root*)(*\color{ForestGreen}@hostname:\textasciitilde\#*)

• Thanks for the prompt answer. This seems the simplest option for the code I already have in place, the only issue is that, as the comment in my code indicates, this still places the tilde too high. I'm new to Latex, so perhaps that's a font issue. – bgrundy May 6 '19 at 8:23