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.