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

Loop through all lines in a file

Expand Messages
  • Johannes Schwarz
    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
    Message 1 of 6 , Jun 1, 2006
    • 0 Attachment
      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

      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

      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?
    • Eric Arnold
      ... You need to say exactly how you executed the command, since that will define how the lines were acquired, whether they went from the file into a buffer
      Message 2 of 6 , Jun 1, 2006
      • 0 Attachment
        On 6/1/06, Johannes Schwarz <J.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.

        You need to say exactly how you executed the command, since that will
        define how the lines were acquired, whether they went from the file
        into a buffer correctly, etc.

        > One filename per line.
        >
        > For each of the filenames I want to execute another command.
        > I tried it with code:
        >

        let j = 1
        1

        > let line=getline(".")
        > while (strlen(line)!=0)

        This loop is best done comparing line(".") <= line("$")

        > "do sth. here -- construct the external command and so on
        > j

        'j' is incrementing, right?

        > let line=getline(".")
        > endwhile
        >
        > When I execute the code, it runns into an infinite loop, because the
        > lines are joined together with each loop

        The infinite loop is probably due to other reasons, ie. above.

        > file:
        > text1.txt
        > text2.txt
        > text3.txt

        Is the file (disk) or file loaded into a Vim buffer window?

        >
        > after interrupting the loop the looks like
        > text1.txt text2.txt text3.txt

        Not enough code examples to understand why it would be like this.

        > 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?

        If it's simple enough, you can use global commands

        :g/.*/commands
      • 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 3 of 6 , Jun 1, 2006
        • 0 Attachment
          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 4 of 6 , Jun 1, 2006
          • 0 Attachment
            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 5 of 6 , Jun 1, 2006
            • 0 Attachment
              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 6 of 6 , Jun 1, 2006
              • 0 Attachment
                > 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.