00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "katevinormalmode.h"
00022 #include "katevivisualmode.h"
00023 #include "kateviinputmodemanager.h"
00024 #include "katesmartmanager.h"
00025 #include "katesmartrange.h"
00026 #include "katebuffer.h"
00027 #include <QApplication>
00028 #include <QList>
00029
00030 KateViNormalMode::KateViNormalMode( KateViInputModeManager *viInputModeManager, KateView * view, KateViewInternal * viewInternal )
00031 {
00032 m_view = view;
00033 m_viewInternal = viewInternal;
00034 m_viInputModeManager = viInputModeManager;
00035 m_stickyColumn = -1;
00036
00037
00038 m_extraWordCharacters = "";
00039 m_matchingItems["/*"] = "*/";
00040 m_matchingItems["*/"] = "-/*";
00041
00042 m_matchItemRegex = generateMatchingItemRegex();
00043
00044 m_defaultRegister = '"';
00045 m_marks = new QMap<QChar, KTextEditor::SmartCursor*>;
00046 m_keyParser = new KateViKeySequenceParser();
00047
00048 initializeCommands();
00049 resetParser();
00050 }
00051
00052 KateViNormalMode::~KateViNormalMode()
00053 {
00054 delete m_marks;
00055 delete m_keyParser;
00056 }
00057
00062 bool KateViNormalMode::handleKeypress( const QKeyEvent *e )
00063 {
00064 int keyCode = e->key();
00065 QString text = e->text();
00066
00067
00068 if ( keyCode == Qt::Key_Shift || keyCode == Qt::Key_Control
00069 || keyCode == Qt::Key_Alt || keyCode == Qt::Key_Meta ) {
00070 return false;
00071 }
00072
00073 if ( keyCode == Qt::Key_Escape ) {
00074 reset();
00075 return true;
00076 }
00077
00078 QChar key = m_keyParser->KeyEventToQChar( e->key(), e->text(), e->modifiers(), e->nativeScanCode() );
00079
00080 m_keysVerbatim.append( m_keyParser->decodeKeySequence( key ) );
00081
00082 QChar c = QChar::Null;
00083 if ( m_keys.size() > 0 ) {
00084 c = m_keys.at( m_keys.size()-1 );
00085 }
00086
00087 if ( ( keyCode >= Qt::Key_0 && keyCode <= Qt::Key_9 && c != '"' )
00088 && ( m_countTemp != 0 || keyCode != Qt::Key_0 )
00089 && ( c != 'f' && c != 't' && c != 'F' && c != 'T' && c != 'r' ) ){
00090
00091 m_countTemp *= 10;
00092 m_countTemp += keyCode-Qt::Key_0;
00093
00094 return true;
00095 } else if ( m_countTemp != 0 ) {
00096 m_count = getCount() * m_countTemp;
00097 m_countTemp = 0;
00098
00099 kDebug( 13070 ) << "count = " << getCount();
00100 }
00101
00102 m_keys.append( key );
00103
00104
00105
00106
00107 if ( ( m_keys == "cw" || m_keys == "cW" ) && !getCharUnderCursor().isSpace() ) {
00108
00109
00110 KTextEditor::Cursor c1( m_view->cursorPosition() );
00111 KTextEditor::Cursor c2 = findWordEnd(c1.line(), c1.column()-1, true);
00112
00113 if ( c1 == c2 ) {
00114 m_keys = "cl";
00115 } else {
00116 if ( m_keys.at(1) == 'w' ) {
00117 m_keys = "ce";
00118 } else {
00119 m_keys = "cE";
00120 }
00121 }
00122 }
00123
00124 if ( m_keys[ 0 ] == Qt::Key_QuoteDbl ) {
00125 if ( m_keys.size() < 2 ) {
00126 return true;
00127 }
00128 else {
00129 QChar r = m_keys[ 1 ].toLower();
00130
00131 if ( ( r >= '0' && r <= '9' ) || ( r >= 'a' && r <= 'z' ) || r == '_' || r == '+' || r == '*' ) {
00132 m_register = r;
00133 kDebug( 13070 ) << "Register set to " << r;
00134 m_keys.clear();
00135 return true;
00136 }
00137 else {
00138 resetParser();
00139 return true;
00140 }
00141 }
00142 }
00143
00144
00145
00146 if ( m_matchingCommands.size() > 0 ) {
00147 int n = m_matchingCommands.size()-1;
00148
00149
00150 for ( int i = n; i >= 0; i-- ) {
00151 if ( !m_commands.at( m_matchingCommands.at( i ) )->matches( m_keys ) ) {
00152
00153 if ( m_commands.at( m_matchingCommands.at( i ) )->needsMotion() ) {
00154
00155
00156 m_motionOperatorIndex = m_matchingCommands.at( i );
00157 }
00158 m_matchingCommands.remove( i );
00159 }
00160 }
00161
00162
00163
00164
00165 for ( int i = 0; i < m_matchingCommands.size(); i++ ) {
00166 if ( m_commands.at( m_matchingCommands.at( i ) )->needsMotion() ) {
00167 m_awaitingMotionOrTextObject.push( m_keys.size() );
00168 break;
00169 }
00170 }
00171 } else {
00172
00173 for ( int i = 0; i < m_commands.size(); i++ ) {
00174 if ( m_commands.at( i )->matches( m_keys ) ) {
00175 m_matchingCommands.push_back( i );
00176 if ( m_commands.at( i )->needsMotion() && m_commands.at( i )->pattern().length() == m_keys.size() ) {
00177 m_awaitingMotionOrTextObject.push( m_keys.size() );
00178 }
00179 }
00180 }
00181 }
00182
00183
00184 int checkFrom = ( m_awaitingMotionOrTextObject.isEmpty() ? 0 : m_awaitingMotionOrTextObject.top() );
00185
00186
00187
00188
00189
00190
00191 if ( checkFrom < m_keys.size() ) {
00192 for ( int i = 0; i < m_motions.size(); i++ ) {
00193
00194 if ( m_motions.at( i )->matches( m_keys.mid( checkFrom ) ) ) {
00195
00196 m_matchingMotions.push_back( i );
00197
00198
00199 if ( m_motions.at( i )->matchesExact( m_keys.mid( checkFrom ) ) ) {
00200 if ( checkFrom == 0 ) {
00201
00202
00203 KateViRange r = m_motions.at( i )->execute();
00204
00205
00206 if ( r.valid
00207 && r.endLine >= 0
00208 && ( r.endLine == 0 || r.endLine <= doc()->lines()-1 )
00209 && r.endColumn >= 0
00210 && ( r.endColumn == 0 || r.endColumn < doc()->lineLength( r.endLine ) ) ) {
00211 kDebug( 13070 ) << "No command given, going to position ("
00212 << r.endLine << "," << r.endColumn << ")";
00213 goToPos( r );
00214 m_viInputModeManager->clearLog();
00215 } else {
00216 kDebug( 13070 ) << "Invalid position: (" << r.endLine << "," << r.endColumn << ")";
00217 }
00218
00219 resetParser();
00220 return true;
00221 } else {
00222
00223
00224
00225 m_commandRange = m_motions.at( i )->execute();
00226
00227
00228 if ( m_commandRange.startLine == -1 ) {
00229 KTextEditor::Cursor c( m_view->cursorPosition() );
00230 m_commandRange.startLine = c.line();
00231 m_commandRange.startColumn = c.column();
00232 }
00233
00234
00235
00236 if ( ( m_keys.right(1) == "w" || m_keys.right(1) == "W" )
00237 && m_commandRange.endLine > m_commandRange.startLine ) {
00238 m_commandRange = motionToEOL();
00239
00240 KTextEditor::Cursor c( m_view->cursorPosition() );
00241 m_commandRange.startLine = c.line();
00242 m_commandRange.startColumn = c.column();
00243 }
00244
00245 if ( m_commandRange.valid ) {
00246 kDebug( 13070 ) << "Run command" << m_commands.at( m_motionOperatorIndex )->pattern()
00247 << "from (" << m_commandRange.startLine << "," << m_commandRange.endLine << ")"
00248 << "to (" << m_commandRange.endLine << "," << m_commandRange.endColumn << ")";
00249 executeCommand( m_commands.at( m_motionOperatorIndex ) );
00250 } else {
00251 kDebug( 13070 ) << "Invalid range: "
00252 << "from (" << m_commandRange.startLine << "," << m_commandRange.endLine << ")"
00253 << "to (" << m_commandRange.endLine << "," << m_commandRange.endColumn << ")";
00254 }
00255
00256 reset();
00257 return true;
00258 }
00259 }
00260 }
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 if ( m_matchingCommands.size() == 1 ) {
00271 if ( m_commands.at( m_matchingCommands.at( 0 ) )->matchesExact( m_keys )
00272 && !m_commands.at( m_matchingCommands.at( 0 ) )->needsMotion() ) {
00273
00274
00275 KateViCommand *cmd = m_commands.at( m_matchingCommands.at( 0 ) );
00276 executeCommand( cmd );
00277
00278
00279 if ( cmd->shouldReset() ) {
00280 reset();
00281 }
00282 resetParser();
00283
00284 return true;
00285 }
00286 } else if ( m_matchingCommands.size() == 0 && m_matchingMotions.size() == 0 ) {
00287
00288 resetParser();
00289 return false;
00290
00291
00292
00293 }
00294
00295 m_matchingMotions.clear();
00296 return false;
00297 }
00298
00303 void KateViNormalMode::resetParser()
00304 {
00305 kDebug( 13070 ) << "***RESET***";
00306 m_keys.clear();
00307 m_keysVerbatim.clear();
00308 m_count = 0;
00309 m_countTemp = 0;
00310 m_register = QChar::Null;
00311 m_findWaitingForChar = false;
00312 m_waitingForMotionOrTextObject = -1;
00313 m_matchingCommands.clear();
00314 m_matchingMotions.clear();
00315 m_awaitingMotionOrTextObject.clear();
00316 m_motionOperatorIndex = 0;
00317 }
00318
00319
00320 void KateViNormalMode::reset()
00321 {
00322 resetParser();
00323 m_commandRange.startLine = -1;
00324 m_commandRange.startColumn = -1;
00325 }
00326
00327 void KateViNormalMode::goToPos( const KateViRange &r )
00328 {
00329 KTextEditor::Cursor c;
00330 c.setLine( r.endLine );
00331 c.setColumn( r.endColumn );
00332
00333 if ( r.jump ) {
00334 addCurrentPositionToJumpList();
00335 }
00336
00337 if ( c.line() >= doc()->lines() ) {
00338 c.setLine( doc()->lines()-1 );
00339 }
00340
00341 updateCursor( c );
00342 }
00343
00344 void KateViNormalMode::executeCommand( const KateViCommand* cmd )
00345 {
00346 cmd->execute();
00347
00348
00349
00350 if ( m_viInputModeManager->getCurrentViMode() != InsertMode ) {
00351 if ( cmd->isChange() && !m_viInputModeManager->isRunningMacro() ) {
00352 m_viInputModeManager->storeChangeCommand();
00353 }
00354
00355 m_viInputModeManager->clearLog();
00356 }
00357
00358
00359 KTextEditor::Cursor c( m_view->cursorPosition() );
00360 if ( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
00361 int lineLength = doc()->lineLength( c.line() );
00362
00363 if ( c.column() >= lineLength ) {
00364 if ( lineLength == 0 ) {
00365 c.setColumn( 0 );
00366 } else {
00367 c.setColumn( lineLength-1 );
00368 }
00369 }
00370 updateCursor( c );
00371 }
00372 }
00373
00374 void KateViNormalMode::addCurrentPositionToJumpList()
00375 {
00376 KTextEditor::Cursor c( m_view->cursorPosition() );
00377
00378 KateSmartCursor *cursor = doc()->smartManager()->newSmartCursor( c );
00379
00380 m_marks->insert( '\'', cursor );
00381 }
00382
00384
00386
00391 bool KateViNormalMode::commandEnterInsertMode()
00392 {
00393 return startInsertMode();
00394 }
00395
00400 bool KateViNormalMode::commandEnterInsertModeAppend()
00401 {
00402 KTextEditor::Cursor c( m_view->cursorPosition() );
00403 c.setColumn( c.column()+1 );
00404
00405
00406 if ( doc()->lineLength( c.line() ) == 0 ) {
00407 c.setColumn( 0 );
00408 }
00409
00410 updateCursor( c );
00411
00412 return startInsertMode();
00413 }
00414
00419 bool KateViNormalMode::commandEnterInsertModeAppendEOL()
00420 {
00421 KTextEditor::Cursor c( m_view->cursorPosition() );
00422 c.setColumn( doc()->lineLength( c.line() ) );
00423 updateCursor( c );
00424
00425 return startInsertMode();
00426 }
00427
00428 bool KateViNormalMode::commandEnterInsertModeBeforeFirstCharacterOfLine()
00429 {
00430 KTextEditor::Cursor cursor( m_view->cursorPosition() );
00431 QRegExp nonSpace( "\\S" );
00432 int c = getLine().indexOf( nonSpace );
00433 if ( c == -1 ) {
00434 c = 0;
00435 }
00436 cursor.setColumn( c );
00437 updateCursor( cursor );
00438
00439 return startInsertMode();
00440 }
00441
00442 bool KateViNormalMode::commandEnterVisualLineMode()
00443 {
00444 if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
00445 reset();
00446 return true;
00447 }
00448
00449 return startVisualLineMode();
00450 }
00451
00452 bool KateViNormalMode::commandEnterVisualMode()
00453 {
00454 if ( m_viInputModeManager->getCurrentViMode() == VisualMode ) {
00455 reset();
00456 return true;
00457 }
00458
00459 return startVisualMode();
00460 }
00461
00462 bool KateViNormalMode::commandToOtherEnd()
00463 {
00464 if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode
00465 || m_viInputModeManager->getCurrentViMode() == VisualMode ) {
00466 m_viInputModeManager->getViVisualMode()->switchStartEnd();
00467 return true;
00468 }
00469
00470 return false;
00471 }
00472
00473 KateViRange KateViNormalMode::motionWordForward()
00474 {
00475 KTextEditor::Cursor c( m_view->cursorPosition() );
00476 KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
00477
00478
00479
00480 if ( c.line() == doc()->lines()-1 && c.column() == doc()->lineLength( c.line() )-1 ) {
00481 r.motionType = ViMotion::InclusiveMotion;
00482 } else {
00483 for ( unsigned int i = 0; i < getCount(); i++ ) {
00484 c = findNextWordStart( c.line(), c.column() );
00485
00486
00487 if ( c.line() == doc()->lines()-1 && c.column() == doc()->lineLength( c.line() )-1 ) {
00488
00489
00490 if ( i < getCount() ) {
00491 r.motionType = ViMotion::InclusiveMotion;
00492 }
00493 break;
00494 }
00495 }
00496 }
00497
00498 r.endColumn = c.column();
00499 r.endLine = c.line();
00500
00501 return r;
00502 }
00503
00504 KateViRange KateViNormalMode::motionWordBackward()
00505 {
00506 KTextEditor::Cursor c( m_view->cursorPosition() );
00507 KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
00508
00509 for ( unsigned int i = 0; i < getCount(); i++ ) {
00510 c = findPrevWordStart( c.line(), c.column() );
00511
00512
00513 if ( c.line() == 0 && c.column() == 0 ) {
00514 break;
00515 }
00516 }
00517
00518 r.endColumn = c.column();
00519 r.endLine = c.line();
00520
00521 return r;
00522 }
00523
00524 KateViRange KateViNormalMode::motionWORDForward()
00525 {
00526 KTextEditor::Cursor c( m_view->cursorPosition() );
00527 KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
00528
00529 for ( unsigned int i = 0; i < getCount(); i++ ) {
00530 c = findNextWORDStart( c.line(), c.column() );
00531
00532
00533 if ( c.line() == doc()->lines()-1 && c.column() == doc()->lineLength( c.line() )-1 ) {
00534 break;
00535 }
00536 }
00537
00538 r.endColumn = c.column();
00539 r.endLine = c.line();
00540
00541 return r;
00542 }
00543
00544 KateViRange KateViNormalMode::motionWORDBackward()
00545 {
00546 KTextEditor::Cursor c( m_view->cursorPosition() );
00547 KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
00548
00549 for ( unsigned int i = 0; i < getCount(); i++ ) {
00550 c = findPrevWORDStart( c.line(), c.column() );
00551
00552
00553 if ( c.line() == 0 && c.column() == 0 ) {
00554 break;
00555 }
00556 }
00557
00558 r.endColumn = c.column();
00559 r.endLine = c.line();
00560
00561 return r;
00562 }
00563
00564 KateViRange KateViNormalMode::motionToEndOfWord()
00565 {
00566 KTextEditor::Cursor c( m_view->cursorPosition() );
00567 KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
00568
00569 for ( unsigned int i = 0; i < getCount(); i++ ) {
00570 c = findWordEnd( c.line(), c.column() );
00571 }
00572
00573 r.endColumn = c.column();
00574 r.endLine = c.line();
00575
00576 return r;
00577 }
00578
00579 KateViRange KateViNormalMode::motionToEndOfWORD()
00580 {
00581 KTextEditor::Cursor c( m_view->cursorPosition() );
00582 KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
00583
00584 for ( unsigned int i = 0; i < getCount(); i++ ) {
00585 c = findWORDEnd( c.line(), c.column() );
00586 }
00587
00588 r.endColumn = c.column();
00589 r.endLine = c.line();
00590
00591 return r;
00592 }
00593
00594 KateViRange KateViNormalMode::motionToEndOfPrevWord()
00595 {
00596 KTextEditor::Cursor c( m_view->cursorPosition() );
00597 KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
00598
00599 for ( unsigned int i = 0; i < getCount(); i++ ) {
00600 c = findPrevWordEnd( c.line(), c.column() );
00601
00602
00603 if ( c.line() == 0 && c.column() == 0 ) {
00604 break;
00605 }
00606 }
00607
00608 r.endColumn = c.column();
00609 r.endLine = c.line();
00610
00611 return r;
00612 }
00613
00614 KateViRange KateViNormalMode::motionToEndOfPrevWORD()
00615 {
00616 KTextEditor::Cursor c( m_view->cursorPosition() );
00617 KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
00618
00619 for ( unsigned int i = 0; i < getCount(); i++ ) {
00620 c = findPrevWORDEnd( c.line(), c.column() );
00621
00622
00623 if ( c.line() == 0 && c.column() == 0 ) {
00624 break;
00625 }
00626 }
00627
00628 r.endColumn = c.column();
00629 r.endLine = c.line();
00630
00631 return r;
00632 }
00633
00634 bool KateViNormalMode::commandDeleteLine()
00635 {
00636 KTextEditor::Cursor c( m_view->cursorPosition() );
00637
00638 KateViRange r;
00639
00640 r.startLine = c.line();
00641 r.endLine = c.line()+getCount()-1;
00642
00643 int column = c.column();
00644
00645 bool ret = deleteRange( r, true );
00646
00647 c = m_view->cursorPosition();
00648 if ( column > getLine().length()-1 ) {
00649 column = getLine().length()-1;
00650 }
00651 if ( column < 0 ) {
00652 column = 0;
00653 }
00654
00655 if ( c.line() > doc()->lines()-1 ) {
00656 c.setLine( doc()->lines()-1 );
00657 }
00658
00659 c.setColumn( column );
00660 updateCursor( c );
00661
00662 return ret;
00663 }
00664
00665 bool KateViNormalMode::commandDelete()
00666 {
00667 bool linewise = m_viInputModeManager->getCurrentViMode() == VisualLineMode
00668 || ( m_commandRange.startLine != m_commandRange.endLine
00669 && m_viInputModeManager->getCurrentViMode() != VisualMode );
00670
00671 return deleteRange( m_commandRange, linewise );
00672 }
00673
00674 bool KateViNormalMode::commandDeleteToEOL()
00675 {
00676 KTextEditor::Cursor c( m_view->cursorPosition() );
00677
00678 m_commandRange.endLine = c.line();
00679 m_commandRange.endColumn = doc()->lineLength( c.line() );
00680
00681 if ( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
00682 m_commandRange.startLine = c.line();
00683 m_commandRange.startColumn = c.column();
00684 }
00685
00686 bool linewise = ( m_viInputModeManager->getCurrentViMode() == VisualMode
00687 || m_viInputModeManager->getCurrentViMode() == VisualLineMode );
00688
00689 bool r = deleteRange( m_commandRange, linewise );
00690
00691 if ( !linewise ) {
00692 c.setColumn( doc()->lineLength( c.line() )-1 );
00693 } else {
00694 c.setLine( m_commandRange.startLine-1 );
00695 c.setColumn( m_commandRange.startColumn );
00696 }
00697
00698
00699 if ( c.line() < 0 ) {
00700 c.setLine( 0 );
00701 }
00702 if ( c.column() > doc()->lineLength( c.line() )-1 ) {
00703 c.setColumn( doc()->lineLength( c.line() )-1 );
00704 }
00705 if ( c.column() < 0 ) {
00706 c.setColumn( 0 );
00707 }
00708
00709 updateCursor( c );
00710
00711 return r;
00712 }
00713
00714 bool KateViNormalMode::commandMakeLowercase()
00715 {
00716 KTextEditor::Cursor c( m_view->cursorPosition() );
00717
00718 int line1 = m_commandRange.startLine;
00719 int line2 = m_commandRange.endLine;
00720
00721 if ( line1 == line2 ) {
00722 int endColumn = ( m_commandRange.endColumn > c.column() ) ? m_commandRange.endColumn : c.column();
00723 int startColumn = ( m_commandRange.startColumn < c.column() ) ? m_commandRange.startColumn : c.column();
00724 if ( m_commandRange.isInclusive() )
00725 endColumn++;
00726
00727 KTextEditor::Range range( KTextEditor::Cursor( c.line(), startColumn ), KTextEditor::Cursor( c.line(), endColumn ) );
00728 doc()->replaceText( range, getLine().mid( startColumn, endColumn-startColumn ).toLower() );
00729 }
00730 else {
00731 QString s;
00732 for ( int i = ( line1 < line2 ? line1 : line2 ); i <= ( line1 < line2 ? line2 : line1 ); i++ ) {
00733 s.append( doc()->line( i ).toLower() + '\n' );
00734 }
00735
00736
00737 s.chop( 1 );
00738
00739 KTextEditor::Range range( KTextEditor::Cursor( c.line(), 0 ),
00740 KTextEditor::Cursor( line2, doc()->lineLength( line2 ) ) );
00741
00742 doc()->replaceText( range, s );
00743 }
00744
00745 updateCursor( c );
00746
00747 return true;
00748 }
00749
00750 bool KateViNormalMode::commandMakeLowercaseLine()
00751 {
00752 KTextEditor::Cursor c( m_view->cursorPosition() );
00753
00754 m_commandRange.startLine = c.line();
00755 m_commandRange.endLine = c.line();
00756 m_commandRange.startColumn = 0;
00757 m_commandRange.endColumn = doc()->lineLength( c.line() );
00758
00759 return commandMakeLowercase();
00760 }
00761
00762 bool KateViNormalMode::commandMakeUppercase()
00763 {
00764 KTextEditor::Cursor c( m_view->cursorPosition() );
00765
00766 int line1 = m_commandRange.startLine;
00767 int line2 = m_commandRange.endLine;
00768
00769 if ( line1 == line2 ) {
00770 int endColumn = ( m_commandRange.endColumn > c.column() ) ? m_commandRange.endColumn : c.column();
00771 int startColumn = ( m_commandRange.startColumn < c.column() ) ? m_commandRange.startColumn : c.column();
00772 if ( m_commandRange.isInclusive() )
00773 endColumn++;
00774
00775 KTextEditor::Range range( KTextEditor::Cursor( c.line(), startColumn ), KTextEditor::Cursor( c.line(), endColumn ) );
00776 doc()->replaceText( range, getLine().mid( startColumn, endColumn-startColumn ).toUpper() );
00777 }
00778 else {
00779 QString s;
00780 for ( int i = ( line1 < line2 ? line1 : line2 ); i <= ( line1 < line2 ? line2 : line1 ); i++ ) {
00781 s.append( doc()->line( i ).toUpper() + '\n' );
00782 }
00783
00784
00785 s.chop( 1 );
00786
00787 KTextEditor::Range range( KTextEditor::Cursor( c.line(), 0 ),
00788 KTextEditor::Cursor( line2, doc()->lineLength( line2 ) ) );
00789
00790 doc()->replaceText( range, s );
00791 }
00792
00793 updateCursor( c );
00794
00795 return true;
00796 }
00797
00798 bool KateViNormalMode::commandMakeUppercaseLine()
00799 {
00800 KTextEditor::Cursor c( m_view->cursorPosition() );
00801
00802 m_commandRange.startLine = c.line();
00803 m_commandRange.endLine = c.line();
00804 m_commandRange.startColumn = 0;
00805 m_commandRange.endColumn = doc()->lineLength( c.line() );
00806
00807 return commandMakeUppercase();
00808 }
00809
00810 bool KateViNormalMode::commandChangeCase()
00811 {
00812 QString text;
00813 KTextEditor::Range range;
00814 KTextEditor::Cursor c( m_view->cursorPosition() );
00815
00816
00817 if ( m_viInputModeManager->getCurrentViMode() == VisualMode ) {
00818 KTextEditor::Cursor c2 = m_viInputModeManager->getViVisualMode()->getStart();
00819
00820 if ( c2 > c ) {
00821 c2.setColumn( c2.column()+1 );
00822 } else {
00823 c.setColumn( c.column()+1 );
00824 }
00825
00826 range.setRange( c, c2 );
00827
00828
00829 } else if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
00830 KTextEditor::Cursor c2 = m_viInputModeManager->getViVisualMode()->getStart();
00831
00832 if ( c2 > c ) {
00833 c2.setColumn( doc()->lineLength( c2.line() ) );
00834 c.setColumn( 0 );
00835 } else {
00836 c.setColumn( doc()->lineLength( c.line() ) );
00837 c2.setColumn( 0 );
00838 }
00839
00840 range.setRange( c, c2 );
00841
00842
00843 } else {
00844 KTextEditor::Cursor c2 = c;
00845 c2.setColumn( c.column()+getCount() );
00846
00847 if ( c2.column() > doc()->lineLength( c.line() ) ) {
00848 c2.setColumn( doc()->lineLength( c.line() ) );
00849 }
00850
00851 range.setRange( c, c2 );
00852 }
00853
00854
00855 text = doc()->text ( range );
00856
00857
00858 for ( int i = 0; i < text.length(); i++ ) {
00859 if ( text.at(i).isUpper() ) {
00860 text[i] = text.at(i).toLower();
00861 } else if ( text.at(i).isLower() ) {
00862 text[i] = text.at(i).toUpper();
00863 }
00864 }
00865
00866
00867 doc()->replaceText( range, text );
00868
00869
00870
00871 if ( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
00872 updateCursor( range.end() );
00873 } else {
00874 updateCursor( range.start() );
00875 }
00876
00877 return true;
00878 }
00879
00880 bool KateViNormalMode::commandOpenNewLineUnder()
00881 {
00882 KTextEditor::Cursor c( m_view->cursorPosition() );
00883
00884 c.setColumn( getLine().length() );
00885 updateCursor( c );
00886
00887 for ( unsigned int i = 0; i < getCount(); i++ ) {
00888 doc()->newLine( m_view );
00889 }
00890
00891 startInsertMode();
00892 m_viewInternal->repaint ();
00893
00894 return true;
00895 }
00896
00897 bool KateViNormalMode::commandOpenNewLineOver()
00898 {
00899 KTextEditor::Cursor c( m_view->cursorPosition() );
00900
00901 if ( c.line() == 0 ) {
00902 for (unsigned int i = 0; i < getCount(); i++ ) {
00903 doc()->insertLine( 0, QString() );
00904 }
00905 c.setColumn( 0 );
00906 c.setLine( 0 );
00907 updateCursor( c );
00908 } else {
00909 c.setLine( c.line()-1 );
00910 c.setColumn( getLine( c.line() ).length() );
00911 updateCursor( c );
00912 for ( unsigned int i = 0; i < getCount(); i++ ) {
00913 doc()->newLine( m_view );
00914 }
00915
00916 if ( getCount() > 1 ) {
00917 c = m_view->cursorPosition();
00918 c.setLine( c.line()-(getCount()-1 ) );
00919 updateCursor( c );
00920 }
00921
00922 }
00923
00924 startInsertMode();
00925 m_viewInternal->repaint ();
00926
00927 return true;
00928 }
00929
00930 bool KateViNormalMode::commandJoinLines()
00931 {
00932 KTextEditor::Cursor c( m_view->cursorPosition() );
00933
00934 int n = getCount();
00935
00936
00937 if ( m_commandRange.startLine != -1 && m_commandRange.endLine != -1 ) {
00938 c.setLine ( m_commandRange.startLine );
00939 n = m_commandRange.endLine-m_commandRange.startLine;
00940 }
00941
00942
00943 if ( n > doc()->lines()-1-c.line() ) {
00944 n = doc()->lines()-1-c.line();
00945 }
00946
00947 doc()->joinLines( c.line(), c.line()+n );
00948
00949 return true;
00950 }
00951
00952 bool KateViNormalMode::commandChange()
00953 {
00954 KTextEditor::Cursor c( m_view->cursorPosition() );
00955
00956 bool linewise = ( m_commandRange.startLine != m_commandRange.endLine
00957 && m_viInputModeManager->getCurrentViMode() != VisualMode );
00958
00959 doc()->editStart();
00960 commandDelete();
00961
00962
00963 if ( linewise ) {
00964 doc()->insertLine( m_commandRange.startLine, QString() );
00965 c.setLine( m_commandRange.startLine );
00966 updateCursor( c );
00967 }
00968 doc()->editEnd();
00969
00970 commandEnterInsertMode();
00971
00972 return true;
00973 }
00974
00975 bool KateViNormalMode::commandChangeToEOL()
00976 {
00977 commandDeleteToEOL();
00978 commandEnterInsertModeAppend();
00979
00980 return true;
00981 }
00982
00983 bool KateViNormalMode::commandChangeLine()
00984 {
00985 KTextEditor::Cursor c( m_view->cursorPosition() );
00986 c.setColumn( 0 );
00987 updateCursor( c );
00988
00989 doc()->editStart();
00990
00991
00992 if ( getCount() >= 2 ) {
00993 KateViRange r( c.line(), 0, c.line()+getCount()-2, 0, ViMotion::InclusiveMotion );
00994 deleteRange( r );
00995 }
00996
00997
00998 KateViRange r( c.line(), c.column(), c.line(), doc()->lineLength( c.line() )-1,
00999 ViMotion::InclusiveMotion );
01000 deleteRange( r, false, true );
01001 doc()->editEnd();
01002
01003
01004 commandEnterInsertModeAppend();
01005
01006 return true;
01007 }
01008
01009 bool KateViNormalMode::commandSubstituteChar()
01010 {
01011 if ( commandDeleteChar() ) {
01012 return commandEnterInsertMode();
01013 }
01014
01015 return false;
01016 }
01017
01018 bool KateViNormalMode::commandSubstituteLine()
01019 {
01020 return commandChangeLine();
01021 }
01022
01023 bool KateViNormalMode::commandYank()
01024 {
01025 KTextEditor::Cursor c( m_view->cursorPosition() );
01026
01027 bool r = false;
01028 QString yankedText;
01029
01030 bool linewise = ( m_commandRange.startLine != m_commandRange.endLine
01031 && m_viInputModeManager->getCurrentViMode() != VisualMode );
01032
01033 yankedText = getRange( m_commandRange, linewise );
01034
01035 fillRegister( getChosenRegister( '0' ), yankedText );
01036
01037 return r;
01038 }
01039
01040 bool KateViNormalMode::commandYankLine()
01041 {
01042 KTextEditor::Cursor c( m_view->cursorPosition() );
01043 QString lines;
01044 int linenum = c.line();
01045
01046 for ( unsigned int i = 0; i < getCount(); i++ ) {
01047 lines.append( getLine( linenum + i ) + '\n' );
01048 }
01049 fillRegister( getChosenRegister( '0' ), lines );
01050
01051 return true;
01052 }
01053
01054 bool KateViNormalMode::commandYankToEOL()
01055 {
01056 return false;
01057 }
01058
01059
01060
01061 bool KateViNormalMode::commandPaste()
01062 {
01063 KTextEditor::Cursor c( m_view->cursorPosition() );
01064 KTextEditor::Cursor cAfter = c;
01065 QChar reg = getChosenRegister( m_defaultRegister );
01066
01067 QString textToInsert = getRegisterContent( reg );
01068
01069 if ( getCount() > 1 ) {
01070 QString temp = textToInsert;
01071 for ( unsigned int i = 1; i < getCount(); i++ ) {
01072 textToInsert.append( temp );
01073 }
01074 }
01075
01076 if ( textToInsert.indexOf('\n') != -1 ) {
01077 textToInsert.chop( 1 );
01078 c.setColumn( getLine().length() );
01079 textToInsert.prepend( QChar( '\n' ) );
01080
01081 cAfter.setLine( cAfter.line()+1 );
01082 } else {
01083 if ( getLine( c.line() ).length() > 0 ) {
01084 c.setColumn( c.column()+1 );
01085 }
01086
01087 cAfter.setColumn( cAfter.column() + textToInsert.length() );
01088 }
01089
01090 doc()->insertText( c, textToInsert );
01091
01092 updateCursor( cAfter );
01093
01094 return true;
01095 }
01096
01097
01098
01099 bool KateViNormalMode::commandPasteBefore()
01100 {
01101 KTextEditor::Cursor c( m_view->cursorPosition() );
01102 KTextEditor::Cursor cAfter = c;
01103 QChar reg = getChosenRegister( m_defaultRegister );
01104
01105 QString textToInsert = getRegisterContent( reg );
01106
01107 if ( getCount() > 1 ) {
01108 QString temp = textToInsert;
01109 for ( unsigned int i = 1; i < getCount(); i++ ) {
01110 textToInsert.append( temp );
01111 }
01112 }
01113
01114 if ( textToInsert.indexOf('\n') != -1 ) {
01115 c.setColumn( 0 );
01116 } else {
01117 cAfter.setColumn( cAfter.column()+textToInsert.length()-1 );
01118 }
01119
01120 doc()->insertText( c, textToInsert );
01121
01122 updateCursor( cAfter );
01123
01124 return true;
01125 }
01126
01127 bool KateViNormalMode::commandDeleteChar()
01128 {
01129 KTextEditor::Cursor c( m_view->cursorPosition() );
01130 KateViRange r( c.line(), c.column(), c.line(), c.column()+getCount(), ViMotion::ExclusiveMotion );
01131
01132 if ( m_commandRange.startLine != -1 && m_commandRange.startColumn != -1 ) {
01133 r = m_commandRange;
01134 } else {
01135 if ( r.endColumn > doc()->lineLength( r.startLine ) ) {
01136 r.endColumn = doc()->lineLength( r.startLine );
01137 }
01138 }
01139
01140
01141 bool linewise = m_viInputModeManager->getCurrentViMode() == VisualLineMode;
01142
01143 return deleteRange( r, linewise );
01144 }
01145
01146 bool KateViNormalMode::commandDeleteCharBackward()
01147 {
01148 KTextEditor::Cursor c( m_view->cursorPosition() );
01149
01150 KateViRange r( c.line(), c.column()-getCount(), c.line(), c.column(), ViMotion::ExclusiveMotion );
01151
01152 if ( m_commandRange.startLine != -1 && m_commandRange.startColumn != -1 ) {
01153 r = m_commandRange;
01154 } else {
01155 if ( r.startColumn < 0 ) {
01156 r.startColumn = 0;
01157 }
01158 }
01159
01160
01161 bool linewise = m_viInputModeManager->getCurrentViMode() == VisualLineMode;
01162
01163 return deleteRange( r, linewise );
01164 }
01165
01166 bool KateViNormalMode::commandReplaceCharacter()
01167 {
01168 KTextEditor::Cursor c1( m_view->cursorPosition() );
01169 KTextEditor::Cursor c2( m_view->cursorPosition() );
01170
01171 c2.setColumn( c2.column()+1 );
01172
01173 bool r = doc()->replaceText( KTextEditor::Range( c1, c2 ), m_keys.right( 1 ) );
01174
01175 updateCursor( c1 );
01176
01177 return r;
01178 }
01179
01180 bool KateViNormalMode::commandSwitchToCmdLine()
01181 {
01182 m_view->switchToCmdLine();
01183 return true;
01184 }
01185
01186 bool KateViNormalMode::commandSearch()
01187 {
01188 m_view->find();
01189 return true;
01190 }
01191
01192 bool KateViNormalMode::commandUndo()
01193 {
01194 doc()->undo();
01195 return true;
01196 }
01197
01198 bool KateViNormalMode::commandRedo()
01199 {
01200 doc()->redo();
01201 return true;
01202 }
01203
01204 bool KateViNormalMode::commandSetMark()
01205 {
01206 KTextEditor::Cursor c( m_view->cursorPosition() );
01207
01208 KateSmartCursor *cursor = doc()->smartManager()->newSmartCursor( c );
01209
01210 m_marks->insert( m_keys.at( m_keys.size()-1 ), cursor );
01211 kDebug( 13070 ) << "set mark at (" << c.line() << "," << c.column() << ")";
01212
01213 return true;
01214 }
01215
01216 bool KateViNormalMode::commandFindPrev()
01217 {
01218 m_view->findPrevious();
01219
01220 return true;
01221 }
01222
01223 bool KateViNormalMode::commandFindNext()
01224 {
01225 m_view->findNext();
01226
01227 return true;
01228 }
01229
01230 bool KateViNormalMode::commandIndentLine()
01231 {
01232 KTextEditor::Cursor c( m_view->cursorPosition() );
01233
01234 for ( unsigned int i = 0; i < getCount(); i++ ) {
01235 doc()->indent( m_view, c.line()+i, 1 );
01236 }
01237
01238 return true;
01239 }
01240
01241 bool KateViNormalMode::commandUnindentLine()
01242 {
01243 KTextEditor::Cursor c( m_view->cursorPosition() );
01244
01245 for ( unsigned int i = 0; i < getCount(); i++ ) {
01246 doc()->indent( m_view, c.line()+i, -1 );
01247 }
01248
01249 return true;
01250 }
01251
01252 bool KateViNormalMode::commandIndentLines()
01253 {
01254 KTextEditor::Cursor c( m_view->cursorPosition() );
01255
01256 m_commandRange.normalize();
01257
01258 int line1 = m_commandRange.startLine;
01259 int line2 = m_commandRange.endLine;
01260
01261 doc()->editStart();
01262 for ( int i = line1; i <= line2; i++ ) {
01263 doc()->indent( m_view, i, 1 );
01264 }
01265 doc()->editEnd();
01266
01267 return true;
01268 }
01269
01270 bool KateViNormalMode::commandUnindentLines()
01271 {
01272 KTextEditor::Cursor c( m_view->cursorPosition() );
01273
01274 m_commandRange.normalize();
01275
01276 int line1 = m_commandRange.startLine;
01277 int line2 = m_commandRange.endLine;
01278
01279 doc()->editStart();
01280 for ( int i = line1; i <= line2; i++ ) {
01281 doc()->indent( m_view, i, -1 );
01282 }
01283 doc()->editEnd();
01284
01285 return true;
01286 }
01287
01288 bool KateViNormalMode::commandScrollPageDown()
01289 {
01290 m_view->pageDown();
01291
01292 return true;
01293 }
01294
01295 bool KateViNormalMode::commandScrollPageUp()
01296 {
01297 m_view->pageUp();
01298
01299 return true;
01300 }
01301
01302 bool KateViNormalMode::commandAbort()
01303 {
01304 reset();
01305 return true;
01306 }
01307
01308 bool KateViNormalMode::commandPrintCharacterCode()
01309 {
01310 QChar ch = getCharUnderCursor();
01311
01312 if ( ch == QChar::Null ) {
01313 message( QString( "NUL" ) );
01314 } else {
01315
01316 int code = ch.unicode();
01317
01318 message( QString("<%1> %2, Hex %3, Octal %4")
01319 .arg( ch )
01320 .arg( code )
01321 .arg( code, 0, 16 )
01322 .arg( code, 3, 8, QChar('0') ) );
01323 }
01324
01325 return true;
01326 }
01327
01328 bool KateViNormalMode::commandRepeatLastChange()
01329 {
01330 resetParser();
01331 m_viInputModeManager->repeatLastChange();
01332
01333 return true;
01334 }
01335
01336 bool KateViNormalMode::commandAlignLine()
01337 {
01338 const int line = m_view->cursorPosition().line();
01339 KTextEditor::Range alignRange( KTextEditor::Cursor(line, 0), KTextEditor::Cursor(line, 0) );
01340
01341 doc()->align( m_view, alignRange );
01342
01343 return true;
01344 }
01345
01346 bool KateViNormalMode::commandAlignLines()
01347 {
01348 KTextEditor::Cursor c( m_view->cursorPosition() );
01349 m_commandRange.normalize();
01350
01351 KTextEditor::Cursor start(m_commandRange.startLine, 0);
01352 KTextEditor::Cursor end(m_commandRange.endLine, 0);
01353
01354 doc()->align( m_view, KTextEditor::Range( start, end ) );
01355
01356 return true;
01357 }
01358
01360
01362
01363 KateViRange KateViNormalMode::motionDown()
01364 {
01365 return goLineDown();
01366 }
01367
01368
01369 KateViRange KateViNormalMode::motionUp()
01370 {
01371 return goLineUp();
01372 }
01373
01374 KateViRange KateViNormalMode::motionLeft()
01375 {
01376 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01377 m_stickyColumn = -1;
01378 KateViRange r( cursor.line(), cursor.column(), ViMotion::ExclusiveMotion );
01379 r.endColumn -= getCount();
01380
01381 return r;
01382 }
01383
01384 KateViRange KateViNormalMode::motionRight()
01385 {
01386 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01387 m_stickyColumn = -1;
01388 KateViRange r( cursor.line(), cursor.column(), ViMotion::ExclusiveMotion );
01389 r.endColumn += getCount();
01390
01391 return r;
01392 }
01393
01394 KateViRange KateViNormalMode::motionToEOL()
01395 {
01396 m_stickyColumn = -1;
01397 KTextEditor::Cursor c( m_view->cursorPosition() );
01398 KateViRange r( c.line(), getLine().length()-1, ViMotion::InclusiveMotion );
01399
01400 return r;
01401 }
01402
01403 KateViRange KateViNormalMode::motionToColumn0()
01404 {
01405 m_stickyColumn = -1;
01406 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01407 KateViRange r( cursor.line(), 0, ViMotion::ExclusiveMotion );
01408
01409 return r;
01410 }
01411
01412 KateViRange KateViNormalMode::motionToFirstCharacterOfLine()
01413 {
01414 m_stickyColumn = -1;
01415
01416 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01417 QRegExp nonSpace( "\\S" );
01418 int c = getLine().indexOf( nonSpace );
01419
01420 KateViRange r( cursor.line(), c, ViMotion::ExclusiveMotion );
01421
01422 return r;
01423 }
01424
01425 KateViRange KateViNormalMode::motionFindChar()
01426 {
01427 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01428 QString line = getLine();
01429
01430 int matchColumn = cursor.column();
01431
01432 for ( unsigned int i = 0; i < getCount(); i++ ) {
01433 matchColumn = line.indexOf( m_keys.right( 1 ), matchColumn+1 );
01434 if ( matchColumn == -1 )
01435 break;
01436 }
01437
01438 KateViRange r;
01439
01440 r.startColumn = cursor.column();
01441 r.startLine = cursor.line();
01442 r.endColumn = matchColumn;
01443 r.endLine = cursor.line();
01444
01445 return r;
01446 }
01447
01448 KateViRange KateViNormalMode::motionFindCharBackward()
01449 {
01450 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01451 QString line = getLine();
01452
01453 int matchColumn = -1;
01454
01455 unsigned int hits = 0;
01456 int i = cursor.column()-1;
01457
01458 while ( hits != getCount() && i >= 0 ) {
01459 if ( line.at( i ) == m_keys.at( m_keys.size()-1 ) )
01460 hits++;
01461
01462 if ( hits == getCount() )
01463 matchColumn = i;
01464
01465 i--;
01466 }
01467
01468 KateViRange r;
01469
01470 r.endColumn = matchColumn;
01471 r.endLine = cursor.line();
01472
01473 return r;
01474 }
01475
01476 KateViRange KateViNormalMode::motionToChar()
01477 {
01478 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01479 QString line = getLine();
01480
01481 int matchColumn = cursor.column()+1;
01482
01483 for ( unsigned int i = 0; i < getCount(); i++ ) {
01484 matchColumn = line.indexOf( m_keys.right( 1 ), matchColumn+1 );
01485 if ( matchColumn == -1 )
01486 break;
01487 }
01488
01489 KateViRange r;
01490
01491 r.endColumn = matchColumn-1;
01492 r.endLine = cursor.line();
01493
01494 return r;
01495 }
01496
01497 KateViRange KateViNormalMode::motionToCharBackward()
01498 {
01499 KTextEditor::Cursor cursor ( m_view->cursorPosition() );
01500 QString line = getLine();
01501
01502 int matchColumn = -1;
01503
01504 unsigned int hits = 0;
01505 int i = cursor.column()-2;
01506
01507 while ( hits != getCount() && i >= 0 ) {
01508 if ( line.at( i ) == m_keys.at( m_keys.size()-1 ) )
01509 hits++;
01510
01511 if ( hits == getCount() )
01512 matchColumn = i;
01513
01514 i--;
01515 }
01516
01517 KateViRange r;
01518
01519 r.endColumn = matchColumn+1;
01520 r.endLine = cursor.line();
01521
01522 return r;
01523 }
01524
01525 KateViRange KateViNormalMode::motionToLineFirst()
01526 {
01527 KateViRange r( getCount()-1, 0, ViMotion::InclusiveMotion );
01528 m_stickyColumn = -1;
01529
01530 if ( r.endLine > doc()->lines() - 1 ) {
01531 r.endLine = doc()->lines() - 1;
01532 }
01533 r.jump = true;
01534
01535 return r;
01536 }
01537
01538 KateViRange KateViNormalMode::motionToLineLast()
01539 {
01540 KateViRange r( doc()->lines()-1, 0, ViMotion::InclusiveMotion );
01541 m_stickyColumn = -1;
01542
01543
01544 if ( m_count != 0 ) {
01545 r.endLine = m_count-1;
01546 }
01547
01548 if ( r.endLine > doc()->lines() - 1 ) {
01549 r.endLine = doc()->lines() - 1;
01550 }
01551 r.jump = true;
01552
01553 return r;
01554 }
01555
01556 KateViRange KateViNormalMode::motionToScreenColumn()
01557 {
01558 m_stickyColumn = -1;
01559
01560 KTextEditor::Cursor c( m_view->cursorPosition() );
01561
01562 int column = getCount()-1;
01563
01564 if ( doc()->lineLength( c.line() )-1 < (int)getCount()-1 ) {
01565 column = doc()->lineLength( c.line() )-1;
01566 }
01567
01568 return KateViRange( c.line(), column, ViMotion::ExclusiveMotion );
01569 }
01570
01571 KateViRange KateViNormalMode::motionToMark()
01572 {
01573 KateViRange r;
01574
01575 QChar reg = m_keys.at( m_keys.size()-1 );
01576
01577
01578 if ( reg == '`' ) {
01579 reg = '\'';
01580 }
01581
01582 KTextEditor::SmartCursor* cursor;
01583 if ( m_marks->contains( reg ) ) {
01584 cursor = m_marks->value( reg );
01585 r.endLine = cursor->line();
01586 r.endColumn = cursor->column();
01587 } else {
01588 error(QString("Mark not set: ") + m_keys.right( 1 ) );
01589 r.valid = false;
01590 }
01591
01592 r.jump = true;
01593
01594 return r;
01595 }
01596
01597 KateViRange KateViNormalMode::motionToMarkLine()
01598 {
01599 KateViRange r = motionToMark();
01600 r.endColumn = 0;
01601
01602 r.jump = true;
01603
01604 return r;
01605 }
01606
01607 KateViRange KateViNormalMode::motionToMatchingItem()
01608 {
01609 KateViRange r;
01610 KTextEditor::Cursor c( m_view->cursorPosition() );
01611 int lines = doc()->lines();
01612 QString l = getLine();
01613 int n1 = l.indexOf( m_matchItemRegex, c.column() );
01614 int n2;
01615
01616 if ( n1 == -1 ) {
01617 r.valid = false;
01618 return r;
01619 } else {
01620 n2 = l.indexOf( QRegExp( "\\s|$" ), n1 );
01621 }
01622
01623
01624 QString item = l.mid( n1, n2-n1 );
01625
01626
01627 if ( QString("{}()[]").indexOf( item ) != -1 ) {
01628
01629
01630 c.setColumn( n1+1 );
01631 updateCursor( c );
01632
01633
01634 c = m_viewInternal->findMatchingBracket();
01635
01636 if ( c > m_view->cursorPosition() ) {
01637 c.setColumn( c.column()-1 );
01638 }
01639 } else {
01640 int toFind = 1;
01641
01642
01643
01644 QString matchingItem = m_matchingItems[ item ];
01645
01646 int line = c.line();
01647 int column = n2-item.length();
01648 bool reverse = false;
01649
01650 if ( matchingItem.left( 1 ) == "-" ) {
01651 matchingItem.remove( 0, 1 );
01652 reverse = true;
01653 }
01654
01655
01656 if ( column == 0 && reverse ) {
01657 column -= item.length();
01658 }
01659
01660 int itemIdx;
01661 int matchItemIdx;
01662
01663 while ( toFind > 0 ) {
01664 if ( !reverse ) {
01665 itemIdx = l.indexOf( item, column );
01666 matchItemIdx = l.indexOf( matchingItem, column );
01667
01668 if ( itemIdx != -1 && ( matchItemIdx == -1 || itemIdx < matchItemIdx ) ) {
01669 toFind++;
01670 }
01671 } else {
01672 itemIdx = l.lastIndexOf( item, column-1 );
01673 matchItemIdx = l.lastIndexOf( matchingItem, column-1 );
01674
01675 if ( itemIdx != -1 && ( matchItemIdx == -1 || itemIdx > matchItemIdx ) ) {
01676 toFind++;
01677 }
01678 }
01679
01680 if ( matchItemIdx != -1 || itemIdx != -1 ) {
01681 if ( !reverse ) {
01682 column = qMin( (unsigned int)itemIdx, (unsigned int)matchItemIdx );
01683 } else {
01684 column = qMax( itemIdx, matchItemIdx );
01685 }
01686 }
01687
01688 if ( matchItemIdx != -1 ) {
01689 if ( matchItemIdx == column ) {
01690 toFind--;
01691 c.setLine( line );
01692 c.setColumn( column );
01693 }
01694 } else {
01695 ( reverse) ? line-- : line++;
01696 column = 0;
01697
01698 if ( ( !reverse && line >= lines ) || ( reverse && line < 0 ) ) {
01699 r.valid = false;
01700 break;
01701 } else {
01702 l = getLine( line );
01703 }
01704 }
01705 }
01706 }
01707
01708 r.endLine = c.line();
01709 r.endColumn = c.column();
01710 r.jump = true;
01711
01712 return r;
01713 }
01714
01715 KateViRange KateViNormalMode::motionToNextBraceBlockStart()
01716 {
01717 KateViRange r;
01718
01719 int line = findLineStartingWitchChar( '{', getCount() );
01720
01721 if ( line == -1 ) {
01722 r.valid = false;
01723 return r;
01724 }
01725
01726 r.endLine = line;
01727 r.endColumn = 0;
01728 r.jump = true;
01729
01730 return r;
01731 }
01732
01733 KateViRange KateViNormalMode::motionToPreviousBraceBlockStart()
01734 {
01735 KateViRange r;
01736
01737 int line = findLineStartingWitchChar( '{', getCount(), false );
01738
01739 if ( line == -1 ) {
01740 r.valid = false;
01741 return r;
01742 }
01743
01744 r.endLine = line;
01745 r.endColumn = 0;
01746 r.jump = true;
01747
01748 return r;
01749 }
01750
01751 KateViRange KateViNormalMode::motionToNextBraceBlockEnd()
01752 {
01753 KateViRange r;
01754
01755 int line = findLineStartingWitchChar( '}', getCount() );
01756
01757 if ( line == -1 ) {
01758 r.valid = false;
01759 return r;
01760 }
01761
01762 r.endLine = line;
01763 r.endColumn = 0;
01764 r.jump = true;
01765
01766 return r;
01767 }
01768
01769 KateViRange KateViNormalMode::motionToPreviousBraceBlockEnd()
01770 {
01771 KateViRange r;
01772
01773 int line = findLineStartingWitchChar( '{', getCount(), false );
01774
01775 if ( line == -1 ) {
01776 r.valid = false;
01777 return r;
01778 }
01779
01780 r.endLine = line;
01781 r.endColumn = 0;
01782 r.jump = true;
01783
01784 return r;
01785 }
01786
01788
01790
01791 KateViRange KateViNormalMode::textObjectAWord()
01792 {
01793 KTextEditor::Cursor c( m_view->cursorPosition() );
01794
01795 KTextEditor::Cursor c1 = findPrevWordStart( c.line(), c.column()+1, true );
01796 KTextEditor::Cursor c2( c );
01797
01798 for ( unsigned int i = 0; i < getCount(); i++ ) {
01799 c2 = findNextWordStart( c2.line(), c2.column(), true );
01800 }
01801
01802 c2.setColumn( c2.column()-1 );
01803 KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
01804
01805
01806 if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
01807 r.valid = false;
01808 } else {
01809 r.startLine = c1.line();
01810 r.endLine = c2.line();
01811 r.startColumn = c1.column();
01812 r.endColumn = c2.column();
01813 }
01814
01815 return r;
01816 }
01817
01818 KateViRange KateViNormalMode::textObjectInnerWord()
01819 {
01820 KTextEditor::Cursor c( m_view->cursorPosition() );
01821
01822 KTextEditor::Cursor c1 = findPrevWordStart( c.line(), c.column()+1, true );
01823
01824 KTextEditor::Cursor c2( c.line(), c.column()-1 );
01825
01826 for ( unsigned int i = 0; i < getCount(); i++ ) {
01827 c2 = findWordEnd( c2.line(), c2.column(), true );
01828 }
01829
01830 KateViRange r;
01831
01832
01833 if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
01834 r.valid = false;
01835 } else {
01836 r.startLine = c1.line();
01837 r.endLine = c2.line();
01838 r.startColumn = c1.column();
01839 r.endColumn = c2.column();
01840 }
01841
01842 return r;
01843 }
01844
01845 KateViRange KateViNormalMode::textObjectAWORD()
01846 {
01847 KTextEditor::Cursor c( m_view->cursorPosition() );
01848
01849 KTextEditor::Cursor c1 = findPrevWORDStart( c.line(), c.column()+1, true );
01850 KTextEditor::Cursor c2( c );
01851
01852 for ( unsigned int i = 0; i < getCount(); i++ ) {
01853 c2 = findNextWORDStart( c2.line(), c2.column(), true );
01854 }
01855
01856 KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
01857
01858
01859 if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
01860 r.valid = false;
01861 } else {
01862 r.startLine = c1.line();
01863 r.endLine = c2.line();
01864 r.startColumn = c1.column();
01865 r.endColumn = c2.column();
01866 }
01867
01868 return r;
01869 }
01870
01871 KateViRange KateViNormalMode::textObjectInnerWORD()
01872 {
01873 KTextEditor::Cursor c( m_view->cursorPosition() );
01874
01875 KTextEditor::Cursor c1 = findPrevWORDStart( c.line(), c.column()+1, true );
01876 KTextEditor::Cursor c2( c );
01877
01878 for ( unsigned int i = 0; i < getCount(); i++ ) {
01879 c2 = findWORDEnd( c2.line(), c2.column(), true );
01880 }
01881
01882 KateViRange r;
01883
01884
01885 if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
01886 r.valid = false;
01887 } else {
01888 r.startLine = c1.line();
01889 r.endLine = c2.line();
01890 r.startColumn = c1.column();
01891 r.endColumn = c2.column();
01892 }
01893
01894 return r;
01895 }
01896
01897 KateViRange KateViNormalMode::textObjectAQuoteDouble()
01898 {
01899 return findSurrounding( '"', '"', false );
01900 }
01901
01902 KateViRange KateViNormalMode::textObjectInnerQuoteDouble()
01903 {
01904 return findSurrounding( '"', '"', true );
01905 }
01906
01907 KateViRange KateViNormalMode::textObjectAQuoteSingle()
01908 {
01909 return findSurrounding( '\'', '\'', false );
01910 }
01911
01912 KateViRange KateViNormalMode::textObjectInnerQuoteSingle()
01913 {
01914 return findSurrounding( '\'', '\'', true );
01915 }
01916
01917 KateViRange KateViNormalMode::textObjectAParen()
01918 {
01919 return findSurrounding( '(', ')', false );
01920 }
01921
01922 KateViRange KateViNormalMode::textObjectInnerParen()
01923 {
01924 return findSurrounding( '(', ')', true );
01925 }
01926
01927 KateViRange KateViNormalMode::textObjectABracket()
01928 {
01929 return findSurrounding( '[', ']', false );
01930 }
01931
01932 KateViRange KateViNormalMode::textObjectInnerBracket()
01933 {
01934 return findSurrounding( '[', ']', true );
01935 }
01936
01937
01938
01939 void KateViNormalMode::initializeCommands()
01940 {
01941 m_commands.push_back( new KateViCommand( this, "a", &KateViNormalMode::commandEnterInsertModeAppend, IS_CHANGE ) );
01942 m_commands.push_back( new KateViCommand( this, "A", &KateViNormalMode::commandEnterInsertModeAppendEOL, IS_CHANGE ) );
01943 m_commands.push_back( new KateViCommand( this, "i", &KateViNormalMode::commandEnterInsertMode, IS_CHANGE ) );
01944 m_commands.push_back( new KateViCommand( this, "I", &KateViNormalMode::commandEnterInsertModeBeforeFirstCharacterOfLine, IS_CHANGE ) );
01945 m_commands.push_back( new KateViCommand( this, "v", &KateViNormalMode::commandEnterVisualMode ) );
01946 m_commands.push_back( new KateViCommand( this, "V", &KateViNormalMode::commandEnterVisualLineMode ) );
01947 m_commands.push_back( new KateViCommand( this, "o", &KateViNormalMode::commandOpenNewLineUnder, IS_CHANGE ) );
01948 m_commands.push_back( new KateViCommand( this, "O", &KateViNormalMode::commandOpenNewLineOver, IS_CHANGE ) );
01949 m_commands.push_back( new KateViCommand( this, "J", &KateViNormalMode::commandJoinLines, IS_CHANGE ) );
01950 m_commands.push_back( new KateViCommand( this, "c", &KateViNormalMode::commandChange, IS_CHANGE | NEEDS_MOTION ) );
01951 m_commands.push_back( new KateViCommand( this, "C", &KateViNormalMode::commandChangeToEOL, IS_CHANGE ) );
01952 m_commands.push_back( new KateViCommand( this, "cc", &KateViNormalMode::commandChangeLine, IS_CHANGE ) );
01953 m_commands.push_back( new KateViCommand( this, "s", &KateViNormalMode::commandSubstituteChar, IS_CHANGE ) );
01954 m_commands.push_back( new KateViCommand( this, "S", &KateViNormalMode::commandSubstituteLine, IS_CHANGE ) );
01955 m_commands.push_back( new KateViCommand( this, "dd", &KateViNormalMode::commandDeleteLine, IS_CHANGE ) );
01956 m_commands.push_back( new KateViCommand( this, "d", &KateViNormalMode::commandDelete, IS_CHANGE | NEEDS_MOTION ) );
01957 m_commands.push_back( new KateViCommand( this, "D", &KateViNormalMode::commandDeleteToEOL, IS_CHANGE ) );
01958 m_commands.push_back( new KateViCommand( this, "x", &KateViNormalMode::commandDeleteChar, IS_CHANGE ) );
01959 m_commands.push_back( new KateViCommand( this, "X", &KateViNormalMode::commandDeleteCharBackward, IS_CHANGE ) );
01960 m_commands.push_back( new KateViCommand( this, "gu", &KateViNormalMode::commandMakeLowercase, IS_CHANGE | NEEDS_MOTION ) );
01961 m_commands.push_back( new KateViCommand( this, "guu", &KateViNormalMode::commandMakeLowercaseLine, IS_CHANGE ) );
01962 m_commands.push_back( new KateViCommand( this, "gU", &KateViNormalMode::commandMakeUppercase, IS_CHANGE | NEEDS_MOTION ) );
01963 m_commands.push_back( new KateViCommand( this, "gUU", &KateViNormalMode::commandMakeUppercaseLine, IS_CHANGE ) );
01964 m_commands.push_back( new KateViCommand( this, "y", &KateViNormalMode::commandYank, NEEDS_MOTION ) );
01965 m_commands.push_back( new KateViCommand( this, "yy", &KateViNormalMode::commandYankLine ) );
01966 m_commands.push_back( new KateViCommand( this, "Y", &KateViNormalMode::commandYankToEOL, NEEDS_MOTION ) );
01967 m_commands.push_back( new KateViCommand( this, "p", &KateViNormalMode::commandPaste, IS_CHANGE ) );
01968 m_commands.push_back( new KateViCommand( this, "P", &KateViNormalMode::commandPasteBefore, IS_CHANGE ) );
01969 m_commands.push_back( new KateViCommand( this, "r.", &KateViNormalMode::commandReplaceCharacter, IS_CHANGE | REGEX_PATTERN ) );
01970 m_commands.push_back( new KateViCommand( this, ":", &KateViNormalMode::commandSwitchToCmdLine ) );
01971 m_commands.push_back( new KateViCommand( this, "/", &KateViNormalMode::commandSearch ) );
01972 m_commands.push_back( new KateViCommand( this, "u", &KateViNormalMode::commandUndo) );
01973 m_commands.push_back( new KateViCommand( this, "<c-r>", &KateViNormalMode::commandRedo ) );
01974 m_commands.push_back( new KateViCommand( this, "U", &KateViNormalMode::commandRedo ) );
01975 m_commands.push_back( new KateViCommand( this, "m.", &KateViNormalMode::commandSetMark, REGEX_PATTERN ) );
01976 m_commands.push_back( new KateViCommand( this, "n", &KateViNormalMode::commandFindNext ) );
01977 m_commands.push_back( new KateViCommand( this, "N", &KateViNormalMode::commandFindPrev ) );
01978 m_commands.push_back( new KateViCommand( this, ">>", &KateViNormalMode::commandIndentLine, IS_CHANGE ) );
01979 m_commands.push_back( new KateViCommand( this, "<<", &KateViNormalMode::commandUnindentLine, IS_CHANGE ) );
01980 m_commands.push_back( new KateViCommand( this, ">", &KateViNormalMode::commandIndentLines, IS_CHANGE | NEEDS_MOTION ) );
01981 m_commands.push_back( new KateViCommand( this, "<", &KateViNormalMode::commandUnindentLines, IS_CHANGE | NEEDS_MOTION ) );
01982 m_commands.push_back( new KateViCommand( this, "<c-f>", &KateViNormalMode::commandScrollPageDown ) );
01983 m_commands.push_back( new KateViCommand( this, "<pagedown>", &KateViNormalMode::commandScrollPageDown ) );
01984 m_commands.push_back( new KateViCommand( this, "<c-b>", &KateViNormalMode::commandScrollPageUp ) );
01985 m_commands.push_back( new KateViCommand( this, "<pageup>", &KateViNormalMode::commandScrollPageUp ) );
01986 m_commands.push_back( new KateViCommand( this, "ga", &KateViNormalMode::commandPrintCharacterCode, SHOULD_NOT_RESET ) );
01987 m_commands.push_back( new KateViCommand( this, ".", &KateViNormalMode::commandRepeatLastChange ) );
01988 m_commands.push_back( new KateViCommand( this, "==", &KateViNormalMode::commandAlignLine, IS_CHANGE ) );
01989 m_commands.push_back( new KateViCommand( this, "=", &KateViNormalMode::commandAlignLines, IS_CHANGE | NEEDS_MOTION) );
01990 m_commands.push_back( new KateViCommand( this, "~", &KateViNormalMode::commandChangeCase, IS_CHANGE ) );
01991
01992
01993 m_motions.push_back( new KateViMotion( this, "h", &KateViNormalMode::motionLeft ) );
01994 m_motions.push_back( new KateViMotion( this, "<left>", &KateViNormalMode::motionLeft ) );
01995 m_motions.push_back( new KateViMotion( this, "<backspace>", &KateViNormalMode::motionLeft ) );
01996 m_motions.push_back( new KateViMotion( this, "j", &KateViNormalMode::motionDown ) );
01997 m_motions.push_back( new KateViMotion( this, "<down>", &KateViNormalMode::motionDown ) );
01998 m_motions.push_back( new KateViMotion( this, "k", &KateViNormalMode::motionUp ) );
01999 m_motions.push_back( new KateViMotion( this, "<up>", &KateViNormalMode::motionUp ) );
02000 m_motions.push_back( new KateViMotion( this, "l", &KateViNormalMode::motionRight ) );
02001 m_motions.push_back( new KateViMotion( this, "<right>", &KateViNormalMode::motionRight ) );
02002 m_motions.push_back( new KateViMotion( this, " ", &KateViNormalMode::motionRight ) );
02003 m_motions.push_back( new KateViMotion( this, "$", &KateViNormalMode::motionToEOL ) );
02004 m_motions.push_back( new KateViMotion( this, "<end>", &KateViNormalMode::motionToEOL ) );
02005 m_motions.push_back( new KateViMotion( this, "0", &KateViNormalMode::motionToColumn0 ) );
02006 m_motions.push_back( new KateViMotion( this, "<home>", &KateViNormalMode::motionToColumn0 ) );
02007 m_motions.push_back( new KateViMotion( this, "^", &KateViNormalMode::motionToFirstCharacterOfLine ) );
02008 m_motions.push_back( new KateViMotion( this, "f.", &KateViNormalMode::motionFindChar, REGEX_PATTERN ) );
02009 m_motions.push_back( new KateViMotion( this, "F.", &KateViNormalMode::motionFindCharBackward, REGEX_PATTERN ) );
02010 m_motions.push_back( new KateViMotion( this, "t.", &KateViNormalMode::motionToChar, REGEX_PATTERN ) );
02011 m_motions.push_back( new KateViMotion( this, "T.", &KateViNormalMode::motionToCharBackward, REGEX_PATTERN ) );
02012 m_motions.push_back( new KateViMotion( this, "gg", &KateViNormalMode::motionToLineFirst ) );
02013 m_motions.push_back( new KateViMotion( this, "G", &KateViNormalMode::motionToLineLast ) );
02014 m_motions.push_back( new KateViMotion( this, "w", &KateViNormalMode::motionWordForward ) );
02015 m_motions.push_back( new KateViMotion( this, "W", &KateViNormalMode::motionWORDForward ) );
02016 m_motions.push_back( new KateViMotion( this, "b", &KateViNormalMode::motionWordBackward ) );
02017 m_motions.push_back( new KateViMotion( this, "B", &KateViNormalMode::motionWORDBackward ) );
02018 m_motions.push_back( new KateViMotion( this, "e", &KateViNormalMode::motionToEndOfWord ) );
02019 m_motions.push_back( new KateViMotion( this, "E", &KateViNormalMode::motionToEndOfWORD ) );
02020 m_motions.push_back( new KateViMotion( this, "ge", &KateViNormalMode::motionToEndOfPrevWord ) );
02021 m_motions.push_back( new KateViMotion( this, "gE", &KateViNormalMode::motionToEndOfPrevWORD ) );
02022 m_motions.push_back( new KateViMotion( this, "|", &KateViNormalMode::motionToScreenColumn ) );
02023 m_motions.push_back( new KateViMotion( this, "%", &KateViNormalMode::motionToMatchingItem ) );
02024 m_motions.push_back( new KateViMotion( this, "`[a-zA-Z]", &KateViNormalMode::motionToMark, REGEX_PATTERN ) );
02025 m_motions.push_back( new KateViMotion( this, "'[a-zA-Z]", &KateViNormalMode::motionToMarkLine, REGEX_PATTERN ) );
02026 m_motions.push_back( new KateViMotion( this, "[[", &KateViNormalMode::motionToPreviousBraceBlockStart ) );
02027 m_motions.push_back( new KateViMotion( this, "]]", &KateViNormalMode::motionToNextBraceBlockStart ) );
02028 m_motions.push_back( new KateViMotion( this, "[]", &KateViNormalMode::motionToPreviousBraceBlockEnd ) );
02029 m_motions.push_back( new KateViMotion( this, "][", &KateViNormalMode::motionToNextBraceBlockEnd ) );
02030
02031
02032 m_motions.push_back( new KateViMotion( this, "iw", &KateViNormalMode::textObjectInnerWord ) );
02033 m_motions.push_back( new KateViMotion( this, "aw", &KateViNormalMode::textObjectAWord ) );
02034 m_motions.push_back( new KateViMotion( this, "i\"", &KateViNormalMode::textObjectInnerQuoteDouble ) );
02035 m_motions.push_back( new KateViMotion( this, "a\"", &KateViNormalMode::textObjectAQuoteDouble ) );
02036 m_motions.push_back( new KateViMotion( this, "i'", &KateViNormalMode::textObjectInnerQuoteSingle ) );
02037 m_motions.push_back( new KateViMotion( this, "a'", &KateViNormalMode::textObjectAQuoteSingle ) );
02038 m_motions.push_back( new KateViMotion( this, "i[()]", &KateViNormalMode::textObjectInnerParen, REGEX_PATTERN ) );
02039 m_motions.push_back( new KateViMotion( this, "a[()]", &KateViNormalMode::textObjectAParen, REGEX_PATTERN ) );
02040 m_motions.push_back( new KateViMotion( this, "i[\\[\\]]", &KateViNormalMode::textObjectInnerBracket, REGEX_PATTERN ) );
02041 m_motions.push_back( new KateViMotion( this, "a[\\[\\]]", &KateViNormalMode::textObjectABracket, REGEX_PATTERN ) );
02042 }
02043
02044 QRegExp KateViNormalMode::generateMatchingItemRegex()
02045 {
02046 QString pattern("\\[|\\]|\\{|\\}|\\(|\\)|");
02047 QList<QString> keys = m_matchingItems.keys();
02048
02049 for ( int i = 0; i < keys.size(); i++ ) {
02050 QString s = m_matchingItems[ keys[ i ] ];
02051 s = s.replace( QRegExp( "^-" ), QChar() );
02052 s = s.replace( QRegExp( "\\*" ), "\\*" );
02053 s = s.replace( QRegExp( "\\+" ), "\\+" );
02054 s = s.replace( QRegExp( "\\[" ), "\\[" );
02055 s = s.replace( QRegExp( "\\]" ), "\\]" );
02056 s = s.replace( QRegExp( "\\(" ), "\\(" );
02057 s = s.replace( QRegExp( "\\)" ), "\\)" );
02058 s = s.replace( QRegExp( "\\{" ), "\\{" );
02059 s = s.replace( QRegExp( "\\}" ), "\\}" );
02060
02061 pattern.append( s );
02062
02063 if ( i != keys.size()-1 ) {
02064 pattern.append( "|" );
02065 }
02066 }
02067
02068 return QRegExp( pattern );
02069 }