Community

    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    "Sel:" in status bar is off-by-1 on line count?

    Help wanted · · · – – – · · ·
    5
    9
    6347
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Alan Kilborn
      Alan Kilborn last edited by

      Sometimes I want to select a certain number of whole lines.

      When I create my stream selection, the “Sel: X | Y” section of the status bar shows me the number of characters I have blocked (X) and the number of lines (Y).

      The problem is that “Y” seems to be off-by-one (too high) and I have to remember and compensate in my mind for this.

      For example, If I want to select 7 full lines (including all line endings), I have to select until the Y in the status bar shows 8.

      This seems an awful design to me as I can never remember if it is one too high or one too low when I need to use it.

      I can remember for the duration of writing this posting because I just looked at it in-depth, but…

      Is there a reason it just doesn’t show what I think it should show?

      1 Reply Last reply Reply Quote 2
      • PeterJones
        PeterJones last edited by

        1. On the right, I have selected from the beginning to the end of line 1, without selecting the EOL. My cursor has stayed on one line, so Sel: 3|1 tells me my selection of three characters (“o”, “n”, “e”) spans 1 line.
        2. On the left, I have selected all of line one, and moved the cursor to line two. Because the selection includes the EOL, and the cursor is on a second line compared to the start of the selection, Sel: 5|2 tells me that I’ve selected 5 characters (“o”, “n”, “e”, CR, LF) across a total of 2 lines.
        1 Reply Last reply Reply Quote 2
        • Alan Kilborn
          Alan Kilborn last edited by

          @PeterJones

          I don’t agree with the “spans lines” answer…if I select 7 lines by click-drag on the line numbers margin, I expect to see 7 in the status bar, not 8. There really isn’t a valid argument that this somehow “spans 8 lines” – I’ve got seven complete lines and seven line endings. Thus, off-by-1!

          Scott Sumner 1 Reply Last reply Reply Quote 0
          • Scott Sumner
            Scott Sumner @Alan Kilborn last edited by

            @Alan-Kilborn

            I also don’t like the way this works; I don’t know that I would call it a bug, just “how it works”. Some time ago I wrote some Pythonscript to “fix” it. I’ll look at that code when I get some time, and if it is fit for human consumption, I’ll post it. :-)

            1 Reply Last reply Reply Quote 0
            • botman99
              botman99 last edited by

              Selecting a line using the line number margin causes the cursor to move to the line below what you have selected. The line that the cursor is on seems to be included in the lines “selected” so this seems like a bug to me.

              1 Reply Last reply Reply Quote 0
              • Claudia Frank
                Claudia Frank last edited by

                A bug, I don’t know - it depends how you look at it.
                As the whole line gets selected it means the EOL get selected as well.
                As the cursor needs to be placed to create a target for selection,
                it can only be placed after EOL which means next line.

                Cheers
                Claudia

                1 Reply Last reply Reply Quote 0
                • botman99
                  botman99 last edited by

                  I guess if you use the line number margin to select lines, to get the proper selection information you would need to move the cursor back one position to move it to the end of the last selected line. Then the numbers would be correct.

                  1 Reply Last reply Reply Quote 0
                  • Claudia Frank
                    Claudia Frank last edited by

                    but then you won’t select the eol.

                    Cheers
                    Claudia

                    1 Reply Last reply Reply Quote 0
                    • Scott Sumner
                      Scott Sumner last edited by Scott Sumner

                      Here’s the Pythonscript I mentioned earlier.

                      After running it, it will update the “Sel:” area in the status bar as follows:

                      • If selection contains partial lines which do not include the first line’s first character, not the last line’s last character (non-line-ending), then NO CHANGE from normal Notepad++ behavior.

                      • If the selection contains the first line’s first character, the part after the vertical bar (|) in “Sel: X | Y” will have a caret character (^) before the number of lines, e.g. ^7

                      • If the selection contains the last line’s last character (but not the line ending character(s)), the part after the vertical bar will have a dollar sign character ($) after the number of lines, e.g. 7$

                      • If the selection contains the last line’s last character AND the line ending character(s), the part after the vertical bar will have a dollar sign character ($) and \R after the number of lines, e.g. 7$\R

                      • If the selection contains lines in their entirety, the part after the vertical bar will combine all of these symbols, an example being ^7$\R. Note that this example means that 7 FULL LINES are in the selection, fixing the original “bad” Notepad++ behavior for this case.

                      Regular expression users will feel very comfortable with the meaning behind the choice of special symbols used here.

                      Okay, so here’s the Pythonscript code:

                      # Sel : C | L in the status bar shows an off-by-one L (line count) sometimes (open to debate)
                      # make it better:
                      #  Sel : C | L      <-- selection spans L partial lines
                      #  Sel : C | ^L     <-- selection spans L partial lines and includes first character on its first line
                      #  Sel : C | L$     <-- selection spans L partial lines and includes last char (but not line-ending) on its last line
                      #  Sel : C | L$\R   <-- selection spans L partial lines and includes line-ending on its last line
                      #  Sel : C | ^L$\R  <-- selection spans L FULL lines and includes line-ending on its last line
                      
                      def StatusbarSelOverride(args):
                          curr_pos = editor.getCurrentPos()
                          curr_line = editor.lineFromPosition(curr_pos)
                          curr_col = editor.getColumn(curr_pos)
                          sel_part = 'N/A'
                          if editor.getSelections() == 1:
                              sel_mode = editor.getSelectionMode()
                              rect_sel_mode = True if (sel_mode == SELECTIONMODE.RECTANGLE or sel_mode == SELECTIONMODE.THIN) else False
                              if not rect_sel_mode:
                                  if editor.getSelectionEmpty():
                                      sel_part = '0 | 0'
                                  else:
                                      sel_start_pos = editor.getSelectionStart()
                                      sel_end_pos = editor.getSelectionEnd()
                                      sel_start_line = editor.lineFromPosition(sel_start_pos)
                                      sel_end_line = editor.lineFromPosition(editor.getSelectionEnd())
                                      lines_touched_by_sel = sel_end_line - sel_start_line + 1
                                      start_of_line_symbol = '^' if sel_start_pos == editor.positionFromLine(sel_start_line) else ''
                                      end_of_line_symbols = '$' if sel_end_pos == editor.getLineEndPosition(sel_end_line) else ''
                                      selected_text = editor.getSelText()
                                      line_ending = ['\r\n', '\r', '\n'][notepad.getFormatType()]
                                      if selected_text.endswith(line_ending): end_of_line_symbols = r'$\R'; lines_touched_by_sel -= 1
                                      sel_text_len = len(selected_text)
                                      sel_part = '{tl} | {sol}{lis}{eol}'.format(
                                          tl=sel_text_len,
                                          sol=start_of_line_symbol,
                                          lis=lines_touched_by_sel,
                                          eol=end_of_line_symbols,
                                          )
                          line_col_sel_info_for_sb = 'Ln : {user_line}     Col : {user_col}     Sel : {sel}'.format(
                              user_line=curr_line+1,
                              user_col=curr_col+1,
                              sel=sel_part,
                              )
                          notepad.setStatusBar(STATUSBARSECTION.CURPOS, line_col_sel_info_for_sb)
                      
                      editor.callback(StatusbarSelOverride, [SCINTILLANOTIFICATION.UPDATEUI])  # register callback
                      
                      1 Reply Last reply Reply Quote 4
                      • First post
                        Last post
                      Copyright © 2014 NodeBB Forums | Contributors