How about using a user mode?
declare-user-mode surround
define-command declare-surrounding-pair -params 4 -docstring 'declare-surrounding-pair <description> <alias> <opening> <closing>: declare surrounding pair' %{
map -docstring %arg{1} global surround %arg{2} "Z\i%arg{3}<esc>\a%arg{4}<esc>Hz"
map -docstring %arg{1} global surround %arg{3} "Z\i%arg{3}<esc>\a%arg{4}<esc>Hz"
map -docstring %arg{1} global surround %arg{4} "Z\i%arg{3}<esc>\a%arg{4}<esc>Hz"
}
declare-surrounding-pair 'parenthesis block' b ( )
declare-surrounding-pair 'brace block' B { }
declare-surrounding-pair 'bracket block' r [ ]
declare-surrounding-pair 'angle block' a <lt> <gt>
map -docstring 'enter surround mode' global normal q ': enter-user-mode surround<ret>'