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

Re: Loop through all lines in a file

Expand Messages
  • Benji Fisher
    ... Remember that a vim script (including a plugin) is a list of commands in Command-Line (Ex) mode, not Normal mode. So that j means ... it will be a step in
    Message 1 of 6 , Jun 1, 2006
      On Thu, Jun 01, 2006 at 01:43:48PM +0200, Johannes Schwarz wrote:
      > Hello,
      >
      > I'm trying to write my first vim-plugin, but I got stucked.
      >
      > I managed to execute an external command, which gives me back a list of
      > filenames.
      > One filename per line.
      >
      > For each of the filenames I want to execute another command.
      > I tried it with code:
      >
      > let line=getline(".")
      > while (strlen(line)!=0)
      > "do sth. here -- construct the external command and so on
      > j
      > let line=getline(".")
      > endwhile

      Remember that a vim script (including a plugin) is a list of
      commands in Command-Line (Ex) mode, not Normal mode. So that j means
      :j[oin], not "move the cursor down one line." If you change "j" to "+"
      it will be a step in the right direction.

      > When I execute the code, it runns into an infinite loop, because the
      > lines are joined together with each loop
      >
      > file:
      > text1.txt
      > text2.txt
      > text3.txt
      >
      > after interrupting the loop the looks like
      > text1.txt text2.txt text3.txt

      That's right.

      > it seems j is interpreted as a J (join line) here.
      > And by the way, I think this is a bad solution anyway.
      > Can someone give me a hint how to do it in a clean way?

      Either

      :g/./<any Command-Line mode command here>

      or

      let linenr = 0
      while linenr < line("$")
      let linenr += 1 " The += construction requires vim 7.0 .
      let line = getline(linenr)
      " ...
      endwhile

      HTH --Benji Fisher
    • Johannes Schwarz
      First of all I want to thank everyone, who contributes to this list. It s one of the best lists I know of. The response time is so quick and the quality of the
      Message 2 of 6 , Jun 1, 2006
        First of all I want to thank everyone, who contributes to this list.
        It's one of the best lists I know of.

        The response time is so quick and the quality of the answer are really
        great ... thank you really much.

        In the meantime I found a solution myself:

        let s:lnr=line(".")
        let s:image=getline(s:lnr)
        while (strlen(s:image) != 0)
        let s:lnr=s:lnr+1
        let s:image=getline(s:lnr)
        endwhile

        Compared to your suggested solutions it's not that good (but anyway I'm
        poud of myself ;-)

        I'm not that familiar with the global commands yet, maybe I have to
        read the documentation again.


        >>> Benji Fisher <benji@...> 01.06.2006 14:41:38 >>>
        > On Thu, Jun 01, 2006 at 01:43:48PM +0200, Johannes Schwarz wrote:
        > > Hello,
        > >
        > > I'm trying to write my first vim-plugin, but I got stucked.
        > >
        > > I managed to execute an external command, which gives me back a
        list of
        > > filenames.
        > > One filename per line.
        > >
        > > For each of the filenames I want to execute another command.
        > > I tried it with code:
        > >
        > > let line=getline(".")
        > > while (strlen(line)!=0)
        > > "do sth. here -- construct the external command and so on
        > > j
        > > let line=getline(".")
        > > endwhile
        >
        > Remember that a vim script (including a plugin) is a list of
        > commands in Command-Line (Ex) mode, not Normal mode. So that j means
        > :j[oin], not "move the cursor down one line." If you change "j" to
        "+"
        > it will be a step in the right direction.
        >
        > > When I execute the code, it runns into an infinite loop, because
        the
        > > lines are joined together with each loop
        > >
        > > file:
        > > text1.txt
        > > text2.txt
        > > text3.txt
        > >
        > > after interrupting the loop the looks like
        > > text1.txt text2.txt text3.txt
        >
        > That's right.
        >
        > > it seems j is interpreted as a J (join line) here.
        > > And by the way, I think this is a bad solution anyway.
        > > Can someone give me a hint how to do it in a clean way?
        >
        > Either
        >
        > :g/./<any Command-Line mode command here>
        >
        > or
        >
        > let linenr = 0
        > while linenr < line("$")
        > let linenr += 1" The += construction requires vim 7.0 .
        > let line = getline(linenr)
        > " ...
        > endwhile
        >
        > HTH--Benji Fisher
        >
      • Eric Arnold
        On 6/1/06, Benji Fisher wrote: ... D oh. For some reason I though j was a variable and jumped to a wishful[wrong] conclusion that it
        Message 3 of 6 , Jun 1, 2006
          On 6/1/06, Benji Fisher <benji@...> wrote:
          ...
          > > let line=getline(".")
          > > while (strlen(line)!=0)
          > > "do sth. here -- construct the external command and so on
          > > j
          > > let line=getline(".")
          > > endwhile
          >
          > Remember that a vim script (including a plugin) is a list of
          > commands in Command-Line (Ex) mode, not Normal mode. So that j means
          > :j[oin], not "move the cursor down one line." If you change "j" to "+"
          > it will be a step in the right direction.

          D'oh. For some reason I though 'j' was a variable and jumped to a
          wishful[wrong] conclusion that it was really:

          exe j

          which would set the line number to an incrementing index. This is
          useful if you are going to use :ex commands in addition to
          function calls.


          > let linenr = 0
          > while linenr < line("$")
          > let linenr += 1 " The += construction requires vim 7.0 .
          > let line = getline(linenr)
          > " ...

          exe linenr

          > endwhile
        • Tim Chase
          ... I second Benji s suggestion of using a :g command if possible. It s more idiomatic, making it easier to understand. While you omit what you re doing with
          Message 4 of 6 , Jun 1, 2006
            > In the meantime I found a solution myself:
            >
            > let s:lnr=line(".")
            > let s:image=getline(s:lnr)
            > while (strlen(s:image) != 0)
            > let s:lnr=s:lnr+1
            > let s:image=getline(s:lnr)
            > endwhile
            >
            > I'm not that familiar with the global commands yet, maybe I
            > have to read the documentation again.


            I second Benji's suggestion of using a ":g" command if possible.
            It's more idiomatic, making it easier to understand.

            While you omit what you're doing with s:image once you have it,
            unless you're doing something with it within the body of your
            while statement, you're only getting the last one. It also looks
            like you're getting the line number only to pass it to getline().

            The idiomatic way would be something like

            :g/^/let s:image=getline(".")


            If you only want from the current line to the end of file, you
            can use

            :.,$g/^/let s:image=getline(".")

            (:g defaults to the whole file if you don't specify a range, such
            as ".,$")

            If you want to call a function with each line, or run an external
            command, you can do something like

            :g/^/exec "!somecommand ".getline(".")

            Hope this gives you some additional ideas regarding how to use
            the :g command.

            -tim
          Your message has been successfully submitted and would be delivered to recipients shortly.