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