Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VIM command to insert multiline text with argument

new VIM user. I'm trying to make creating python properties easier for my class definitions. What I would like for say I type

:pyp x

then VIM will autofill where my cursor is

@property
def x(self):
   return self.x
@property.setter
   def x(self,val):
      self._x = val

or more abstractly I type

:pyp <property_name>

and VIM fills

@property
def <property_name>(self):
   return self.<property_name>
@property.setter
   def <property_name>(self,val):
      self._<property_name> = val

I've looked at a few posts and the wikis on functions, macros but I'm very unsure of how to go about it or what to even look up as I am brand new VIM user, less than a week old.

I tried using [this][1] as an example, in my .vimrc but I couldn't even get that to work.

Edit:

So the code I am currently trying is

function! PythonProperty(prop_name)
 let cur_line = line('.')
 let num_spaces = indent('.')
 let spaces = repeat(' ',num_spaces)
 let lines = [ spaces."@property",
             \ spaces."def ".prop_name."(self):",
             \ spaces."   return self.".property,
             \ spaces."@property.setter",
             \ spaces."def".prop_name."(self,val)",
             \ spaces."   self._".prop_name." = val" ]
 call append(cur_line,lines)
endfunction

and I am getting the errors

E121: Undefined variable: prop_name

I am typing
`:call PythonProperty("x")`

  [1]: https://vi.stackexchange.com/questions/9644/how-to-use-a-variable-in-the-expression-of-a-normal-command
like image 594
Melendowski Avatar asked Nov 19 '25 14:11

Melendowski


1 Answers

E121: Undefined variable: prop_name

In VimScript variables have scopes. The scope for function arguments is a:, while the default inside a function is l: (local variable). So the error means that l:prop_name was not yet defined.

Now how I do this:

function! s:insert_pyp(property)
    let l:indent = repeat(' ', indent('.'))
    let l:text = [
        \ '@property',
        \ 'def <TMPL>(self):',
        \ '    return self.<TMPL>',
        \ '@property.setter',
        \ '    def <TMPL>(self,val):',
        \ '        self._<TMPL> = val'
    \ ]
    call map(l:text, {k, v -> l:indent . substitute(v, '\C<TMPL>', a:property, 'g')})
    call append('.', l:text)
endfunction

command! -nargs=1 Pyp :call <SID>insert_pyp(<q-args>)

Alternatively, we can simulate actual key presses (note that we don't need to put indents in the template anymore; hopefully, the current buffer has set ft=python):

function! s:insert_pyp2(property)
    let l:text = [
        \ '@property',
        \ 'def <TMPL>(self):',
        \ 'return self.<TMPL>',
        \ '@property.setter',
        \ 'def <TMPL>(self,val):',
        \ 'self._<TMPL> = val'
    \ ]
    execute "normal! o" . substitute(join(l:text, "\n"), '\C<TMPL>', a:property, 'g') . "\<Esc>"
endfunction

command! -nargs=1 Pyp2 :call <SID>insert_pyp2(<q-args>)

its very very difficult if not impossible to get pluggins

I suggest you to watch this video on youtube. In fact, many of Vim plugins are just overkill.

like image 91
Matt Avatar answered Nov 21 '25 03:11

Matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!