# Putting a lstlisting in a minipage breaks xleftmargin settings

I want to display a listing in a gray box with some space around the sides.
I've set up \lstset the way I like it:

\lstset{basicstyle=\ttfamily,keywordstyle=\bfseries
xleftmargin=\parindent,  <<--- minipage breaks this setting.
backgroundcolor=\color{light-gray},
framexleftmargin=\parindent,
framextopmargin=6pt,
framexbottommargin=6pt,
frame=tb, framerule=0pt}


I don't want page breaks in short listings. I fix this using a minipage. However this breaks my margin settings.

\documentclass[]{article}
\usepackage{float}
\usepackage{listings}
\usepackage{color}
\usepackage[margin=1in]{geometry}
%\usepackage{fontspec}
%\setmonofont{Bitstream Vera Sans Mono}[Scale=0.85]
\definecolor{light-gray}{gray}{0.95}
\definecolor{darkgreen}{RGB}{0,64,0}
framexleftmargin=\parindent,
framextopmargin=6pt,
framexbottommargin=6pt,
frame=tb, framerule=0pt}
\begin{document}
\section{listing}
\noindent
\begin{minipage}[H]{\linewidth}
\begin{lstlisting}[language=Delphi,caption={get the next block},label={ref:bitset_next},
keywords={function,int,asm,end},xleftmargin=\parindent]
function bitset.next(previous_block_index: int): int;
//***************************************************************************
//pseudo code:
//***************************************************************************
//Load the bitset into a register
//shift out the bits that we've already processed
//count the number of inactive blocks
//next_block_index = previous_block_index + inactive_blocks_inbetween + 1
asm
//rcx = self = pointer to bitset
//edx = previous_block_index
mov rax,[rcx]            //rax = bitset.
lea ecx,[edx+1]          //go to the next bit
shr rax,cl               //shift out the bits we've already processed
tzcnt rax,rax            //count empty positions to skip
add eax,ecx              //return (prev+1+empty positions found)
end;
\end{lstlisting}
\end{minipage}
\end{document}


This produces the following output:

If I remove the \noindent and the minipage it looks like this.

Which has the correct indentation inside the listing. How do I get the listing to not have a page break inside, but keep the correct spacing inside the gray box.

I've tried

\begin{lstlisting}[float,floatplacement=H]


But that produces the same output as the minipage above.

• Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. – Arzigoglu Jul 6 '17 at 11:24
• \parindent is set to zero in a minipage. – egreg Jul 6 '17 at 11:34

Thanks to @egreg. I found the answer here: How to preserve the same parskip in minipage

Simply copy pasting the above linked answer will yield a gray background that extends beyond the rest of the text, so some adjustments are needed.

The fix is to define a new -fixed- length that will replace the variable \parindent inside the minipage.

The following change fixes the issue:

\newlength{\listingindent}                %declare a new length
\setlength{\listingindent}{\parindent}    %make it a fixed version of \parindent
xleftmargin=\listingindent,         <<-- make fixed
framexleftmargin=\listingindent,    <<-- make fixed
framextopmargin=6pt,
framexbottommargin=6pt,
frame=tlrb, framerule=0pt,linewidth=\linewidth}
....
\noindent      <<-- force noident, or the frame will appear out of bounds
\begin{minipage}[H]{\linewidth}
\begin{lstlisting}[language=Delphi,caption={get the next block},label={ref:bitset_next},
keywords={function,int,asm,end}]
function bitset.next(previous_block_index: int): int;
...
\end{lstlisting}
\end{minipage}


Now it looks like this:

No page breaks in the middle of a listing and no misaligned background.