vim-surround icon indicating copy to clipboard operation
vim-surround copied to clipboard

Allow multiple characters surround

Open tonicebrian opened this issue 14 years ago • 22 comments

Hi,

I'd like to use your plugin for editing Trac wiki pages. In this language sections have more than one = level, for instance:

= Section1 =

== Section2 ==

=== Section3 ===

would it be possible to specify a number before the character to wrap? For instance if I want to convert a text into Section3 header it will be something like cs<text_selection>3=

Thank you

tonicebrian avatar Nov 29 '10 16:11 tonicebrian

This would also be useful for Mediawiki: ''italic'', '''bold'''

And of course Markdown: bold

tangledhelix avatar Nov 30 '10 17:11 tangledhelix

I guess it'd be possible, though I'm not too keen on implementing it. In the past, I've just created one-offs for those, e.g.:

let g:surround_{char2nr('o')} = "**\r**"

tpope avatar Dec 14 '10 00:12 tpope

I'm resurrecting this because I have a question about your philosophy on this and a specific question regarding multiple characters. I am wondering why ysw<em> works but ysw** does not (to surround the word with two * marks)

fncll avatar Oct 02 '13 18:10 fncll

All surroundings are invoked as a single character. < is a special surrounding that prompts for the tag.

tpope avatar Oct 02 '13 19:10 tpope

I think the majority of use cases for this would be covered by allowing a prefix for the surround plugin; 2ysw* really should run the surround twice, which would give the desired behavior.

isovector avatar Nov 03 '15 16:11 isovector

That seems like a reasonable solution. Today, the count for the operator is unused.

You can still supply a count for the motion (e.g. ys2w*); I'm pretty sure that comes for free when implementing custom operators.

tommcdo avatar Nov 03 '15 16:11 tommcdo

How about using < for this as well? Since XML/HTML tags must start with a letter, and the multi-character tags in markdown and friends usually are non-letter characters, this could make sense.

