In the world of listings
, there are mainly three kinds of characters: letter, digit, and other. (It is not pronounce or adjective, but a class named o-t-h-e-r literally.) The manual says that all keywords (should) consist of a letter followed by alpha-numeric characters. That is to say that ab
, a2
are good keywords and that 12
, 1b
, 1?
, a?
, !b
, !2
, and !?
are not keywords.
So, what makes others so special? An answer is that others are used to separate tokens. In your example, we recognize print
as a method/function because it is separated by .
/::
and ()
. Otherwise if .
and :
were letters we can only see two tokens, namely my_class.print()
and my_class::print
.
In this example, only the second bar
is bold because listings
sets alsoletter={.},
for [5.0]Lua
.
\begin{lstlisting}[language={[5.0]Lua},morekeywords={bar}]
foo.bar
foo:bar
\end{lstlisting}
But sometimes we really need to color such symbols. So listings
allows one to write otherkeywords={=>}
. Notice that the second bar
is still bold --- because listings
still regards =
as other.
\begin{lstlisting}[language={Haskell},morekeywords={bar}]
foo=>bar
foo<=bar
\end{lstlisting}
But otherkeywords
does not support class number. In your example,
classoffset=2,
keywordstyle=\hakuna,
morekeywords={matata},
is equivalent to keywordstyle=[2]\hakuna
, meaning applying \hakuna
for all second class keyword, and morekeywords=[2]{matata}
, meaning adding matata
as a second class keyword.
However, as in your question 1, there is no otherkeywords=[2]
syntax.
For question 2 it is hard to tell why it works. The remaining is my guess: writing morekeywords=[3]{Aal::Izz.Well}
will make listings
add Aal::Izz.Well
as a third class key word. But listings
will not see this keyword when parsing your code because, as I explained, others separates tokens. However, otherkeywords={Aal::Izz.Well}
forces listings
take a look, after it reads Aal
, at :
and do further checks.
You may try something like:
\lstnewenvironment{print}{%
\lstset{style=PRETTYPRINT}
\tracingmacros1
\lstset{morekeywords=[1]{Aal::Izz.Well}}
\tracingmacros0
\lstset{otherkeywords={Aal::Izz.Well}}
}{}
and found that even otherkeywords
add the keyword to the first class. The latter appear to be in the third class. (guess why~~)
Best Answer
The
keyval
approaches all avoid expanding input, so in your\lstset{\flags}
example the code sees\flags
and not the content of the macro. The error message here is a bit unhelpful as it is expanded by TeX, so it looks like what you expect! You need to expand the input before applying the keyval macro(I assume the real problem has this wrapped up inside a macro or similar, where you can do the appropriate expansion.)