[Tex/LaTex] Listings: line number separator rule

line-numberinglistingsrules

Here I found a similar question with horizontal rule, which answer I don't understand to a degree I could use it to solve my problem:

Adding a horizontal rule between caption and lstlisting inside a tcolorbox


I am looking for a separator rule for line numbers when the frame rule has already been extended to include the line numbers (Would be nice if it was possible with just the listings package).
See this example:

Listings: recognize numbers and `1e-3`
sample


Minimal working example:

\documentclass{report}

\usepackage{xcolor}
\definecolor{halfgray}{gray}{0.55}
\definecolor{ipython_frame}{RGB}{207, 207, 207}

\usepackage{listings}

\lstdefinelanguage{iPython}{
    commentstyle=\color{cyan}\ttfamily,
    stringstyle=\color{red}\ttfamily,
    keepspaces=true,
    showspaces=false,
    showstringspaces=false,
    %
    rulecolor=\color{ipython_frame},
    frame=single,
    frameround={t}{t}{t}{t},
    framexleftmargin=6mm,
    numbers=left,
    numberstyle=\tiny\color{halfgray},
    %
    basicstyle=\scriptsize\ttfamily,
    keywordstyle=\color{green}\ttfamily,
}

\begin{document}
\begin{lstlisting}[language=iPython]
import math
import numpy as np
from lib.analytical import csa

sin2_theta  = np.sin(theta)**2
+= -= *= /= + - * / ? < > & % == <=
# += -= *= /= + - * / ? < > & % == <=
def test(a=100, b=True):
    <= >= == 2 + 3j * 7e-3
\end{lstlisting}
\end{document}

Best Answer

A rather hacky solution is to use tcolorbox for the border so that you can use listings frame for the rule. Tcolorbox provides a library for boxes that contain listings and minted codes. Below is a minimal setting but you have lots of room for improvement since tcolorboxes are highly customizable:

\documentclass{report}

\usepackage{xcolor}
\definecolor{halfgray}{gray}{0.55}
\definecolor{ipython_frame}{RGB}{207, 207, 207}
\usepackage{tcolorbox}

\tcbuselibrary{listings}%
\usepackage{lipsum}
\usepackage{listings}
\tcbset{listing engine={listings}}

\lstdefinelanguage[]{iPython}[]{python}{
    commentstyle=\color{cyan}\ttfamily,
    stringstyle=\color{red}\ttfamily,
    keepspaces=true,
    showspaces=false,
    showstringspaces=false,
    %
    rulecolor=\color{ipython_frame},
    frame=l,
    numbers=left,
    numberstyle=\tiny\color{halfgray},
    xleftmargin={0.75cm},
    %
    basicstyle=\scriptsize\ttfamily,
    keywordstyle=\color{green}\ttfamily,
}

\begin{document}
\lipsum[1]
\begin{tcblisting}{boxrule=1pt, listing only,listing options={language=iPython}}
import math
import numpy as np
from lib.analytical import csa

sin2_theta  = np.sin(theta)**2
+= -= *= /= + - * / ? < > & % == <=
# += -= *= /= + - * / ? < > & % == <=
def test(a=100, b=True):
    <= >= == 2 + 3j * 7e-3
\end{tcblisting}
\lipsum[2]
\end{document}

Which will give you this:

enter image description here

A quick note on defining new language in listings: You can use a base dialect for the new language so you don't need to define all the keywords from scratch.

\lstdefinelanguage
   [[hdialecti]]{hlanguagei}
   [[hbase dialecti]{hand base languagei}]
   {hkey=value listi}
   [[hlist of required aspects (keywordcomments,texcs,etc.)]]

hence \lstdefinelanguage[]{iPython}[]{python}.