Kerning for subscripts of \sigma?

I defined a command \AddtoKernList{<token list>}{<mu kern>} which will add the first token of the <token list> to a lookup table (the assignment is local). Later on, the \sigma command is redefined to to check for a subscript; if the subscript is found, then it looks the first token in the subscript in the lookup list. If that token is found, \mkern<mu kern> is applied right before the subscript.

I search for the subscript using \peek_catcode_remove:NTF. I could've significantly reduced the code if I had used xparse's e-type arguments, as Henri Menke suggested (thanks :-) and egreg did. I'll keep my answer with the first approach, however.

With the defined commands, the input:

$\sigma_{abc} \sigma^a_0 \sigma_0^b \sigma^c_T$

\AddtoKernList{0}{-\thinmuskip}

$\sigma_{abc} \sigma_0^a \sigma^b_0 \sigma^c_T$

\AddtoKernList{T}{-1mu}

$\sigma_{abc} \sigma_0^a \sigma^b_0 \sigma^c_T$

produces (with LuaTeX and lua-visual-debug to show the negative kern):

enter image description here

Notice that the order of subscript and superscript does not matter (anymore, thanks to far too many lines of code) and notice also that the character is kerned only after the \AddtoKernList instruction. To add temporarily a token to this list, do the assignment in a group.

Code:

