Loading ...
Sorry, an error occurred while loading the content.

Re: properly yanking word/selection

Expand Messages
  • ZyX
    Reply to message «properly yanking word/selection», sent 19:25:55 31 January 2011, Monday ... Possible suggestions here: 1. use «let @ =expand( )»
    Message 1 of 3 , Jan 31, 2011
    • 0 Attachment
      Reply to message «properly yanking word/selection»,
      sent 19:25:55 31 January 2011, Monday
      by sgp:

      > 1/ yaw (yank a word) yanks the space before the word (some times it
      > doesn't); I don't want the space.
      Possible suggestions here:
      1. use «let @"=expand("<cword>")» (@" is a register variable, expand("<cword>")
      will expand to the word under the cursor (mnemonic: *c*urrent *word*)).
      2. Use «normal! yiw», it won't take a space.
      3. Do «let @"=substitute(@", '^\s\+', '', '')» thus removing preceding spaces.

      > 2/ bSelection is needed to tell a function that it was invoked from visual
      > mode; is there a better way?
      If you want to use «normal!», then no. You may use «mode()» function for <expr>
      mappings, but mapping expressions are executed inside a textlock with additional
      restrictions including inability to use normal. Changing registers is still
      allowed, but yanking a selection without «normal!» requires much more work, for
      example see my getvrange function:

      "{{{3 map.getvrange
      function s:F.map.getvrange(start, end)
      let [sline, scol]=a:start
      let [eline, ecol]=a:end
      let text=[]
      let ellcol=col([eline, '$'])
      let slinestr=getline(sline)
      if sline==eline
      if ecol>=ellcol
      call extend(text, [slinestr[(scol-1):], ""])
      else
      call add(text, slinestr[(scol-1):(ecol-1)])
      endif
      else
      call add(text, slinestr[(scol-1):])
      let elinestr=getline(eline)
      if (eline-sline)>1
      call extend(text, getline(sline+1, eline-1))
      endif
      if ecol<ellcol
      call add(text, elinestr[:(ecol-1)])
      else
      call extend(text, [elinestr, ""])
      endif
      endif
      return text
      endfunction

      It does not put anything into a register (because it was written in order to
      obtain text in a given range without modifying selection, marks and registers).
      It is able to obtain only characterwise range, for linewise range it will much
      simpler, for blockwise range it is more complex if you want to handle
      virtualedit (otherwise it is simpler). Note that I do not know a way to set a
      register that includes NULL, though vim somehow preserves NULLs when using yank
      commands. This function also preserves NULLs: it returns a list of strings where
      NL in each string really means NULL (it is a common format for
      readfile/writefile and getline/setline/append functions). Note that ecol must
      point to last byte of last character, if it points to first byte (it will when
      you use getpos), use

      let lchar=len(matchstr(getline(eline), '\%'.ecol.'c.'))
      if lchar>1
      let ecol+=lchar-1
      endif

      This function maybe does not worth time spent on it, but it was a good trial.

      Original message:
      > What is the proper way to yank a word or a selection from a vim script?
      > Right now I'm using if !bSelection
      > normal! yaw
      > else
      > normal! gvy
      > endif
      >
      > but I have some gripes:
      >
      > 1/ yaw (yank a word) yanks the space before the word (some times it
      > doesn't); I don't want the space. 2/ bSelection is needed to tell a
      > function that it was invoked from visual mode; is there a better way?
      >
      > TIA
    Your message has been successfully submitted and would be delivered to recipients shortly.