Currently you can use cs*<**> to turn *bold* into <**>bold</**>

That isn't very useful, since <**> is not a valid xml tag name. Instead this could result in **bold**, which is what you want if you write ReStructured Text.

haakenlid avatar Nov 26 '15 16:11 haakenlid

That strikes me as being a hack; then you wouldn't be able to do multiple surrounds of alphanumeric characters.

isovector avatar Nov 26 '15 22:11 isovector

What do you mean "multiple surrounds of alphanumeric characters"?

haakenlid avatar Nov 27 '15 02:11 haakenlid

This proposal fails to allow surrounding with the characters "tt", since that is valid html and would result in "..." rather than "tt...tt". Furthermore it makes surrounding with "***********" a lot of work.

On Thu, Nov 26, 2015 at 6:07 PM, Håken Lid [email protected] wrote:

What do you mean "multiple surrounds of alphanumeric characters"?

— Reply to this email directly or view it on GitHub https://github.com/tpope/vim-surround/issues/15#issuecomment-160022134.

isovector avatar Nov 27 '15 19:11 isovector

I know it's a bit of a hack, but for anyone else trying to figure this out, you can use gv to solve this problem. For instance, I'm using a custom leader mapping to bold sentences, and it looks like this:

nmap <silent> <leader>sb ysis*gvS*

Gets the job done.

derBingle avatar Nov 17 '16 20:11 derBingle

Since the solutions in this thread involved a lot of keypresses, I started the Vim Markup Assistant plugin, which toggles single words in Markdown to italic or bold. Thereby, I lose the flexibility of vim-surround, but I gain simplicity. Examples here.

RubenVerborgh avatar Dec 21 '16 00:12 RubenVerborgh

with vim-repeat, an alternative is: e.g. now has text 123, and the cursor is at 1 type ysf3" result in "123", now the cursor is at " not 1 again, type ysf3/ result in /"123/", now the cursor is at / once more, type ysf3? result in ?/"123?/", now the cursor is at ? so, if " / ? is the same char like a ", the result will be """123""", and just type once ysf3", also the later two can be repeat with ., unfortunately vim-repeat is neither not support for count operation, otherwise repeat may be more easy

feistiny avatar Sep 07 '18 02:09 feistiny

Just adding a possible use-case: Jinja2 has this kind of stuff:

  • {{ ... }} (doable with counts or repeats)
  • {% ... %}
  • {# ... #}

and it's common to put a space between those and the contents. So I'd love to do something like this:

  1. test comment please ignore
  2. a vim-surround miracle occurs
  3. {# test comment please ignore #}

jacktose avatar Oct 23 '18 00:10 jacktose

I guess it'd be possible, though I'm not too keen on implementing it. In the past, I've just created one-offs for those, e.g.:

let g:surround_{char2nr('o')} = "**\r**"

I came across this issue while looking for a way to do **bold** in Markdown. The quoted way works fine, but then I thought it might be nice to have a prompt for a generic multi-char surround

let g:surround_{char2nr('m')} = "\1Surround: \1\r\1\1"

This seems to work fine as long as the characters on one side are identical to the ones on the other (so no ((( )))). For that I could also do

let g:surround_{char2nr('M')} = "\1S-Open: \1\r\2S-Close: \2"

but at that point I might as well just do it manually.

My main issue is how to make these, or at least the Markdown bold **\r** one, available in replacement or deletion as well.

achilleas-k avatar Jan 29 '19 16:01 achilleas-k

Glad I wasn't the only one wanting this! (This was part of why I liked using Asciidoc vs Markdown.) If this changes, please let me know! Use your plugin all the time!

russurquhart1 avatar Jan 30 '20 17:01 russurquhart1

If I'm not mistaken this is addressed in PR #226 from 2017 that has not been merged yet.

ccaprani avatar Nov 28 '20 02:11 ccaprani

For anyone finding this thread later... it's kind of a hack but the best solution I've found is to just press i as the character you want to surround stuff with, and it prompts you for what will be added to each side. (for example, ysiWi for a WORD or VSi for the current line).

Lamby777 avatar Aug 12 '23 08:08 Lamby777

I'm trying to resurrect this thread... I have these in my vimrc... I'd like to be able to surround words with two or more characters to have "bold" in markdown.

autocmd filetype python nmap <leader>7 <Esc>yiwoprint('*:', *)o<CR>

" inserisce * per formattazine in grassetto
autocmd filetype wri,markdown nmap <Leader>1 <Esc>ysiw*
autocmd filetype wri,markdown nmap <Leader>2 <Esc>ys2aw*
autocmd filetype wri,markdown nmap <Leader>3 <Esc>ys3aw*

g-i-o-r-g-i-o avatar Oct 15 '23 10:10 g-i-o-r-g-i-o

For anyone finding this thread later... it's kind of a hack but the best solution I've found is to just press i as the character you want to surround stuff with, and it prompts you for what will be added to each side. (for example, ysiWi for a WORD or VSi for the current line).

That doesn't seem to work for me... :thinking:

fancsali avatar Dec 06 '23 11:12 fancsali

For anyone finding this thread later... it's kind of a hack but the best solution I've found is to just press i as the character you want to surround stuff with, and it prompts you for what will be added to each side. (for example, ysiWi for a WORD or VSi for the current line).

That doesn't seem to work for me... 🤔

oh, I'm not sure if I wrote that before or after using surround.nvim... might be for that instead

Lamby777 avatar Dec 06 '23 21:12 Lamby777

For those use Neovim + Lazy.nvim as plugin manager, to make a target bold (**target**) in markdown files, here are two lua versions to add the support.

use vim.cmd

{
  'tpope/vim-surround',
  config = function()
    -- add a custom emphasis for markdown filetype
    vim.cmd('aug MY.AUG.surround | au FileType markdown let b:surround_{char2nr("e")} = "**\r**" | aug END')
  end,
},

use lua api

{
  'tpope/vim-surround',
  config = function()
    -- add a custom emphasis for markdown filetype
    vim.api.nvim_create_autocmd({ "FileType" }, {
      group = vim.api.nvim_create_augroup("MY.AUG.surround", {}),
      pattern = { "markdown" },
      desc = "add a custom emphasis surround command for markdown filetype",
      command = 'let b:surround_{char2nr("e")} = "**\r**"',
    })
  end,
},

After setup, type

  • ysiWe: make a WORD bold
  • ysse: make a line bold
  • ys5we: make 5 words bold

NOTE

  1. adjust the trigger letter "e" to your liking, I use "e" to represent emphasis, since "b" is reserved for () and "B" for {}.
  2. adjust the surrounding "**" to other multiple chars as needed.
  3. adjust "markdown" to other file type as needed.
  4. adjust the augroup "MY.AUG.surround" to your liking.

rltyty avatar Jul 04 '24 18:07 rltyty