8進エスケープではなく16進エスケープとしてバイトを表示する


8

ショートバージョン:Emacsを表示する\ffか、\xff代わりに表示できます\377か?

長いバージョン:完全にテキストではなく、バイナリデータが含まれているファイル(たとえば、PostScriptまたはPDFファイル)を開いたとします。たとえば、GNU Emacsリファレンスカード(PDF)を開いたとします。

refcard.pdfを表示するEmacs(Aquamacs)のスクリーンショット

次に、ASCII印刷可能範囲(32〜126)の外のバイトについては、

  • Emacsは「上位」バイト(128〜255の値を持つバイト)を8進数のエスケープシーケンスとして表示します。128は\200、129は\201、…、255はと表示され\377ます。
  • Emacsは、バイト0から31(タブとして表示されないバイト9 ^I、および改行として表示されないバイト10を除いて^J)をキャレットとして示し、その後に64文字先の文字が続きます:バイト0は^@、バイトとして表示されます1は^A、…、バイト26は^Z、バイト27は^[、…、バイト31はと表示され^_ます。また、Emacsはバイト127をとして示しています^?

Emacsが8進数を表示する理由は歴史的なものであることは知っています。数十年前のある時点で、8進数がより一般的に使用されていました。(たとえば、man ascii最初は8進数で始まり、TeXは8進数のエスケープシーケンスをサポートします。)しかし、最近では8進数は16進数よりも有用ではないので(たとえば、出力hexdumpまたはPythonバイト文字列表現と比較するため)、16進数を表示したいと思います。エスケープシーケンス。どうすれば変更できますか?

(注:8進数のエスケープシーケンスは、通常のテキストのように見える代わりに強調表示されます。もちろん、エスケープ文字に「入る」ことはできません(つまりC-f、前のポイントでヒット\343すると、後のポイントに移動します\343)。これを保持します。)

回答:


4

表示テーブルでそれを行うことができます。これは少し扱いに​​くいかもしれませんが、これが独自の目的で表示テーブルを使用するパッケージにどのように影響するかは調査していませんが、基本的なユースケースは機能します。

(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))))

おかげで、これは役に立ちましたので、これを受け入れます。私は私の答えにあるいくつかのマイナーな変更を行わなければなりませんでした。是非確認して、修正する必要があるかどうかをお知らせください。
ShreevatsaR

8

編集:Emacs 26.1以降では、それはあり(setq display-raw-bytes-as-hex t)ません。

いいえ、できません。印刷可能なASCII範囲を超える印刷不可の表示は、次のようにハードコーディングされていxdisp.cます。

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

これを修正するパッチをdebbugsに送りました


「いいえ、できません」は誤りです。Gillesの提案を参照してください。ただし、これを適切に修正するパッチを提供するために+1します。
npostavs

ええと、私はあなたがこれをハッキングできないと思ったとき、誰かが私を間違っていると証明しました。ありがとう!
wasamasa

1
素晴らしい、素晴らしい!Emacsにパッチを適用することは完全に不可能ではありません。:-)あなたの仕事のためのおかげで...これを楽しみにしては、26 Emacsでリリースされて
ShreevatsaR

1
Emacs 26でうまく動作します!ありがとう!!! (今すぐ回答を編集することもできます。)
Michael Hoffman

6

Gillesの回答と2010/2011のスレッドgnu.emacs.help「エスケープされた8進文字コードからエスケープされたHEXに切り替える方法」のおかげで私はそれを理解しました。(GoogleグループNabble)。

Emacsが文字を表示する方法の詳細は、Emacsマニュアルのディスプレイ>テキスト表示(「テキストの表示方法」)C-h rセクション、およびEmacs Lispリファレンスマニュアルのディスプレイ>文字表示セクションにあります。やるべきことは、128から255の文字(および16進エスケープとして表示したい他の文字)の表示テーブルを変更することです。

Gillesの回答から2つの小さな変更を加える必要がありました。

  1. のようなものの代わりに

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

    私は何かを使わなければならなかった

    (aset standard-display-table (unibyte-char-to-multibyte 128) [?\\ ?8 ?0])
    
  2. standard-display-table一部のモード(などglobal-whitespace-mode)によって台無しにされる可能性があるため、設定だけでは必ずしも十分ではありません。そして、buffer-display-table代わりに設定する必要があるようです。

そのため、代わりに、特定のバッファーで表示を変更したいときに呼び出すことができるインタラクティブ関数を作成しました。

(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)))))

これで、を開いrefcard.pdfて実行するM-x use-hex-not-octalと、質問と同じリージョンで次のようになります。

Mx use-hex-not-octalを含むrefcard.pdf


1

Emacsのhexlモードはあなたが望むことをするべきです-それはバイナリファイルの閲覧と編集をサポートするメジャーモードです。Cx Cfの代わりにMx hexl-find-fileを使用して、ファイルにアクセスして開始します。詳細については、Emacs情報マニュアル、またはhttps://www.gnu.org/software/emacs/manual/html_node/emacs/Editing-Binary-Files.htmlを参照してください


1
いいえ、私はhexlモードを使いたくありません。postscriptファイルはほとんどがテキストであり、バイナリデータが時々しかなく、hexlモードに切り替えて多くのテキスト編集機能を失うのは不便です。明確にするため、質問にスクリーンショットを追加しましょう。
ShreevatsaR

ああ、私はあなたの意味を知っていますが、それを変更できる簡単な方法は知りません。表示テーブルがどこかに関係しているのではないかと
思い

あなたの提案をありがとう。ところで投票はしませんでした!
ShreevatsaR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.