As regras de avaliação do Vim são diferentes da maioria das linguagens de programação. Você precisa usar :execute para avaliar uma variável (ou expressão); caso contrário, é tomado literalmente; Ou seja, o Vim usa o próprio nome da variável como argumento.
let type = expand('%:e')
execute 'au BufNewFile *.' . type 'so ~/.vim/' . type . '_header.txt'
Provavelmente usaria printf() em vez de concatenação para melhorar a legibilidade.
execute printf('au BufNewFile *.%s so ~/.vim/%s_header.txt', type, type)
Note que com a sua abordagem, você está basicamente duplicando a detecção de tipo de arquivo , que já fornece um mapeamento de extensões de arquivos para tipos. Eu prefiro definir um gancho genérico em BufNewFile e, em seguida, avaliar &filetype . Você só precisa ter certeza de que o seu evento está definido após aquele para a detecção do tipo de arquivo, por exemplo movendo a definição de ~/.vimrc para um script ~/.vim/plugin/ .