[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: tpope\ncustom: [\"https://www.paypal.me/vimpope\"]\n"
  },
  {
    "path": ".gitignore",
    "content": "/doc/tags\n"
  },
  {
    "path": "README.markdown",
    "content": "# surround.vim\n\nSurround.vim is all about \"surroundings\": parentheses, brackets, quotes,\nXML tags, and more.  The plugin provides mappings to easily delete,\nchange and add such surroundings in pairs.\n\nIt's easiest to explain with examples.  Press `cs\"'` inside\n\n    \"Hello world!\"\n\nto change it to\n\n    'Hello world!'\n\nNow press `cs'<q>` to change it to\n\n    <q>Hello world!</q>\n\nTo go full circle, press `cst\"` to get\n\n    \"Hello world!\"\n\nTo remove the delimiters entirely, press `ds\"`.\n\n    Hello world!\n\nNow with the cursor on \"Hello\", press `ysiw]` (`iw` is a text object).\n\n    [Hello] world!\n\nLet's make that braces and add some space (use `}` instead of `{` for no\nspace): `cs]{`\n\n    { Hello } world!\n\nNow wrap the entire line in parentheses with `yssb` or `yss)`.\n\n    ({ Hello } world!)\n\nRevert to the original text: `ds{ds)`\n\n    Hello world!\n\nEmphasize hello: `ysiw<em>`\n\n    <em>Hello</em> world!\n\nFinally, let's try out visual mode. Press a capital V (for linewise\nvisual mode) followed by `S<p class=\"important\">`.\n\n    <p class=\"important\">\n      <em>Hello</em> world!\n    </p>\n\nThis plugin is very powerful for HTML and XML editing, a niche which\ncurrently seems underfilled in Vim land.  (As opposed to HTML/XML\n*inserting*, for which many plugins are available).  Adding, changing,\nand removing pairs of tags simultaneously is a breeze.\n\nThe `.` command will work with `ds`, `cs`, and `yss` if you install\n[repeat.vim](https://github.com/tpope/vim-repeat).\n\n## Installation\n\nInstall using your favorite package manager, or use Vim's built-in package\nsupport:\n\n    mkdir -p ~/.vim/pack/tpope/start\n    cd ~/.vim/pack/tpope/start\n    git clone https://tpope.io/vim/surround.git\n    vim -u NONE -c \"helptags surround/doc\" -c q\n\n## FAQ\n\n> How do I surround without adding a space?\n\nOnly the opening brackets—`[`, `{`, and `(`—add a space.  Use a closing\nbracket, or the `b` (`(`) and `B` (`{`) aliases.\n\n## Contributing\n\nSee the contribution guidelines for\n[pathogen.vim](https://github.com/tpope/vim-pathogen#readme).\n\n## Self-Promotion\n\nLike surround.vim?  Star the repository on\n[GitHub](https://github.com/tpope/vim-surround) and vote for it on\n[vim.org](https://www.vim.org/scripts/script.php?script_id=1697).\n\nLove surround.vim?  Follow [tpope](http://tpo.pe/) on\n[GitHub](https://github.com/tpope) and\n[Twitter](http://twitter.com/tpope).\n\n## License\n\nCopyright (c) Tim Pope.  Distributed under the same terms as Vim itself.\nSee `:help license`.\n"
  },
  {
    "path": "doc/surround.txt",
    "content": "*surround.txt*  Plugin for deleting, changing, and adding \"surroundings\"\n\nAuthor:  Tim Pope <http://tpo.pe/>\nLicense: Same terms as Vim itself (see |license|)\n\nThis plugin is only available if 'compatible' is not set.\n\nINTRODUCTION                                    *surround*\n\nThis plugin is a tool for dealing with pairs of \"surroundings.\"  Examples\nof surroundings include parentheses, quotes, and HTML tags.  They are\nclosely related to what Vim refers to as |text-objects|.  Provided\nare mappings to allow for removing, changing, and adding surroundings.\n\nDetails follow on the exact semantics, but first, consider the following\nexamples.  An asterisk (*) is used to denote the cursor position.\n\n  Old text                  Command     New text ~\n  \"Hello *world!\"           ds\"         Hello world!\n  [123+4*56]/2              cs])        (123+456)/2\n  \"Look ma, I'm *HTML!\"     cs\"<q>      <q>Look ma, I'm HTML!</q>\n  if *x>3 {                 ysW(        if ( x>3 ) {\n  my $str = *whee!;         vllllS'     my $str = 'whee!';\n\nWhile a few features of this plugin will work in older versions of Vim,\nVim 7 is recommended for full functionality.\n\nMAPPINGS                                        *surround-mappings*\n\nDelete surroundings is *ds* .  The next character given determines the target\nto delete.  The exact nature of the target is explained in |surround-targets|\nbut essentially it is the last character of a |text-object|.  This mapping\ndeletes the difference between the \"i\"nner object and \"a\"n object.  This is\neasiest to understand with some examples:\n\n  Old text                  Command     New text ~\n  \"Hello *world!\"           ds\"         Hello world!\n  (123+4*56)/2              ds)         123+456/2\n  <div>Yo!*</div>           dst         Yo!\n\nChange surroundings is *cs* .  It takes two arguments, a target like with\n|ds|, and a replacement.  *cS* changes surroundings, placing the surrounded\ntext on its own line(s) like |yS|.  Details about the second argument can be\nfound below in |surround-replacements|.  Once again, examples are in order.\n\n  Old text                  Command     New text ~\n  \"Hello *world!\"           cs\"'        'Hello world!'\n  \"Hello *world!\"           cs\"<q>      <q>Hello world!</q>\n  (123+4*56)/2              cs)]        [123+456]/2\n  (123+4*56)/2              cs)[        [ 123+456 ]/2\n  <div>Yo!*</div>           cst<p>      <p>Yo!</p>\n\n*ys* takes a valid Vim motion or text object as the first object, and wraps\nit using the second argument as with |cs|.  (It's a stretch, but a good\nmnemonic for \"ys\" is \"you surround\".)\n\n  Old text                  Command     New text ~\n  Hello w*orld!             ysiw)       Hello (world)!\n\nAs a special case, *yss* operates on the current line, ignoring leading\nwhitespace.\n\n  Old text                  Command     New text ~\n      Hello w*orld!         yssB            {Hello world!}\n\nThere is also *yS* and *ySS* which indent the surrounded text and place it\non a line of its own.\n\nIn visual mode, a simple \"S\" with an argument wraps the selection.  This is\nreferred to as the *vS* mapping, although ordinarily there will be\nadditional keystrokes between the v and S.  In linewise visual mode, the\nsurroundings are placed on separate lines and indented.  In blockwise visual\nmode, each line is surrounded.\n\nA \"gS\" in visual mode, known as *vgS* , behaves similarly.  In linewise visual\nmode, the automatic indenting is suppressed.  In blockwise visual mode, this\nenables surrounding past the end of the line with 'virtualedit' set (there\nseems to be no way in Vim Script to differentiate between a jagged end of line\nselection and a virtual block selected past the end of the line, so two maps\nwere needed).\n\n                                                *i_CTRL-G_s* *i_CTRL-G_S*\nFinally, there is an experimental insert mode mapping on <C-G>s and <C-S>.\nBeware that the latter won't work on terminals with flow control (if you\naccidentally freeze your terminal, use <C-Q> to unfreeze it).  The mapping\ninserts the specified surroundings and puts the cursor between them.  If,\nimmediately after the mapping and before the replacement, a second <C-S> or\ncarriage return is pressed, the prefix, cursor, and suffix will be placed on\nthree separate lines.  <C-G>S (not <C-G>s) also exhibits this behavior.\n\nTARGETS                                         *surround-targets*\n\nThe |ds| and |cs| commands both take a target as their first argument.  The\npossible targets are based closely on the |text-objects| provided by Vim.\nAll targets are currently just one character.\n\nEight punctuation marks, (, ), {, }, [, ], <, and >, represent themselves\nand their counterparts.  If the opening mark is used, contained whitespace is\nalso trimmed.  The targets b, B, r, and a are aliases for ), }, ], and > \n(the first two mirror Vim; the second two are completely arbitrary and\nsubject to change).\n\nThree quote marks, ', \", `, represent themselves, in pairs.  They are only\nsearched for on the current line.\n\nA t is a pair of HTML or XML tags.  See |tag-blocks| for details.  Remember\nthat you can specify a numerical argument if you want to get to a tag other\nthan the innermost one.\n\nThe letters w, W, and s correspond to a |word|, a |WORD|, and a |sentence|,\nrespectively.  These are special in that they have nothing to delete, and\nused with |ds| they are a no-op.  With |cs|, one could consider them a\nslight shortcut for ysi (cswb == ysiwb, more or less).\n\nA p represents a |paragraph|.  This behaves similarly to w, W, and s above;\nhowever, newlines are sometimes added and/or removed.\n\nREPLACEMENTS                                    *surround-replacements*\n\nA replacement argument is a single character, and is required by |cs|, |ys|,\nand |vS|.  Undefined replacement characters (with the exception of alphabetic\ncharacters) default to placing themselves at the beginning and end of the\ndestination, which can be useful for characters like / and |.\n\nIf either ), }, ], or > is used, the text is wrapped in the appropriate pair\nof characters.  Similar behavior can be found with (, {, and [ (but not <),\nwhich append an additional space to the inside.  Like with the targets above,\nb, B, r, and a are aliases for ), }, ], and >.  To fulfill the common need for\ncode blocks in C-style languages, <C-}> (which is really <C-]>) adds braces on\nlines separate from the content.\n\nIf t or < is used, Vim prompts for an HTML/XML tag to insert.  You may specify\nattributes here and they will be stripped from the closing tag. If replacing a\ntag, its attributes are kept in the new tag. End your input with > to discard\nthe those attributes. If <C-T> is used, the tags will appear on lines by\nthemselves.\n\nIf f, F, or <C-F> is used, Vim prompts for a function name to insert.  The target\ntext will be wrapped in a function call. If f is used, the text is wrapped with\n() parentheses; F adds additional spaces inside the parentheses. <C-F> inserts the\nfunction name inside the parentheses.\n\n  Old text                  Command           New text ~\n  \"hello\"                   ysWfprint<cr>     print(\"hello\")\n  \"hello\"                   ysWFprint<cr>     print( \"hello\" )\n  \"hello\"                   ysW<C-f>print<cr> (print \"hello\")\n\nIf s is used, a leading but not trailing space is added.  This is useful for\nremoving parentheses from a function call with csbs.\n\nCUSTOMIZING                                     *surround-customizing*\n\nThe following adds a potential replacement on \"-\" (ASCII 45) in PHP files.\n(To determine the ASCII code to use, :echo char2nr(\"-\")).  The carriage\nreturn will be replaced by the original text.\n>\n  autocmd FileType php let b:surround_45 = \"<?php \\r ?>\"\n<\nThis can be used in a PHP file as in the following example.\n\n  Old text                  Command     New text ~\n  print \"Hello *world!\"     yss-        <?php print \"Hello world!\" ?>\n\nAdditionally, one can use a global variable for globally available\nreplacements.\n>\n  let g:surround_45 = \"<% \\r %>\"\n  let g:surround_61 = \"<%= \\r %>\"\n<\nAdvanced, experimental, and subject to change:  One can also prompt for\nreplacement text.  The syntax for this is to surround the replacement in pairs\nof low numbered control characters.  If this sounds confusing, that's because\nit is (but it makes the parsing easy).  Consider the following example for a\nLaTeX environment on the \"l\" replacement.\n>\n  let g:surround_108 = \"\\\\begin{\\1environment: \\1}\\r\\\\end{\\1\\1}\"\n<\nWhen this replacement is used,  the user is prompted with an \"environment: \"\nprompt for input.  This input is inserted between each set of \\1's.\nAdditional inputs up to \\7 can be used.\n\nFurthermore, one can specify a regular expression substitution to apply.\n>\n  let g:surround_108 = \"\\\\begin{\\1environment: \\1}\\r\\\\end{\\1\\r}.*\\r\\1}\"\n<\nThis will remove anything after the first } in the input when the text is\nplaced within the \\end{} slot.  The first \\r marks where the pattern begins,\nand the second where the replacement text begins.\n\nHere's a second example for creating an HTML <div>.  The substitution cleverly\nprompts for an id, but only adds id=\"\" if it is non-blank.  You may have to\nread this one a few times slowly before you understand it.\n>\n  let g:surround_{char2nr(\"d\")} = \"<div\\1id: \\r..*\\r id=\\\"&\\\"\\1>\\r</div>\"\n<\nInputting text replacements is a proof of concept at this point. The ugly,\nunintuitive interface and the brevity of the documentation reflect this.\n\nFinally, It is possible to always append a string to surroundings in insert\nmode (and only insert mode).  This is useful with certain plugins and mappings\nthat allow you to jump to such markings.\n>\n  let g:surround_insert_tail = \"<++>\"\n<\n vim:tw=78:ts=8:ft=help:norl:\n"
  },
  {
    "path": "plugin/surround.vim",
    "content": "\" surround.vim - Surroundings\n\" Author:       Tim Pope <http://tpo.pe/>\n\" Version:      2.2\n\" GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim\n\nif exists(\"g:loaded_surround\") || &cp || v:version < 700\n  finish\nendif\nlet g:loaded_surround = 1\n\n\" Input functions {{{1\n\nfunction! s:getchar()\n  let c = getchar()\n  if c =~ '^\\d\\+$'\n    let c = nr2char(c)\n  endif\n  return c\nendfunction\n\nfunction! s:inputtarget()\n  let c = s:getchar()\n  while c =~ '^\\d\\+$'\n    let c .= s:getchar()\n  endwhile\n  if c == \" \"\n    let c .= s:getchar()\n  endif\n  if c =~ \"\\<Esc>\\|\\<C-C>\\|\\0\"\n    return \"\"\n  else\n    return c\n  endif\nendfunction\n\nfunction! s:inputreplacement()\n  let c = s:getchar()\n  if c == \" \"\n    let c .= s:getchar()\n  endif\n  if c =~ \"\\<Esc>\" || c =~ \"\\<C-C>\"\n    return \"\"\n  else\n    return c\n  endif\nendfunction\n\nfunction! s:beep()\n  exe \"norm! \\<Esc>\"\n  return \"\"\nendfunction\n\nfunction! s:redraw()\n  redraw\n  return \"\"\nendfunction\n\n\" }}}1\n\n\" Wrapping functions {{{1\n\nfunction! s:extractbefore(str)\n  if a:str =~ '\\r'\n    return matchstr(a:str,'.*\\ze\\r')\n  else\n    return matchstr(a:str,'.*\\ze\\n')\n  endif\nendfunction\n\nfunction! s:extractafter(str)\n  if a:str =~ '\\r'\n    return matchstr(a:str,'\\r\\zs.*')\n  else\n    return matchstr(a:str,'\\n\\zs.*')\n  endif\nendfunction\n\nfunction! s:fixindent(str,spc)\n  let str = substitute(a:str,'\\t',repeat(' ',&sw),'g')\n  let spc = substitute(a:spc,'\\t',repeat(' ',&sw),'g')\n  let str = substitute(str,'\\(\\n\\|\\%^\\).\\@=','\\1'.spc,'g')\n  if ! &et\n    let str = substitute(str,'\\s\\{'.&ts.'\\}',\"\\t\",'g')\n  endif\n  return str\nendfunction\n\nfunction! s:process(string)\n  let i = 0\n  for i in range(7)\n    let repl_{i} = ''\n    let m = matchstr(a:string,nr2char(i).'.\\{-\\}\\ze'.nr2char(i))\n    if m != ''\n      let m = substitute(strpart(m,1),'\\r.*','','')\n      let repl_{i} = input(match(m,'\\w\\+$') >= 0 ? m.': ' : m)\n    endif\n  endfor\n  let s = \"\"\n  let i = 0\n  while i < strlen(a:string)\n    let char = strpart(a:string,i,1)\n    if char2nr(char) < 8\n      let next = stridx(a:string,char,i+1)\n      if next == -1\n        let s .= char\n      else\n        let insertion = repl_{char2nr(char)}\n        let subs = strpart(a:string,i+1,next-i-1)\n        let subs = matchstr(subs,'\\r.*')\n        while subs =~ '^\\r.*\\r'\n          let sub = matchstr(subs,\"^\\r\\\\zs[^\\r]*\\r[^\\r]*\")\n          let subs = strpart(subs,strlen(sub)+1)\n          let r = stridx(sub,\"\\r\")\n          let insertion = substitute(insertion,strpart(sub,0,r),strpart(sub,r+1),'')\n        endwhile\n        let s .= insertion\n        let i = next\n      endif\n    else\n      let s .= char\n    endif\n    let i += 1\n  endwhile\n  return s\nendfunction\n\nfunction! s:wrap(string,char,type,removed,special)\n  let keeper = a:string\n  let newchar = a:char\n  let s:input = \"\"\n  let type = a:type\n  let linemode = type ==# 'V' ? 1 : 0\n  let before = \"\"\n  let after  = \"\"\n  if type ==# \"V\"\n    let initspaces = matchstr(keeper,'\\%^\\s*')\n  else\n    let initspaces = matchstr(getline('.'),'\\%^\\s*')\n  endif\n  let pairs = \"b()B{}r[]a<>\"\n  let extraspace = \"\"\n  if newchar =~ '^ '\n    let newchar = strpart(newchar,1)\n    let extraspace = ' '\n  endif\n  let idx = stridx(pairs,newchar)\n  if newchar == ' '\n    let before = ''\n    let after  = ''\n  elseif exists(\"b:surround_\".char2nr(newchar))\n    let all    = s:process(b:surround_{char2nr(newchar)})\n    let before = s:extractbefore(all)\n    let after  =  s:extractafter(all)\n  elseif exists(\"g:surround_\".char2nr(newchar))\n    let all    = s:process(g:surround_{char2nr(newchar)})\n    let before = s:extractbefore(all)\n    let after  =  s:extractafter(all)\n  elseif newchar ==# \"p\"\n    let before = \"\\n\"\n    let after  = \"\\n\\n\"\n  elseif newchar ==# 's'\n    let before = ' '\n    let after  = ''\n  elseif newchar ==# ':'\n    let before = ':'\n    let after = ''\n  elseif newchar =~# \"[tT\\<C-T><]\"\n    let dounmapp = 0\n    let dounmapb = 0\n    if !maparg(\">\",\"c\")\n      let dounmapb = 1\n      \" Hide from AsNeeded\n      exe \"cn\".\"oremap > ><CR>\"\n    endif\n    let default = \"\"\n    if newchar ==# \"T\"\n      if !exists(\"s:lastdel\")\n        let s:lastdel = \"\"\n      endif\n      let default = matchstr(s:lastdel,'<\\zs.\\{-\\}\\ze>')\n    endif\n    let tag = input(\"<\",default)\n    if dounmapb\n      silent! cunmap >\n    endif\n    let s:input = tag\n    if tag != \"\"\n      let keepAttributes = ( match(tag, \">$\") == -1 )\n      let tag = substitute(tag,'>*$','','')\n      let attributes = \"\"\n      if keepAttributes\n        let attributes = matchstr(a:removed, '<[^ \\t\\n]\\+\\zs\\_.\\{-\\}\\ze>')\n      endif\n      let s:input = tag . '>'\n      if tag =~ '/$'\n        let tag = substitute(tag, '/$', '', '')\n        let before = '<'.tag.attributes.' />'\n        let after = ''\n      else\n        let before = '<'.tag.attributes.'>'\n        let after  = '</'.substitute(tag,' .*','','').'>'\n      endif\n      if newchar == \"\\<C-T>\"\n        if type ==# \"v\" || type ==# \"V\"\n          let before .= \"\\n\\t\"\n        endif\n        if type ==# \"v\"\n          let after  = \"\\n\". after\n        endif\n      endif\n    endif\n  elseif newchar ==# 'l' || newchar == '\\'\n    \" LaTeX\n    let env = input('\\begin{')\n    if env != \"\"\n      let s:input = env.\"\\<CR>\"\n      let env = '{' . env\n      let env .= s:closematch(env)\n      echo '\\begin'.env\n      let before = '\\begin'.env\n      let after  = '\\end'.matchstr(env,'[^}]*').'}'\n    endif\n  elseif newchar ==# 'f' || newchar ==# 'F'\n    let fnc = input('function: ')\n    if fnc != \"\"\n      let s:input = fnc.\"\\<CR>\"\n      let before = substitute(fnc,'($','','').'('\n      let after  = ')'\n      if newchar ==# 'F'\n        let before .= ' '\n        let after = ' ' . after\n      endif\n    endif\n  elseif newchar ==# \"\\<C-F>\"\n    let fnc = input('function: ')\n    let s:input = fnc.\"\\<CR>\"\n    let before = '('.fnc.' '\n    let after = ')'\n  elseif idx >= 0\n    let spc = (idx % 3) == 1 ? \" \" : \"\"\n    let idx = idx / 3 * 3\n    let before = strpart(pairs,idx+1,1) . spc\n    let after  = spc . strpart(pairs,idx+2,1)\n  elseif newchar == \"\\<C-[>\" || newchar == \"\\<C-]>\"\n    let before = \"{\\n\\t\"\n    let after  = \"\\n}\"\n  elseif newchar !~ '\\a'\n    let before = newchar\n    let after  = newchar\n  else\n    let before = ''\n    let after  = ''\n  endif\n  let after  = substitute(after ,'\\n','\\n'.initspaces,'g')\n  if type ==# 'V' || (a:special && type ==# \"v\")\n    let before = substitute(before,' \\+$','','')\n    let after  = substitute(after ,'^ \\+','','')\n    if after !~ '^\\n'\n      let after  = initspaces.after\n    endif\n    if keeper !~ '\\n$' && after !~ '^\\n'\n      let keeper .= \"\\n\"\n    elseif keeper =~ '\\n$' && after =~ '^\\n'\n      let after = strpart(after,1)\n    endif\n    if keeper !~ '^\\n' && before !~ '\\n\\s*$'\n      let before .= \"\\n\"\n      if a:special\n        let before .= \"\\t\"\n      endif\n    elseif keeper =~ '^\\n' && before =~ '\\n\\s*$'\n      let keeper = strcharpart(keeper,1)\n    endif\n    if type ==# 'V' && keeper =~ '\\n\\s*\\n$'\n      let keeper = strcharpart(keeper,0,strchars(keeper) - 1)\n    endif\n  endif\n  if type ==# 'V'\n    let before = initspaces.before\n  endif\n  if before =~ '\\n\\s*\\%$'\n    if type ==# 'v'\n      let keeper = initspaces.keeper\n    endif\n    let padding = matchstr(before,'\\n\\zs\\s\\+\\%$')\n    let before  = substitute(before,'\\n\\s\\+\\%$','\\n','')\n    let keeper = s:fixindent(keeper,padding)\n  endif\n  if type ==# 'V'\n    let keeper = before.keeper.after\n  elseif type =~ \"^\\<C-V>\"\n    \" Really we should be iterating over the buffer\n    let repl = substitute(before,'[\\\\~]','\\\\&','g').'\\1'.substitute(after,'[\\\\~]','\\\\&','g')\n    let repl = substitute(repl,'\\n',' ','g')\n    let keeper = substitute(keeper.\"\\n\",'\\(.\\{-\\}\\)\\(\\n\\)',repl.'\\n','g')\n    let keeper = substitute(keeper,'\\n\\%$','','')\n  else\n    let keeper = before.extraspace.keeper.extraspace.after\n  endif\n  return keeper\nendfunction\n\nfunction! s:wrapreg(reg,char,removed,special)\n  let orig = getreg(a:reg)\n  let type = substitute(getregtype(a:reg),'\\d\\+$','','')\n  let new = s:wrap(orig,a:char,type,a:removed,a:special)\n  call setreg(a:reg,new,type)\nendfunction\n\" }}}1\n\nfunction! s:insert(...) \" {{{1\n  \" Optional argument causes the result to appear on 3 lines, not 1\n  let linemode = a:0 ? a:1 : 0\n  let char = s:inputreplacement()\n  while char == \"\\<CR>\" || char == \"\\<C-S>\"\n    \" TODO: use total count for additional blank lines\n    let linemode += 1\n    let char = s:inputreplacement()\n  endwhile\n  if char == \"\"\n    return \"\"\n  endif\n  let cb_save = &clipboard\n  set clipboard-=unnamed clipboard-=unnamedplus\n  let reg_save = @@\n  call setreg('\"',\"\\032\",'v')\n  call s:wrapreg('\"',char,\"\",linemode)\n  \" If line mode is used and the surrounding consists solely of a suffix,\n  \" remove the initial newline.  This fits a use case of mine but is a\n  \" little inconsistent.  Is there anyone that would prefer the simpler\n  \" behavior of just inserting the newline?\n  if linemode && match(getreg('\"'),'^\\n\\s*\\zs.*') == 0\n    call setreg('\"',matchstr(getreg('\"'),'^\\n\\s*\\zs.*'),getregtype('\"'))\n  endif\n  \" This can be used to append a placeholder to the end\n  if exists(\"g:surround_insert_tail\")\n    call setreg('\"',g:surround_insert_tail,\"a\".getregtype('\"'))\n  endif\n  if &ve != 'all' && col('.') >= col('$')\n    if &ve == 'insert'\n      let extra_cols = virtcol('.') - virtcol('$')\n      if extra_cols > 0\n        let [regval,regtype] = [getreg('\"',1,1),getregtype('\"')]\n        call setreg('\"',join(map(range(extra_cols),'\" \"'),''),'v')\n        norm! \"\"p\n        call setreg('\"',regval,regtype)\n      endif\n    endif\n    norm! \"\"p\n  else\n    norm! \"\"P\n  endif\n  if linemode\n    call s:reindent()\n  endif\n  norm! `]\n  call search(\"\\032\",'bW')\n  let @@ = reg_save\n  let &clipboard = cb_save\n  return \"\\<Del>\"\nendfunction \" }}}1\n\nfunction! s:reindent() abort \" {{{1\n  if get(b:, 'surround_indent', get(g:, 'surround_indent', 1)) && (!empty(&equalprg) || !empty(&indentexpr) || &cindent || &smartindent || &lisp)\n    silent norm! '[=']\n  endif\nendfunction \" }}}1\n\nfunction! s:dosurround(...) \" {{{1\n  let sol_save = &startofline\n  set startofline\n  let scount = v:count1\n  let char = (a:0 ? a:1 : s:inputtarget())\n  let spc = \"\"\n  if char =~ '^\\d\\+'\n    let scount = scount * matchstr(char,'^\\d\\+')\n    let char = substitute(char,'^\\d\\+','','')\n  endif\n  if char =~ '^ '\n    let char = strpart(char,1)\n    let spc = 1\n  endif\n  if char == 'a'\n    let char = '>'\n  endif\n  if char == 'r'\n    let char = ']'\n  endif\n  let newchar = \"\"\n  if a:0 > 1\n    let newchar = a:2\n    if newchar == \"\\<Esc>\" || newchar == \"\\<C-C>\" || newchar == \"\"\n      if !sol_save\n        set nostartofline\n      endif\n      return s:beep()\n    endif\n  endif\n  let cb_save = &clipboard\n  set clipboard-=unnamed clipboard-=unnamedplus\n  let append = \"\"\n  let original = getreg('\"')\n  let otype = getregtype('\"')\n  call setreg('\"',\"\")\n  let strcount = (scount == 1 ? \"\" : scount)\n  if char == '/'\n    exe 'norm! '.strcount.'[/d'.strcount.']/'\n  elseif char =~# '[[:punct:][:space:]]' && char !~# '[][(){}<>\"''`]'\n    exe 'norm! T'.char\n    if getline('.')[col('.')-1] == char\n      exe 'norm! l'\n    endif\n    exe 'norm! dt'.char\n  else\n    exe 'norm! d'.strcount.'i'.char\n  endif\n  let keeper = getreg('\"')\n  let okeeper = keeper \" for reindent below\n  if keeper == \"\"\n    call setreg('\"',original,otype)\n    let &clipboard = cb_save\n    if !sol_save\n      set nostartofline\n    endif\n    return \"\"\n  endif\n  let oldline = getline('.')\n  let oldlnum = line('.')\n  if char ==# \"p\"\n    call setreg('\"','','V')\n  elseif char ==# \"s\" || char ==# \"w\" || char ==# \"W\"\n    \" Do nothing\n    call setreg('\"','')\n  elseif char =~ \"[\\\"'`]\"\n    exe \"norm! i \\<Esc>d2i\".char\n    call setreg('\"',substitute(getreg('\"'),' ','',''))\n  elseif char == '/'\n    norm! \"_x\n    call setreg('\"','/**/',\"c\")\n    let keeper = substitute(substitute(keeper,'^/\\*\\s\\=','',''),'\\s\\=\\*$','','')\n  elseif char =~# '[[:punct:][:space:]]' && char !~# '[][(){}<>]'\n    exe 'norm! F'.char\n    exe 'norm! df'.char\n  else\n    \" One character backwards\n    call search('\\m.', 'bW')\n    exe \"norm! da\".char\n  endif\n  let removed = getreg('\"')\n  let rem2 = substitute(removed,'\\n.*','','')\n  let oldhead = strpart(oldline,0,strlen(oldline)-strlen(rem2))\n  let oldtail = strpart(oldline,  strlen(oldline)-strlen(rem2))\n  let regtype = getregtype('\"')\n  if char =~# '[\\[({<T]' || spc\n    let keeper = substitute(keeper,'^\\s\\+','','')\n    let keeper = substitute(keeper,'\\s\\+$','','')\n  endif\n  if col(\"']\") == col(\"$\") && virtcol('.') + 1 == virtcol('$')\n    if oldhead =~# '^\\s*$' && a:0 < 2\n      let keeper = substitute(keeper,'\\%^\\n'.oldhead.'\\(\\s*.\\{-\\}\\)\\n\\s*\\%$','\\1','')\n    endif\n    let pcmd = \"p\"\n  else\n    let pcmd = \"P\"\n  endif\n  if line('.') + 1 < oldlnum && regtype ==# \"V\"\n    let pcmd = \"p\"\n  endif\n  call setreg('\"',keeper,regtype)\n  if newchar != \"\"\n    let special = a:0 > 2 ? a:3 : 0\n    call s:wrapreg('\"',newchar,removed,special)\n  endif\n  silent exe 'norm! \"\"'.pcmd.'`['\n  if removed =~ '\\n' || okeeper =~ '\\n' || getreg('\"') =~ '\\n'\n    call s:reindent()\n  endif\n  if getline('.') =~ '^\\s\\+$' && keeper =~ '^\\s*\\n'\n    silent norm! cc\n  endif\n  call setreg('\"',original,otype)\n  let s:lastdel = removed\n  let &clipboard = cb_save\n  if newchar == \"\"\n    silent! call repeat#set(\"\\<Plug>Dsurround\".char,scount)\n  else\n    silent! call repeat#set(\"\\<Plug>C\".(a:0 > 2 && a:3 ? \"S\" : \"s\").\"urround\".char.newchar.s:input,scount)\n  endif\n  if !sol_save\n    set nostartofline\n  endif\nendfunction \" }}}1\n\nfunction! s:changesurround(...) \" {{{1\n  let a = s:inputtarget()\n  if a == \"\"\n    return s:beep()\n  endif\n  let b = s:inputreplacement()\n  if b == \"\"\n    return s:beep()\n  endif\n  call s:dosurround(a,b,a:0 && a:1)\nendfunction \" }}}1\n\nfunction! s:opfunc(type, ...) abort \" {{{1\n  if a:type ==# 'setup'\n    let &opfunc = matchstr(expand('<sfile>'), '<SNR>\\w\\+$')\n    return 'g@'\n  endif\n  let char = s:inputreplacement()\n  if char == \"\"\n    return s:beep()\n  endif\n  let reg = '\"'\n  let sel_save = &selection\n  let &selection = \"inclusive\"\n  let cb_save  = &clipboard\n  set clipboard-=unnamed clipboard-=unnamedplus\n  let reg_save = getreg(reg)\n  let reg_type = getregtype(reg)\n  let type = a:type\n  if a:type == \"char\"\n    silent exe 'norm! v`[o`]\"'.reg.'y'\n    let type = 'v'\n  elseif a:type == \"line\"\n    silent exe 'norm! `[V`]\"'.reg.'y'\n    let type = 'V'\n  elseif a:type ==# \"v\" || a:type ==# \"V\" || a:type ==# \"\\<C-V>\"\n    let &selection = sel_save\n    let ve = &virtualedit\n    if !(a:0 && a:1)\n      set virtualedit=\n    endif\n    silent exe 'norm! gv\"'.reg.'y'\n    let &virtualedit = ve\n  elseif a:type =~ '^\\d\\+$'\n    let type = 'v'\n    silent exe 'norm! ^v'.a:type.'$h\"'.reg.'y'\n    if mode() ==# 'v'\n      norm! v\n      return s:beep()\n    endif\n  else\n    let &selection = sel_save\n    let &clipboard = cb_save\n    return s:beep()\n  endif\n  let keeper = getreg(reg)\n  if type ==# \"v\" && a:type !=# \"v\"\n    let append = matchstr(keeper,'\\_s\\@<!\\s*$')\n    let keeper = substitute(keeper,'\\_s\\@<!\\s*$','','')\n  endif\n  call setreg(reg,keeper,type)\n  call s:wrapreg(reg,char,\"\",a:0 && a:1)\n  if type ==# \"v\" && a:type !=# \"v\" && append != \"\"\n    call setreg(reg,append,\"ac\")\n  endif\n  silent exe 'norm! gv'.(reg == '\"' ? '' : '\"' . reg).'p`['\n  if type ==# 'V' || (getreg(reg) =~ '\\n' && type ==# 'v')\n    call s:reindent()\n  endif\n  call setreg(reg,reg_save,reg_type)\n  let &selection = sel_save\n  let &clipboard = cb_save\n  if a:type =~ '^\\d\\+$'\n    silent! call repeat#set(\"\\<Plug>Y\".(a:0 && a:1 ? \"S\" : \"s\").\"surround\".char.s:input,a:type)\n  else\n    silent! call repeat#set(\"\\<Plug>SurroundRepeat\".char.s:input)\n  endif\nendfunction\n\nfunction! s:opfunc2(...) abort\n  if !a:0 || a:1 ==# 'setup'\n    let &opfunc = matchstr(expand('<sfile>'), '<SNR>\\w\\+$')\n    return 'g@'\n  endif\n  call s:opfunc(a:1, 1)\nendfunction \" }}}1\n\nfunction! s:closematch(str) \" {{{1\n  \" Close an open (, {, [, or < on the command line.\n  let tail = matchstr(a:str,'.[^\\[\\](){}<>]*$')\n  if tail =~ '^\\[.\\+'\n    return \"]\"\n  elseif tail =~ '^(.\\+'\n    return \")\"\n  elseif tail =~ '^{.\\+'\n    return \"}\"\n  elseif tail =~ '^<.+'\n    return \">\"\n  else\n    return \"\"\n  endif\nendfunction \" }}}1\n\nnnoremap <silent> <Plug>SurroundRepeat .\nnnoremap <silent> <Plug>Dsurround  :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>\nnnoremap <silent> <Plug>Csurround  :<C-U>call <SID>changesurround()<CR>\nnnoremap <silent> <Plug>CSurround  :<C-U>call <SID>changesurround(1)<CR>\nnnoremap <expr>   <Plug>Yssurround '^'.v:count1.<SID>opfunc('setup').'g_'\nnnoremap <expr>   <Plug>YSsurround <SID>opfunc2('setup').'_'\nnnoremap <expr>   <Plug>Ysurround  <SID>opfunc('setup')\nnnoremap <expr>   <Plug>YSurround  <SID>opfunc2('setup')\nvnoremap <silent> <Plug>VSurround  :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 1 : 0)<CR>\nvnoremap <silent> <Plug>VgSurround :<C-U>call <SID>opfunc(visualmode(),visualmode() ==# 'V' ? 0 : 1)<CR>\ninoremap <silent> <Plug>Isurround  <C-R>=<SID>insert()<CR>\ninoremap <silent> <Plug>ISurround  <C-R>=<SID>insert(1)<CR>\n\nif !exists(\"g:surround_no_mappings\") || ! g:surround_no_mappings\n  nmap ds  <Plug>Dsurround\n  nmap cs  <Plug>Csurround\n  nmap cS  <Plug>CSurround\n  nmap ys  <Plug>Ysurround\n  nmap yS  <Plug>YSurround\n  nmap yss <Plug>Yssurround\n  nmap ySs <Plug>YSsurround\n  nmap ySS <Plug>YSsurround\n  xmap S   <Plug>VSurround\n  xmap gS  <Plug>VgSurround\n  if !exists(\"g:surround_no_insert_mappings\") || ! g:surround_no_insert_mappings\n    if !hasmapto(\"<Plug>Isurround\",\"i\") && \"\" == mapcheck(\"<C-S>\",\"i\")\n      imap    <C-S> <Plug>Isurround\n    endif\n    imap      <C-G>s <Plug>Isurround\n    imap      <C-G>S <Plug>ISurround\n  endif\nendif\n\n\" vim:set ft=vim sw=2 sts=2 et:\n"
  }
]