I saw that you could display the current byte offset in the statusline using %o
, but I found no function or command which does the same. Is there a way of getting the current byte offset pragmatically?
2 Answers
Try this:
function! FileOffset()
return line2byte(line('.')) + col('.') - 1
endfunction
This returns the 1-based offset in file, which is the same as %o
in statusline
. You can, of course, subtract 1 to get the 0-based offset.
-
One question, does
col('.')
actually return the byte offset in the line? Last I looked, it just showed the cursor column. Commented Jul 6, 2015 at 16:12 -
@EvergreenTree According to
:help col()
: [t]he result is a Number, which is the byte index of the column position given with {expr}. I take it that's the 1-based byte offset...– lcd047Commented Jul 6, 2015 at 16:14 -
Will the answer work in a file having this line only:
abcäb
? (I haven't checked)– VanLaserCommented Jul 6, 2015 at 16:14 -
1@VanLaser It works in my quick tests. You tell us if it still works after extended testing.– lcd047Commented Jul 6, 2015 at 16:16
-
The other answer did not work for me when I opened a binary file without line ending. It seems that there is a bug in vim when it comes to counting bytes in a binary file without eol. (edit: yes, this was a bug. I have submitted a patch, which got accepted in 7.4.781).
To find the byte offset, while accounting for the bug in old Vim versions, use:
let offset = line2byte(line('.')) + col('.') - 1
if version < 781 && &l:binary == 1 && &l:eol == 0
" Vim prior 7.4.781 had a bug where the line count is off by 1 or 2.
" See https://groups.google.com/forum/#!msg/vim_dev/zX45zm-cnc0/-BWjjh5tlX8J
let offset += 1
let offset += line('.') == 1
endif
This bug also affects the %o
specifier in e.g. rulerformat
.