• Counting text selection lines

    From Luc@21:1/5 to All on Fri Dec 1 18:51:27 2023
    I am trying to count the text selection. I want to count words and lines.

    We have been through words. Now let's see lines.

    I have this code:

    set ::selectionWC 0
    set ::selectionlinecount 0
    set selectionindices [$::text tag ranges sel]
    if {[llength $selectionindices] > 0} {
    set ::selection "[$::text get {*}$selectionindices]"
    set ::selectionWC [p.wc $::selection]
    set ::selectionlinecount [$::text count -lines {*}$selectionindices]
    }

    It doesn't really work. Whether I select nothing, one word, many words
    or the entire line, the line count is 0.

    If I select two lines, then the line count is 1. That is evidently wrong.

    So I added this line to the code:

    incr ::selectionlinecount

    OK. Now the count is correct.

    Wait. Should I be doing that?

    When I go to the absolute end of the text widget, which is a line that
    contains text, I know I am on line 5.

    I can't go any farther than the end of the last line which contains text
    which is line number 5. There is no empty last line. Line 5 is the last
    line.

    So I go to the absolute beginning, line 1 and column 0. I select the
    entire line. Selection line count: 1.

    Remember that I get "1" thanks to the 'incr' hack.

    Press Shift+Down. Two lines are selected. Selection line count: 2.

    I keep pressing Shift+Down until all five lines are selected.
    Selection line count: 5. OK.

    Pressing Shift+Down again has no effect, but pressing Shift+Right does
    increase the line count to 6.

    I can't agree with that. There is no line 6. The widget only holds
    five lines.

    The only debugging I did was to print the selection range indices and
    after a little thinking I believe that maybe I could do a better
    job myself than $::text count -lines by taking the indices and doing
    some math with it and maybe other tricks.

    But I wonder if that would be trying to invent an unnecessary wheel.

    What do you think?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Fri Dec 1 22:59:26 2023
    Luc <luc@sep.invalid> wrote:
    I am trying to count the text selection. I want to count words and lines.

    We have been through words. Now let's see lines.

    Please be more precise. Do you want to count text widget "logical
    lines" (the man page's term) or do you want to count "lines as
    displayed on screen with current word wrap (if applicable) in effect"
    (which the man page names "display lines".

    I have this code:

    set ::selectionWC 0
    set ::selectionlinecount 0
    set selectionindices [$::text tag ranges sel]
    if {[llength $selectionindices] > 0} {
    set ::selection "[$::text get {*}$selectionindices]"
    set ::selectionWC [p.wc $::selection]
    set ::selectionlinecount [$::text count -lines {*}$selectionindices] }

    The -lines option counts text widget logical lines (which are not
    display lines as soon as any one line word wraps).

    It doesn't really work. Whether I select nothing, one word, many words
    or the entire line, the line count is 0.

    This works exactly as documented:

    -lines logical lines (irrespective of wrapping) from the line of
    the first index up to, but not including the line of the second
    index. Therefore if they are both on the same line, zero will
    be returned. Logical lines are counted whether they are
    currently visible (non-elided) or not.

    Note the "if they are both on the same line, zero will be returned."
    part of the documentation. One word, many words, or the line will all
    be "on the same line" and so a zero is exactly what is documented as
    the return value.

    If I select two lines, then the line count is 1. That is evidently wrong.

    No, it is not. Note the first part of the documentation:

    from the line of the first index up to, but not including the line
    of the second index.

    You get "1" back when only "two lines are selected", exactly as
    documented.

    So I added this line to the code:

    ...

    Wait. Should I be doing that?

    That's up to you.

    Pressing Shift+Down again has no effect, but pressing Shift+Right does increase the line count to 6.

    I can't agree with that. There is no line 6. The widget only holds
    five lines.

    Your 'incr' hack gave you that.

    The only debugging I did was to print the selection range indices and
    after a little thinking I believe that maybe I could do a better job
    myself than $::text count -lines by taking the indices and doing some
    math with it and maybe other tricks.

    But I wonder if that would be trying to invent an unnecessary wheel.

    What do you think?

    Yes, trying to reinvent an unnecessary wheel. Begin by carefully
    reading the documented behavior of the 'count' sub-command to the text
    widget.

    Also ponder upon whether you want -lines or -displaylines as the count.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)