package Kephra::Edit::Format; our $VERSION = '0.26'; use strict; use warnings; sub _ep_ref { Kephra::App::EditPanel::_ref() } sub _config { Kephra::API::settings()->{editpanel} } # change indention width of selected text sub _indent_selection { my $width = shift || 0; my $ep = _ep_ref(); $ep->BeginUndoAction; for ( $ep->LineFromPosition($ep->GetSelectionStart) .. $ep->LineFromPosition($ep->GetSelectionEnd) ) { $ep->SetLineIndentation( $_, $ep->GetLineIndentation($_) + $width ) unless $ep->PositionFromLine($_) == $ep->GetLineEndPosition($_); } $ep->EndUndoAction; } sub autoindent { my $ep = _ep_ref(); my $line = $ep->GetCurrentLine; $ep->BeginUndoAction; $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE); my $indent = $ep->GetLineIndentation( $line ); $ep->SetLineIndentation( $line + 1, $indent); $ep->GotoPos( $ep->GetLineIndentPosition( $line + 1 ) ); $ep->EndUndoAction; } sub blockindent_open { my $ep = _ep_ref(); my $tabsize = Kephra::Document::Data::attr('tab_size'); my $line = $ep->GetCurrentLine; my $first_cpos = $ep->PositionFromLine($line) + $ep->GetLineIndentation($line); # position of first char in line my $matchfirst = $ep->BraceMatch($first_cpos); $ep->BeginUndoAction; # dedent a "} else {" correct if ($ep->GetCharAt($first_cpos) == 125 and $matchfirst > -1) { $ep->SetLineIndentation( $line, $ep->GetLineIndentation( $ep->LineFromPosition($matchfirst) ) ); } # grabbing my $bracepos = $ep->GetCurrentPos - 1; my $leadindent = $ep->GetLineIndentation($line); my $matchbrace = $ep->BraceMatch( $bracepos ); my $matchindent= $ep->GetLineIndentation($ep->LineFromPosition($matchbrace)); # make newl line $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE); # make new brace if there is missing one if (_config()->{auto}{brace}{make} and ($matchbrace == -1 or $ep->GetLineIndentation($line) != $matchindent )){ $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE); $ep->AddText('}'); $ep->SetLineIndentation( $line + 2, $leadindent ); } $ep->SetLineIndentation( $line + 1, $leadindent + $tabsize ); $ep->GotoPos( $ep->GetLineIndentPosition( $line + 1 ) ); $ep->EndUndoAction; } sub blockindent_close { my $ep = _ep_ref(); my $bracepos = shift; unless ($bracepos) { $bracepos = $ep->GetCurrentPos - 1; $bracepos-- while $ep->GetCharAt($bracepos) == 32; } $ep->BeginUndoAction; # 1 if it not textend, goto next line my $match = $ep->BraceMatch($bracepos); my $line = $ep->GetCurrentLine; unless ($ep->GetLineIndentPosition($line)+1 == $ep->GetLineEndPosition($line) or $ep->LineFromPosition($match) == $line ) { $ep->GotoPos($bracepos); $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE); $ep->GotoPos( $ep->GetCurrentPos + 1 ); $line++; } # 2 wenn match dann korrigiere einrückung ansonst letzte - tabsize if ( $match > -1 ) { $ep->SetLineIndentation( $line, $ep->GetLineIndentation( $ep->LineFromPosition($match) ) ); } else { $ep->SetLineIndentation( $line, $ep->GetLineIndentation( $line - 1 ) - Kephra::Document::Data::attr('tab_size') ); } # make new line _config()->{auto}{indent} ? autoindent() : $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE); # 3 lösche dubs wenn in nächster zeile nur spaces bis dup #if ( _config()->{auto}{brace}{join} ) { #my $delbrace = $ep->PositionFromLine( $line + 2 ) #+ $ep->GetLineIndentation( $line + 1 ); #if ( $ep->GetCharAt($delbrace) == 125 ) { #$ep->SetTargetStart( $ep->GetCurrentPos ); #$ep->SetTargetEnd( $delbrace + 1 ); #$ep->ReplaceTarget(''); #} #} $ep->EndUndoAction; } sub indent_space { _indent_selection( 1) } sub dedent_space { _indent_selection(-1) } sub indent_tab { _indent_selection( Kephra::Document::Data::attr('tab_size') ) } sub dedent_tab { _indent_selection(-Kephra::Document::Data::attr('tab_size') ) } # sub align_indent { my $ep = _ep_ref(); my $firstline = $ep->LineFromPosition( $ep->GetSelectionStart ); my $align = $ep->GetLineIndentation($firstline); $ep->BeginUndoAction(); $ep->SetLineIndentation($_ ,$align) for $firstline + 1 .. $ep->LineFromPosition($ep->GetSelectionEnd); $ep->EndUndoAction(); } # deleting trailing spaces on line ends sub del_trailing_spaces { &Kephra::Edit::_save_positions; my $ep = _ep_ref(); my $text = Kephra::Edit::_select_all_if_none(); $text =~ s/[ \t]+(\r|\n|\Z)/$1/g; $ep->BeginUndoAction; $ep->ReplaceSelection($text); $ep->EndUndoAction; Kephra::Edit::_restore_positions(); } # sub join_lines { my $ep = _ep_ref(); my $text = $ep->GetSelectedText(); $text =~ s/[\r|\n]+/ /g; # delete end of line marker $ep->BeginUndoAction; $ep->ReplaceSelection($text); $ep->EndUndoAction; } sub blockformat{ return unless Scalar::Util::looks_like_number($_[0]); my $width = (int shift) + 1; my $ep = _ep_ref(); my ($begin, $end) = $ep->GetSelection; my $bline = $ep->LineFromPosition($begin); my $tmp_begin = $ep->PositionFromLine($bline); my $bspace = ' ' x $ep->GetLineIndentation($bline); my $space = _config()->{auto}{indention} ? $bspace : ''; chop $bspace; $ep->SetSelection($tmp_begin, $end); require Text::Wrap; $Text::Wrap::columns = $width; $Text::Wrap::unexpand = Kephra::Document::Data::attr('tab_use'); $Text::Wrap::tabstop = Kephra::Document::Data::attr('tab_size'); my $text = $ep->GetSelectedText; $text =~ s/[\r|\n]+/ /g; $ep->BeginUndoAction(); $ep->ReplaceSelection( Text::Wrap::fill($bspace, $space, $text) ); $ep->EndUndoAction(); } sub blockformat_LLI{ blockformat( _config()->{indicator}{right_margin}{position} ); } sub blockformat_custom { my $l18n = Kephra::Config::Localisation::strings()->{dialog}{edit}; my $width = Kephra::Dialog::get_text( $l18n->{wrap_width_input}, $l18n->{wrap_custom_headline} ); blockformat( $width ) if defined $width; } # breaking too long lines into smaller one sub line_break { return unless Scalar::Util::looks_like_number($_[0]); my $width = (int shift) + 1; my $ep = _ep_ref(); my ($begin, $end)= $ep->GetSelection; my $tmp_begin = $ep->LineFromPosition( $ep->PositionFromLine($begin) ); $ep->SetSelection($tmp_begin, $end); require Text::Wrap; $Text::Wrap::columns = $width; $Text::Wrap::unexpand = Kephra::Document::Data::attr('tab_use'); $Text::Wrap::tabstop = Kephra::Document::Data::attr('tab_size'); $ep->BeginUndoAction(); $ep->ReplaceSelection( Text::Wrap::wrap('', '', $ep->GetSelectedText) ); $ep->EndUndoAction(); } sub linebreak_custom { my $l10n = Kephra::Config::Localisation::strings()->{dialog}{edit}; my $width = Kephra::Dialog::get_text ($l10n->{wrap_width_input}, $l10n->{wrap_custom_headline} ); line_break( $width ) if defined $width; } sub linebreak_LLI { line_break( _config()->{indicator}{right_margin}{position} ); } sub linebreak_window { my $app = Kephra::App::Window::_ref(); my $ep = _ep_ref(); my ($width) = $app->GetSizeWH(); my $pos = $ep->GetColumn( $ep->PositionFromPointClose(100, 67) ); Kephra::Dialog::msg_box( $pos, '' ); #line_break($width); } 1; __END__ =head1 NAME Kephra::App::Format - functions that play with indention and length of lines =head1 DESCRIPTION