# Unindent code inserted with \lstinputlisting

Is it possible to unindent the code inserted using \lstinputlisting? In particular I'd like to be able to unindent by a fixed amount of whitespace.

I have to write a relation on a OS scripting course and I'd like to include the sources of some bash scripts. I noticed that gobble is ignored by \lstinputlisting but I'd like to avoid to copy-paste the code and unindent it by hand. Is there any solution for this?

• Well, as the documentation states, gobble has no effect when using lstinputlisting. Is it impractical to unindent by hand? Do you have a large code section, or lots of files to be unindented? In any event, you may want to give a try to the minted package. Nov 19 '12 at 15:11
• @guillem No, I could unindent by hand but they are about 600 lines of code and I'd like to avoid unindenting too many blocks by hand. I'll give a try to the minted package. Nov 19 '12 at 15:48
• Just to add some information here, the gobble option of minted package works well on \inputminted[gobble=n,...]{language}{file}. It eliminates the first n characters, even if they are not whitespaces. Nov 20 '12 at 14:07
• @Bakuriu: if you do not need sytax highliting you can use \VerbatimInput from package fancyvrb It takes gobble into account
– user2478
Nov 21 '12 at 7:05

According to listings documentation, this is not possible:

Could I use ‘gobble’ together with ‘\lstinputlisting’ ? Yes, but it has no effect.

The minted package, on the other hand, will gobble files that are inserted to a document using

\inputminted[gobble=n,...]{language}{file}


Be warned that, in this case, the minted package will remove the first n characters of each line of the input file, whether these characters are whitespaces or not.

• minted is (somewhat) deprecated... May 19 '19 at 3:04

package fancyvrb can handle the gobble option

\documentclass{article}
\usepackage{fancyvrb}

\begin{document}
\VerbatimInput[gobble=4]{\jobname.tex}
\end{document}


There is a way to use something like gobble with lstinputlistings by using the xkeyvalpackage. The idea is based on this answer to a related question.

The basic idea is to shift the whole content to the left using xleftmargin and adapt the position of the numbers by numbersep. First we define a command which simply holds the argument passed to the basicstyle key of lstlistings

\def\lsttextstyle{\footnotesize\ttfamily}


This is used when defining a new length that holds the length of a whitespace in that specific textformat (it is used again in the \lstset part)

\newlength{\myspace}
\settowidth{\myspace}{\lsttextstyle{\ }}


Additionaly to length will be needed for the macro following

\newlength{\mytemp}
\newlength{\mytempb}


Then using the package xkeyval we define a new key called xgobble

\makeatletter
\define@key{lst}{xgobble}{%
\setlength{\mytemp}{\lst@xleftmargin}
\def\lst@xleftmargin{\mytemp}%
\setlength{\mytempb}{\lst@numbersep}
\def\lst@numbersep{\mytempb}%
}
\makeatother


Using the current value xleftmargin to set \mytemp subtracting the length of one whitespace multiplied by the value passed to xgobble and writing the result back to xleftmargin the whole code is shifted to the left. The similar thing is done with numbersepto shift the numbers back to the right (their original position).

It can simply be used like

\lstinputlisting[xgobble=<value>]{sourcecode.file}


Here is the full MWE

\documentclass{scrartcl}

\usepackage{listings}
\usepackage{xkeyval}

\def\lsttextstyle{\footnotesize\ttfamily}

\lstset{
language=bash,
xleftmargin=4\myspace,
basicstyle=\lsttextstyle,
numbers=left,
numbersep=2\myspace
}

\newlength{\myspace}
\settowidth{\myspace}{\lsttextstyle{\ }}

\newlength{\mytemp}
\newlength{\mytempb}

\makeatletter
\define@key{lst}{xgobble}{%
\setlength{\mytemp}{\lst@xleftmargin}
\def\lst@xleftmargin{\mytemp}%
\setlength{\mytempb}{\lst@numbersep}
\def\lst@numbersep{\mytempb}%
}
\makeatother

\begin{document}
This is the normal code of the full script
\begin{verbatim}
\lstinputlisting{testcode.sh}
\end{verbatim}
\lstinputlisting{testcode.sh}
now the echo part without indentation
\begin{verbatim}
\lstinputlisting[linerange={6-8}]{testcode.sh}
\end{verbatim}
\lstinputlisting[linerange={6-8}]{testcode.sh}
and now three examples with indentation
\begin{verbatim}
\lstinputlisting[linerange={6-8},xgobble=2]{testcode.sh}
\lstinputlisting[linerange={7-8},xgobble=4]{testcode.sh}
\lstinputlisting[linerange={7-8},xgobble=0]{testcode.sh}
\end{verbatim}
\lstinputlisting[linerange={6-8},xgobble=2]{testcode.sh}
\lstinputlisting[linerange={7-8},xgobble=4]{testcode.sh}
\lstinputlisting[linerange={7-8},xgobble=0]{testcode.sh}

\end{document}


... and the example bash script which probably doesn't even work:

#!/bin/bash

echo "Hello World!"

if ( whatever ) ;
echo "this"
echo "is"
echo "indented"
echo "and this is an incredible long line to check if linebreaking still works fine"
fi


Since I know hardly anything about xkeyval, I am not sure how stable that whole construct is.