Mercurial > octave
changeset 24232:e0bcd17ac070
smart indentation for selections or current line in code editor
* file-editor.h, file-editor.cc
(file_editor::fetab_smart_indent_line_or_selected_text): New signal.
(file_editor::request_smart_indent_line_or_selected_text): New slot.
(file_editor::m_smart_indent_line_or_selection_action): New menu
action.
(file_editor::construct): Create action.
(file_editor::check_actions): Enable it.
(file_editor::set_shortcuts): Define a shortcut for it.
(file_editor::add_file_editor_tab): Connect
fetab_smart_indent_line_or_selected_text signal to
smart_indent_line_or_selected_text slot.
* file-editor-tab.h, file-editor-tab.cc
(file_editor_tab::smart_indent_line_or_selected_text): New slot.
(file_editor_tab::do_smart_indent_line_or_selected_text): New function.
* octave-qscintilla.h, octave-qscintilla.cc
(octave_qscintilla::smart_indent_line_or_selected_text): New function.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 14 Nov 2017 16:52:42 -0500 |
parents | 6bd7d2eb6434 |
children | ec837ef7ee3b |
files | libgui/src/m-editor/file-editor-tab.cc libgui/src/m-editor/file-editor-tab.h libgui/src/m-editor/file-editor.cc libgui/src/m-editor/file-editor.h libgui/src/m-editor/octave-qscintilla.cc libgui/src/m-editor/octave-qscintilla.h |
diffstat | 6 files changed, 123 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/m-editor/file-editor-tab.cc Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/file-editor-tab.cc Tue Nov 14 16:52:42 2017 -0500 @@ -1208,6 +1208,15 @@ } void +file_editor_tab::smart_indent_line_or_selected_text (const QWidget *ID) +{ + if (ID != this) + return; + + do_smart_indent_line_or_selected_text (); +} + +void file_editor_tab::convert_eol (const QWidget *ID, QsciScintilla::EolMode eol_mode) { if (ID != this) @@ -1423,6 +1432,34 @@ } void +file_editor_tab::do_smart_indent_line_or_selected_text (void) +{ + _edit_area->beginUndoAction (); + + int lineFrom, lineTo; + + if (_edit_area->hasSelectedText ()) + { + int colFrom, colTo; + _edit_area->getSelection (&lineFrom, &colFrom, &lineTo, &colTo); + + if (colTo == 0) // the beginning of last line is not selected + lineTo--; // stop at line above + } + else + { + int col; + _edit_area->getCursorPosition (&lineFrom, &col); + + lineTo = lineFrom; + } + + _edit_area->smart_indent_line_or_selected_text (lineFrom, lineTo); + + _edit_area->endUndoAction (); +} + +void file_editor_tab::do_comment_selected_text (bool comment) { QString comment_str = _edit_area->comment_string ();
--- a/libgui/src/m-editor/file-editor-tab.h Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/file-editor-tab.h Tue Nov 14 16:52:42 2017 -0500 @@ -108,6 +108,7 @@ void indent_selected_text (const QWidget *ID); void unindent_selected_text (const QWidget *ID); + void smart_indent_line_or_selected_text (const QWidget *ID); void convert_eol (const QWidget *ID, QsciScintilla::EolMode); void zoom_in (const QWidget *ID); @@ -250,6 +251,7 @@ int check_file_modified (); void do_comment_selected_text (bool comment); void do_indent_selected_text (bool indent); + void do_smart_indent_line_or_selected_text (void); void add_breakpoint_callback (const bp_info& info); void remove_breakpoint_callback (const bp_info& info);
--- a/libgui/src/m-editor/file-editor.cc Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/file-editor.cc Tue Nov 14 16:52:42 2017 -0500 @@ -263,6 +263,7 @@ m_uncomment_selection_action->setEnabled (have_tabs); m_indent_selection_action->setEnabled (have_tabs); m_unindent_selection_action->setEnabled (have_tabs); + m_smart_indent_line_or_selection_action->setEnabled (have_tabs); m_context_help_action->setEnabled (have_tabs); m_context_doc_action->setEnabled (have_tabs); @@ -797,6 +798,12 @@ } void +file_editor::request_smart_indent_line_or_selected_text () +{ + emit fetab_smart_indent_line_or_selected_text (m_tab_widget->currentWidget ()); +} + +void file_editor::request_conv_eol_windows (bool) { emit fetab_convert_eol (m_tab_widget->currentWidget (), @@ -1209,6 +1216,7 @@ shortcut_manager::set_shortcut (m_lower_case_action, "editor_edit:lower_case"); shortcut_manager::set_shortcut (m_indent_selection_action, "editor_edit:indent_selection"); shortcut_manager::set_shortcut (m_unindent_selection_action, "editor_edit:unindent_selection"); + shortcut_manager::set_shortcut (m_smart_indent_line_or_selection_action, "editor_edit:smart_indent_line_or_selection"); shortcut_manager::set_shortcut (m_completion_action, "editor_edit:completion_list"); shortcut_manager::set_shortcut (m_goto_line_action, "editor_edit:goto_line"); shortcut_manager::set_shortcut (m_move_to_matching_brace, "editor_edit:move_to_brace"); @@ -1844,9 +1852,13 @@ m_edit_fmt_menu->addSeparator (); m_indent_selection_action = add_action (m_edit_fmt_menu, QIcon (), - tr ("&Indent"), SLOT (request_indent_selected_text (bool))); + tr ("&Indent Selection Rigidly"), SLOT (request_indent_selected_text (bool))); m_unindent_selection_action = add_action (m_edit_fmt_menu, QIcon (), - tr ("&Unindent"), SLOT (request_unindent_selected_text (bool))); + tr ("&Unindent Selection Rigidly"), SLOT (request_unindent_selected_text (bool))); + + m_smart_indent_line_or_selection_action + = add_action (m_edit_fmt_menu, QIcon (), + tr ("Indent Code"), SLOT (request_smart_indent_line_or_selected_text (void))); m_edit_fmt_menu->addSeparator (); @@ -2219,6 +2231,9 @@ connect (this, SIGNAL (fetab_unindent_selected_text (const QWidget*)), f, SLOT (unindent_selected_text (const QWidget*))); + connect (this, SIGNAL (fetab_smart_indent_line_or_selected_text (const QWidget*)), + f, SLOT (smart_indent_line_or_selected_text (const QWidget*))); + connect (this, SIGNAL (fetab_convert_eol (const QWidget*, QsciScintilla::EolMode)), f, SLOT (convert_eol (const QWidget*, QsciScintilla::EolMode)));
--- a/libgui/src/m-editor/file-editor.h Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/file-editor.h Tue Nov 14 16:52:42 2017 -0500 @@ -173,6 +173,7 @@ void fetab_uncomment_selected_text (const QWidget *ID); void fetab_indent_selected_text (const QWidget *ID); void fetab_unindent_selected_text (const QWidget *ID); + void fetab_smart_indent_line_or_selected_text (const QWidget *ID); void fetab_convert_eol (const QWidget *ID, QsciScintilla::EolMode eol_mode); void fetab_find (const QWidget *ID, QList<QAction *>); void fetab_find_next (const QWidget *ID); @@ -251,6 +252,7 @@ void request_lower_case (bool); void request_indent_selected_text (bool); void request_unindent_selected_text (bool); + void request_smart_indent_line_or_selected_text (void); void request_conv_eol_windows (bool); void request_conv_eol_unix (bool); void request_conv_eol_mac (bool); @@ -377,6 +379,7 @@ QAction *m_uncomment_selection_action; QAction *m_indent_selection_action; QAction *m_unindent_selection_action; + QAction *m_smart_indent_line_or_selection_action; QAction *m_conv_eol_windows_action; QAction *m_conv_eol_unix_action; QAction *m_conv_eol_mac_action;
--- a/libgui/src/m-editor/octave-qscintilla.cc Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/octave-qscintilla.cc Tue Nov 14 16:52:42 2017 -0500 @@ -558,7 +558,69 @@ } return; } +} +// Do smart indendation of current selection or line. +void +octave_qscintilla::smart_indent_line_or_selected_text (int lineFrom, int lineTo) +{ + QRegExp blank_line_regexp = QRegExp ("^[\t ]*$"); + + QRegExp begin_block_regexp + = QRegExp ("^([\t ]*)(if|elseif|else" + "|for|while|do|parfor" + "|switch|case|otherwise" + "|function" + "|classdef|properties|events|enumeration|methods" + "|unwind_protect|unwind_protect_cleanup|try|catch)" + "[\r\n\t #%]"); + + QRegExp end_block_regexp + = QRegExp ("^([\t ]*)(end" + "|end(for|function|if|parfor|switch|while" + "|classdef|enumeration|events|methods|properties)" + "|end_(try_catch|unwind_protect)" + "|until)" + "[\r\n\t #%]"); + + int indent_column = -1; + int indent_increment = indentationWidth (); + + for (int line = lineFrom-1; line >= 0; line--) + { + QString line_text = text (line); + + if (blank_line_regexp.indexIn (line_text) < 0) + { + // Found first non-blank line above beginning of region or + // current line. Base indentation from this line, increasing + // indentation by indentationWidth if it looks like the + // beginning of a code block. + + indent_column = indentation (line); + + if (begin_block_regexp.indexIn (line_text) > -1) + indent_column += indent_increment; + + break; + } + } + + if (indent_column < 0) + indent_column = indentation (lineFrom); + + for (int line = lineFrom; line <= lineTo; line++) + { + QString line_text = text (line); + + if (end_block_regexp.indexIn (line_text) > -1) + indent_column -= indent_increment; + + setIndentation (line, indent_column); + + if (begin_block_regexp.indexIn (line_text) > -1) + indent_column += indent_increment; + } } void
--- a/libgui/src/m-editor/octave-qscintilla.h Thu Apr 06 13:30:47 2017 +0200 +++ b/libgui/src/m-editor/octave-qscintilla.h Tue Nov 14 16:52:42 2017 -0500 @@ -63,6 +63,8 @@ int is_style_comment (int pos = -1); void smart_indent (bool do_smart_indent, int do_auto_close, int line); + void smart_indent_line_or_selected_text (int lineFrom, int lineTo); + void set_word_selection (const QString& word = QString ()); void show_selection_markers (int line, int col, int len);