Is it a listings package bug?

Yes, it's a bug and a very old one.

The lstlisting environment does, at the end, \let\if@nobreak\iffalse, which is wrong because it's a local assignment, whereas the kernel command \@nobreakfalse does the job globally.

\documentclass{article}
\usepackage{listings}

\makeatletter
\let\lstlisting\relax
\let\lstlisting@\relax
\lstnewenvironment{lstlisting}[2][]{%
     \lst@TestEOLChar{#2}%
     \lstset{#1}%
     \csname\@lst @SetFirstNumber\endcsname
   }{%
     \@nobreakfalse
     \csname\@lst @SaveFirstNumber\endcsname
   }
\makeatother


\begin{document}

\section{Title}
\begin{lstlisting}
lstlisting content
\end{lstlisting}
text

\section{Title}
text
\begin{lstlisting}
lstlisting content
\end{lstlisting}
text

\section{Title}
text
\end{document}

enter image description here


This seems to be related to the way listings places its output if it is the first box after a section title (I didn't really investigate). You can work around this by placing a \leavevmode after \section and before \begin{lstlisting}:

\documentclass{article}
\usepackage{listings}
\begin{document}

\section{Title}
\leavevmode
\begin{lstlisting}
lstlisting content
\end{lstlisting}
text

\section{Title}
text
\begin{lstlisting}
lstlisting content
\end{lstlisting}
text

\section{Title}
text
\end{document}

enter image description here

Tags:

Listings