History Report a problem
Article Edit this page Discussion

Improved Hex editing

From Vim Tips Wiki

Jump to: navigation, search
 

Tip 1518Previous TipNext Tip

Created: October 3, 2007 Complexity: basic Author: Fritzophrenic Version: 7.0


The help files for Vim include the following advice for automating the xxd-style hex editing capabilities for Vim:

" vim -b : edit binary using xxd-format!
augroup Binary
  au!
  au BufReadPre  *.bin let &bin=1
  au BufReadPost *.bin if &bin | %!xxd
  au BufReadPost *.bin set ft=xxd | endif
  au BufWritePre *.bin if &bin | %!xxd -r
  au BufWritePre *.bin endif
  au BufWritePost *.bin if &bin | %!xxd
  au BufWritePost *.bin set nomod | endif
augroup END

There are a few problems with this approach:

  1. Only files with a .bin extension are opened this way, even if editing a file in binary mode (e.g. with ++bin)
  2. This sets the binary option for any future documents opened as well. If you use tabe, for example, or if you have Vim set up to open new files in tabs, then any new files opened will open in binary mode.
  3. If you decide to edit a binary file without the xxd, the BufWrite autocommands will try to convert it with xxd -r anyway.
  4. Viewing a file in "xxd mode" requires you to modify the file, so read-only files will warn you if you try to do so, even if you make no changes. Buffers with 'nomodifiable' will cause errors.
  5. If you go back into non-xxd editing, the filetype will still be xxd.

These problems can be fixed as follows:

  1. Trigger on all files if they are being edited with the binary option. Modify the extension-specific autocmd to set the binary option.
  2. Use setlocal rather than using the global binary option.
  3. Maintain a variable for each buffer that tracks whether the file is in "xxd mode". Only restore to non-xxd before writing if this variable says we are in the appropriate mode.
  4. Temporarily clear the read-only flag whenever you transition between xxd and non-xxd mode, resetting it afterward.
  5. Store the filetype when entering xxd mode and restore it when leaving.

Below is some code for your vimrc file that does all of this:

" autocmds to automatically enter hex mode and handle file writes properly
if has("autocmd")
  " vim -b : edit binary using xxd-format!
  augroup Binary
    au!
    au BufReadPre *.bin,*.hex setlocal binary
    au BufReadPost *
          \ if &binary | Hexmode | endif
    au BufWritePre *
          \ if exists("b:editHex") && b:editHex && &binary |
          \  let oldro=&ro | let &ro=0 |
          \  let oldma=&ma | let &ma=1 |
          \  exe "%!xxd -r" |
          \  let &ma=oldma | let &ro=oldro |
          \  unlet oldma | unlet oldro |
          \ endif
    au BufWritePost *
          \ if exists("b:editHex") && b:editHex && &binary |
          \  let oldro=&ro | let &ro=0 |
          \  let oldma=&ma | let &ma=1 |
          \  exe "%!xxd" |
          \  exe "set nomod" |
          \  let &ma=oldma | let &ro=oldro |
          \  unlet oldma | unlet oldro |
          \ endif
  augroup END
endif

" ex command for toggling hex mode - define mapping if desired
command -bar Hexmode call ToggleHex()

" helper function to toggle hex mode
function ToggleHex()
  " hex mode should be considered a read-only operation
  " save values for modified and read-only for restoration later,
  " and clear the read-only flag for now
  let l:modified=&mod
  let l:oldreadonly=&readonly
  let &readonly=0
  let l:oldmodifiable=&modifiable
  let &modifiable=1
  if !exists("b:editHex") || !b:editHex
    " save old options
    let b:oldft=&ft
    let b:oldbin=&bin
    " set new options
    setlocal binary " make sure it overrides any textwidth, etc.
    let &ft="xxd"
    " set status
    let b:editHex=1
    " switch to hex editor
    %!xxd
  else
    " restore old options
    let &ft=b:oldft
    if !b:oldbin
      setlocal nobinary
    endif
    " set status
    let b:editHex=0
    " return to normal editing
    %!xxd -r
  endif
  " restore values for modified and read only state
  let &mod=l:modified
  let &readonly=l:oldreadonly
  let &modifiable=l:oldmodifiable
endfunction

This will make Vim automatically use xxd-format hex editing when the file is opened in binary mode, and will automatically (locally) set binary mode for .bin and .hex files! In addition, it provides a command "Hexmode" for entering the xxd format properly. You may want to use key mappings to allow easier access.

You may need to take steps to avoid the "Hit ENTER to continue prompt if you use this tip.

Here are commands to use to launch any file(s) in hex mode in a separate "hex editor" Vim server. Under Windows, you can easily add these commands to your "Send To" menu if you use the full path for gvim.exe in place of "vim". Remove the "-p" and "--remote-tab-silent" option if you do not want the tabbed interface. The -c "set binary" ensures that any tabwidth, wrap, etc. settings are overwritten after the file finishes loading.

  • Launch in tabs in a new dedicated Vim hex editor: vim -p -b -c "set binary" --servername HEXVIM <files>
  • Launch in tabs in an existing dedicated Vim hex editor: vim -b -c "set binary" --servername HEXVIM --remote-tab-silent <files>

[edit] References

[edit] Comments

 

script#666 provides similar (and extended) capability, though I have never used it and can't vouch for its usefulness/completeness/correctness.


Rate this article:

Share this article:

Hubs Highlights International Sites Wikia messages
Entertainment
Gaming
Cartoons & Comics
Science Fiction
Hobbies
Sports
See all...
Grand Theft Auto
Doctor Who
Legend of Zelda Wiki
Terminator Wiki
Everquest II Wiki
Mystery Science Theater 3000
German
Spanish
Chinese
Japanese
More...
Wikia is hiring for several open positions
Send this article to a friend
"Improved Hex editing"
 
 
Hi!

I thought you'd like this page from Wikia!

http://vim.wikia.com

Come check it out!
Send confirmation