# How can I properly align the line numbers of a source code listing with the margin?

I want to include a code snippet in a document using the listings package. In my document, I have the following:

\begin{figure}[!htbp]
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0pt}%
\begin{center}
\lstset{language=Java, numbers=left, showspaces=false,
showstringspaces=false, tabsize=2, breaklines=true}

\begin{lstlisting}
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
\end{center}
\vspace{-12pt}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}


When I generate my PDF document using pdflatex, the line numbers are too far to the left - I don't want them to be in the margin. (See image below.) How can I correct this?

-

You can use \begin{lstlisting}[xleftmargin=5.0ex] to adjust the left margin, or add this option to \lstset. This will move your listing to the right including the lines numbers and any frames.

The lipsum package is used to provide some dummy text before the listing. I also included the geometry package with [showframe] option to see the margins.

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{lipsum}
\usepackage{listings}
\begin{document}
\lipsum[1]

\begin{figure}[!htbp]
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0pt}%
%\begin{center}
\centering
\lstset{language=Java, numbers=left, showspaces=false,
showstringspaces=false, tabsize=2, breaklines=true,
xleftmargin=5.0ex,
%numberstyle=\scriptsize,numbersep=0pt
}

\begin{lstlisting}
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
%\end{center}
%\vspace{-12pt}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
\end{document}


As pointed out by @Mico, you should use \centering instead of \begin{center}...\end{center}. This would also allow you to eliminate the \vspace{-12pt}. See Should I use center or centering for figures? for more details. In case someone copies the above code and does not read the other solutions, I have made those changes in the code, and left your original code as comments.

Align Number to just right of column

If you are tight on space and want to align the numbers just to the right of the column, then use:

\newlength{\MaxSizeOfLineNumbers}%
\settowidth{\MaxSizeOfLineNumbers}{99}% Adjust to maximum number of lines


and set:

xleftmargin=\MaxSizeOfLineNumbers


The 2.5ex is the adjustment that gets the numbers just to the left of the margin, and we shift over by the width of the digits 99.

This of course assumes that the number of lines in your listings is less than 100, so adjust accordingly. Also, if you happen to change the number style using something like numberstyle=\tiny, the {99} parameter should be adjusted accordingly to {\tiny 99}.

-

The listings package typesets line numbers via the macro \lst@PlaceNumber. This macro has different meanings based on the value specified to the key numbers. However, the margin alignment key xleftmargin has no connection with the elements contained within \lst@PlaceNumber, making it difficult to accurately have the numbers flush with the left margin. Even though @JanHlavacek's answer does a good job of adding length elements together such that the listing line numbers are flush with the left margin, I think a redefinition of \lst@PlaceNumber provides the user with much more control over the spacing of the line number and separator, and makes for a much easier adjustment with xleftmargin. For example,

\makeatletter
\def\lst@PlaceNumber{%
\makebox[3em][l]{\normalfont\lst@numberstyle{\thelstnumber}}%
}
\makeatother


places the number in a left-aligned box of width 3em (thereby fixing the width and not having to bother with the line number separator or shifting of the left margin). As such, the meaning of xleftmargin has been modified and is more readily understood as the indent of the entire listing, including the line numbers.

Here is an example:

\documentclass{article}
\usepackage[showframe]{geometry}% http://ctan.org/pkg/geometry
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{lipsum}% http://ctan.org/pkg/lipsum

\begin{document}

\newlength{\linenumwidth} \setlength{\linenumwidth}{3em}% Redefine as required
\makeatletter
\def\lst@PlaceNumber{%
\makebox[\linenumwidth][l]{\normalfont\lst@numberstyle{\thelstnumber}}%
}
\makeatother

\lipsum[1]
\begin{figure}[!htb]
\centering
\lstset{language=Java, showspaces=false,%
showstringspaces=false, tabsize=2, breaklines=true}
\begin{lstlisting}[firstnumber=8]
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
\lipsum[2]

\end{document}


Here is an example that indents the entire listing by 20pt:

\lstset{language=Java, showspaces=false, xleftmargin=20pt,%
showstringspaces=false, tabsize=2, breaklines=true}


Here is a slightly more complicated line number alignment:

\usepackage{calc}% http://ctan.org/pkg/calc
...
\makeatletter
\newlength{\linenumwidth} \setlength{\linenumwidth}{3em}% Redefine as required
\newlength{\numwidth}%
\setlength{\numwidth}{\widthof{\normalfont{\lst@numberstyle{99}}}}% Up to 2-digit (99) line numbers
\def\lst@PlaceNumber{%
\makebox[\numwidth+1em][l]{%
\makebox[\numwidth][r]{\normalfont\lst@numberstyle{\thelstnumber}}%
}%
}
\makeatother


-

You could issue the instruction

\lstset{numberstyle=\scriptsize,numbersep=3pt}


to reduce the fontsize and horizontal separation of the line numbers.

Incidentally, if you replace the pair of commands \begin{center} ... \end{center} with the single instruction \centering, you can get rid of the command \vspace{-12pt} before the \caption command as well. :-)

