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

Re: Loop through all lines in a file

Expand Messages
  • 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 1 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 2 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 3 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 4 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 5 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.