Mostrando bytes como escape hexadecimal em vez de escape octal


8

Versão curta: Posso fazer o Emacs mostrar \ffou em \xffvez de \377?

Versão longa: suponha que você abra um arquivo que não seja totalmente texto e tenha alguns dados binários (por exemplo, um arquivo PostScript ou PDF). Por exemplo, suponha que você abra o Cartão de Referência GNU Emacs (PDF) .

Captura de tela do Emacs (Aquamacs) exibindo refcard.pdf

Em seguida, para bytes fora do intervalo imprimível ASCII (32–126),

  • O Emacs mostra os bytes "altos" (bytes com valor 128 a 255) como seqüências de escape octais: 128 é mostrado como \200, 129 é mostrado como \201,…, 255 é mostrado como \377.
  • O Emacs mostra os bytes de 0 a 31 (exceto o byte 9, que não é mostrado como uma guia ^Ie o byte 10, que não é uma nova linha ^J) como um sinal de intercalação seguido pelo caractere que está 64 à frente: o byte 0 é mostrado como ^@, byte 1 é mostrado como ^A,…, byte 26 é mostrado como ^Z, byte 27 é mostrado como ^[,…, byte 31 é mostrado como ^_. Além disso, o Emacs mostra o byte 127 como ^?.

Sei que a razão pela qual o Emacs mostra octal é histórica: em algum momento, algumas décadas atrás, octal era mais comumente usado. (Por exemplo, man asciicomeça com octal primeiro e o TeX suporta seqüências de escape octal.) Mas como octal é menos útil que o hexadecimal atualmente (por exemplo, para comparar com a saída hexdumpou representações de string de bytes do Python), gostaria de ver o hexadecimal seqüências de escape. Como posso mudar isto?

(Nota: as seqüências octais de escape são mostradas realçadas em vez de parecerem texto normal e, é claro, não é possível entrar "no caractere de escape" (por exemplo, bater C-fno ponto anterior \343leva você ao ponto seguinte \343); para reter isso.)

Respostas:


4

Você pode fazer isso com tabelas de exibição . Isso pode ser um pouco desajeitado e eu não investiguei como isso pode interferir nos pacotes que usam tabelas de exibição para seus próprios fins, mas o caso de uso básico funciona.

(require 'cl-lib)
(setq standard-display-table (make-display-table))
(cl-loop
 for x from 128 to 255
 do (aset standard-display-table x
      (cl-map 'vector
          (lambda (c) (make-glyph-code c 'escape-glyph))
          (format "\\%02x" x))))

Obrigado, isso foi útil, então estou aceitando isso. Eu tive que fazer algumas pequenas alterações que estão na minha resposta ; dê uma olhada e deixe-me saber se devo corrigir alguma coisa.
— ShreevatsaR

8

edit : Com o Emacs 26.1 ou posterior, está (setq display-raw-bytes-as-hex t)fora.

Não, você não pode. A exibição de não imprimíveis acima da faixa ASCII imprimível é codificada em xdisp.c:

if (CHAR_BYTE8_P (c))
  /* Display \200 instead of \17777600.  */
  c = CHAR_TO_BYTE8 (c);
len = sprintf (str, "%03o", c + 0u);

Enviei um patch corrigindo isso para depuração .


"Não, você não pode" está errado, veja a sugestão de Gilles , mas +1 de qualquer maneira por fornecer um patch para corrigir isso corretamente.
— npostavs

Huh, justamente quando pensei que você não poderia se intrometer nessa questão, alguém me prova errado. Obrigado!
— Wasamasa

11
Oh legal, maravilhoso! Colocar um patch no Emacs não é totalmente impossível. :-) Obrigado por seu trabalho ... olhar para a frente a este que está sendo lançado em Emacs 26.
— ShreevatsaR

11
Funciona muito bem no Emacs 26! Obrigado!!! (Você pode querer editar a sua resposta agora.)
— Michael Hoffman

6

Eu descobri isso graças à resposta de Gilles e ao tópico 2010/2011 gnu.emacs.helpchamado "Como alternar do código de caractere octal com escape para o HEX com escape?" ( Grupos do Google , Nabble ).

Os detalhes de como o Emacs exibe caracteres estão na seção Exibição> Exibição de texto (“Como o texto é exibido”) do manual do Emacs ( C-h r) e na seção Exibição> Exibição de caracteres do Manual de referência do Emacs Lisp. O que se deve fazer é alterar a tabela de exibição dos caracteres 128 para 255 (e quaisquer outros caracteres desejados, como escapes hexadecimais).

Eu tive que fazer duas pequenas alterações na resposta de Gilles:

  1. Em vez de algo como

    (aset standard-display-table 128 [?\\ ?8 ?0])
    

    Eu tive que usar algo como

    (aset standard-display-table (unibyte-char-to-multibyte 128) [?\\ ?8 ?0])
    
  2. A configuração standard-display-tablenem sempre é suficiente, porque alguns modos (como global-whitespace-mode) podem atrapalhar. E então parece que você precisa definir buffer-display-table.

Então, em vez disso, criei uma função interativa que posso chamar quando quero que a exibição seja alterada em um buffer específico.

(defun use-hex-not-octal ()
  "Use hexadecimal escape sequences instead of octal."
  (interactive)
  (require 'cl-lib)
  (unless buffer-display-table
    (setq buffer-display-table (make-display-table)))
  (setq unprintable (append (number-sequence 127 255) (number-sequence 0 8) (number-sequence 11 31)))
  (cl-loop
   for x in unprintable
   do (aset buffer-display-table (unibyte-char-to-multibyte x)
            (cl-map 'vector
                    (lambda (c) (make-glyph-code c 'escape-glyph))
                    (format "\\%02x" x)))))

Com isso, se eu abrir refcard.pdfe executar M-x use-hex-not-octal, obtenho o seguinte, para a mesma região da pergunta:

refcard.pdf com Mx use-hex-not-octal


1

O modo hexl do Emacs deve fazer o que você deseja - é um modo principal que fornece suporte para visualizar e editar arquivos binários. Use Mx hexl-find-file em vez de Cx Cf para visitar o arquivo e começar. Mais detalhes podem ser encontrados no manual de informações do Emacs ou em https://www.gnu.org/software/emacs/manual/html_node/emacs/Editing-Binary-Files.html .


11
Não, eu não quero o modo hexl: os arquivos postscript são principalmente textos com apenas dados binários ocasionais, e não é conveniente alternar para o modo hexl e perder muitas funcionalidades de edição de texto. Deixe-me adicionar uma captura de tela à pergunta para esclarecer.
— precisa

Ah, eu sei o que você quer dizer, mas não conheço nenhuma maneira fácil de mudar isso. I exibição tabelas suspeito pode estar em algum lugar envolvido ...
— stevoooo

Agradeço-te pela tua sugestão mesmo assim. Eu não votei contra!
— ShreevatsaR
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.