-
That reduces the spacing, but the numbers are still in the margin. Try with \usepackage[showframe]{geometry}. But, good point about \centering. – Peter Grill Oct 5 '11 at 2:11
@PeterGrill: Maybe I misunderstood the OP's point about the distance between the line numbers and listing: I thought the OP just wanted to reduce this distance (I believe the default separation is 10pt) while leaving the numbers in the margin. Indeed, if the numbers are not to protrude into the margin at all, one would have to issue a command such as \lstset{numbersep=5pt,xleftmargin=10pt}. Cheers! – Mico Oct 5 '11 at 2:28
+1 for the helpful advice on centering. I've also clarified the wording of the question to make it clearer that I don't want the line numbers in the margin. – kc2001 Oct 5 '11 at 2:35
Is the centering actually doing anything here? I think the width of the listing is \textwidth, so centering it on a page will not actually change anything. Perhaps if a line in the listing was too long, centering it would make the listing stick out by the same amount on both sides. – Jan Hlavacek Oct 5 '11 at 3:19
@JanHlavacek: you're correct about the \centering command not doing anything if the listing width is equal to \textwidth, which is the default setting. My point was more about avoiding the extra vertical whitespace created by the center environment. – Mico Oct 5 '11 at 9:40

I am not sure how exactly do you want your numbers to be aligned to the margin, but you can start with this and play with it:

\documentclass{article}
\usepackage{listings}
\usepackage{lipsum}

\newdimen\numbersdimen

\begin{document}
\lipsum[1]
\begin{figure}[!htbp]
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0pt}%
\begin{center}
% calculate xleftmargin:
\numbersdimen=2em% reserve space for 2 digit numbers

\lstset{language=Java, numbers=left, showspaces=false,
showstringspaces=false, tabsize=2, breaklines=true,
xleftmargin=\numbersdimen}

%make numbers left aligned, so they will align with the margin
\renewcommand*\thelstnumber{\hbox to 2em{\the\value{lstnumber}\hfil}}

\begin{lstlisting}[firstnumber=8]
public class AutoRegistry {
public void registerCar(int ssn, int vin) {
// ...
PersonCarDirect personCar = new PersonCarDirect();
personCar.setId(ssn);
personCar.setVin(vin);
// ...
}
}
\end{lstlisting}
\end{center}
\vspace{-12pt}
\caption{AutoRegistry client class}
\label{fig:autoRegistryClientC}
\end{figure}
\lipsum[1]

\end{document}


The main idea is to use the xleftmargin option for listings.

-

Here is a mix of Peter Grill's automatic width detection (Align Number to just right of column), Werner's \lst@PlaceNumber, and my own bit which uses the totcount package and some ugly code to remember the maximum lstnumber, and loop across all numbers looking for the largest. I do this in case for example 9999 would be wider than 11111, and your biggest line number would be 11111. This is not the case with LaTeX's default font, but it might be for another font, or you might have some conditional stuff when typesetting the line number.

Note that you'll need to process this through LaTeX twice (because it stores the maximum line number in the aux file, and uses the previous run's value to compute the reserved width).

\documentclass{article}
\usepackage{lipsum}

\usepackage{listings}
\usepackage{totcount}
\newcounter{maxlstnumber}
\regtotcounter{maxlstnumber}
\def\updatemaxlstnumber{%
\ifnum\value{lstnumber}>\value{maxlstnumber}%
\setcounter{maxlstnumber}{\the\value{lstnumber}}%
\fi%
}
\lstset{numbers=left, gobble=2, numbersep=5pt, firstnumber=11109, escapeinside={//*}{*//}}
\newlength{\MaxSizeOfLineNumbers}%

\makeatletter
% The following command allows you to customize line number style, without affecting \ref{}.
% Here, the style is "\thelstnumber." (with a dot at the end)
\def\renderlstnumber{\normalfont\lst@numberstyle{\thelstnumber.}\kern\lst@numbersep}
\def\lst@PlaceNumber{\updatemaxlstnumber\makebox[\MaxSizeOfLineNumbers][r]{\renderlstnumber}}
% This must be called after \begin{document}
\def\autosizelstnumber{
\newlength{\LoopSizeOfLineNumber}
\setcounter{lstnumber}{\the\totvalue{maxlstnumber}}
\loop\ifnum\value{lstnumber}>\z@
\settowidth{\LoopSizeOfLineNumber}{\renderlstnumber}
\ifdim\LoopSizeOfLineNumber>\MaxSizeOfLineNumbers
\setlength{\MaxSizeOfLineNumbers}{\LoopSizeOfLineNumber}
%\message{Found larger line number \the\value{lstnumber}}
\fi
\repeat
%  \setcounter{maxlstnumber}{0}
}
\makeatother

\begin{document}
\autosizelstnumber

\parindent 0pt

\lipsum[1]

\begin{lstlisting}
aline
bline//*\label{bline}*//
yet another line//*\label{largestline}*//
\end{lstlisting}

Line \ref{bline} contains the character \verb!b!. Notice that even
though the line numbering says \ref{bline}.'', the
\verb!\ref{bline}! used here says \ref{bline}''. The dot is taken
into account when calculating the width to reserve for line numbers.

\begin{lstlisting}[firstnumber=123]
class Foo {
public static void main() {}
}//*\label{lastline}*//
\end{lstlisting}

Notice that even if we end with line \ref{lastline}, the with reserved
for line numbers is large enough to include \ref{largestline}, the
largest line.

\lipsum[2]

\end{document}

-