" ------------------------------------------------------------------------------ " File: plugin/utl_scm.vim -- callbacks implementing the different " schemes " Part of the Utl plugin, see ./utl.vim " Author: Stefan Bittner " Licence: This program is free software; you can redistribute it and/or " modify it under the terms of the GNU General Public License. " See http://www.gnu.org/copyleft/gpl.txt " Version: utl 3.0a " ------------------------------------------------------------------------------ " In this file some scheme specific retrieval functions are defined. " For each scheme one function named Utl_AddrScheme_xxx() is needed. " " - If a scheme (i.e. functions) is missing, the caller Utl_processUrl() " will notice it and show an appropriate message to the user. " " - You can define your own functions: " How to write a Utl_AddrScheme_xxx function (id=implscmfunc) " ------------------------------------------ " To implement a specific scheme (e.g. `file', `http') you have to write " write a handler function named `Utl_AddrScheme_' which obeys the " following rules: " " - It takes three arguments: " " 1. Arg: Absolute URI " (See to get an absolute URI explained). The " given `auri' will not have a fragment (without #... at the end). " " 2. Arg: Fragment " Where the value will be '' if there is no fragment. In most cases a " handler will not actually deal with the fragment but leaves that job for " standard fragment processing in Utl by returning a non empty list (see " next). Examples for fragment processing handlers are " Utl_AddressScheme_http and Utl_AddressScheme_foot. " " 3. Arg: display Mode (dispMode) " Most handlers will ignore this argument. Exception for instance handlers " which actually display the retrieved or determined file like " Utl_AddressScheme_foot. If your function is smart it might, if applicable, " support the special dispMode values copyFileName (see examples in this file). " " " - It then does what ever it wants. " But what it normally wants is: retrieve, load, query, address the resource " identified by `auri'. " - It Returns a list with 0 (empty list), 1 or 2 elements. [id=scm_ret_list] " (See vimhelp:List if you don't know what a list is in Vim) " " * Empty list means: no subsequent processing by Utl.vim " Examples where this makes sense: " ° If the retrieve was not successful, or " ° if handler already cared for displaying the file (e.g. URL " delegated to external handler) " " * 1st list element = file name (called localPath) provided means: " a) Utl.vim will delegate localPath to the appropriate file type handler " or display it the file in Vim-Window. " It also possible, that the localPath is already displayed in this case " (Utl.vim will check if the localPath corresponds to a buffer name.) " Note : It is even possible that localPath does not correspond to " an existing file or to a file at all. Executing a http URL with " netrw is an example for this, see: ../plugin/utl_rc.vim#http_netrw. " Netrw uses the URL as buffer name. " c) Fragment will be processed (if any). " " Details : " ° File name should be a pathname to (an existing) local file or directory. " Note : the " ° File name's path separator should be slash (not backslash). " ° It does not hurt if file is already displayed (an example for this is " vimhelp scheme). " " * 2nd list element = fragment Mode (fragMode). Allowed values: " `abs', 'rel'. Defaults to `abs' if no 2nd list element. " `abs': Fragment will be addressed to beginning of file. " `rel': Fragment will be addressed relative to current cursor position " (example: Vimhelp scheme). " " Specification of 'scheme handler variable interface' (id=spec_ihsv) " ---------------------------------------------------- " " - Variable naming: utl_cfg_hdl_scm_ " " - Variables executed by :exe (see ). " This implies that the variable has to a valid ex command. (to execute more " than one line of ex commands a function can be called). " " - Should handle the actual link, e.g. download the file. " But it can do whatever it wants :-) " " - Input data: scheme specific conversion specifiers should appear in the " variable. They will be replaced by Utl.vim when executing an URL, e.g %u " will be replaced by the actual URL. The available conversion specifiers are " defined at for http etc. " " - Output data: an optional global list, which is the same as that of the " handler itself, see . Since the " variable's value can be any ex command (and, for instance, not always a " function) a global variable is used: " g:utl_hdl_scm_ret_list " This variable will be initialized to an empty list [] by Utl.vim before " executing the contents of the variable. " " - Exception handling: Normally nothing needs to be done in the variable code. " Utl.vim checks for v:shell_error and v:errmsg after execution. There are " situation where setting v:errmsg makes sense. The variable might want to " issue the error message (Utl.vim does not). " if exists("loaded_utl_scm") || &cp || v:version < 700 finish endif let loaded_utl_scm = 1 let s:save_cpo = &cpo set cpo&vim let g:utl__file_scm = expand("") let s:utl_esccmdspecial = '%#' " keep equal to utl.vim#__esc "------------------------------------------------------------------------------- " Addresses/retrieves a local file. " " - If `auri' gives a query, then the file is executed (it should be an " executable program) with the query expression passed as arguments " arguments. The program's output is written to a (tempname constructed) " result file. " " - else, the local file itself is the result file and is returned. " fu! Utl_AddressScheme_file(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_file",1,1) " authority: can be a " - windows drive, e.g. `c:' " - server name - interpret URL as a network share let authority = UtlUri_authority(a:auri) let path = '' if authority =~? '^[a-z]:$' if has("win32") || has("win16") || has("win64") || has("dos32") || has("dos16") call Utl_trace("- Am under Windows. Server part denotes a Windows drive: `".authority."'") let path = authority endif elseif authority != '' && authority != '' if has("win32") || has("win16") || has("win64") || has("dos32") || has("dos16") call Utl_trace("- Am under Windows. Server part specified: `".authority."',") call Utl_trace(" will convert to UNC path //server/sharefolder/path.") let path = '//' . authority elseif has("unix") call Utl_trace("- Am under Unix. Server part specified: `".authority."',") call Utl_trace(" will convert to server:/path") " don't know if this really makes sense. See let path = authority . ':' endif endif let path = path . UtlUri_unescape(UtlUri_path(a:auri)) call Utl_trace("- local path constructed from URL: `".path."'") " Support of tilde ~ notation. if stridx(path, "~") != -1 let tildeuser = expand( substitute(path, '\(.*\)\(\~[^/]*\)\(.*\)', '\2', "") ) let path = tildeuser . substitute(path, '\(.*\)\(\~[^/]*\)\(.*\)', '\3', "") call Utl_trace("- found a ~ (tilde) character in path, expand to $HOME in local path:") let path = Utl_utilBack2FwdSlashes( path ) call Utl_trace(" ".path."'") endif if a:dispMode =~ '^copyFileName' call Utl_trace("- mode is `copyFileName to clipboard': so quit after filename is known now") call Utl_trace("- end execution of Utl_AddressScheme_file",1,-1) return [path] endif " If Query defined, then execute the Path (id=filequery) let query = UtlUri_query(a:auri) if query != '' " (N.B. empty query is not undef) call Utl_trace("- URL contains query expression (".query.") - so try to execute path") " (Should make functions Query_form(), Query_keywords()) if match(query, '&') != -1 " id=query_form " (application/x-www-form-urlencoded query to be implemented " e.g. `?foo=bar&otto=karl') let v:errmsg = 'form encoded query to be implemented' echohl ErrorMsg | echo v:errmsg | echohl None elseif match(query, '+') != -1 " id=query_keywords let query = substitute(query, '+', ' ', 'g') endif let query = UtlUri_unescape(query) " (Whitespace in keywords should now be escaped before handing off to shell) let cacheFile = '' " If redirection char '>' at the end: " Supply a temp file for redirection and execute the program " synchronously to wait for its output if strlen(query)!=0 && stridx(query, '>') == strlen(query)-1 call Utl_trace("- query with > character at end: assume output to a temp file and use it as local path") let cacheFile = Utl_utilBack2FwdSlashes( tempname() ) let cmd = "!".path." ".query." ".cacheFile call Utl_trace("- trying to execute command `".cmd."'") exe cmd " else start it detached else if has("win32") || has("win16") || has("win64") || has("dos32") || has("dos16") let cmd = "!start ".path." ".query else let cmd = "!".path." ".query.'&' endif call Utl_trace("- trying to execute command `".cmd."'") exe cmd endif if v:shell_error let v:errmsg = 'Shell Error from execute searchable Resource' echohl ErrorMsg | echo v:errmsg | echohl None if cacheFile != '' call delete(cacheFile) endif call Utl_trace("- end execution of Utl_AddressScheme_file",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_file",1,-1) if cacheFile == '' return [] else return [cacheFile] endif endif call Utl_trace("- end execution of Utl_AddressScheme_file",1,-1) return [path] endfu "------------------------------------------------------------------------------- " fu! Utl_AddressScheme_ftp(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_ftp",1,1) call Utl_trace("- delegating to http scheme handler") let ret = Utl_AddressScheme_http(a:auri, a:fragment, a:dispMode) call Utl_trace("- end execution of Utl_AddressScheme_ftp",1,-1) return ret endfu "------------------------------------------------------------------------------- " fu! Utl_AddressScheme_https(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_https",1,1) call Utl_trace("- delegating to http scheme handler") let ret = Utl_AddressScheme_http(a:auri, a:fragment, a:dispMode) call Utl_trace("- end execution of Utl_AddressScheme_https",1,-1) return ret endfu "------------------------------------------------------------------------------- " fu! Utl_AddressScheme_http(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_http",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName to clipboard' not possible for scheme `http:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_http",1,-1) return [] endif if ! exists('g:utl_cfg_hdl_scm_http') " Entering setup call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_http does not exist") echohl WarningMsg call input("No scheme handler variable g:utl_cfg_hdl_scm_http defined yet. Entering Setup now. ") echohl None Utl openLink config:#r=utl_cfg_hdl_scm_http split " (recursion, setup) call Utl_trace("- end execution of Utl_AddressScheme_http",1,-1) return [] endif call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_http exists, value=`".g:utl_cfg_hdl_scm_http."'") let convSpecDict= { 'u': a:auri, 'f': a:fragment, 'd': a:dispMode } let [errmsg,cmd] = Utl_utilExpandConvSpec(g:utl_cfg_hdl_scm_http, convSpecDict) if errmsg != "" echohl ErrorMsg echo "The content of your Vim variable `".g:utl_cfg_hdl_scm_http."' is invalid and has to be fixed!" echo "Reason: `".errmsg."'" echohl None call Utl_trace("- end execution of Utl_AddressScheme_http",1,-1) return [] endif call Utl_trace("- Escape cmdline-special characters (".s:utl_esccmdspecial.") before execution") " see ). let cmd = escape( cmd, s:utl_esccmdspecial) let g:utl__hdl_scm_ret_list=[] let v:errmsg = "" call Utl_trace("- trying to execute command: `".cmd."'") exe cmd if v:shell_error || v:errmsg!="" call Utl_trace("- execution of scm handler returned with v:shell_error or v:errmsg set") call Utl_trace(" v:shell_error=`".v:shell_error."'") call Utl_trace(" v:errmsg=`".v:errmsg."'") call Utl_trace("- end execution of Utl_AddressScheme_http (not successful)",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_http (successful)",1,-1) return g:utl__hdl_scm_ret_list endfu "------------------------------------------------------------------------------- " Retrieve file via scp. " fu! Utl_AddressScheme_scp(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_scp",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `scp:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_scp",1,-1) return [] endif if ! exists('g:utl_cfg_hdl_scm_scp') " Entering setup call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_scp does not exist") echohl WarningMsg call input("No scheme handler variable g:utl_cfg_hdl_scm_scp defined yet. Entering Setup now. ") echohl None Utl openLink config:#r=utl_cfg_hdl_scm_scp split " (recursion, setup) call Utl_trace("- end execution of Utl_AddressScheme_scp",1,-1) return [] endif call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_scp exists, value=`".g:utl_cfg_hdl_scm_scp."'") let convSpecDict= { 'u': a:auri, 'f': a:fragment, 'd': a:dispMode } let [errmsg,cmd] = Utl_utilExpandConvSpec(g:utl_cfg_hdl_scm_scp, convSpecDict) if errmsg != "" echohl ErrorMsg echo "The content of your Vim variable `".g:utl_cfg_hdl_scm_scp."' is invalid and has to be fixed!" echo "Reason: `".errmsg."'" echohl None call Utl_trace("- end execution of Utl_AddressScheme_scp",1,-1) return [] endif call Utl_trace("- Escape cmdline-special characters (".s:utl_esccmdspecial.") before execution") " see ). let cmd = escape( cmd, s:utl_esccmdspecial) let g:utl__hdl_scm_ret_list=[] let v:errmsg = "" call Utl_trace("- trying to execute command: `".cmd."'") exe cmd if v:shell_error || v:errmsg!="" call Utl_trace("- execution of scm handler returned with v:shell_error or v:errmsg set") call Utl_trace("- end execution of Utl_AddressScheme_scp (not successful)",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_scp",1,-1) return g:utl__hdl_scm_ret_list endfu "------------------------------------------------------------------------------- " The mailto scheme. " It was mainly implemented to serve as a demo. To show that a resource " needs not to be a file or document. " " Returns empty list. But you could create one perhaps containing " the return receipt, e.g. 'mail sent succesfully'. " fu! Utl_AddressScheme_mailto(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_mailto",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `http:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_http",1,-1) return [] endif if ! exists('g:utl_cfg_hdl_scm_mailto') " Entering setup call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_mailto does not exist") echohl WarningMsg call input("No scheme handler variable g:utl_cfg_hdl_scm_mailto defined yet. Entering Setup now. ") echohl None Utl openLink config:#r=utl_cfg_hdl_scm_mailto split " (recursion, setup) call Utl_trace("- end execution of Utl_AddressScheme_mailto",1,-1) return [] endif call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_mailto exists, value=`".g:utl_cfg_hdl_scm_mailto."'") let convSpecDict= { 'u': UtlUri_build_2(a:auri,a:fragment) } let [errmsg,cmd] = Utl_utilExpandConvSpec(g:utl_cfg_hdl_scm_mailto, convSpecDict) if errmsg != "" echohl ErrorMsg echo "The content of your Vim variable `".g:utl_cfg_hdl_scm_mailto."' is invalid and has to be fixed!" echo "Reason: `".errmsg."'" echohl None call Utl_trace("- end execution of Utl_AddressScheme_mailto",1,-1) return [] endif call Utl_trace("- Escape cmdline-special characters (".s:utl_esccmdspecial.") before execution") let cmd = escape( cmd, s:utl_esccmdspecial) let g:utl__hdl_scm_ret_list=[] let v:errmsg = "" call Utl_trace("- trying to execute command: `".cmd."'") exe cmd if v:shell_error || v:errmsg!="" call Utl_trace("- execution of scm handler returned with v:shell_error or v:errmsg set") call Utl_trace("- end execution of Utl_AddressScheme_mailto (not successful)",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_mailto",1,-1) return g:utl__hdl_scm_ret_list endfu "------------------------------------------------------------------------------- " Scheme for accessing Unix Man Pages. " Useful for commenting program sources. " " Example: /* "See for the r+ argument" */ " " Possible enhancement: Support sections, i.e. " fu! Utl_AddressScheme_man(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_man",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `man:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_man",1,-1) return [] endif exe "Man " . UtlUri_unescape( UtlUri_opaque(a:auri) ) if v:errmsg =~ '^Sorry, no man entry for' return [] endif call Utl_trace("- end execution of Utl_AddressScheme_man",1,-1) return [Utl_utilBack2FwdSlashes( expand("%:p") ), 'rel'] endfu "------------------------------------------------------------------------------- " Scheme for footnotes. Normally by heuristic URL like [1], which is " transformed into foot:1 before calling this handler. Given " foot:1 as reference, a referent is searched beginning from " the end of the current file. The referent can look like: " [1] or " [1]: " where only whitespace can appear in front in the same line. If the reference " has a fragment, e.g. [1]#string or even an empty fragment, e.g. [1]# " the value of the footnote is tried to derefence, i.e. automatic forwarding. " fu! Utl_AddressScheme_foot(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_foot",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `foot:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_foot",1,-1) return [] endif let opaque = UtlUri_unescape( UtlUri_opaque(a:auri) ) let reftPat = '\c\m^\s*\(\['.opaque.'\]:\?\)' call Utl_trace("- searching for referent pattern `".reftPat."' bottom up until current line...",0) let refcLine = line('.') | let refcCol = col('.') call cursor( line('$'), col('$') ) let reftLine = search(reftPat, 'Wb', refcLine+1) if reftLine==0 call Utl_trace("not found") endif if reftLine==0 call Utl_trace("- now searching for referent pattern `".reftPat."' top down until current line...",0) call cursor(1, 1) " (avoid stopline==0, this is special somehow. With -1 instead, " stopping works in the case of reference in line 1) let reftLine = search(reftPat, 'Wc', refcLine==1 ? -1 : refcLine-1 ) if reftLine==0 call Utl_trace("not found. Giving up") call cursor(refcLine, refcCol) endif endif if reftLine==0 let v:errmsg = "Reference has not target in current buffer. Provide another line starting with `[".opaque."]' or `".opaque.".' !" echohl ErrorMsg | echo v:errmsg | echohl None return [] endif call Utl_trace("found, in line `".reftLine."'") " Feature automatic forwarding if a:fragment != '' call Utl_trace("- fragment is defined, so try dereferencing foonote's content") call Utl_trace(" by trying to position one character past referent") " This should exactly fail in case there is no one additional non white character let l=search(reftPat.'.', 'ce', reftLine) if l == 0 let v:errmsg = "Cannot dereference footnote: Empty footnote" echohl ErrorMsg | echo v:errmsg | echohl None return [] elseif l != reftLine let v:errmsg = "Cannot dereference footnote: Internal Error: line number mismatch" echohl ErrorMsg | echo v:errmsg | echohl None return [] endif call Utl_trace("- fine, footnote not empty and cursor positioned to start of its") call Utl_trace(" content (column ".col('.').") and try to get URL from under the cursor") let uriRef = Utl_getUrlUnderCursor() if uriRef == '' let v:errmsg = "Cannot not dereference footnote: No URL under cursor" echohl ErrorMsg | echo v:errmsg | echohl None return [] endif call Utl_trace("- combine URL / URL-reference under cursor with fragment of [] reference") let uri = UriRef_getUri(uriRef) let fragmentOfReferent = UriRef_getFragment(uriRef) if fragmentOfReferent != '' call Utl_trace("- discard non empty fragment `".fragmentOfReferent."' of referent") endif call Utl('openLink', UtlUri_build_2(uri, a:fragment), a:dispMode) endif call Utl_trace("- end execution of Utl_AddressScheme_foot",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_foot",1,-1) return [Utl_utilBack2FwdSlashes( expand("%:p") )] endfu "------------------------------------------------------------------------------- " A scheme for quickly going to the setup file utl_rc.vim, e.g. " :Gu config: " fu! Utl_AddressScheme_config(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_config",1,1) let path = g:utl__file_rc call Utl_trace("- set local path to equal utl variable g:utl__file_scm: `".path."'") call Utl_trace("- end execution of Utl_AddressScheme_config",1,-1) return [ Utl_utilBack2FwdSlashes(path) ] endfu "id=vimscript------------------------------------------------------------------- " A non standard scheme for executing vim commands " " fu! Utl_AddressScheme_vimscript(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_vimscript",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `vimscript:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_vimscript",1,-1) return [] endif let exCmd = UtlUri_unescape( UtlUri_opaque(a:auri) ) call Utl_trace("- executing Vim Ex-command: `:".exCmd."'\n") " CR054_extra_nl "echo " DBG utl_opt_verbose=`".g:utl_opt_verbose."'" exe exCmd "echo " DBG (after) utl_opt_verbose=`".g:utl_opt_verbose."'" call Utl_trace("- end execution of Utl_AddressScheme_vimscript (successful)",1,-1) return [] endfu fu! Utl_AddressScheme_vimtip(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_vimtip",1,1) let url = "http://vim.sf.net/tips/tip.php?tip_id=". UtlUri_unescape( UtlUri_opaque(a:auri) ) call Utl_trace("- delegating to http scheme handler with URL `".url."'") let ret = Utl_AddressScheme_http(url, a:fragment, a:dispMode) call Utl_trace("- end execution of Utl_AddressScheme_vimtip",1,-1) return ret endfu "------------------------------------------------------------------------------- " A non standard scheme for getting Vim help " fu! Utl_AddressScheme_vimhelp(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_vimhelp",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `vimhelp:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_vimhelp",1,-1) return [] endif let exCmd = "help ".UtlUri_unescape( UtlUri_opaque(a:auri) ) call Utl_trace("- executing Vim Ex-command: `:".exCmd."'\n") " CR054_extra_nl exe exCmd if v:errmsg =~ '^Sorry, no help for' call Utl_trace("- end execution of Utl_AddressScheme_vimhelp",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_vimhelp (successful)",1,-1) return [ Utl_utilBack2FwdSlashes( expand("%:p") ), 'rel' ] endfu "------------------------------------------------------------------------------- " The mail-scheme. " This is not an official scheme in the internet. I invented it to directly " access individual Mails from a mail client. " " Synopsis : " mail://?query " " where query = [date=][&from=][&subject=] " " Examples : " " " fu! Utl_AddressScheme_mail(auri, fragment, dispMode) call Utl_trace("- start execution of Utl_AddressScheme_mail",1,1) if a:dispMode =~ '^copyFileName' echohl ErrorMsg | echo "function `copyFileName name to clipboard' not possible for scheme `mail:'" | echohl None call Utl_trace("- end execution of Utl_AddressScheme_mail",1,-1) return [] endif if ! exists('g:utl_cfg_hdl_scm_mail') " Entering setup call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_mail does not exist") echohl WarningMsg call input("No scheme handler variable g:utl_cfg_hdl_scm_mail defined yet. Entering Setup now. ") echohl None Utl openLink config:#r=utl_cfg_hdl_scm_mail split call Utl_trace("- end execution of Utl_AddressScheme_mail",1,-1) return [] endif call Utl_trace("- Vim variable g:utl_cfg_hdl_scm_mail exists, value=`".g:utl_cfg_hdl_scm_mail."'") let authority = UtlUri_unescape( UtlUri_authority(a:auri) ) let path = UtlUri_unescape( UtlUri_path(a:auri) ) let query = UtlUri_unescape( UtlUri_query(a:auri) ) call Utl_trace("- URL path components: authority=`".authority."', path=`".path."'" ) " Parse query expression if query == '' || query == "" let v:errmsg = 'Query expression missing' echohl ErrorMsg | echo v:errmsg | echohl None return [] endif let q_from = '' let q_subject = '' let q_date = '' while 1 let pos = stridx(query, '&') if pos == -1 let entry = query else let entry = strpart(query, 0, pos) let query = strpart(query, pos+1) endif if entry =~ '^from=' let q_from = substitute(entry, '.*=', '', '') elseif entry =~ '^subject=' let q_subject = substitute(entry, '.*=', '', '') elseif entry =~ '^date=' let q_date = substitute(entry, '.*=', '', '') else let q_date = entry endif if pos == -1 break endif endwhile call Utl_trace("- URL query attributes: date=`".q_date."', subject=`".q_subject."', from=`".q_from."'" ) let convSpecDict= { 'a': authority, 'p': path, 'd': q_date, 'f': q_from, 's': q_subject } let [errmsg,cmd] = Utl_utilExpandConvSpec(g:utl_cfg_hdl_scm_mail, convSpecDict) if errmsg != "" echohl ErrorMsg echo "The content of your Vim variable g:utl_cfg_hdl_scm_mail=".g:utl_cfg_hdl_scm_mail."' is invalid and has to be fixed!" echo "Reason: `".errmsg."'" echohl None call Utl_trace("- end execution of Utl_AddressScheme_mail (not successful)",1,-1) return [] endif call Utl_trace("- Escape cmdline-special characters (".s:utl_esccmdspecial.") before execution") let cmd = escape( cmd, s:utl_esccmdspecial) let g:utl__hdl_scm_ret_list=[] let v:errmsg = "" call Utl_trace("- trying to execute command `".cmd."'") exe cmd if v:shell_error || v:errmsg!="" call Utl_trace("- execution of scm handler returned with v:shell_error or v:errmsg set") call Utl_trace("- end execution of Utl_AddressScheme_mail (not successful)",1,-1) return [] endif call Utl_trace("- end execution of Utl_AddressScheme_mail (successful)",1,-1) return g:utl__hdl_scm_ret_list endfu let &cpo = s:save_cpo