\documentclass[varwidth]{standalone}
\usepackage{lua-visual-debug}
\usepackage{luatexbase}
\usepackage{unravel}
\usepackage{fontspec}
\usepackage[american,british,french,norsk,german,ngerman]{babel}
\usepackage{mathtools}
\mathtoolsset{mathic=true} %%% See http://tex.stackexchange.com/a/3496/
\usepackage{amssymb}
\usepackage{unicode-math}
\setmainfont[Ligatures=TeX]{TeX Gyre Termes}
\setsansfont{TeX Gyre Heros}[Scale=0.88]
\setmonofont{TeX Gyre Cursor}
\setmathfont[Ligatures=TeX]{TeX Gyre Termes Math}
\setmathfont[Ligatures=TeX,range={\setminus}]{Asana Math}
\setmathfont[Ligatures=TeX,Extension=.otf,range={"2A3E},BoldFont=XITSMath-Bold]{XITSMath-Regular}%%% The fat semicolon
\usepackage[babel=true,verbose=errors]{microtype}

\ExplSyntaxOn
\tl_new:N \l__userxlixk_kern_case_tl
\AtBeginDocument{
  \cs_new_eq:NN \__userxlixk_actual_sigma: \sigma
  \RenewDocumentCommand\sigma{}
    { \__userxlixk_sigma: }
}
\NewDocumentCommand\AddtoKernList{mm}
  {
    \tl_put_right:Nn \l__userxlixk_kern_case_tl
      { { #1 }{ \tex_mskip:D #2 \scan_stop: #1 } }
  }
\cs_new_protected:Npn \__userxlixk_sigma:
  {
    \peek_catcode_remove:NTF \c_math_subscript_token
      { \__userxlixk_sigma_check_group:n }
      { \__userxlixk_sigma_check_superscript: }
  }
\cs_new_protected:Npn \__userxlixk_sigma_check_group:n #1
  {
    \exp_args:NNf
    \__userxlixk_actual_sigma: \c_math_subscript_token
      { \__userxlixk_check_kern_list_use:n {#1} }
  }
\cs_new_protected:Npn \__userxlixk_sigma_check_superscript:
  {
    \peek_catcode_remove:NTF \c_math_superscript_token
      { \__userxlixk_sigma_check_sub_after_sup:n }
      { \__userxlixk_actual_sigma: }
  }
\cs_new_protected:Npn \__userxlixk_sigma_check_sub_after_sup:n #1
  {
    \peek_catcode_remove:NTF \c_math_subscript_token
      { \__userxlixk_sigma_sub_after_sup:nn {#1} }
      { \__userxlixk_actual_sigma: \c_math_superscript_token {#1} }
  }
\cs_new_protected:Npn \__userxlixk_sigma_sub_after_sup:nn #1 #2
  {
    \exp_args:NNf
    \__userxlixk_actual_sigma: \c_math_subscript_token
      { \__userxlixk_check_kern_list_use:n {#2} }
    \c_math_superscript_token {#1}
  }

\cs_new:Npn \__userxlixk_check_kern_list_use:n #1
  { \__userxlixk_check_kern_list_use:Nw #1 \q_stop }
\cs_new:Npn \__userxlixk_check_kern_list_use:Nw #1 #2 \q_stop
  {
    \exp_args:NNo
    \tl_case:NnF #1
      { \l__userxlixk_kern_case_tl }
      {#1}
    #2
  }
\ExplSyntaxOff

\begin{document}

$\sigma_{abc} \sigma^a_0 \sigma_0^b \sigma^c_T$

\AddtoKernList{0}{-\thinmuskip}

$\sigma_{abc} \sigma_0^a \sigma^b_0 \sigma^c_T$

\AddtoKernList{T}{-1mu}

$\sigma_{abc} \sigma_0^a \sigma^b_0 \sigma^c_T$

\end{document}

If you prefer the e-type argument you can add my lookup list to egreg's answer:

\AtBeginDocument{%
  \let\standardsigma\sigma
  \let\sigma\kernedsigma
}
\ExplSyntaxOn
\tl_new:N \l__userxlixk_kern_case_tl
\NewDocumentCommand\AddtoKernList{mm}
  {
    \tl_put_right:Nn \l__userxlixk_kern_case_tl
      { { #1 }{ \tex_mskip:D #2 \scan_stop: #1 } }
  }
\cs_new:Npn \__userxlixk_check_kern_list_use:n #1
  { \__userxlixk_check_kern_list_use:Nw #1 \q_stop }
\cs_new:Npn \__userxlixk_check_kern_list_use:Nw #1 #2 \q_stop
  {
    \exp_args:NNo
    \tl_case:NnF #1
      { \l__userxlixk_kern_case_tl }
      {#1}
    #2
  }
\cs_new_eq:NN \CheckKernListUse \__userxlixk_check_kern_list_use:n
\ExplSyntaxOff

\NewDocumentCommand{\kernedsigma}{e{_^}}{%
  \csname exp_args:NNf\endcsname
  \standardsigma_
    {\IfValueT{#1}{\CheckKernListUse{#1}}}%
  \IfValueT{#2}{^{#2}}%
}

I'd use the e argument type of xparse.

\documentclass{book}
\usepackage{fontspec}
\usepackage[american,british,french,norsk,german,ngerman]{babel}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{unicode-math}
\usepackage[babel=true,verbose=errors]{microtype}

\setmainfont{TeX Gyre Termes}
\setsansfont{TeX Gyre Heros}[Scale=0.88]
\setmonofont{TeX Gyre Cursor}
\setmathfont{TeX Gyre Termes Math}
\setmathfont{Asana Math}[
  range={\setminus},
]
\setmathfont{XITSMath-Regular}[
  Extension=.otf,
  range={"2A3E},
  BoldFont=XITSMath-Bold,
]

%\mathtoolsset{mathic=true} %%% See http://tex.stackexchange.com/a/3496/

\AtBeginDocument{%
  \let\standardsigma\sigma
  \let\sigma\kernedsigma
}

\NewDocumentCommand{\kernedsigma}{e{_^}}{%
  \standardsigma
  \IfValueT{#1}{_{\!#1}}%
  \IfValueT{#2}{^{#2}}%
}

\begin{document}

\[\sigma_0 \sigma_0^2 \sigma^2_0\]
\[\standardsigma_{\!0} \standardsigma_{\!0}^2 \standardsigma^2_{\!0}\]

\end{document}

enter image description here