![在emacs(或其他编辑器)中如何显示光标的字节偏移量?](https://linux22.com/image/23112/%E5%9C%A8emacs%EF%BC%88%E6%88%96%E5%85%B6%E4%BB%96%E7%BC%96%E8%BE%91%E5%99%A8%EF%BC%89%E4%B8%AD%E5%A6%82%E4%BD%95%E6%98%BE%E7%A4%BA%E5%85%89%E6%A0%87%E7%9A%84%E5%AD%97%E8%8A%82%E5%81%8F%E7%A7%BB%E9%87%8F%EF%BC%9F.png)
这个问题表明我更喜欢使用 emacs,但最重要的问题是我希望能够进行正常的文本搜索并以某种方式查看/复制粘贴字节偏移量的匹配文本。
需要明确的是,通过字节偏移量,我不是指 emac 的观点值,显示数量人物从缓冲区的开头开始,例如。在 UTF-16LE 中,观点被\x0d\x00\x0a\x00
视为 1 个字符,而我对它感兴趣的是 4 个字节。
任何其他在以“正常”可读和可搜索的方式显示文本的同时呈现此基本信息的编辑器(或查看器)都是值得的。
即使是带有同步的十六进制视图普通文本视图就可以了,但是典型的十六进制转储查看器/编辑器不是我想要的,因为它们(通常)仅显示 ASCII 字符,而且我还没有找到可以执行以下操作的 FOSS 十六进制转储查看器/编辑器对非 ASCII UTF-8 或任何 UTF-16 字符串的简单文本模式搜索。
我主要关心文本的易读性和可搜索性,因此“普通”十六进制转储程序只是一个后备方案(我已经在使用)。
答案1
首先,如果您不知道的话,Emacs 可以hexl-find-file
以十六进制编辑模式打开文件。我知道这不是您所要求的,但如果您已经在使用 Emacs,并且您对 Emacs 很熟悉,那么了解它对于将来的需要是有好处的。
其次,对于这种文件的“原始”编辑(我经常这样做)find-file-literally
真的很棒。它会执行您期望它执行的操作,并假装自己是 unicode 之前的版本,并打开文件,并显示非 ascii 字符(和控制字符等)的转义符。这可能会达到您想要的效果,但它确实有一个明显的缺点,即如果您有大量非 ASCII 内容,则无法实际阅读文本。
因此,进一步深入原始支持,有enable-multibyte-characters
变量和set-buffer-multibyte
用于切换它的函数。这样做的好处是它动态地改变缓冲区的呈现——例如,试试这个:
(defun my-multi-toggle ()
(interactive)
(set-buffer-multibyte (not enable-multibyte-characters)))
(global-set-key (kbd "C-~") 'my-multi-toggle)
现在您就有了一个可以动态切换原始模式的按键。它还具有将光标保留在同一位置的良好特性。 但此原始模式向您显示内部表示形式(看起来像 UTF-8),而不是文件恰好用作其编码的任何内容。应该可以通过一些技巧来完成您正在谈论的事情(例如,find-file-literally
在打开的文件上使用会询问您是否重新访问它,但这会重置位置并重新加载文件) - 但听起来像上面的已经好了。 (也就是说,我的猜测是您正在尝试编辑二进制文件中的某些文本字段......)
答案2
听起来像你想要的position-bytes
。您可以看到光标的字节偏移量(Emacs 术语中的“点”):
M-: (1- (position-bytes (point)))
请注意,它position-bytes
是 1 索引的,因此1-
.您可以将其包装在一个方便的命令中:
(defun wh/byte-offset-at-point ()
"Report the byte offset (0-indexed) in the file
corresponding to the position of point."
(interactive)
(message "byte offset: %d" (1- (position-bytes (point)))))
答案3
我已经成功地编写了一个 elisp 脚本来显示点 (poff) 处的字节偏移量(通过快捷键)。
它的演示目前非常粗糙,但它对于 UTF-16LE/CR-LF 工作得很好(在文件开始和文件结束时进行了测试。UTF-16 是让我了解这个主题的格式,实际上是最简单的工作格式和..
UTF-8 会有点棘手。因为它需要一些文件 I/O...
这是脚本。
(defun poff-zap ()
"Get the byte offset of point - A prototye, tested minimally only with UTF-16LE"
(interactive)
(let ((linect (- (line-number-at-pos) 1)) ;; line count to point
(choncl (- (point) (point-at-bol))) ;; characters to point on current line
(chrpnl 0) ;; chars per newline
(bytpch 0) ;; bytes per char
(bytpnl 0) ;; bytes per newline
(offset 0) ;; the byte offset
(coding (car (split-string (symbol-name buffer-file-coding-system) "-")))
(format (cadr (split-string (symbol-name buffer-file-coding-system) "-"))))
(case (coding-system-eol-type buffer-file-coding-system)
('0 (setq chrpnl 1)) ;; unix
('1 (setq chrpnl 2)) ;; dos
('2 (setq chrpnl 1)) ;; mac
(t))
(if (> chrpnl 0)
(cond
((string= "utf" coding)
(cond
((string= "8" format)
(progn
(setq bytpch -1)
;; need to do an actual byte count
;; using a UTF-8 parser
;; ...plus a BOM check(?)
))
((or
(string= "16" format)
(string= "16le" format))
(progn
(setq bytpch 2)
(if (= 2 chrpnl) (setq offset linect))
(setq offset (+ offset (point)))
(setq offset (* offset bytpch))
))
(t)))
(t)))
(message (concat
"poff-zap: " (number-to-string bytpch) " bytes-per-char\n"
" " (number-to-string chrpnl) " chars-per-newliner\n"
" " (number-to-string bytpnl) " bytes-per-newliner\n"
" " (number-to-string (point)) " point-emacs\n"
" " (number-to-string offset) " offset poff-zap\n"
" " (symbol-name buffer-file-coding-system) ))
))
(global-set-key (kbd "C-#") 'poff-zap)
答案4
维姆
在 中vim
,g^G
屏幕底部显示如下内容:
第 1 栏(共 3 栏);第 2 行(共 2 行);第 2 个单词,共 2 个单词;第 5 个字符(共 8 个);字节 7(共 10 个)
要使光标的字节偏移量始终位于状态行中,请添加%o
到statusline
选项:
:set statusline+=\ %o
(您可能需要输入 a ,:set laststatus=2
以便即使屏幕未分割,状态行也始终可见。要使偏移量显示在正确的尺寸上,请将其放在a%o
的右侧)。%=
statusline
另请参见:go 123
或123go
将光标定位到最接近第 123个字节。