changeset 23230:f7fdc9ef3971

improve line breaking in the editor * file-editor-tab.cc (handle_cursor_moved): use real cursor position taking the tab length into account and do not leave blanks at the end of the line * octave-qscintilla..h / octave-qscintilla.cc (get_current_position): new function calculating the real column taking the tab length into account
author Torsten <mttl@mailbox.org>
date Fri, 24 Feb 2017 21:37:11 +0100
parents 2bed6d6bb2e2
children ac09d0a6c6a0
files libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/octave-qscintilla.cc libgui/src/m-editor/octave-qscintilla.h
diffstat 3 files changed, 44 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc	Fri Feb 24 11:43:56 2017 -0800
+++ b/libgui/src/m-editor/file-editor-tab.cc	Fri Feb 24 21:37:11 2017 +0100
@@ -2693,48 +2693,52 @@
 
 // Slot that is entered each time a new character was typed.
 // It is used for handling line breaking if this is desired.
+// The related signal is emitted after the signal for a moved cursor
+// such that _col and _line can not be used for current position.
 void
 file_editor_tab::handle_char_added (int character)
 {
   if (_line_break)
   {
-    // if line breaking is desired, get the current line and column
-    int line, col;
-    _edit_area->getCursorPosition (&line, &col);
+    // If line breaking is desired, get the current line and column.
+    // For taking the tab width into consideration, use own function
+    int line, col, pos;
+    _edit_area->get_current_position (&pos, &line, &col);
 
     // immediately return if line has not reached the max. line length
-    if (col < _line_break)
+    if (col <= _line_break)
       return;
 
-    if (character == ' ' || character == '\t')
-      {
-        // the new character is space or tab, break already here
-        _edit_area->insertAt (QString ("\n"), line, col);
-      }
-    else
+    // Here we go for breaking the current line by inserting a newline.
+    // For determining the position of a specific column, we have to get
+    // the column from the QScintila function without taking tab lengths
+    // into account, since the calculation from line/col to position ignores
+    // this, too
+    _edit_area->getCursorPosition (&line, &col);
+    int c = 0;
+    int col_space = col;
+    int indentation = _edit_area->indentation (line);
+
+    // Search the first occurence of space or tab backwards starting from
+    // the current column (col_space).
+    while (c != ' ' && c != '\t' && col_space > indentation)
       {
-        // search backward for the first space or tab
-        int col_space = col - 1;
-        int c = 0, pos;
-
-        while (c != ' ' && c != '\t' && col_space-- > 0)
-          {
-            pos = _edit_area->positionFromLineIndex (line, col_space);
-            c = _edit_area->SendScintilla (QsciScintillaBase::SCI_GETCHARAT,
-                                           pos);
-          }
-
-        // if a space or tab was found, break after that char;
-        // otherwise break at cursor position
-        int col_newline = col - 1;
-        if (c == ' ' || c == '\t')
-          col_newline = col_space + 1;
-        // insert a newline char for breaking the line
-        _edit_area->insertAt (QString ("\n"), line, col_newline);
+        pos = _edit_area->positionFromLineIndex (line, col_space--);
+        c = _edit_area->SendScintilla (QsciScintillaBase::SCI_GETCHARAT, pos);
       }
 
-    // automatically indent new line to the indentation of previous line
-    _edit_area->setIndentation (line + 1, _edit_area->indentation (line));
+    // If a space or tab was found, break at this char,
+    // otherwise break at cursor position
+    int col_newline = col - 1;
+    if (c == ' ' || c == '\t')
+      col_newline = col_space + 1;
+    // Insert a newline char for breaking the line
+    _edit_area->insertAt (QString ("\n"), line, col_newline);
+
+    // Automatically indent the new line to the indentation of previous line
+    // and set the cursor position to the end of the indentation.
+    _edit_area->setIndentation (line + 1, indentation);
+    _edit_area->SendScintilla (QsciScintillaBase::SCI_LINEEND);
   }
 }
 
--- a/libgui/src/m-editor/octave-qscintilla.cc	Fri Feb 24 11:43:56 2017 -0800
+++ b/libgui/src/m-editor/octave-qscintilla.cc	Fri Feb 24 21:37:11 2017 +0100
@@ -352,4 +352,13 @@
   clearIndicatorRange (0, 0, end_line, end_col, indicator_style);
 }
 
+// Function returning the true cursor position where the tab length
+// is taken into account.
+void
+octave_qscintilla::get_current_position (int *pos, int *line, int *col)
+{
+  *pos = SendScintilla (QsciScintillaBase::SCI_GETCURRENTPOS);
+  *line = SendScintilla (QsciScintillaBase::SCI_LINEFROMPOSITION, *pos);
+  *col = SendScintilla (QsciScintillaBase::SCI_GETCOLUMN, *pos);
+}
 #endif
--- a/libgui/src/m-editor/octave-qscintilla.h	Fri Feb 24 11:43:56 2017 -0800
+++ b/libgui/src/m-editor/octave-qscintilla.h	Fri Feb 24 21:37:11 2017 +0100
@@ -46,6 +46,7 @@
   void get_global_textcursor_pos (QPoint *global_pos, QPoint *local_pos);
   bool get_actual_word ();
   void clear_indicator (int indicator_style);
+  void get_current_position (int *pos, int *line, int *col);
 
 signals: