Your code is similar in principle to how I've done it on my templates. So I will suggest a couple of other things you may not have considered yet.
In our documents, often we want to refer to the heading outline number rather than the text. So when the selection.range is empty, rather than producing a warning to first select text, I create an xRef to the paragraph number (by including '\n' in the ref field code) and add a prefix (eg. Section X)
Secondly, when testing to see if a bookmark already exists in the same range, you don't need to compare it to every bookmark in the document - you should compare it to every bookmark that included that range.
Code:
'search for existing bookmark reference the same range
'doc.Bookmarks.ShowHidden = True 'this isn't needed for the loop
For Each bmi In rg.Bookmarks
If bmi.Range.IsEqual(rg) Then
Set oldbm = bmi
Exit For
End If
Next bmi
'doc.Bookmarks.ShowHidden = False 'this can annoy users who want it on