3

I comment sections in python via a centered title surrounded by #. What I would like is to make a command so that I can automatically generate such headers. For example, to generate a line like the following:

############################### Logging ################################

and also a line to close a section (which is just n # symbols in a row.

3 Answers 3

1

You can start with the following (add it to you vimrc)

func! MyComment(text)
    let width = 80
    let text = printf(" %s ", a:text)
    let chrome = repeat('#', width/2 - strdisplaywidth(text)/2)
    call setline('.', chrome . text . chrome)
endfunc

nnoremap <leader>c :call MyComment(input("Header: "))<CR>

nnoremap <leader>d :call MyComment(getline('.'))<CR>

I believe you will be able to tune it to get a line with all #.

enter image description here

0

You can call winwidth() to get the number of chars in line that fit the screen. And use printf('%#'. width. 's' , str). It should fill it with #, in a similar way to zero fill (I believe). You can encapsulate it in a function to be called by a command.

0

Here's an alternative approach:

Doing it manually with built in commands

To convert a line that contains just your title you can do the following:

  1. Run the command :center to move the title to the centre of the line.*

  2. To add the # characters type the following normal mode commands:

    hhv0r#ywASpaceEscp

    If this is not self explanatory, just try typing them in!

* Vim calculates the position based on your 'textwidth' setting, using a value of 80 if 'textwidth' is set to 0. You can pass in a different value if necessary: :center 72

To add an "end of section" line below the cursor, you can do the following:

  1. Type in the normal mode command to add a line containing a single # character o#Esc

  2. Run the command :right to right align it.

  3. Fill in the entire line with # characters with the normal mode commands: Vr#

Creating command-line commands

You can easily convert these into commands:

:command StartComment center | execute "normal! hhv0r#ywA \<Esc>p"
:command EndComment execute "normal! o#" | right | normal! Vr#

Note that we use :execute in the first command in order to more easily include an Esc keypress, and we use it again in the second line in order to end insert mode so we can continue with another ex command.

Creating normal mode mappings

And it's even easier to create mappings instead:

:nnoremap <leader>c :center<CR>hhv0r#ywA <Esc>p
:nnoremap <leader>e o#<Esc>:right<CR>Vr#

Extra credit

Eagle-eyed readers might have spotted that depending on whether your title has an odd or even number of characters, the resulting comment will end in the 79th or 80th column. If this is an issue, here's a slightly more complicated mapping that always creates an exactly 80 character heading by first creating an entire line of 80 # characters and then moving the title into the middle of that line with blockwise visual mode yank/put:

:nnoremap <leader>c :center<CR>o#<Esc>:right<CR>Vr#kA <Esc>v^hyj1vpkdd

It's left as an exercise to the reader to convert this into a command-line command.

Watch out for 'noexpandtab'

Note that none of the above will work well if you have 'expandtab' set, because each tab will be replaced with a single # character. But you're writing Python, so of course you're indenting with the PEP 8 mandated four spaces, so this won't be an issue!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.