-
Notifications
You must be signed in to change notification settings - Fork 0
/
hexl.el
178 lines (144 loc) · 5.55 KB
/
hexl.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
;;; init/hexl.el --- Hexl (hex editor) customizations -*- lexical-binding: t; -*-
;;; Code:
(with-eval-after-load 'hexl
(hook-mode hexl-mode-hook
(hexl-follow-line)
(hexl-activate-ruler)
(turn-on-eldoc-mode)
(setf truncate-lines t)))
;;; Custom commands:
(with-eval-after-load 'hexl
(keymap-set hexl-mode-map "<remap> <self-insert-command>"
'hexl-my-self-insert-command)
(keymap-set hexl-mode-map "C-m" 'hexl-my-self-insert-command)
(keymap-set hexl-mode-map "<remap> <hexl-backward-char>"
'hexl-my-backward-char)
(keymap-set hexl-mode-map "<remap> <hexl-forward-char>"
'hexl-my-forward-char)
(keymap-set hexl-mode-map "<remap> <hexl-previous-line>"
'hexl-my-previous-line)
(keymap-set hexl-mode-map "<remap> <hexl-next-line>"
'hexl-my-next-line)
(keymap-set hexl-mode-map "<remap> <hexl-beginning-of-buffer>"
'hexl-my-beginning-of-buffer)
(keymap-set hexl-mode-map "<remap> <hexl-end-of-buffer>"
'hexl-my-end-of-buffer)
(keymap-set hexl-mode-map "<remap> <hexl-beginning-of-line>"
'hexl-my-beginning-of-line)
(keymap-set hexl-mode-map "<remap> <hexl-end-of-line>"
'hexl-my-end-of-line))
;; TODO(upstream)
(defun hexl-insert-nybble (ch arg)
"Insert nybble for character CH, ARG times.
CH: Character for a nybble to insert. This should be a
hexadecimal digit, ?0 - ?9 or ?A -?F.
ARG: Number of times to insert the above character."
(when (not (or (<= ?0 ch ?9)
(<= ?a ch ?f)
(<= ?A ch ?F)))
(error "Invalid nybble %c" ch))
(dotimes (_ arg)
(let* ((hex-position (hexl-address-to-marker (hexl-current-address)))
(byte-str (buffer-substring hex-position (+ hex-position 2)))
;; nybble index
(index (if (= (point) (1+ hex-position))
1 0)))
(setf (aref byte-str index) ch)
(save-excursion (hexl-insert-hex-string byte-str 1))
(goto-char (+ hex-position index 1)))))
(defun hexl-my-self-insert-command (arg)
"Replacement for `hexl-self-insert-command'.
ARG: Number of times to insert the character."
(interactive "p")
(if (< (current-column) (hexl-ascii-start-column))
(hexl-insert-nybble last-command-event arg)
(hexl-insert-multibyte-char last-command-event arg)))
(defun hexl-my-forward-char-internal (arg)
"Move to right ARG bytes (left if ARG negative) in Hexl mode."
(interactive "p")
(let* ((hex-position (hexl-address-to-marker (hexl-current-address)))
(index (if (= (point) (1+ hex-position))
1 0)))
(hexl-goto-address (+ (hexl-current-address)
arg
(if (and (< arg 0) (/= index 0))
1 0)))))
(defun hexl-my-ascii-position (addr)
"Return the buffer position in the ascii column.
ADDR: Address to get the position for, as returned from
`hexl-current-address'."
(+ (* (/ addr 16) (hexl-line-displen))
(hexl-ascii-start-column)
(point-min)
(% addr 16)))
(defun hexl-my-movement (f arg)
"Execute movement function F, staying in ASCII or bytes column.
F: Function to execute.
ARG: Argument to pass to F, as (F ARG)."
(let ((at-ascii-position (>= (current-column) (hexl-ascii-start-column))))
(funcall f arg)
(when at-ascii-position
(goto-char (hexl-my-ascii-position (hexl-current-address t))))))
(defun hexl-my-movement0 (f)
"Execute movement function F, staying in ASCII or bytes column.
F: Function to execute."
(let ((at-ascii-position (>= (current-column) (hexl-ascii-start-column))))
(funcall f)
(when at-ascii-position
(goto-char (hexl-my-ascii-position (hexl-current-address t))))))
(defun hexl-my-backward-char (arg)
"Replacement for `hexl-backward-char'.
ARG: Number of characters to move."
(interactive "p")
(hexl-my-forward-char (- arg)))
(defun hexl-my-forward-char (arg)
"Replacement for `hexl-forward-char'.
ARG: Number of characters to move."
(interactive "p")
(hexl-my-movement 'hexl-my-forward-char-internal arg))
(defun hexl-my-previous-line (arg)
"Replacement for `hexl-previous-line'.
ARG: Number of lines to move."
(interactive "p")
(hexl-my-movement 'hexl-previous-line arg))
(defun hexl-my-next-line (arg)
"Replacement for `hexl-next-line'.
ARG: Number of lines to move."
(interactive "p")
(hexl-my-movement 'hexl-next-line arg))
(defun hexl-my-beginning-of-buffer (arg)
"Replacement for `hexl-beginning-of-buffer'.
ARG: Passed to `hexl-beginning-of-buffer'."
(interactive "p")
(hexl-my-movement 'hexl-beginning-of-buffer arg))
(defun hexl-my-end-of-buffer (arg)
"Replcaement for `hexl-end-of-buffer'.
ARG: Passed to `hexl-end-of-buffer'."
(interactive "p")
(hexl-my-movement 'hexl-end-of-buffer arg))
(defun hexl-my-beginning-of-line ()
"Replacement for `hexl-beginning-of-line'."
(interactive)
(hexl-my-movement0 'hexl-beginning-of-line))
(defun hexl-my-end-of-line ()
"Replacement for `hexl-end-of-line'."
(interactive)
(hexl-my-movement0 'hexl-end-of-line))
(defun hexl-my-max-data-address ()
"Return the maximum data address available.
Unlike `hexl-max-address', this is not rounded up to a whole
number of lines."
(save-excursion
(hexl-goto-address hexl-max-address)
(if (= (point-min) (point-max))
0
;; Actual calculation.
(beginning-of-line)
(forward-char 10)
;; Look for the end of the binary buffer.
(while (and (< (hexl-current-address) hexl-max-address)
(/= (char-after) ?\s))
(hexl-forward-char 1))
(when (= (char-after) ?\s)
(hexl-backward-char 1))
(hexl-current-address))))