Como posso fazer colorizar os arquivos .dotfiles com destaque de origem por padrão?

4

Normalmente, quando eu gato um arquivo como este

édifícillersemcolorir.

Euconseguiobtercatparausarorecursodedestaquecomoeste:

cdc(){forfnin"$@"; do
    source-highlight --out-format=esc -o STDOUT -i $fn 2>/dev/null || /bin/cat $fn
  done; }; alias cat='cdc'

que agora produz o seguinte para uma extensão de arquivo reconhecida - .sh neste caso:

Noentanto,semo.sh,porex.seoarquivoéchamadoapenasde.bash_functions,acolorizaçãonãoacontece-porqueaextensãodoarquivonãoéconhecida.

Existealgumamaneiradeobtercolor-highlightparacolorirarquivosdeponto(arquivosquecomeçamcomumponto)comoshcolors?

btwissosebaseiaem Como posso colorir a saída do gato, incluindo tipos de arquivos desconhecidos em b & w?

man source-higlight mostra o seguinte, mas não estou claro o que fazer:

...
--outlang-def=filename
      output language definition file

--outlang-map=filename
      output language map file (default='outlang.map')

--data-dir=path
      directory where language definition files and language maps are searched for.   If  not  specified
      these files are searched for in the current directory and in the data dir installation directory

--output-dir=path
      output directory

--lang-def=filename
      language definition file

--lang-map=filename
      language map file  (default='lang.map')

--show-lang-elements=filename
      prints the language elements that are defined

      in the language definition file

--infer-lang
      force to infer source script language (overriding given language specification)
    
por Michael Durrant 07.06.2015 / 03:03

4 respostas

2

Defina sua função cdc como

cdc() {
    for fn do
        if [[ "${fn##*/}" == .* ]]
        then
            source-highlight --src-lang=sh --out-format=esc -i "$fn"
        else
            source-highlight               --out-format=esc -i "$fn"
        fi 2> /dev/null  ||  /bin/cat "$fn"
    done
}
  • for fn do é a abreviação de for fn in "$@"; do .
  • ${fn##*/} analisa o valor de $fn e remove tudo desde o começo até (e incluindo) o último / . Ou seja, se $fn for um nome de caminho completo, essa será apenas a parte do nome do arquivo.
  • [[ (the_above) == .* ]] cheques se o nome do arquivo corresponde ao padrão .* glob / curinga; ou seja, se o nome do arquivo começa com . . Observe que esse uso de == funciona somente dentro de [[ … ]] ; não funciona dentro de [ … ] .
  • Então, se $fn for um "arquivo de ponto", execute source-highlight com a opção --src-lang=sh .

    • Você deve sempre colocar referências de variáveis de shell entre aspas duplas a menos que você tenha uma boa razão para não e você tem certeza de que sabe o que está fazendo. Nomes de arquivos Unix / Linux podem conter espaços. Se você tivesse um arquivo chamado foo bar e dissesse /bin/cat "foo bar" , cat exibiria o conteúdo do arquivo foo bar . Mas, se você disse cdc "foo bar" (com a versão atual da sua função cdc ), você executaria source-highlight com -i foo bar , que procuraria por um arquivo chamado foo e geralmente faria uma bagunça das coisas. E assim, ele falharia, e sua função tentaria /bin/cat foo bar , que também falhará. Usar "$fn" faz esse trabalho para nomes de arquivos que contêm espaços.
    • O programa cp requer que você especifique, na lista de argumentos, o nome do arquivo ou diretório para o qual você deseja gravar. Esta é uma das poucas exceções à regra de que a maioria dos programas gravar na saída padrão por padrão (a menos que você especifique de outra forma). Você não precisa dizer -o STDOUT e gostaria de saber por que o (s) autor (es) do programa tornou possível que você especificasse isso.

    E, sim, percebo que você acabou de copiar tudo isso da resposta à sua outra pergunta.

  • Obviamente, se $fn não for um arquivo de ponto, basta executar source-highlight da maneira normal e verificar se há uma extensão.
  • Observe que 2> /dev/null e || /bin/cat "$fn" podem ser feitos para o bloco if … then … else … fi na sua totalidade; eles não precisam ser repetidos para cada filial.

Hmm. Minha versão de source-highlight (3.1.7) tem uma opção --src-lang=LANGUAGE ( -s LANGUAGE , como usado por yaegashi, para breve). Acabei de perceber que não está no excerto da página source-highlight man você incluiu na sua pergunta. Então, obviamente se sua versão de source-highlight não suportar essa opção, minha resposta não vai funcionar para você. (E, claro, nem o yaegashi.) Se esse for o caso, você deve ver se consegue instalar a versão 3.1.7 (ou compatível) de source-highlight .

    
por 07.06.2015 / 06:47
3

Especifique -s sh somente quando $fn se parecer com um arquivo de ponto.

cdc() {
  for fn in "$@"; do
    OPTIONS="-f esc"
    case "${fn##*/}" in
      .*) OPTIONS="$OPTIONS -s sh" ;;
    esac
    source-highlight $OPTIONS -i "$fn" 2>/dev/null || \cat "$fn"
  done
}
alias cat=cdc

Você pode adicionar outras regras de correspondência de nome de arquivo personalizado em case .

    
por 07.06.2015 / 05:51
3

yaegashi tem a ideia certa , embora eu faça assim:

cdc() {
    for path
    do
        command=(source-highlight --out-format=esc -o STDOUT --failsafe)
        case "${path##*/}" in
            .*) command+=(-s sh)
                ;;
        esac
        "${command[@]}" -i "$path"
    done
}
  • --failsafe age como cat se a linguagem não puder ser detectada - muito melhor do que ignorar todos os erros
  • Usa uma matriz para os argumentos de comando
por 07.06.2015 / 13:16
2

Além de observar a extensão do arquivo, o source-highlight tem algumas outras maneiras de detectar o idioma. Você poderia anotar seus arquivos de script de shell assim:

  1. A linha shabang: coloque #!/bin/sh ou #!/bin/bash na primeira linha do arquivo.
  2. Anotações de tipo de arquivo no estilo Emacs: adicione um comentário como # -*- shell -*- ou # -*- bash -*- no arquivo (não precisa ser a primeira linha).

Para mais detalhes, consulte Como o idioma de entrada é descoberto no manual do source-highlight.

    
por 07.06.2015 / 13:27