chrisbra / NrrwRgn

A Narrow Region Plugin for vim (like Emacs Narrow Region)
http://www.vim.org/scripts/script.php?script_id=3075
674 stars 25 forks source link

Add an option to remove common indentation from a block. #19

Closed jszakmeister closed 11 years ago

jszakmeister commented 11 years ago

It'd be really nice if there was an option in NrrwRgn to help remove common indentation from the block being narrowed, and insert it back when finished. It would help editing embedded documents, such as code buried in Sphinx code blocks, and other formats where the indentation is normally not welcome.

chrisbra commented 11 years ago

Hi John!

On Sa, 10 Aug 2013, John Szakmeister wrote:

It'd be really nice if there was an option in NrrwRgn to help remove common indentation from the block being narrowed, and insert it back when finished. It would help editing embedded documents, such as code buried in Sphinx code blocks, and other formats where the indentation is normally not welcome.

Isn't this already possible by block-selecting the desired region (while leaving the indentation off) and then using \nr to narrow the visual selected region?

regards,

Christian

Für Zeiten standen Junge vor Alten höflich auf, Jetzt heißt es: Junger sitze! Und alter Greiner, lauf! -- Friedrich von Logau (Sinngedichte)

jszakmeister commented 11 years ago

Perhaps a picture would help:

screen shot 2013-08-10 at 8 47 23 am

I selected the code embedded in the code block, but in the narrow region buffer, you can see that it's still indented. I'd like an option that would remove the common indentation, so it would look more like this:

screen shot 2013-08-10 at 8 50 31 am

Hopefully that clarifies what I'm asking for. Thanks!

chrisbra commented 11 years ago

Hi John!

On Sa, 10 Aug 2013, John Szakmeister wrote:

Perhaps a picture would help:

screen shot 2013-08-10 at 8 47 23 am

I selected the code embedded in the code block, but in the narrow region buffer, you can see that it's still indented. I'd like an option that would remove the common indentation, so it would look more like this:

screen shot 2013-08-10 at 8 50 31 am

Hopefully that clarifies what I'm asking for. Thanks!

This should be possible, using the \nr key-binding together with block-selecting the selected region.

See this screencast (attached to this mail, not sure it works with github):

regards,

Christian

Sowenig man die Liebe den Prostituierten anvertrauen darf, sowenig die Religion den Pfaffen. -- Karlheinz Deschner

chrisbra commented 11 years ago

Ok, I almost thought, attaching files wouldn't work for githut. Well see this screencast: http://www.256bit.org/~chrisbra/Vim_Recording_20130811.mkv

chrisbra commented 11 years ago

If this doesn't work good enough for you (since Vim will write the changes back using block mode), I'll probably add the desired option.

jszakmeister commented 11 years ago

My apologies, I saw "block select" and thought you meant "select the area". I was hoping to get by with this using a linewise selection though. I have some mapping to help select regions, and they use linewise selections (which are more useful to me than block selections). Plus block selections get a little wonky to work with when the last line is not the longest line.

Thanks for taking the time to put the little screencast together! That was awfully nice of you.

chrisbra commented 11 years ago

Hi John!

On So, 11 Aug 2013, John Szakmeister wrote:

My apologies, I saw "block select" and thought you meant "select the area". I was hoping to get by with this using a linewise selection though. I have some mapping to help select regions, and they use linewise selections (which are more useful to me than block selections). Plus block selections get a little wonky to work with when the last line is not the longest line.

Thanks for taking the time to put the little screencast together! That was awfully nice of you.

How about this. NarrowRegion supports hooks, that can be run when the text is placed in the new window ("create" hook) or before the text is written back ("close" hook). The help even has an entry about this (:h NR-hooks)

Using this, I think you can already do what you want:

:let b:nrrw_aucmd_create=':%s/^\s\{4}//'

This removes 4 spaces at the beginning of the line when creating the narrowed window

:let b:nrrw_aucmd_close='%s/^/    /'

This adds 4 spaces at the start of the line, before the content is written back

Does this do what you want or is this to complicated?

regards,

Christian

Lieber voll heimkommen, als leer ausgehen.

jszakmeister commented 11 years ago

How about this. NarrowRegion supports hooks, that can be run when the text is placed in the new window ("create" hook) or before the text is written back ("close" hook). The help even has an entry about this (:h NR-hooks)

Using this, I think you can already do what you want:

:let b:nrrw_aucmd_create=':%s/^\s\{4}//'

This removes 4 spaces at the beginning of the line when creating the narrowed window

:let b:nrrw_aucmd_close='%s/^/    /'

This adds 4 spaces at the start of the line, before the content is written back

I actually want to remove all common indentation (not just the 4 spaces in this one case) and insert it back when done, but I'll play around with the hooks and see if I can get what I want.

Does this do what you want or is this to complicated?

I saw the hooks before, but for some reason was reluctant to use them. Let me see what I can put together though.

Thanks!

jszakmeister commented 11 years ago

@chrisbra I tried the hooks and managed to get something that works. However, I think I found a bug in NrrwRgn. Using your example:

let b:nrrw_aucmd_create=':%s/^\s\{4}//'
let b:nrrw_aucmd_close='%s/^/    /'

If I select the block, narrow it, and then run :WidenRegion the text in the narrow region buffer is re-indented via the close hook, but the buffer is not closed (the last part is expected). If you then run :WidenRegion! the close hook executes again, and the result is then double indented.

Should :WidenRegion be running the create hook again if it's not going to close the buffer?

chrisbra commented 11 years ago

I think, if :WidenRegion doesn't close the window, it should undo the hook command and that is what I have now implemented. If you notice any more errors, just tell me.

jszakmeister commented 11 years ago

Yes, that makes more sense. I tried it out and it fixed the issue. Thanks!

agguser commented 3 years ago

This "removing common indents" is especially useful when folding levels are more than foldnestmax, which is limited to 20. Here is my try:

fu! s:Nind() range   " adjust indents on buffer's (new) narrowed windows
   for l in range(a:firstline, a:lastline)
      let [ind, spos, epos] = matchstrpos(getline(l), '^\s*\S\@=')   " ignore blank lines
      if spos > -1 && (l == a:firstline || ind < ind_min)
         let ind_min = ind | endif | endfor
   if exists('ind_min') && len(ind_min) > 0
      let b:nrrw_aucmd_create = 'sil %s/^'.ind_min.'// | setl nomodified'
      let b:nrrw_aucmd_close = 'sil %s/^/'.ind_min.'/' | endif
   endf
com! -range Nind <line1>,<line2>call s:Nind() | <line1>,<line2>NR!
map ,n :Nind<CR>