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

Re: Something to wrap a selection

Expand Messages
  • Paul Isambert
    ... I was just trying to advertise VimÆs excellent help :) ... The code relies on an analysis of the ôcommentsö option, which is normally set by filetype.
    Message 1 of 10 , Sep 26, 2013
      Harry Putnam <reader@...> a écrit:
      > Paul Isambert <zappathustra@...> writes:
      >
      >
      > > For any further fun, try “:help [range]”.
      >
      > Oh no... you're not getting off that easy... hehe.

      I was just trying to advertise Vim’s excellent help :)

      > Honestly, you'll probably wish you never started, but I'm not getting
      > enough out of this bit of code to see how to make it do what I want.
      >
      > Quest 1) How is the code determining what comment char to use?
      > I created a file some.conf With some commented lines followed by
      > variable value. The comments are `#', and yet the code uses '//'.
      > Plus there is no space after // . But seems like it should be '# '
      >
      > The emacs code tries to guess the right comment char, but if it
      > doesn't know from the file name, then it asks me which one to use.

      The code relies on an analysis of the “comments” option, which is
      normally set by filetype. For .conf files, I can see that the option
      is ambiguous (for our purpose), as it contains several characters for
      one-line comments, and the code picked up the wrong one (the first
      encountered).

      The new code below does the following thing: “:MarkChange” can be
      called with a exclamation mark, as in:

      :MarkChange! {<optional keywords>}

      Without the mark, it works as before, trying to find the proper comment
      sign by itself. With the exclamation mark, it will prompt for the
      proper symbol. The code could be modified further so those symbols are
      stored in an external file and you won’t have to specify them again.
      (Another syntax that you may prefer is “:MarkChange {optional sign}”,
      with, I hope, an obvious semantics, while the command would always
      prompt for keywords.)

      As for the space, the new code below adds it.

      > Quest 2)
      > Further, the already commented lines are not recommented as in my
      > posted example (Not the first post... I had it wrong there) So, In
      > that case, I can't tell at a glance, 2yrs later, what the original
      > suggested value was
      >
      > Example:
      > Lets say we start with this:
      >
      > # commented line1
      > # commented line2
      > # suggested value
      > my newvalue
      >
      > Or maybe as often this:
      >
      > # commented line1
      > # commented line2
      > suggested value
      > my_newvalue
      >
      >
      >
      > After calling MarkChange, I want to see this:
      >
      > # Keywords: whatever I typed
      > # [Keydate: DATE]
      > # # commented line
      > # # commented line
      > # # suggested value
      > my_newvalue
      >
      > or
      >
      > # Keywords: whatever I typed
      > # [Keydate: DATE]
      > # # commented line
      > # # commented line
      > # suggested value
      > my_newvalue
      > ------- --------- ---=--- --------- --------
      >
      > so I can see right away what was the original value and how I changed
      > it.

      That’s no big problem. The new code does that, although you’ll have to
      uncomment “my_newvalue” by hand.

      > I tried changing even a few minor things in the code and right away it
      > blows up and fills the buffer with numerous threats and warnings hehe.
      >
      > I'm not understanding the syntax much at all.

      Man, you can write in Elisp but not in Vimscript? Those Emacs users
      are very strange indeed.

      Anyway, here’s the code:

      " Put this in your vimrc file.
      function! s:markchange (kw, com) range
      if a:com
      let comment = input("Comment sign, please?\n")
      else
      " Retrieve the one-line comment string, hoping it exists (could be
      " defined otherwise, too).
      let comment = matchstr(&comments, '[[:alnum:]]\@<!:\zs[^,]*\ze')
      endif
      let comment .= " "

      " Ask for keywords if not given when calling MarkChange.
      if a:kw !~ '\S'
      let keywords = input((a:com ? "\n" : "") . "Keywords, please?\n")
      else
      let keywords = a:kw
      endif
      let keywords = "Keywords: " . keywords

      " Append the end symbol.
      call append(a:lastline, "&&")

      " Append the keywords and date lines; use :undojoin so ``u'' will undo
      " the entire operation.
      undojoin
      call append(a:firstline-1, [keywords, strftime("[Keydate: %c.]")])

      " Comment everything.
      let i = a:firstline
      while i <= a:lastline+3
      call setline(i, comment . getline(i))
      let i += 1
      endwhile
      endfunction

      com! -bang -range -nargs=* MarkChange <line1>,<line2>call s:markchange(<q-args>, <bang>0)
      " End of code.

      Best,
      Paul

      --
      --
      You received this message from the "vim_use" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_use" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Harry Putnam
      ... Thanks for your efforts. The script is doing what I wanted alright but it appears not to know any comment char other than //. I named the input file:
      Message 2 of 10 , Sep 27, 2013
        Paul Isambert <zappathustra@...> writes:

        > The code relies on an analysis of the “comments” option, which is
        > normally set by filetype. For .conf files, I can see that the option
        > is ambiguous (for our purpose), as it contains several characters for
        > one-line comments, and the code picked up the wrong one (the first
        > encountered).

        Thanks for your efforts. The script is doing what I wanted alright
        but it appears not to know any comment char other than //.

        I named the input file:
        some.conf
        some.rc
        some.bash
        some.pl

        And every case it inserts '//'.

        Finally I opened a real, honest to god, perl script and tried it
        there. And still it inserts '//'

        I wonder if there is a way to make vim tell me what kind of file it
        thinks its editing?

        Or maybe better still a way for me to tell vim what kind of file I
        want it to be editing (temporarily at least)

        My googling keeps getting tangled up with piles of *.vim files,
        echoing $RUNTIME blah blah and so on and so on. Not finding a definitive
        way to choke it out of vim for the current file.

        Just typing :Filetype lets me know:
        filetype detection:ON plugin:ON indent:ON

        But how can I coax vim into telling me what the current filetype is?

        Or barring all that maybe just make the script insert octathorps in
        all cases. At least that would be useful most of the time.

        --
        --
        You received this message from the "vim_use" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php

        ---
        You received this message because you are subscribed to the Google Groups "vim_use" group.
        To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
      • Paul Isambert
        ... ThereÆs obviously something wrong with filetypes or the setting of the æcommentsÆ option. Since I donÆt know where it comes from, and since relying on
        Message 3 of 10 , Sep 28, 2013
          Harry Putnam <reader@...> a écrit:
          > Paul Isambert <zappathustra@...> writes:
          >
          > > The code relies on an analysis of the “comments” option, which is
          > > normally set by filetype. For .conf files, I can see that the option
          > > is ambiguous (for our purpose), as it contains several characters for
          > > one-line comments, and the code picked up the wrong one (the first
          > > encountered).
          >
          > Thanks for your efforts. The script is doing what I wanted alright
          > but it appears not to know any comment char other than //.
          >
          > I named the input file:
          > some.conf
          > some.rc
          > some.bash
          > some.pl
          >
          > And every case it inserts '//'.
          >
          > Finally I opened a real, honest to god, perl script and tried it
          > there. And still it inserts '//'

          There’s obviously something wrong with filetypes or the setting of the
          ‘comments’ option. Since I don’t know where it comes from, and since
          relying on the ‘comments’ option was not very sound anyway, we’ll
          follow another course of action, see below.

          > I wonder if there is a way to make vim tell me what kind of file it
          > thinks its editing?
          >
          > Or maybe better still a way for me to tell vim what kind of file I
          > want it to be editing (temporarily at least)
          >
          > My googling keeps getting tangled up with piles of *.vim files,
          > echoing $RUNTIME blah blah and so on and so on. Not finding a definitive
          > way to choke it out of vim for the current file.
          >
          > Just typing :Filetype lets me know:
          > filetype detection:ON plugin:ON indent:ON
          >
          > But how can I coax vim into telling me what the current filetype is?

          Use ‘:echo &filetype’ to see the buffer’s filetype, and ‘:echo &comments’
          for the comments (and ‘:echo &option’ in general for any Vim option).
          The ‘comments’ option might be a bit cryptic, see ‘:help format-comments’
          if you want to understand it – but the code below doesn’t rely on all
          that anyway.

          > Or barring all that maybe just make the script insert octathorps in
          > all cases. At least that would be useful most of the time.

          Let’s not give up! What you’re asking for is really not complicated, I
          just shouldn’t have relied on ‘comments’ to begin with (the option is
          not meant to insert comments, but to format commented paragraph
          properly; it doesn’t have to be unambiguous for its own purpose).

          The new command works as follows; type:

          :MarkChange {optional keywords}

          (The keywords work as in the previous versions of the code.)

          If no comment sign is recorded for the current filetype, the code will
          analyze the ‘comments’ option and ask you whether the character(s) it
          found are ok; if not, you can give it something else. Then you will be
          asked whether you want that comment to be remembered, and it can be
          remembered either for the current session only (until you exit Vim) or
          until the end of time (more or less); in the latter case, an external
          file will be used to remember comments from session to session. If a
          comment is remembered for a given filetype, you will not be asked
          again to confirm whether it’s ok or not, unless you use:

          :MarkChange! {optional keywords}

          which asks for confirmation and allows you to change the comment
          again, as if none were recorded.

          (Not using a recorded comment and/or not remembering the comment you
          will use may be useful for files containing several languages; for
          instance, a vimscript file can contain snippets of Lua or Ruby or
          whatever, which you’ll comment with a special character, but you’ll
          probably want to keep the default Vimscript comment.)

          The external file used to record comments is created the first time
          you want a comment to be definitely remembered. It will be called
          ‘.markchangerc’, and you’ll be able to modify it by hand. It will be
          located in the same directory as the file where the ‘:MarkChange’
          command is defined; if that is in your .vimrc file, then
          ‘.markchangerc’ will be where your .vimrc file is ($HOME, I should
          guess). Actually, I guess you’d better put the entire code in a file
          of its own (say ‘markchange.vim’) and put that file in ‘.vim/plugin/’
          (itself in $HOME by default), so the ‘.markchangerc’ file will be
          there too and won’t puzzle you a few years hence when you find it in
          $HOME, and you’ll be able to delete all relevant files when the code
          doesn’t suit your needs anymore. Better yet, use ‘pathogen’ (see
          http://www.vim.org/scripts/script.php?script_id=2332).

          I say goodbye here, the code follows. I’ll hope you’ll be satisfied
          this time (there might be glitches, I did not test the command much,
          just basic tries).

          Best,
          Paul

          " Put this somewhere.
          let s:markchangecomments = {}

          let s:commentfile = expand("<sfile>:p:h") . "/.markchangerc"
          if filereadable(s:commentfile)
          let s:data = readfile(s:commentfile)
          for line in s:data
          if line !~ '^#' && line =~ '='
          let s:matches = matchlist(line, '\([^=[:blank:]]\+\)\s*=\s*\(\S\+\)')
          if len(s:matches)
          let s:markchangecomments[s:matches[1]] = s:matches[2]
          endif
          endif
          endfor
          endif

          function! s:markchange (kw, confirm) range
          if has_key(s:markchangecomments, &filetype)
          let comment = s:markchangecomments[&filetype]
          else
          " Retrieve the one-line comment string, hoping it exists (could be
          " defined otherwise, too).
          let comment = matchstr(&comments, '[[:alnum:]]\@<!:\zs[^,]*\ze')
          endif

          " Confirm comment.
          if !has_key(s:markchangecomments, &filetype) || a:confirm
          let newcomment = input("I will use "
          \ . comment
          \ . " to comment lines. Press <Enter> if it is ok, or type in what you wish to use.\n")
          if newcomment =~ '\S'
          let comment = newcomment
          endif
          let remember = input("\nShall I remember this comment? [y{es}, n{o}, o{nly for this session}]\n")
          while 1
          if remember =~ '^y'
          let s:markchangecomments[&filetype] = comment
          " Remember the comment in an external file.
          let cms = ['# Format of this file:', '# {filetype} = {comment}', '']
          for k in keys(s:markchangecomments)
          let cms += [k . ' = ' . s:markchangecomments[k]]
          endfor
          call writefile(cms, s:commentfile)
          elseif remember =~ '^o'
          let s:markchangecomments[&filetype] = comment
          endif
          if remember =~ '^[yno]'
          break
          else
          let remember = input("\nCould you please repeat? [y{es}, n{o}, o{nly for this session}]\n")
          endif
          endwhile
          redraw
          endif
          let comment .= " "

          " Ask for keywords if not given when calling MarkChange.
          if a:kw !~ '\S'
          let keywords = input("Keywords, please?\n")
          else
          let keywords = a:kw
          endif
          let keywords = "Keywords: " . keywords

          " Append the end symbol.
          call append(a:lastline, "&&")

          " Append the keywords and date lines; use :undojoin so ``u'' will undo
          " the entire operation.
          undojoin
          call append(a:firstline-1, [keywords, strftime("[Keydate: %c.]")])

          " Comment everything.
          let i = a:firstline
          while i <= a:lastline+3
          call setline(i, comment . getline(i))
          let i += 1
          endwhile
          endfunction

          com! -bang -range -nargs=* MarkChange <line1>,<line2>call s:markchange(<q-args>, <bang>0)
          " End of code.

          --
          --
          You received this message from the "vim_use" maillist.
          Do not top-post! Type your reply below the text you are replying to.
          For more information, visit http://www.vim.org/maillist.php

          ---
          You received this message because you are subscribed to the Google Groups "vim_use" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
          For more options, visit https://groups.google.com/groups/opt_out.
        • Harry Putnam
          ... Oh boy, yup this baby works now. Man, you went so far beyond the call of duty, and let me tell you that it was really appreciated here. There are so many
          Message 4 of 10 , Sep 28, 2013
            Paul Isambert <zappathustra@...> writes:

            > I say goodbye here, the code follows. I’ll hope you’ll be satisfied
            > this time (there might be glitches, I did not test the command much,
            > just basic tries).

            Oh boy, yup this baby works now.

            Man, you went so far beyond the call of duty, and let me tell you that
            it was really appreciated here.

            There are so many examples and techniques in that code I will be
            learning from it for a good while.

            Oh, and I promise not to post one more thing to this thread.. : )

            --
            --
            You received this message from the "vim_use" maillist.
            Do not top-post! Type your reply below the text you are replying to.
            For more information, visit http://www.vim.org/maillist.php

            ---
            You received this message because you are subscribed to the Google Groups "vim_use" group.
            To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
            For more options, visit https://groups.google.com/groups/opt_out.
          • Paul Isambert
            ... If duty there was, it was only not to give you half-baked code. Plus writing scriptlets is so funnier than dish-washing. ... But you should if the code
            Message 5 of 10 , Sep 29, 2013
              Harry Putnam <reader@...> a écrit:
              > Paul Isambert <zappathustra@...> writes:
              >
              > > I say goodbye here, the code follows. I’ll hope you’ll be satisfied
              > > this time (there might be glitches, I did not test the command much,
              > > just basic tries).
              >
              > Oh boy, yup this baby works now.
              >
              > Man, you went so far beyond the call of duty, and let me tell you that
              > it was really appreciated here.

              If duty there was, it was only not to give you half-baked code. Plus
              writing scriptlets is so funnier than dish-washing.

              > There are so many examples and techniques in that code I will be
              > learning from it for a good while.
              >
              > Oh, and I promise not to post one more thing to this thread.. : )

              But you should if the code goes wrong. By the way there was a small
              mistake. In:

              let s:commentfile = expand("<sfile>:p:h") . "/.markchangerc"
              if filereadable(s:commentfile)
              let s:data = readfile(s:commentfile)
              for line in s:data
              if line !~ '^#' && line =~ '='
              let s:matches = matchlist(line, '\([^=[:blank:]]\+\)\s*=\s*\(\S\+\)')
              if len(s:matches)
              let s:markchangecomments[s:matches[1]] = s:matches[2]
              endif
              endif
              endfor
              endif

              you should replace all occurrences of “line” with “s:line”, otherwise
              it defines a global variable whereas you want it to be only visible in
              the script (I’m used to loop variables being local, à la Lua).

              Best,
              Paul

              --
              --
              You received this message from the "vim_use" maillist.
              Do not top-post! Type your reply below the text you are replying to.
              For more information, visit http://www.vim.org/maillist.php

              ---
              You received this message because you are subscribed to the Google Groups "vim_use" group.
              To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
              For more options, visit https://groups.google.com/groups/opt_out.
            Your message has been successfully submitted and would be delivered to recipients shortly.