• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Kate

  • kde-4.14
  • applications
  • kate
  • part
  • vimode
katevinormalmode.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries and the Kate part.
2  *
3  * Copyright (C) 2008-2009 Erlend Hamberg <ehamberg@gmail.com>
4  * Copyright (C) 2008 Evgeniy Ivanov <powerfox@kde.ru>
5  * Copyright (C) 2009 Paul Gideon Dann <pdgiddie@gmail.com>
6  * Copyright (C) 2011 Svyatoslav Kuzmich <svatoslav1@gmail.com>
7  * Copyright (C) 2012 - 2013 Simon St James <kdedevel@etotheipiplusone.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB. If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include "katevinormalmode.h"
26 #include "katevivisualmode.h"
27 #include "kateviinsertmode.h"
28 #include "kateviinputmodemanager.h"
29 #include "kateviglobal.h"
30 #include "katevikeymapper.h"
31 #include "kateviemulatedcommandbar.h"
32 #include "kateglobal.h"
33 #include "kateconfig.h"
34 #include "katebuffer.h"
35 #include "kateviewhelpers.h"
36 #include <kateundomanager.h>
37 #include <ktexteditor/attribute.h>
38 #include <katecompletionwidget.h>
39 #include "kateconfig.h"
40 
41 #include <QApplication>
42 #include <QList>
43 
44 using KTextEditor::Cursor;
45 using KTextEditor::Range;
46 
47 #define ADDCMD(STR, FUNC, FLGS) m_commands.push_back( \
48  new KateViCommand( this, STR, &KateViNormalMode::FUNC, FLGS ) );
49 
50 #define ADDMOTION(STR, FUNC, FLGS) m_motions.push_back( \
51  new KateViMotion( this, STR, &KateViNormalMode::FUNC, FLGS ) );
52 
53 KateViNormalMode::KateViNormalMode( KateViInputModeManager *viInputModeManager, KateView * view,
54  KateViewInternal * viewInternal ) : KateViModeBase()
55 {
56  m_view = view;
57  m_viewInternal = viewInternal;
58  m_viInputModeManager = viInputModeManager;
59  m_stickyColumn = -1;
60  m_lastMotionWasVisualLineUpOrDown = false;
61  m_currentMotionWasVisualLineUpOrDown = false;
62 
63  // FIXME: make configurable
64  m_extraWordCharacters = "";
65  m_matchingItems["/*"] = "*/";
66  m_matchingItems["*/"] = "-/*";
67 
68  m_matchItemRegex = generateMatchingItemRegex();
69 
70  m_defaultRegister = '"';
71 
72  m_scroll_count_limit = 1000; // Limit of count for scroll commands.
73 
74  initializeCommands();
75  m_pendingResetIsDueToExit = false;
76  m_isRepeatedTFcommand = false;
77  m_lastMotionWasLinewiseInnerBlock = false;
78  m_motionCanChangeWholeVisualModeSelection = false;
79  resetParser(); // initialise with start configuration
80 
81  m_isUndo = false;
82  connect(doc()->undoManager(), SIGNAL(undoStart(KTextEditor::Document*)),
83  this, SLOT(undoBeginning()));
84  connect(doc()->undoManager(), SIGNAL(undoEnd(KTextEditor::Document*)),
85  this, SLOT(undoEnded()));
86 
87  updateYankHighlightAttrib();
88  connect(view, SIGNAL(configChanged()),
89  this, SLOT(updateYankHighlightAttrib()));
90  connect(doc(), SIGNAL(aboutToInvalidateMovingInterfaceContent(KTextEditor::Document*)),
91  this, SLOT(clearYankHighlight()));
92  connect(doc(), SIGNAL(aboutToDeleteMovingInterfaceContent(KTextEditor::Document*)),
93  this, SLOT(aboutToDeleteMovingInterfaceContent()));
94 }
95 
96 KateViNormalMode::~KateViNormalMode()
97 {
98  qDeleteAll( m_commands );
99  qDeleteAll( m_motions) ;
100  qDeleteAll(m_highlightedYanks);
101 }
102 
107 bool KateViNormalMode::handleKeypress( const QKeyEvent *e )
108 {
109  const int keyCode = e->key();
110  const QString text = e->text();
111 
112  // ignore modifier keys alone
113  if ( keyCode == Qt::Key_Shift || keyCode == Qt::Key_Control
114  || keyCode == Qt::Key_Alt || keyCode == Qt::Key_Meta ) {
115  return false;
116  }
117 
118  clearYankHighlight();
119 
120  if ( keyCode == Qt::Key_Escape || (keyCode == Qt::Key_C && e->modifiers() == Qt::ControlModifier) || (keyCode == Qt::Key_BracketLeft && e->modifiers() == Qt::ControlModifier)) {
121  m_view->setCaretStyle( KateRenderer::Block, true );
122  m_pendingResetIsDueToExit = true;
123  // Vim in weird as if we e.g. i<ctrl-o><ctrl-c> it claims (in the status bar) to still be in insert mode,
124  // but behaves as if it's in normal mode. I'm treating the status bar thing as a bug and just exiting
125  // insert mode altogether.
126  m_viInputModeManager->setTemporaryNormalMode(false);
127  reset();
128  return true;
129  }
130 
131  const QChar key = KateViKeyParser::self()->KeyEventToQChar(*e);
132 
133  const QChar lastChar = m_keys.isEmpty() ? QChar::Null : m_keys.at(m_keys.size() - 1);
134  const bool waitingForRegisterOrCharToSearch = this->waitingForRegisterOrCharToSearch();
135 
136  // Use replace caret when reading a character for "r"
137  if ( key == 'r' && !waitingForRegisterOrCharToSearch) {
138  m_view->setCaretStyle( KateRenderer::Underline, true );
139  }
140 
141  m_keysVerbatim.append( KateViKeyParser::self()->decodeKeySequence( key ) );
142 
143  if ( ( keyCode >= Qt::Key_0 && keyCode <= Qt::Key_9 && lastChar != '"' ) // key 0-9
144  && ( m_countTemp != 0 || keyCode != Qt::Key_0 ) // first digit can't be 0
145  && (!waitingForRegisterOrCharToSearch) // Not in the middle of "find char" motions or replacing char.
146  && e->modifiers() == Qt::NoModifier) {
147 
148  m_countTemp *= 10;
149  m_countTemp += keyCode-Qt::Key_0;
150 
151  return true;
152  } else if ( m_countTemp != 0 ) {
153  m_count = getCount() * m_countTemp;
154  m_countTemp = 0;
155  m_iscounted = true;
156 
157  kDebug( 13070 ) << "count = " << getCount();
158  }
159 
160  m_keys.append( key );
161 
162  if (m_viInputModeManager->isRecordingMacro() && key == 'q')
163  {
164  // Need to special case this "finish macro" q, as the "begin macro" q
165  // needs a parameter whereas the finish macro does not.
166  m_viInputModeManager->finishRecordingMacro();
167  resetParser();
168  return true;
169  }
170 
171  if ((key == '/' || key == '?') && !waitingForRegisterOrCharToSearch)
172  {
173  // Special case for "/" and "?": these should be motions, but this is complicated by
174  // the fact that the user must interact with the search bar before the range of the
175  // motion can be determined.
176  // We hack around this by showing the search bar immediately, and, when the user has
177  // finished interacting with it, have the search bar send a "synthetic" keypresses
178  // that will either abort everything (if the search was aborted) or "complete" the motion
179  // otherwise.
180  m_positionWhenIncrementalSearchBegan = m_view->cursorPosition();
181  if (key == '/')
182  {
183  commandSearchForward();
184  }
185  else
186  {
187  commandSearchBackward();
188  }
189  return true;
190  }
191 
192  // Special case: "cw" and "cW" work the same as "ce" and "cE" if the cursor is
193  // on a non-blank. This is because Vim interprets "cw" as change-word, and a
194  // word does not include the following white space. (:help cw in vim)
195  if ( ( m_keys == "cw" || m_keys == "cW" ) && !getCharUnderCursor().isSpace() ) {
196  // Special case of the special case: :-)
197  // If the cursor is at the end of the current word rewrite to "cl"
198  const bool isWORD = (m_keys.at(1) == 'W');
199  const Cursor currentPosition( m_view->cursorPosition() );
200  const Cursor endOfWordOrWORD = (isWORD ? findWORDEnd(currentPosition.line(), currentPosition.column()-1, true) :
201  findWordEnd(currentPosition.line(), currentPosition.column()-1, true));
202 
203  if ( currentPosition == endOfWordOrWORD ) {
204  m_keys = "cl";
205  } else {
206  if (isWORD) {
207  m_keys = "cE";
208  } else {
209  m_keys = "ce";
210  }
211  }
212  }
213 
214  if ( m_keys[ 0 ] == Qt::Key_QuoteDbl ) {
215  if ( m_keys.size() < 2 ) {
216  return true; // waiting for a register
217  }
218  else {
219  QChar r = m_keys[ 1 ].toLower();
220 
221  if ( ( r >= '0' && r <= '9' ) || ( r >= 'a' && r <= 'z' ) ||
222  r == '_' || r == '+' || r == '*' || r == '#' || r == '^' ) {
223  m_register = r;
224  kDebug( 13070 ) << "Register set to " << r;
225  m_keys.clear();
226  return true;
227  }
228  else {
229  resetParser();
230  return true;
231  }
232  }
233  }
234 
235  // if we have any matching commands so far, check which ones still match
236  if ( m_matchingCommands.size() > 0 ) {
237  int n = m_matchingCommands.size()-1;
238 
239  // remove commands not matching anymore
240  for ( int i = n; i >= 0; i-- ) {
241  if ( !m_commands.at( m_matchingCommands.at( i ) )->matches( m_keys ) ) {
242  //kDebug( 13070 ) << "removing " << m_commands.at( m_matchingCommands.at( i ) )->pattern() << ", size before remove is " << m_matchingCommands.size();
243  if ( m_commands.at( m_matchingCommands.at( i ) )->needsMotion() ) {
244  // "cache" command needing a motion for later
245  //kDebug( 13070 ) << "m_motionOperatorIndex set to " << m_motionOperatorIndex;
246  m_motionOperatorIndex = m_matchingCommands.at( i );
247  }
248  m_matchingCommands.remove( i );
249  }
250  }
251 
252  // check if any of the matching commands need a motion/text object, if so
253  // push the current command length to m_awaitingMotionOrTextObject so one
254  // knows where to split the command between the operator and the motion
255  for ( int i = 0; i < m_matchingCommands.size(); i++ ) {
256  if ( m_commands.at( m_matchingCommands.at( i ) )->needsMotion() ) {
257  m_awaitingMotionOrTextObject.push( m_keys.size() );
258  break;
259  }
260  }
261  } else {
262  // go through all registered commands and put possible matches in m_matchingCommands
263  for ( int i = 0; i < m_commands.size(); i++ ) {
264  if ( m_commands.at( i )->matches( m_keys ) ) {
265  m_matchingCommands.push_back( i );
266  if ( m_commands.at( i )->needsMotion() && m_commands.at( i )->pattern().length() == m_keys.size() ) {
267  m_awaitingMotionOrTextObject.push( m_keys.size() );
268  }
269  }
270  }
271  }
272 
273  // this indicates where in the command string one should start looking for a motion command
274  int checkFrom = ( m_awaitingMotionOrTextObject.isEmpty() ? 0 : m_awaitingMotionOrTextObject.top() );
275 
276  // Use operator-pending caret when reading a motion for an operator
277  // in normal mode. We need to check that we are indeed in normal mode
278  // since visual mode inherits from it.
279  if( m_viInputModeManager->getCurrentViMode() == NormalMode &&
280  !m_awaitingMotionOrTextObject.isEmpty() ) {
281  m_view->setCaretStyle( KateRenderer::Half, true );
282  }
283 
284  //kDebug( 13070 ) << "checkFrom: " << checkFrom;
285 
286  // look for matching motion commands from position 'checkFrom'
287  // FIXME: if checkFrom hasn't changed, only motions whose index is in
288  // m_matchingMotions should be checked
289  bool motionExecuted = false;
290  if ( checkFrom < m_keys.size() ) {
291  for ( int i = 0; i < m_motions.size(); i++ ) {
292  //kDebug( 13070 ) << "\tchecking " << m_keys.mid( checkFrom ) << " against " << m_motions.at( i )->pattern();
293  if ( m_motions.at( i )->matches( m_keys.mid( checkFrom ) ) ) {
294  m_lastMotionWasLinewiseInnerBlock = false;
295  //kDebug( 13070 ) << m_keys.mid( checkFrom ) << " matches!";
296  m_matchingMotions.push_back( i );
297 
298  // if it matches exact, we have found the motion command to execute
299  if ( m_motions.at( i )->matchesExact( m_keys.mid( checkFrom ) ) ) {
300  m_currentMotionWasVisualLineUpOrDown = false;
301  motionExecuted = true;
302  if ( checkFrom == 0 ) {
303  // no command given before motion, just move the cursor to wherever
304  // the motion says it should go to
305  KateViRange r = m_motions.at( i )->execute();
306  m_motionCanChangeWholeVisualModeSelection = m_motions.at( i )->canChangeWholeVisualModeSelection();
307 
308  // jump over folding regions since we are just moving the cursor
309  int currLine = m_view->cursorPosition().line();
310  int delta = r.endLine - currLine;
311  int vline = m_view->textFolding().lineToVisibleLine( currLine );
312  r.endLine = m_view->textFolding().visibleLineToLine( qMax (vline+delta, 0) /* ensure we have a valid line */ );
313  if ( r.endLine >= doc()->lines() ) r.endLine = doc()->lines()-1;
314 
315  // make sure the position is valid before moving the cursor there
316  // TODO: can this be simplified? :/
317  if ( r.valid
318  && r.endLine >= 0
319  && ( r.endLine == 0 || r.endLine <= doc()->lines()-1 )
320  && r.endColumn >= 0 ) {
321  if ( r.endColumn >= doc()->lineLength( r.endLine )
322  && doc()->lineLength( r.endLine ) > 0 ) {
323  r.endColumn = doc()->lineLength( r.endLine ) - 1;
324  }
325 
326  kDebug( 13070 ) << "No command given, going to position ("
327  << r.endLine << "," << r.endColumn << ")";
328  goToPos( r );
329 
330  // in the case of VisualMode we need to remember the motion commands as well.
331  if (!m_viInputModeManager->isAnyVisualMode())
332  m_viInputModeManager->clearCurrentChangeLog();
333  } else {
334  kDebug( 13070 ) << "Invalid position: (" << r.endLine << "," << r.endColumn << ")";
335  }
336 
337  resetParser();
338 
339  // if normal mode was started by using Ctrl-O in insert mode,
340  // it's time to go back to insert mode.
341  if (m_viInputModeManager->getTemporaryNormalMode()) {
342  startInsertMode();
343  m_viewInternal->repaint();
344  }
345 
346  m_lastMotionWasVisualLineUpOrDown = m_currentMotionWasVisualLineUpOrDown;
347 
348  break;
349  } else {
350  // execute the specified command and supply the position returned from
351  // the motion
352 
353  m_commandRange = m_motions.at( i )->execute();
354  m_linewiseCommand = m_motions.at( i )->isLineWise();
355 
356  // if we didn't get an explicit start position, use the current cursor position
357  if ( m_commandRange.startLine == -1 ) {
358  Cursor c( m_view->cursorPosition() );
359  m_commandRange.startLine = c.line();
360  m_commandRange.startColumn = c.column();
361  }
362 
363  // special case: When using the "w" motion in combination with an operator and
364  // the last word moved over is at the end of a line, the end of that word
365  // becomes the end of the operated text, not the first word in the next line.
366  if (m_motions.at(i)->pattern() == "w" || m_motions.at(i)->pattern() == "W") {
367  if (m_commandRange.endLine != m_commandRange.startLine &&
368  m_commandRange.endColumn == getFirstNonBlank(m_commandRange.endLine)) {
369  m_commandRange.endLine--;
370  m_commandRange.endColumn = doc()->lineLength(m_commandRange.endLine );
371  }
372  }
373 
374  m_commandWithMotion = true;
375 
376  if ( m_commandRange.valid ) {
377  kDebug( 13070 ) << "Run command" << m_commands.at( m_motionOperatorIndex )->pattern()
378  << "from (" << m_commandRange.startLine << "," << m_commandRange.startColumn << ")"
379  << "to (" << m_commandRange.endLine << "," << m_commandRange.endColumn << ")";
380  executeCommand( m_commands.at( m_motionOperatorIndex ) );
381  } else {
382  kDebug( 13070 ) << "Invalid range: "
383  << "from (" << m_commandRange.startLine << "," << m_commandRange.startColumn << ")"
384  << "to (" << m_commandRange.endLine << "," << m_commandRange.endColumn << ")";
385  }
386 
387  if( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
388  m_view->setCaretStyle( KateRenderer::Block, true );
389  }
390  m_commandWithMotion = false;
391  reset();
392  break;
393  }
394  }
395  }
396  }
397  }
398 
399  if (this->waitingForRegisterOrCharToSearch())
400  {
401  // If we are waiting for a char to search or a new register,
402  // don't translate next character; we need the actual character so that e.g.
403  // 'ab' is translated to 'fb' if the mappings 'a' -> 'f' and 'b' -> something else
404  // exist.
405  m_viInputModeManager->keyMapper()->setDoNotMapNextKeypress();
406  }
407 
408  if (motionExecuted)
409  {
410  return true;
411  }
412 
413  //kDebug( 13070 ) << "'" << m_keys << "' MATCHING COMMANDS: " << m_matchingCommands.size();
414  //kDebug( 13070 ) << "'" << m_keys << "' MATCHING MOTIONS: " << m_matchingMotions.size();
415  //kDebug( 13070 ) << "'" << m_keys << "' AWAITING MOTION OR TO (INDEX): " << ( m_awaitingMotionOrTextObject.isEmpty() ? 0 : m_awaitingMotionOrTextObject.top() );
416 
417  // if we have only one match, check if it is a perfect match and if so, execute it
418  // if it's not waiting for a motion or a text object
419  if ( m_matchingCommands.size() == 1 ) {
420  if ( m_commands.at( m_matchingCommands.at( 0 ) )->matchesExact( m_keys )
421  && !m_commands.at( m_matchingCommands.at( 0 ) )->needsMotion() ) {
422  //kDebug( 13070 ) << "Running command at index " << m_matchingCommands.at( 0 );
423 
424  if( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
425  m_view->setCaretStyle( KateRenderer::Block, true );
426  }
427 
428  KateViCommand *cmd = m_commands.at( m_matchingCommands.at( 0 ) );
429  executeCommand( cmd );
430 
431  // check if reset() should be called. some commands in visual mode should not end visual mode
432  if ( cmd->shouldReset() ) {
433  reset();
434  m_view->setBlockSelection(false);
435  }
436  resetParser();
437 
438  return true;
439  }
440  } else if ( m_matchingCommands.size() == 0 && m_matchingMotions.size() == 0 ) {
441  resetParser();
442  return false;
443  }
444 
445  m_matchingMotions.clear();
446  return false;
447 }
448 
453 void KateViNormalMode::resetParser()
454 {
455 // kDebug( 13070 ) << "***RESET***";
456  m_keys.clear();
457  m_keysVerbatim.clear();
458  m_count = 0;
459  m_oneTimeCountOverride = -1;
460  m_iscounted = false;
461  m_countTemp = 0;
462  m_register = QChar::Null;
463  m_findWaitingForChar = false;
464  m_matchingCommands.clear();
465  m_matchingMotions.clear();
466  m_awaitingMotionOrTextObject.clear();
467  m_motionOperatorIndex = 0;
468 
469  m_commandWithMotion = false;
470  m_linewiseCommand = true;
471  m_deleteCommand = false;
472 
473  m_commandShouldKeepSelection = false;
474 
475  m_currentChangeEndMarker = Cursor::invalid();
476 }
477 
478 // reset the command parser
479 void KateViNormalMode::reset()
480 {
481  resetParser();
482  m_commandRange.startLine = -1;
483  m_commandRange.startColumn = -1;
484 }
485 
486 void KateViNormalMode::beginMonitoringDocumentChanges()
487 {
488  connect(doc(), SIGNAL(textInserted(KTextEditor::Document*,KTextEditor::Range)),
489  this, SLOT(textInserted(KTextEditor::Document*,KTextEditor::Range)));
490  connect(doc(), SIGNAL(textRemoved(KTextEditor::Document*,KTextEditor::Range)),
491  this, SLOT(textRemoved(KTextEditor::Document*,KTextEditor::Range)));
492 }
493 
494 void KateViNormalMode::goToPos( const KateViRange &r )
495 {
496  Cursor c;
497  c.setLine( r.endLine );
498  c.setColumn( r.endColumn );
499 
500  if ( r.jump ) {
501  addCurrentPositionToJumpList();
502  }
503 
504  if ( c.line() >= doc()->lines() ) {
505  c.setLine( doc()->lines()-1 );
506  }
507 
508  updateCursor( c );
509 }
510 
511 void KateViNormalMode::executeCommand( const KateViCommand* cmd )
512 {
513  const ViMode originalViMode = m_viInputModeManager->getCurrentViMode();
514 
515  cmd->execute();
516 
517  // if normal mode was started by using Ctrl-O in insert mode,
518  // it's time to go back to insert mode.
519  if (m_viInputModeManager->getTemporaryNormalMode()) {
520  startInsertMode();
521  m_viewInternal->repaint();
522  }
523 
524  // if the command was a change, and it didn't enter insert mode, store the key presses so that
525  // they can be repeated with '.'
526  if ( m_viInputModeManager->getCurrentViMode() != InsertMode ) {
527  if ( cmd->isChange() && !m_viInputModeManager->isReplayingLastChange() ) {
528  m_viInputModeManager->storeLastChangeCommand();
529  }
530 
531  // when we transition to visual mode, remember the command in the keys history (V, v, ctrl-v, ...)
532  // this will later result in buffer filled with something like this "Vjj>" which we can use later with repeat "."
533  const bool commandSwitchedToVisualMode = ((originalViMode == NormalMode) && m_viInputModeManager->isAnyVisualMode());
534  if (!commandSwitchedToVisualMode)
535  m_viInputModeManager->clearCurrentChangeLog();
536  }
537 
538  // make sure the cursor does not end up after the end of the line
539  Cursor c( m_view->cursorPosition() );
540  if ( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
541  int lineLength = doc()->lineLength( c.line() );
542 
543  if ( c.column() >= lineLength ) {
544  if ( lineLength == 0 ) {
545  c.setColumn( 0 );
546  } else {
547  c.setColumn( lineLength-1 );
548  }
549  }
550  updateCursor( c );
551  }
552 }
553 
554 void KateViNormalMode::addCurrentPositionToJumpList() {
555  m_viInputModeManager->addJump(m_view->cursorPosition());
556 }
557 
559 // COMMANDS AND OPERATORS
561 
566 bool KateViNormalMode::commandEnterInsertMode()
567 {
568  m_stickyColumn = -1;
569  m_viInputModeManager->getViInsertMode()->setCount(getCount());
570  return startInsertMode();
571 }
572 
577 bool KateViNormalMode::commandEnterInsertModeAppend()
578 {
579  Cursor c( m_view->cursorPosition() );
580  c.setColumn( c.column()+1 );
581 
582  // if empty line, the cursor should start at column 0
583  if ( doc()->lineLength( c.line() ) == 0 ) {
584  c.setColumn( 0 );
585  }
586 
587  // cursor should never be in a column > number of columns
588  if ( c.column() > doc()->lineLength( c.line() ) ) {
589  c.setColumn( doc()->lineLength( c.line() ) );
590  }
591 
592  updateCursor( c );
593 
594  m_stickyColumn = -1;
595  m_viInputModeManager->getViInsertMode()->setCount(getCount());
596  return startInsertMode();
597 }
598 
603 bool KateViNormalMode::commandEnterInsertModeAppendEOL()
604 {
605  Cursor c( m_view->cursorPosition() );
606  c.setColumn( doc()->lineLength( c.line() ) );
607  updateCursor( c );
608 
609  m_stickyColumn = -1;
610  m_viInputModeManager->getViInsertMode()->setCount(getCount());
611  return startInsertMode();
612 }
613 
614 bool KateViNormalMode::commandEnterInsertModeBeforeFirstNonBlankInLine()
615 {
616  Cursor cursor( m_view->cursorPosition() );
617  int c = getFirstNonBlank();
618  cursor.setColumn( c );
619  updateCursor( cursor );
620 
621  m_stickyColumn = -1;
622  m_viInputModeManager->getViInsertMode()->setCount(getCount());
623  return startInsertMode();
624 }
625 
630 bool KateViNormalMode::commandEnterInsertModeLast()
631 {
632  Cursor c = m_view->getViInputModeManager()->getMarkPosition( '^' );
633  if ( c.isValid() ) {
634  updateCursor( c );
635  }
636 
637  m_stickyColumn = -1;
638  return startInsertMode();
639 }
640 
641 bool KateViNormalMode::commandEnterVisualLineMode()
642 {
643  if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
644  reset();
645  return true;
646  }
647 
648  return startVisualLineMode();
649 }
650 
651 bool KateViNormalMode::commandEnterVisualBlockMode()
652 {
653  if ( m_viInputModeManager->getCurrentViMode() == VisualBlockMode ) {
654  reset();
655  return true;
656  }
657 
658  return startVisualBlockMode();
659 }
660 
661 bool KateViNormalMode::commandReselectVisual()
662 {
663  // start last visual mode and set start = `< and cursor = `>
664  Cursor c1 = m_view->getViInputModeManager()->getMarkPosition( '<' );
665  Cursor c2 = m_view->getViInputModeManager()->getMarkPosition( '>' );
666 
667  // we should either get two valid cursors or two invalid cursors
668  Q_ASSERT( c1.isValid() == c2.isValid() );
669 
670  if ( c1.isValid() && c2.isValid() ) {
671  m_viInputModeManager->getViVisualMode()->setStart( c1 );
672  bool returnValue = false;
673 
674  switch ( m_viInputModeManager->getViVisualMode()->getLastVisualMode() ) {
675  case VisualMode:
676  returnValue = commandEnterVisualMode();
677  break;
678  case VisualLineMode:
679  returnValue = commandEnterVisualLineMode();
680  break;
681  case VisualBlockMode:
682  returnValue = commandEnterVisualBlockMode();
683  break;
684  default:
685  Q_ASSERT( "invalid visual mode" );
686  }
687  m_viInputModeManager->getViVisualMode()->goToPos(c2);
688  return returnValue;
689  } else {
690  error("No previous visual selection");
691  }
692 
693  return false;
694 }
695 
696 bool KateViNormalMode::commandEnterVisualMode()
697 {
698  if ( m_viInputModeManager->getCurrentViMode() == VisualMode ) {
699  reset();
700  return true;
701  }
702 
703  return startVisualMode();
704 }
705 
706 bool KateViNormalMode::commandToOtherEnd()
707 {
708  if (m_viInputModeManager->isAnyVisualMode()) {
709  m_viInputModeManager->getViVisualMode()->switchStartEnd();
710  return true;
711  }
712 
713  return false;
714 }
715 
716 bool KateViNormalMode::commandEnterReplaceMode()
717 {
718  return startReplaceMode();
719 }
720 
721 bool KateViNormalMode::commandDeleteLine()
722 {
723  Cursor c( m_view->cursorPosition() );
724 
725  KateViRange r;
726 
727  r.startLine = c.line();
728  r.endLine = c.line()+getCount()-1;
729 
730  int column = c.column();
731 
732  bool ret = deleteRange( r, LineWise );
733 
734  c = m_view->cursorPosition();
735  if ( column > doc()->lineLength( c.line() )-1 ) {
736  column = doc()->lineLength( c.line() )-1;
737  }
738  if ( column < 0 ) {
739  column = 0;
740  }
741 
742  if ( c.line() > doc()->lines()-1 ) {
743  c.setLine( doc()->lines()-1 );
744  }
745 
746  c.setColumn( column );
747  m_stickyColumn = -1;
748  updateCursor( c );
749 
750  m_deleteCommand = true;
751  return ret;
752 }
753 
754 bool KateViNormalMode::commandDelete()
755 {
756  m_deleteCommand = true;
757  return deleteRange( m_commandRange, getOperationMode() );
758 }
759 
760 bool KateViNormalMode::commandDeleteToEOL()
761 {
762  Cursor c(m_view->cursorPosition());
763  OperationMode m = CharWise;
764 
765  m_commandRange.endColumn = KateVi::EOL;
766  switch (m_viInputModeManager->getCurrentViMode()) {
767  case NormalMode:
768  m_commandRange.startLine = c.line();
769  m_commandRange.startColumn = c.column();
770  m_commandRange.endLine = c.line() + getCount() - 1;
771  break;
772  case VisualMode:
773  case VisualLineMode:
774  m = LineWise;
775  break;
776  case VisualBlockMode:
777  m_commandRange.normalize();
778  m = Block;
779  break;
780  default:
781  /* InsertMode and ReplaceMode will never call this method. */
782  Q_ASSERT(false);
783  }
784 
785  bool r = deleteRange(m_commandRange, m);
786 
787  switch (m) {
788  case CharWise:
789  c.setColumn(doc()->lineLength(c.line()) - 1);
790  break;
791  case LineWise:
792  c.setLine(m_commandRange.startLine);
793  c.setColumn(getFirstNonBlank(m_commandRange.startLine));
794  break;
795  case Block:
796  c.setLine(m_commandRange.startLine);
797  c.setColumn(m_commandRange.startColumn - 1);
798  break;
799  }
800 
801  // make sure cursor position is valid after deletion
802  if (c.line() < 0) {
803  c.setLine(0);
804  }
805  if (c.line() > doc()->lastLine()) {
806  c.setLine(doc()->lastLine());
807  }
808  if (c.column() > doc()->lineLength(c.line()) - 1) {
809  c.setColumn(doc()->lineLength(c.line()) - 1);
810  }
811  if (c.column() < 0) {
812  c.setColumn(0);
813  }
814 
815  updateCursor(c);
816 
817  m_deleteCommand = true;
818  return r;
819 }
820 
821 bool KateViNormalMode::commandMakeLowercase()
822 {
823  Cursor c = m_view->cursorPosition();
824 
825  OperationMode m = getOperationMode();
826  QString text = getRange( m_commandRange, m );
827  if (m == LineWise)
828  text = text.left(text.size() - 1); // don't need '\n' at the end;
829  QString lowerCase = text.toLower();
830 
831  m_commandRange.normalize();
832  Cursor start( m_commandRange.startLine, m_commandRange.startColumn );
833  Cursor end( m_commandRange.endLine, m_commandRange.endColumn );
834  Range range( start, end );
835 
836  doc()->replaceText( range, lowerCase, m == Block );
837 
838  if (m_viInputModeManager->getCurrentViMode() == NormalMode)
839  updateCursor( start );
840  else
841  updateCursor(c);
842 
843  return true;
844 }
845 
846 bool KateViNormalMode::commandMakeLowercaseLine()
847 {
848  Cursor c( m_view->cursorPosition() );
849 
850  if (doc()->lineLength(c.line()) == 0)
851  {
852  // Nothing to do.
853  return true;
854  }
855 
856  m_commandRange.startLine = c.line();
857  m_commandRange.endLine = c.line() + getCount() - 1;
858  m_commandRange.startColumn = 0;
859  m_commandRange.endColumn = doc()->lineLength( c.line() )-1;
860 
861  return commandMakeLowercase();
862 }
863 
864 bool KateViNormalMode::commandMakeUppercase()
865 {
866  kDebug(13070) << "Heere!";
867  if (!m_commandRange.valid)
868  {
869  kDebug(13070) << "Here2";
870  return false;
871  }
872  Cursor c = m_view->cursorPosition();
873  OperationMode m = getOperationMode();
874  QString text = getRange( m_commandRange, m );
875  if (m == LineWise)
876  text = text.left(text.size() - 1); // don't need '\n' at the end;
877  QString upperCase = text.toUpper();
878 
879  m_commandRange.normalize();
880  Cursor start( m_commandRange.startLine, m_commandRange.startColumn );
881  Cursor end( m_commandRange.endLine, m_commandRange.endColumn );
882  Range range( start, end );
883 
884  doc()->replaceText( range, upperCase, m == Block );
885  if (m_viInputModeManager->getCurrentViMode() == NormalMode)
886  updateCursor( start );
887  else
888  updateCursor(c);
889 
890  return true;
891 }
892 
893 bool KateViNormalMode::commandMakeUppercaseLine()
894 {
895  Cursor c( m_view->cursorPosition() );
896 
897  if (doc()->lineLength(c.line()) == 0)
898  {
899  // Nothing to do.
900  return true;
901  }
902 
903  m_commandRange.startLine = c.line();
904  m_commandRange.endLine = c.line() + getCount() - 1;
905  m_commandRange.startColumn = 0;
906  m_commandRange.endColumn = doc()->lineLength( c.line() )-1;
907 
908  return commandMakeUppercase();
909 }
910 
911 bool KateViNormalMode::commandChangeCase()
912 {
913  switchView();
914  QString text;
915  Range range;
916  Cursor c( m_view->cursorPosition() );
917 
918  // in visual mode, the range is from start position to end position...
919  if ( m_viInputModeManager->getCurrentViMode() == VisualMode
920  || m_viInputModeManager->getCurrentViMode() == VisualBlockMode ) {
921  Cursor c2 = m_viInputModeManager->getViVisualMode()->getStart();
922 
923  if ( c2 > c ) {
924  c2.setColumn( c2.column()+1 );
925  } else {
926  c.setColumn( c.column()+1 );
927  }
928 
929  range.setRange( c, c2 );
930  // ... in visual line mode, the range is from column 0 on the first line to
931  // the line length of the last line...
932  } else if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
933  Cursor c2 = m_viInputModeManager->getViVisualMode()->getStart();
934 
935  if ( c2 > c ) {
936  c2.setColumn( doc()->lineLength( c2.line() ) );
937  c.setColumn( 0 );
938  } else {
939  c.setColumn( doc()->lineLength( c.line() ) );
940  c2.setColumn( 0 );
941  }
942 
943  range.setRange( c, c2 );
944  // ... and in normal mode the range is from the current position to the
945  // current position + count
946  } else {
947  Cursor c2 = c;
948  c2.setColumn( c.column()+getCount() );
949 
950  if ( c2.column() > doc()->lineLength( c.line() ) ) {
951  c2.setColumn( doc()->lineLength( c.line() ) );
952  }
953 
954  range.setRange( c, c2 );
955  }
956 
957  bool block = m_viInputModeManager->getCurrentViMode() == VisualBlockMode;
958 
959  // get the text the command should operate on
960  text = doc()->text ( range, block );
961 
962  // for every character, switch its case
963  for ( int i = 0; i < text.length(); i++ ) {
964  if ( text.at(i).isUpper() ) {
965  text[i] = text.at(i).toLower();
966  } else if ( text.at(i).isLower() ) {
967  text[i] = text.at(i).toUpper();
968  }
969  }
970 
971  // replace the old text with the modified text
972  doc()->replaceText( range, text, block );
973 
974  // in normal mode, move the cursor to the right, in visual mode move the
975  // cursor to the start of the selection
976  if ( m_viInputModeManager->getCurrentViMode() == NormalMode ) {
977  updateCursor( range.end() );
978  } else {
979  updateCursor( range.start() );
980  }
981 
982  return true;
983 }
984 
985 bool KateViNormalMode::commandChangeCaseRange()
986 {
987  OperationMode m = getOperationMode();
988  QString changedCase = getRange( m_commandRange, m );
989  if (m == LineWise)
990  changedCase = changedCase.left(changedCase.size() - 1); // don't need '\n' at the end;
991  Range range = Range(m_commandRange.startLine, m_commandRange.startColumn, m_commandRange.endLine, m_commandRange.endColumn);
992  // get the text the command should operate on
993  // for every character, switch its case
994  for ( int i = 0; i < changedCase.length(); i++ ) {
995  if ( changedCase.at(i).isUpper() ) {
996  changedCase[i] = changedCase.at(i).toLower();
997  } else if ( changedCase.at(i).isLower() ) {
998  changedCase[i] = changedCase.at(i).toUpper();
999  }
1000  }
1001  doc()->replaceText( range, changedCase, m == Block );
1002  return true;
1003 }
1004 
1005 bool KateViNormalMode::commandChangeCaseLine()
1006 {
1007  Cursor c( m_view->cursorPosition() );
1008 
1009  if (doc()->lineLength(c.line()) == 0)
1010  {
1011  // Nothing to do.
1012  return true;
1013  }
1014 
1015  m_commandRange.startLine = c.line();
1016  m_commandRange.endLine = c.line() + getCount() - 1;
1017  m_commandRange.startColumn = 0;
1018  m_commandRange.endColumn = doc()->lineLength( c.line() )-1; // -1 is for excluding '\0'
1019 
1020  if ( !commandChangeCaseRange() )
1021  return false;
1022 
1023  Cursor start( m_commandRange.startLine, m_commandRange.startColumn );
1024  if (getCount() > 1)
1025  updateCursor(c);
1026  else
1027  updateCursor(start);
1028  return true;
1029 
1030 }
1031 
1032 bool KateViNormalMode::commandOpenNewLineUnder()
1033 {
1034  doc()->setUndoMergeAllEdits(true);
1035 
1036  Cursor c( m_view->cursorPosition() );
1037 
1038  c.setColumn( doc()->lineLength( c.line() ) );
1039  updateCursor( c );
1040 
1041  doc()->newLine( m_view );
1042 
1043  m_stickyColumn = -1;
1044  startInsertMode();
1045  m_viInputModeManager->getViInsertMode()->setCount(getCount());
1046  m_viInputModeManager->getViInsertMode()->setCountedRepeatsBeginOnNewLine(true);
1047  m_viewInternal->repaint ();
1048 
1049  return true;
1050 }
1051 
1052 bool KateViNormalMode::commandOpenNewLineOver()
1053 {
1054  doc()->setUndoMergeAllEdits(true);
1055 
1056  Cursor c( m_view->cursorPosition() );
1057 
1058  if ( c.line() == 0 ) {
1059  doc()->insertLine(0, QString());
1060  c.setColumn( 0 );
1061  c.setLine( 0 );
1062  updateCursor( c );
1063  } else {
1064  c.setLine( c.line()-1 );
1065  c.setColumn( getLine( c.line() ).length() );
1066  updateCursor( c );
1067  doc()->newLine( m_view );
1068  }
1069 
1070  m_stickyColumn = -1;
1071  startInsertMode();
1072  m_viInputModeManager->getViInsertMode()->setCount(getCount());
1073  m_viInputModeManager->getViInsertMode()->setCountedRepeatsBeginOnNewLine(true);
1074  m_viewInternal->repaint ();
1075 
1076  return true;
1077 }
1078 
1079 bool KateViNormalMode::commandJoinLines()
1080 {
1081  Cursor c( m_view->cursorPosition() );
1082 
1083  unsigned int from = c.line();
1084  unsigned int to = c.line() + ((getCount() == 1) ? 1 : getCount() - 1);
1085 
1086  // if we were given a range of lines, this information overrides the previous
1087  if ( m_commandRange.startLine != -1 && m_commandRange.endLine != -1 ) {
1088  m_commandRange.normalize();
1089  c.setLine ( m_commandRange.startLine );
1090  from = m_commandRange.startLine;
1091  to = m_commandRange.endLine;
1092  }
1093 
1094  if (to >= (unsigned int)doc()->lines())
1095  {
1096  return false;
1097  }
1098 
1099  bool nonEmptyLineFound = false;
1100  for (unsigned int lineNum = from; lineNum <= to; lineNum++)
1101  {
1102  if (!doc()->line(lineNum).isEmpty())
1103  {
1104  nonEmptyLineFound = true;
1105  }
1106  }
1107 
1108  const int firstNonWhitespaceOnLastLine = doc()->kateTextLine(to)->firstChar();
1109  QString leftTrimmedLastLine;
1110  if (firstNonWhitespaceOnLastLine != -1)
1111  {
1112  leftTrimmedLastLine = doc()->line(to).mid(firstNonWhitespaceOnLastLine);
1113  }
1114 
1115  joinLines( from, to );
1116 
1117  if (nonEmptyLineFound && leftTrimmedLastLine.isEmpty())
1118  {
1119  // joinLines won't have added a trailing " ", whereas Vim does - follow suit.
1120  doc()->insertText(Cursor(from, doc()->lineLength(from)), " ");
1121  }
1122 
1123  // Position cursor just before first non-whitesspace character of what was the last line joined.
1124  c.setColumn(doc()->lineLength(from) - leftTrimmedLastLine.length() - 1);
1125  if (c.column() >= 0) {
1126  updateCursor( c );
1127  }
1128 
1129  m_deleteCommand = true;
1130  return true;
1131 }
1132 
1133 bool KateViNormalMode::commandChange()
1134 {
1135  Cursor c( m_view->cursorPosition() );
1136 
1137  OperationMode m = getOperationMode();
1138 
1139  doc()->setUndoMergeAllEdits(true);
1140 
1141  commandDelete();
1142 
1143  if ( m == LineWise ) {
1144  // if we deleted several lines, insert an empty line and put the cursor there.
1145  doc()->insertLine( m_commandRange.startLine, QString() );
1146  c.setLine( m_commandRange.startLine );
1147  c.setColumn(0);
1148  } else if (m == Block) {
1149  // block substitute can be simulated by first deleting the text
1150  // (done above) and then starting block prepend.
1151  return commandPrependToBlock();
1152  } else {
1153  if (m_commandRange.startLine < m_commandRange.endLine) {
1154  c.setLine(m_commandRange.startLine);
1155  }
1156  c.setColumn(m_commandRange.startColumn);
1157  }
1158 
1159  updateCursor(c);
1160  setCount(0); // The count was for the motion, not the insertion.
1161  commandEnterInsertMode();
1162 
1163  // correct indentation level
1164  if ( m == LineWise ) {
1165  m_view->align();
1166  }
1167 
1168  m_deleteCommand = true;
1169  return true;
1170 }
1171 
1172 bool KateViNormalMode::commandChangeToEOL()
1173 {
1174  commandDeleteToEOL();
1175 
1176  if ( getOperationMode() == Block ) {
1177  return commandPrependToBlock();
1178  }
1179 
1180  m_deleteCommand = true;
1181  return commandEnterInsertModeAppend();
1182 }
1183 
1184 bool KateViNormalMode::commandChangeLine()
1185 {
1186  m_deleteCommand = true;
1187  Cursor c( m_view->cursorPosition() );
1188  c.setColumn( 0 );
1189  updateCursor( c );
1190 
1191  doc()->setUndoMergeAllEdits(true);
1192 
1193  // if count >= 2 start by deleting the whole lines
1194  if ( getCount() >= 2 ) {
1195  KateViRange r( c.line(), 0, c.line()+getCount()-2, 0, ViMotion::InclusiveMotion );
1196  deleteRange( r );
1197  }
1198 
1199  // ... then delete the _contents_ of the last line, but keep the line
1200  KateViRange r( c.line(), c.column(), c.line(), doc()->lineLength( c.line() )-1,
1201  ViMotion::InclusiveMotion );
1202  deleteRange( r, CharWise, true );
1203 
1204  // ... then enter insert mode
1205  if ( getOperationMode() == Block ) {
1206  return commandPrependToBlock();
1207  }
1208  commandEnterInsertModeAppend();
1209 
1210  // correct indentation level
1211  m_view->align();
1212 
1213  return true;
1214 }
1215 
1216 bool KateViNormalMode::commandSubstituteChar()
1217 {
1218  if ( commandDeleteChar() ) {
1219  // The count is only used for deletion of chars; the inserted text is not repeated
1220  setCount(0);
1221  return commandEnterInsertMode();
1222  }
1223 
1224  m_deleteCommand = true;
1225  return false;
1226 }
1227 
1228 bool KateViNormalMode::commandSubstituteLine()
1229 {
1230  m_deleteCommand = true;
1231  return commandChangeLine();
1232 }
1233 
1234 bool KateViNormalMode::commandYank()
1235 {
1236  Cursor c( m_view->cursorPosition() );
1237 
1238  bool r = false;
1239  QString yankedText;
1240 
1241  OperationMode m = getOperationMode();
1242  yankedText = getRange( m_commandRange, m );
1243 
1244  highlightYank(m_commandRange, m);
1245 
1246  QChar chosen_register = getChosenRegister( '0' );
1247  fillRegister(chosen_register, yankedText, m );
1248  yankToClipBoard(chosen_register, yankedText);
1249 
1250  return r;
1251 }
1252 
1253 bool KateViNormalMode::commandYankLine()
1254 {
1255  Cursor c( m_view->cursorPosition() );
1256  QString lines;
1257  int linenum = c.line();
1258 
1259  for ( unsigned int i = 0; i < getCount(); i++ ) {
1260  lines.append( getLine( linenum + i ) + '\n' );
1261  }
1262 
1263  KateViRange yankRange(linenum, 0, linenum + getCount() - 1, getLine(linenum + getCount() - 1).length(), ViMotion::InclusiveMotion);
1264  highlightYank(yankRange);
1265 
1266  QChar chosen_register = getChosenRegister( '0' );
1267  fillRegister(chosen_register, lines, LineWise );
1268  yankToClipBoard(chosen_register, lines);
1269 
1270  return true;
1271 }
1272 
1273 bool KateViNormalMode::commandYankToEOL()
1274 {
1275  OperationMode m = CharWise;
1276  Cursor c(m_view->cursorPosition());
1277 
1278  ViMotion::MotionType motion = m_commandRange.motionType;
1279  m_commandRange.endLine = c.line() + getCount() - 1;
1280  m_commandRange.endColumn = doc()->lineLength(m_commandRange.endLine) - 1;
1281  m_commandRange.motionType = ViMotion::InclusiveMotion;
1282 
1283  switch (m_viInputModeManager->getCurrentViMode()) {
1284  case NormalMode:
1285  m_commandRange.startLine = c.line();
1286  m_commandRange.startColumn = c.column();
1287  break;
1288  case VisualMode:
1289  case VisualLineMode:
1290  m = LineWise;
1291  {
1292  KateViVisualMode *visual = static_cast<KateViVisualMode *>(this);
1293  visual->setStart(Cursor(visual->getStart().line(), 0));
1294  }
1295  break;
1296  case VisualBlockMode:
1297  m = Block;
1298  break;
1299  default:
1300  /* InsertMode and ReplaceMode will never call this method. */
1301  Q_ASSERT(false);
1302  }
1303 
1304  const QString &yankedText = getRange(m_commandRange, m);
1305  m_commandRange.motionType = motion;
1306  highlightYank(m_commandRange);
1307 
1308  QChar chosen_register = getChosenRegister(QLatin1Char('0'));
1309  fillRegister(chosen_register, yankedText, m);
1310  yankToClipBoard(chosen_register, yankedText);
1311 
1312  return true;
1313 }
1314 
1315 // Insert the text in the given register after the cursor position.
1316 // This is the non-g version of paste, so the cursor will usually
1317 // end up on the last character of the pasted text, unless the text
1318 // was multi-line or linewise in which case it will end up
1319 // on the *first* character of the pasted text(!)
1320 // If linewise, will paste after the current line.
1321 bool KateViNormalMode::commandPaste()
1322 {
1323  return paste(AfterCurrentPosition, false, false);
1324 }
1325 
1326 // As with commandPaste, except that the text is pasted *at* the cursor position
1327 bool KateViNormalMode::commandPasteBefore()
1328 {
1329  return paste(AtCurrentPosition, false, false);
1330 }
1331 
1332 // As with commandPaste, except that the cursor will generally be placed *after* the
1333 // last pasted character (assuming the last pasted character is not at the end of the line).
1334 // If linewise, cursor will be at the beginning of the line *after* the last line of pasted text,
1335 // unless that line is the last line of the document; then it will be placed at the beginning of the
1336 // last line pasted.
1337 bool KateViNormalMode::commandgPaste()
1338 {
1339  return paste(AfterCurrentPosition, true, false);
1340 }
1341 
1342 // As with commandgPaste, except that it pastes *at* the current cursor position or, if linewise,
1343 // at the current line.
1344 bool KateViNormalMode::commandgPasteBefore()
1345 {
1346  return paste(AtCurrentPosition, true, false);
1347 }
1348 
1349 bool KateViNormalMode::commandIndentedPaste()
1350 {
1351  return paste(AfterCurrentPosition, false, true);
1352 }
1353 
1354 bool KateViNormalMode::commandIndentedPasteBefore()
1355 {
1356  return paste(AtCurrentPosition, false, true);
1357 }
1358 
1359 bool KateViNormalMode::commandDeleteChar()
1360 {
1361  Cursor c( m_view->cursorPosition() );
1362  KateViRange r( c.line(), c.column(), c.line(), c.column()+getCount(), ViMotion::ExclusiveMotion );
1363 
1364  if ( m_commandRange.startLine != -1 && m_commandRange.startColumn != -1 ) {
1365  r = m_commandRange;
1366  } else {
1367  if ( r.endColumn > doc()->lineLength( r.startLine ) ) {
1368  r.endColumn = doc()->lineLength( r.startLine );
1369  }
1370  }
1371 
1372  // should delete entire lines if in visual line mode and selection in visual block mode
1373  OperationMode m = CharWise;
1374  if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
1375  m = LineWise;
1376  } else if ( m_viInputModeManager->getCurrentViMode() == VisualBlockMode ) {
1377  m = Block;
1378  }
1379 
1380  m_deleteCommand = true;
1381  return deleteRange( r, m );
1382 }
1383 
1384 bool KateViNormalMode::commandDeleteCharBackward()
1385 {
1386  Cursor c( m_view->cursorPosition() );
1387 
1388  KateViRange r( c.line(), c.column()-getCount(), c.line(), c.column(), ViMotion::ExclusiveMotion );
1389 
1390  if ( m_commandRange.startLine != -1 && m_commandRange.startColumn != -1 ) {
1391  r = m_commandRange;
1392  } else {
1393  if ( r.startColumn < 0 ) {
1394  r.startColumn = 0;
1395  }
1396  }
1397 
1398  // should delete entire lines if in visual line mode and selection in visual block mode
1399  OperationMode m = CharWise;
1400  if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode ) {
1401  m = LineWise;
1402  } else if ( m_viInputModeManager->getCurrentViMode() == VisualBlockMode ) {
1403  m = Block;
1404  }
1405 
1406  m_deleteCommand = true;
1407  return deleteRange( r, m );
1408 }
1409 
1410 bool KateViNormalMode::commandReplaceCharacter()
1411 {
1412  QString key = KateViKeyParser::self()->decodeKeySequence(m_keys.right(1));
1413 
1414  // Filter out some special keys.
1415  const int keyCode = KateViKeyParser::self()->encoded2qt(m_keys.right(1));
1416  switch (keyCode) {
1417  case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_Up:
1418  case Qt::Key_Down: case Qt::Key_Home: case Qt::Key_End:
1419  case Qt::Key_PageUp: case Qt::Key_PageDown: case Qt::Key_Delete:
1420  case Qt::Key_Insert: case Qt::Key_Backspace: case Qt::Key_CapsLock:
1421  return true;
1422  case Qt::Key_Return: case Qt::Key_Enter:
1423  key = QLatin1String("\n");
1424  }
1425 
1426  bool r;
1427  if ( m_viInputModeManager->isAnyVisualMode()) {
1428 
1429  OperationMode m = getOperationMode();
1430  QString text = getRange( m_commandRange, m );
1431 
1432  if (m == LineWise)
1433  text = text.left(text.size() - 1); // don't need '\n' at the end;
1434 
1435  text.replace( QRegExp( "[^\n]" ), key );
1436 
1437  m_commandRange.normalize();
1438  Cursor start( m_commandRange.startLine, m_commandRange.startColumn );
1439  Cursor end( m_commandRange.endLine, m_commandRange.endColumn );
1440  Range range( start, end );
1441 
1442  r = doc()->replaceText( range, text, m == Block );
1443 
1444  } else {
1445  Cursor c1( m_view->cursorPosition() );
1446  Cursor c2( m_view->cursorPosition() );
1447 
1448  c2.setColumn( c2.column() + getCount() );
1449 
1450  if (c2.column() > doc()->lineLength(m_view->cursorPosition().line()))
1451  {
1452  return false;
1453  }
1454 
1455  r = doc()->replaceText( Range( c1, c2 ), key.repeated(getCount()) );
1456  updateCursor( c1 );
1457 
1458  }
1459  return r;
1460 }
1461 
1462 bool KateViNormalMode::commandSwitchToCmdLine()
1463 {
1464  Cursor c( m_view->cursorPosition() );
1465 
1466 
1467  QString initialText;
1468  if ( m_viInputModeManager->isAnyVisualMode()) {
1469  // if in visual mode, make command range == visual selection
1470  m_viInputModeManager->getViVisualMode()->saveRangeMarks();
1471  initialText = "'<,'>";
1472  }
1473  else if ( getCount() != 1 ) {
1474  // if a count is given, the range [current line] to [current line] +
1475  // count should be prepended to the command line
1476  initialText = ".,.+" +QString::number( getCount()-1 );
1477  }
1478  if (!KateViewConfig::global()->viInputModeEmulateCommandBar())
1479  {
1480  m_view->switchToCmdLine();
1481  m_view->cmdLineBar()->setText( initialText, false );
1482  }
1483  else
1484  {
1485  m_view->showViModeEmulatedCommandBar();
1486  m_view->viModeEmulatedCommandBar()->init( KateViEmulatedCommandBar::Command, initialText );
1487  }
1488 
1489  m_commandShouldKeepSelection = true;
1490 
1491  return true;
1492 }
1493 
1494 bool KateViNormalMode::commandSearchBackward()
1495 {
1496  if (!KateViewConfig::global()->viInputModeEmulateCommandBar())
1497  {
1498  m_viInputModeManager->setLastSearchBackwards(true);
1499  m_view->find();
1500  }
1501  else
1502  {
1503  m_view->showViModeEmulatedCommandBar();
1504  m_view->viModeEmulatedCommandBar()->init(KateViEmulatedCommandBar::SearchBackward);
1505  }
1506  return true;
1507 }
1508 
1509 bool KateViNormalMode::commandSearchForward()
1510 {
1511  if (!KateViewConfig::global()->viInputModeEmulateCommandBar())
1512  {
1513  m_view->find();
1514  }
1515  else
1516  {
1517  m_view->showViModeEmulatedCommandBar();
1518  m_view->viModeEmulatedCommandBar()->init(KateViEmulatedCommandBar::SearchForward);
1519  }
1520  m_viInputModeManager->setLastSearchBackwards( false );
1521  return true;
1522 }
1523 
1524 bool KateViNormalMode::commandUndo()
1525 {
1526  // See BUG #328277
1527  m_viInputModeManager->clearCurrentChangeLog();
1528 
1529  if (doc()->undoCount() > 0) {
1530  const bool mapped = m_viInputModeManager->keyMapper()->isExecutingMapping();
1531 
1532  if (mapped)
1533  doc()->editEnd();
1534  doc()->undo();
1535  if (mapped)
1536  doc()->editBegin();
1537  return true;
1538  }
1539  return false;
1540 }
1541 
1542 bool KateViNormalMode::commandRedo()
1543 {
1544  if (doc()->redoCount() > 0) {
1545  const bool mapped = m_viInputModeManager->keyMapper()->isExecutingMapping();
1546 
1547  if (mapped)
1548  doc()->editEnd();
1549  doc()->redo();
1550  if (mapped)
1551  doc()->editBegin();
1552  return true;
1553  }
1554  return false;
1555 }
1556 
1557 bool KateViNormalMode::commandSetMark()
1558 {
1559  Cursor c( m_view->cursorPosition() );
1560 
1561  m_view->getViInputModeManager()->addMark( doc(), m_keys.at( m_keys.size()-1 ), c );
1562  kDebug( 13070 ) << "set mark at (" << c.line() << "," << c.column() << ")";
1563 
1564  return true;
1565 }
1566 
1567 bool KateViNormalMode::commandIndentLine()
1568 {
1569  Cursor c( m_view->cursorPosition() );
1570 
1571  doc()->indent( KTextEditor::Range( c.line(), 0, c.line() + getCount(), 0), 1 );
1572 
1573  return true;
1574 }
1575 
1576 bool KateViNormalMode::commandUnindentLine()
1577 {
1578  Cursor c( m_view->cursorPosition() );
1579 
1580  doc()->indent( KTextEditor::Range( c.line(), 0, c.line() + getCount(), 0), -1 );
1581 
1582  return true;
1583 }
1584 
1585 bool KateViNormalMode::commandIndentLines()
1586 {
1587  Cursor c( m_view->cursorPosition() );
1588 
1589  m_commandRange.normalize();
1590 
1591  int line1 = m_commandRange.startLine;
1592  int line2 = m_commandRange.endLine;
1593  int col = getLine( line2 ).length();
1594 
1595  doc()->indent( KTextEditor::Range( line1, 0, line2, col ), getCount() );
1596 
1597  return true;
1598 }
1599 
1600 bool KateViNormalMode::commandUnindentLines()
1601 {
1602  Cursor c( m_view->cursorPosition() );
1603 
1604  m_commandRange.normalize();
1605 
1606  int line1 = m_commandRange.startLine;
1607  int line2 = m_commandRange.endLine;
1608 
1609  doc()->indent( KTextEditor::Range( line1, 0, line2, doc()->lineLength( line2 ) ), -getCount() );
1610 
1611  return true;
1612 }
1613 
1614 bool KateViNormalMode::commandScrollPageDown()
1615 {
1616  if ( getCount() < m_scroll_count_limit ) {
1617 
1618  for(uint i = 0; i < getCount(); i++)
1619  m_view->pageDown();
1620  }
1621  return true;
1622 }
1623 
1624 bool KateViNormalMode::commandScrollPageUp()
1625 {
1626  if ( getCount() < m_scroll_count_limit ) {
1627  for(uint i=0; i < getCount(); i++)
1628  m_view->pageUp();
1629  }
1630  return true;
1631 
1632 }
1633 
1634 bool KateViNormalMode::commandScrollHalfPageUp()
1635 {
1636  if ( getCount() < m_scroll_count_limit ) {
1637 
1638  for(uint i=0; i < getCount(); i++)
1639  m_viewInternal->pageUp(false, true);
1640  }
1641  return true;
1642 }
1643 
1644 bool KateViNormalMode::commandScrollHalfPageDown()
1645 {
1646  if ( getCount() < m_scroll_count_limit ) {
1647  for(uint i=0; i < getCount(); i++)
1648  m_viewInternal->pageDown(false, true);
1649  }
1650  return true;
1651 }
1652 
1653 bool KateViNormalMode::commandCenterView(bool onFirst)
1654 {
1655  Cursor c(m_view->cursorPosition());
1656  const int virtualCenterLine = m_viewInternal->startLine() + linesDisplayed() / 2;
1657  const int virtualCursorLine = m_view->textFolding().lineToVisibleLine(c.line());
1658 
1659  scrollViewLines(virtualCursorLine - virtualCenterLine);
1660  if (onFirst) {
1661  c.setColumn(getFirstNonBlank());
1662  updateCursor(c);
1663  }
1664  return true;
1665 }
1666 
1667 bool KateViNormalMode::commandCenterViewOnNonBlank()
1668 {
1669  return commandCenterView(true);
1670 }
1671 
1672 bool KateViNormalMode::commandCenterViewOnCursor()
1673 {
1674  return commandCenterView(false);
1675 }
1676 
1677 bool KateViNormalMode::commandTopView(bool onFirst)
1678 {
1679  Cursor c(m_view->cursorPosition());
1680  const int virtualCenterLine = m_viewInternal->startLine();
1681  const int virtualCursorLine = m_view->textFolding().lineToVisibleLine(c.line());
1682 
1683  scrollViewLines(virtualCursorLine - virtualCenterLine);
1684  if (onFirst) {
1685  c.setColumn(getFirstNonBlank());
1686  updateCursor(c);
1687  }
1688  return true;
1689 }
1690 
1691 bool KateViNormalMode::commandTopViewOnNonBlank()
1692 {
1693  return commandTopView(true);
1694 }
1695 
1696 bool KateViNormalMode::commandTopViewOnCursor()
1697 {
1698  return commandTopView(false);
1699 }
1700 
1701 bool KateViNormalMode::commandBottomView(bool onFirst)
1702 {
1703  Cursor c(m_view->cursorPosition());
1704  const int virtualCenterLine = m_viewInternal->endLine();
1705  const int virtualCursorLine = m_view->textFolding().lineToVisibleLine(c.line());
1706 
1707  scrollViewLines(virtualCursorLine - virtualCenterLine);
1708  if (onFirst) {
1709  c.setColumn(getFirstNonBlank());
1710  updateCursor(c);
1711  }
1712  return true;
1713 }
1714 
1715 bool KateViNormalMode::commandBottomViewOnNonBlank()
1716 {
1717  return commandBottomView(true);
1718 }
1719 
1720 bool KateViNormalMode::commandBottomViewOnCursor()
1721 {
1722  return commandBottomView(false);
1723 }
1724 
1725 bool KateViNormalMode::commandAbort()
1726 {
1727  m_pendingResetIsDueToExit = true;
1728  reset();
1729  return true;
1730 }
1731 
1732 bool KateViNormalMode::commandPrintCharacterCode()
1733 {
1734  QChar ch = getCharUnderCursor();
1735 
1736  if ( ch == QChar::Null ) {
1737  message( QString( "NUL" ) );
1738  } else {
1739 
1740  int code = ch.unicode();
1741 
1742  QString dec = QString::number( code );
1743  QString hex = QString::number( code, 16 );
1744  QString oct = QString::number( code, 8 );
1745  if ( oct.length() < 3 ) { oct.prepend( '0' ); }
1746  if ( code > 0x80 && code < 0x1000 ) { hex.prepend( ( code < 0x100 ? "00" : "0" ) ); }
1747  message( i18n("'%1' %2, Hex %3, Octal %4", ch, dec, hex, oct ) );
1748  }
1749 
1750  return true;
1751 }
1752 
1753 bool KateViNormalMode::commandRepeatLastChange()
1754 {
1755  const int repeatCount = getCount();
1756  resetParser();
1757  if (repeatCount > 1)
1758  {
1759  m_oneTimeCountOverride = repeatCount;
1760  }
1761  doc()->editStart();
1762  m_viInputModeManager->repeatLastChange();
1763  doc()->editEnd();
1764 
1765  return true;
1766 }
1767 
1768 bool KateViNormalMode::commandAlignLine()
1769 {
1770  const int line = m_view->cursorPosition().line();
1771  Range alignRange( Cursor(line, 0), Cursor(line, 0) );
1772 
1773  doc()->align( m_view, alignRange );
1774 
1775  return true;
1776 }
1777 
1778 bool KateViNormalMode::commandAlignLines()
1779 {
1780  Cursor c( m_view->cursorPosition() );
1781  m_commandRange.normalize();
1782 
1783  Cursor start(m_commandRange.startLine, 0);
1784  Cursor end(m_commandRange.endLine, 0);
1785 
1786  doc()->align( m_view, Range( start, end ) );
1787 
1788  return true;
1789 }
1790 
1791 bool KateViNormalMode::commandAddToNumber()
1792 {
1793  addToNumberUnderCursor( getCount() );
1794 
1795  return true;
1796 }
1797 
1798 bool KateViNormalMode::commandSubtractFromNumber()
1799 {
1800  addToNumberUnderCursor( -getCount() );
1801 
1802  return true;
1803 }
1804 
1805 bool KateViNormalMode::commandPrependToBlock()
1806 {
1807  Cursor c( m_view->cursorPosition() );
1808 
1809  // move cursor to top left corner of selection
1810  m_commandRange.normalize();
1811  c.setColumn( m_commandRange.startColumn );
1812  c.setLine( m_commandRange.startLine );
1813  updateCursor( c );
1814 
1815  m_stickyColumn = -1;
1816  m_viInputModeManager->getViInsertMode()->setBlockPrependMode( m_commandRange );
1817  return startInsertMode();
1818 }
1819 
1820 bool KateViNormalMode::commandAppendToBlock()
1821 {
1822  Cursor c( m_view->cursorPosition() );
1823 
1824  m_commandRange.normalize();
1825  if ( m_stickyColumn == (unsigned int)KateVi::EOL ) { // append to EOL
1826  // move cursor to end of first line
1827  c.setLine( m_commandRange.startLine );
1828  c.setColumn( doc()->lineLength( c.line() ) );
1829  updateCursor( c );
1830  m_viInputModeManager->getViInsertMode()->setBlockAppendMode( m_commandRange, AppendEOL );
1831  } else {
1832  m_viInputModeManager->getViInsertMode()->setBlockAppendMode( m_commandRange, Append );
1833  // move cursor to top right corner of selection
1834  c.setColumn( m_commandRange.endColumn+1 );
1835  c.setLine( m_commandRange.startLine );
1836  updateCursor( c );
1837  }
1838 
1839  m_stickyColumn = -1;
1840 
1841  return startInsertMode();
1842 }
1843 
1844 bool KateViNormalMode::commandGoToNextJump() {
1845  Cursor c = getNextJump(m_view->cursorPosition());
1846  updateCursor(c);
1847 
1848  return true;
1849 }
1850 
1851 bool KateViNormalMode::commandGoToPrevJump() {
1852  Cursor c = getPrevJump(m_view->cursorPosition());
1853  updateCursor(c);
1854 
1855  return true;
1856 }
1857 
1858 bool KateViNormalMode::commandSwitchToLeftView() {
1859  switchView(Left);
1860  return true;
1861 }
1862 
1863 bool KateViNormalMode::commandSwitchToDownView() {
1864  switchView(Down);
1865  return true;
1866 }
1867 
1868 bool KateViNormalMode::commandSwitchToUpView() {
1869  switchView(Up);
1870  return true;
1871 }
1872 
1873 bool KateViNormalMode::commandSwitchToRightView() {
1874  switchView(Right);
1875  return true;
1876 }
1877 
1878 bool KateViNormalMode::commandSwitchToNextView() {
1879  switchView(Next);
1880  return true;
1881 }
1882 
1883 bool KateViNormalMode::commandSplitHoriz() {
1884  m_view->cmdLineBar()->execute("split");
1885  return true;
1886 }
1887 
1888 bool KateViNormalMode::commandSplitVert() {
1889  m_view->cmdLineBar()->execute("vsplit");
1890  return true;
1891 }
1892 
1893 bool KateViNormalMode::commandSwitchToNextTab() {
1894  QString command = "bn";
1895 
1896  if ( m_iscounted )
1897  command = command + ' ' + QString::number(getCount());
1898 
1899  m_view->cmdLineBar()->execute(command);
1900  return true;
1901 }
1902 
1903 bool KateViNormalMode::commandSwitchToPrevTab() {
1904  QString command = "bp";
1905 
1906  if ( m_iscounted )
1907  command = command + ' ' + QString::number(getCount());
1908 
1909  m_view->cmdLineBar()->execute(command);
1910  return true;
1911 }
1912 
1913 bool KateViNormalMode::commandFormatLine()
1914 {
1915  Cursor c( m_view->cursorPosition() );
1916 
1917  reformatLines( c.line(), c.line()+getCount()-1 );
1918 
1919  return true;
1920 }
1921 
1922 bool KateViNormalMode::commandFormatLines()
1923 {
1924  reformatLines( m_commandRange.startLine, m_commandRange.endLine );
1925  return true;
1926 }
1927 
1928 bool KateViNormalMode::commandCollapseToplevelNodes()
1929 {
1930 #if 0
1931  //FIXME FOLDING
1932  doc()->foldingTree()->collapseToplevelNodes();
1933 #endif
1934  return true;
1935 }
1936 
1937 bool KateViNormalMode::commandStartRecordingMacro()
1938 {
1939  const QChar reg = m_keys[m_keys.size() - 1];
1940  m_viInputModeManager->startRecordingMacro(reg);
1941  return true;
1942 }
1943 
1944 bool KateViNormalMode::commandReplayMacro()
1945 {
1946  // "@<registername>" will have been added to the log; it needs to be cleared
1947  // *before* we replay the macro keypresses, else it can cause an infinite loop
1948  // if the macro contains a "."
1949  m_viInputModeManager->clearCurrentChangeLog();
1950  const QChar reg = m_keys[m_keys.size() - 1];
1951  const unsigned int count = getCount();
1952  resetParser();
1953  doc()->editBegin();
1954  for ( unsigned int i = 0; i < count; i++ )
1955  {
1956  m_viInputModeManager->replayMacro(reg);
1957  }
1958  doc()->editEnd();
1959  return true;
1960 }
1961 
1962 bool KateViNormalMode::commandCloseNocheck()
1963 {
1964  m_view->cmdLineBar()->execute("q!");
1965  return true;
1966 }
1967 
1968 bool KateViNormalMode::commandCloseWrite()
1969 {
1970  m_view->cmdLineBar()->execute("wq");
1971  return true;
1972 }
1973 
1974 bool KateViNormalMode::commandCollapseLocal()
1975 {
1976 #if 0
1977  //FIXME FOLDING
1978  Cursor c( m_view->cursorPosition() );
1979  doc()->foldingTree()->collapseOne( c.line(), c.column() );
1980 #endif
1981  return true;
1982 }
1983 
1984 bool KateViNormalMode::commandExpandAll() {
1985 #if 0
1986  //FIXME FOLDING
1987  doc()->foldingTree()->expandAll();
1988 #endif
1989  return true;
1990 }
1991 
1992 bool KateViNormalMode::commandExpandLocal()
1993 {
1994 #if 0
1995  //FIXME FOLDING
1996  Cursor c( m_view->cursorPosition() );
1997  doc()->foldingTree()->expandOne( c.line() + 1, c.column() );
1998 #endif
1999  return true;
2000 }
2001 
2002 bool KateViNormalMode::commandToggleRegionVisibility()
2003 {
2004 #if 0
2005  //FIXME FOLDING
2006  Cursor c( m_view->cursorPosition() );
2007  doc()->foldingTree()->toggleRegionVisibility( c.line() );
2008 #endif
2009  return true;
2010 }
2011 
2012 
2014 // MOTIONS
2016 
2017 KateViRange KateViNormalMode::motionDown()
2018 {
2019  return goLineDown();
2020 }
2021 
2022 KateViRange KateViNormalMode::motionUp()
2023 {
2024  return goLineUp();
2025 }
2026 
2027 KateViRange KateViNormalMode::motionLeft()
2028 {
2029  Cursor cursor ( m_view->cursorPosition() );
2030  m_stickyColumn = -1;
2031  KateViRange r( cursor.line(), cursor.column(), ViMotion::ExclusiveMotion );
2032  r.endColumn -= getCount();
2033 
2034  if ( r.endColumn < 0 ) {
2035  r.endColumn = 0;
2036  }
2037 
2038  return r;
2039 }
2040 
2041 KateViRange KateViNormalMode::motionRight()
2042 {
2043  Cursor cursor ( m_view->cursorPosition() );
2044  m_stickyColumn = -1;
2045  KateViRange r( cursor.line(), cursor.column(), ViMotion::ExclusiveMotion );
2046  r.endColumn += getCount();
2047 
2048  // make sure end position isn't > line length
2049  if ( r.endColumn > doc()->lineLength( r.endLine ) ) {
2050  r.endColumn = doc()->lineLength( r.endLine );
2051  }
2052 
2053  return r;
2054 }
2055 
2056 KateViRange KateViNormalMode::motionPageDown()
2057 {
2058  Cursor c( m_view->cursorPosition() );
2059  int linesToScroll = linesDisplayed();
2060 
2061  KateViRange r( c.line()+linesToScroll, c.column(), ViMotion::InclusiveMotion );
2062 
2063  if ( r.endLine >= doc()->lines() ) {
2064  r.endLine = doc()->lines()-1;
2065  }
2066 
2067  return r;
2068 }
2069 
2070 KateViRange KateViNormalMode::motionPageUp()
2071 {
2072  Cursor c( m_view->cursorPosition() );
2073  int linesToScroll = linesDisplayed();
2074 
2075  KateViRange r( c.line()-linesToScroll, c.column(), ViMotion::InclusiveMotion );
2076 
2077  if ( r.endLine < 0 ) {
2078  r.endLine = 0;
2079  }
2080 
2081  return r;
2082 }
2083 
2084 KateViRange KateViNormalMode::motionDownToFirstNonBlank()
2085 {
2086  Cursor c( m_view->cursorPosition() );
2087  KateViRange r = goLineDown();
2088  r.endColumn = getFirstNonBlank(r.endLine);
2089  return r;
2090 }
2091 
2092 KateViRange KateViNormalMode::motionUpToFirstNonBlank()
2093 {
2094  Cursor c( m_view->cursorPosition() );
2095  KateViRange r = goLineUp();
2096  r.endColumn = getFirstNonBlank(r.endLine);
2097  return r;
2098 }
2099 
2100 KateViRange KateViNormalMode::motionWordForward()
2101 {
2102  Cursor c( m_view->cursorPosition() );
2103  KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
2104 
2105  m_stickyColumn = -1;
2106 
2107  // Special case: If we're already on the very last character in the document, the motion should be
2108  // inclusive so the last character gets included
2109  if ( c.line() == doc()->lines()-1 && c.column() == doc()->lineLength( c.line() )-1 ) {
2110  r.motionType = ViMotion::InclusiveMotion;
2111  } else {
2112  for ( unsigned int i = 0; i < getCount(); i++ ) {
2113  c = findNextWordStart( c.line(), c.column() );
2114 
2115  // stop when at the last char in the document
2116  if (!c.isValid()) {
2117  c = doc()->documentEnd();
2118  // if we still haven't "used up the count", make the motion inclusive, so that the last char
2119  // is included
2120  if ( i < getCount() ) {
2121  r.motionType = ViMotion::InclusiveMotion;
2122  }
2123  break;
2124  }
2125  }
2126  }
2127 
2128  r.endColumn = c.column();
2129  r.endLine = c.line();
2130 
2131  return r;
2132 }
2133 
2134 KateViRange KateViNormalMode::motionWordBackward()
2135 {
2136  Cursor c( m_view->cursorPosition() );
2137  KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
2138 
2139  m_stickyColumn = -1;
2140 
2141  for ( unsigned int i = 0; i < getCount(); i++ ) {
2142  c = findPrevWordStart( c.line(), c.column() );
2143 
2144  if (!c.isValid())
2145  {
2146  c = Cursor(0, 0);
2147  break;
2148  }
2149  }
2150 
2151  r.endColumn = c.column();
2152  r.endLine = c.line();
2153 
2154  return r;
2155 }
2156 
2157 KateViRange KateViNormalMode::motionWORDForward()
2158 {
2159  Cursor c( m_view->cursorPosition() );
2160  KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
2161 
2162  m_stickyColumn = -1;
2163 
2164  for ( unsigned int i = 0; i < getCount(); i++ ) {
2165  c = findNextWORDStart( c.line(), c.column() );
2166 
2167  // stop when at the last char in the document
2168  if ( c.line() == doc()->lines()-1 && c.column() == doc()->lineLength( c.line() )-1 ) {
2169  break;
2170  }
2171  }
2172 
2173  r.endColumn = c.column();
2174  r.endLine = c.line();
2175 
2176  return r;
2177 }
2178 
2179 KateViRange KateViNormalMode::motionWORDBackward()
2180 {
2181  Cursor c( m_view->cursorPosition() );
2182  KateViRange r( c.line(), c.column(), ViMotion::ExclusiveMotion );
2183 
2184  m_stickyColumn = -1;
2185 
2186  for ( unsigned int i = 0; i < getCount(); i++ ) {
2187  c = findPrevWORDStart( c.line(), c.column() );
2188 
2189  if (!c.isValid())
2190  {
2191  c = Cursor(0, 0);
2192  }
2193  }
2194 
2195  r.endColumn = c.column();
2196  r.endLine = c.line();
2197 
2198  return r;
2199 }
2200 
2201 KateViRange KateViNormalMode::motionToEndOfWord()
2202 {
2203  Cursor c( m_view->cursorPosition() );
2204  KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
2205 
2206  m_stickyColumn = -1;
2207 
2208  for ( unsigned int i = 0; i < getCount(); i++ ) {
2209  c = findWordEnd( c.line(), c.column() );
2210  }
2211 
2212  r.endColumn = c.column();
2213  r.endLine = c.line();
2214 
2215  return r;
2216 }
2217 
2218 KateViRange KateViNormalMode::motionToEndOfWORD()
2219 {
2220  Cursor c( m_view->cursorPosition() );
2221  KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
2222 
2223  m_stickyColumn = -1;
2224 
2225  for ( unsigned int i = 0; i < getCount(); i++ ) {
2226  c = findWORDEnd( c.line(), c.column() );
2227  }
2228 
2229  if (!c.isValid())
2230  {
2231  c = doc()->documentEnd();
2232  }
2233 
2234  r.endColumn = c.column();
2235  r.endLine = c.line();
2236 
2237  return r;
2238 }
2239 
2240 KateViRange KateViNormalMode::motionToEndOfPrevWord()
2241 {
2242  Cursor c( m_view->cursorPosition() );
2243  KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
2244 
2245  m_stickyColumn = -1;
2246 
2247  for ( unsigned int i = 0; i < getCount(); i++ ) {
2248  c = findPrevWordEnd( c.line(), c.column() );
2249 
2250  if (c.isValid())
2251  {
2252  r.endColumn = c.column();
2253  r.endLine = c.line();
2254  }
2255  else
2256  {
2257  r.endColumn = 0;
2258  r.endLine = 0;
2259  break;
2260  }
2261 
2262  }
2263 
2264  return r;
2265 }
2266 
2267 KateViRange KateViNormalMode::motionToEndOfPrevWORD()
2268 {
2269  Cursor c( m_view->cursorPosition() );
2270  KateViRange r( c.line(), c.column(), ViMotion::InclusiveMotion );
2271 
2272  m_stickyColumn = -1;
2273 
2274  for ( unsigned int i = 0; i < getCount(); i++ ) {
2275  c = findPrevWORDEnd( c.line(), c.column() );
2276 
2277  if (c.isValid())
2278  {
2279  r.endColumn = c.column();
2280  r.endLine = c.line();
2281  }
2282  else
2283  {
2284  r.endColumn = 0;
2285  r.endLine = 0;
2286  break;
2287  }
2288  }
2289 
2290  return r;
2291 }
2292 
2293 KateViRange KateViNormalMode::motionToEOL()
2294 {
2295  Cursor c( m_view->cursorPosition() );
2296 
2297  // set sticky column to a ridiculously high value so that the cursor will stick to EOL,
2298  // but only if it's a regular motion
2299  if ( m_keys.size() == 1 ) {
2300  m_stickyColumn = KateVi::EOL;
2301  }
2302 
2303  unsigned int line = c.line() + ( getCount() - 1 );
2304  KateViRange r( line, doc()->lineLength(line )-1, ViMotion::InclusiveMotion );
2305 
2306  return r;
2307 }
2308 
2309 KateViRange KateViNormalMode::motionToColumn0()
2310 {
2311  m_stickyColumn = -1;
2312  Cursor cursor ( m_view->cursorPosition() );
2313  KateViRange r( cursor.line(), 0, ViMotion::ExclusiveMotion );
2314 
2315  return r;
2316 }
2317 
2318 KateViRange KateViNormalMode::motionToFirstCharacterOfLine()
2319 {
2320  m_stickyColumn = -1;
2321  int c = getFirstNonBlank();
2322 
2323  Cursor cursor ( m_view->cursorPosition() );
2324  KateViRange r( cursor.line(), c, ViMotion::ExclusiveMotion );
2325 
2326  return r;
2327 }
2328 
2329 KateViRange KateViNormalMode::motionFindChar()
2330 {
2331  m_lastTFcommand = m_keys;
2332  Cursor cursor ( m_view->cursorPosition() );
2333  QString line = getLine();
2334 
2335  m_stickyColumn = -1;
2336 
2337  int matchColumn = cursor.column();
2338 
2339  for ( unsigned int i = 0; i < getCount(); i++ ) {
2340  matchColumn = line.indexOf( m_keys.right( 1 ), matchColumn+1 );
2341  if ( matchColumn == -1 )
2342  break;
2343  }
2344 
2345  KateViRange r;
2346 
2347  if (matchColumn != -1)
2348  {
2349  r.endColumn = matchColumn;
2350  r.endLine = cursor.line();
2351  }
2352  else
2353  {
2354  return KateViRange::invalid();
2355  }
2356 
2357  return r;
2358 }
2359 
2360 KateViRange KateViNormalMode::motionFindCharBackward()
2361 {
2362  m_lastTFcommand = m_keys;
2363  Cursor cursor ( m_view->cursorPosition() );
2364  QString line = getLine();
2365 
2366  m_stickyColumn = -1;
2367 
2368  int matchColumn = -1;
2369 
2370  unsigned int hits = 0;
2371  int i = cursor.column()-1;
2372 
2373  while ( hits != getCount() && i >= 0 ) {
2374  if ( line.at( i ) == m_keys.at( m_keys.size()-1 ) )
2375  hits++;
2376 
2377  if ( hits == getCount() )
2378  matchColumn = i;
2379 
2380  i--;
2381  }
2382 
2383  KateViRange r;
2384 
2385  if (matchColumn != -1)
2386  {
2387  r.endColumn = matchColumn;
2388  r.endLine = cursor.line();
2389  }
2390  else
2391  {
2392  return KateViRange::invalid();
2393  }
2394 
2395  return r;
2396 }
2397 
2398 KateViRange KateViNormalMode::motionToChar()
2399 {
2400  m_lastTFcommand = m_keys;
2401  Cursor cursor ( m_view->cursorPosition() );
2402  QString line = getLine();
2403 
2404  m_stickyColumn = -1;
2405  KateViRange r;
2406  r.endColumn = -1;
2407  r.endLine = -1;
2408 
2409  int matchColumn = cursor.column()+ (m_isRepeatedTFcommand ? 2 : 1);
2410 
2411  for ( unsigned int i = 0; i < getCount(); i++ ) {
2412  const int lastColumn = matchColumn;
2413  matchColumn = line.indexOf( m_keys.right( 1 ), matchColumn + ((i > 0) ? 1 : 0));
2414  if ( matchColumn == -1 )
2415  {
2416  if (m_isRepeatedTFcommand)
2417  {
2418  matchColumn = lastColumn;
2419  }
2420  else
2421  {
2422  return KateViRange::invalid();
2423  }
2424  break;
2425  }
2426  }
2427 
2428 
2429  r.endColumn = matchColumn-1;
2430  r.endLine = cursor.line();
2431 
2432  m_isRepeatedTFcommand = false;
2433  return r;
2434 }
2435 
2436 KateViRange KateViNormalMode::motionToCharBackward()
2437 {
2438  m_lastTFcommand = m_keys;
2439  Cursor cursor ( m_view->cursorPosition() );
2440  QString line = getLine();
2441 
2442  const int originalColumn = cursor.column();
2443  m_stickyColumn = -1;
2444 
2445  int matchColumn = originalColumn - 1;
2446 
2447  unsigned int hits = 0;
2448  int i = cursor.column()- (m_isRepeatedTFcommand ? 2 : 1);
2449 
2450  KateViRange r;
2451 
2452  while ( hits != getCount() && i >= 0 ) {
2453  if ( line.at( i ) == m_keys.at( m_keys.size()-1 ) )
2454  hits++;
2455 
2456  if ( hits == getCount() )
2457  matchColumn = i;
2458 
2459  i--;
2460  }
2461 
2462  if (hits == getCount())
2463  {
2464  r.endColumn = matchColumn+1;
2465  r.endLine = cursor.line();
2466  }
2467  else
2468  {
2469  r.valid = false;
2470  }
2471 
2472  m_isRepeatedTFcommand = false;
2473 
2474  return r;
2475 }
2476 
2477 KateViRange KateViNormalMode::motionRepeatlastTF()
2478 {
2479  if ( !m_lastTFcommand.isEmpty() ) {
2480  m_isRepeatedTFcommand = true;
2481  m_keys = m_lastTFcommand;
2482  if ( m_keys.at( 0 ) == 'f' ) {
2483  return motionFindChar();
2484  }
2485  else if ( m_keys.at( 0 ) == 'F' ) {
2486  return motionFindCharBackward();
2487  }
2488  else if ( m_keys.at( 0 ) == 't' ) {
2489  return motionToChar();
2490  }
2491  else if ( m_keys.at( 0 ) == 'T' ) {
2492  return motionToCharBackward();
2493  }
2494  }
2495 
2496  // there was no previous t/f command
2497  return KateViRange::invalid();
2498 }
2499 
2500 KateViRange KateViNormalMode::motionRepeatlastTFBackward()
2501 {
2502  if ( !m_lastTFcommand.isEmpty() ) {
2503  m_isRepeatedTFcommand = true;
2504  m_keys = m_lastTFcommand;
2505  if ( m_keys.at( 0 ) == 'f' ) {
2506  return motionFindCharBackward();
2507  }
2508  else if ( m_keys.at( 0 ) == 'F' ) {
2509  return motionFindChar();
2510  }
2511  else if ( m_keys.at( 0 ) == 't' ) {
2512  return motionToCharBackward();
2513  }
2514  else if ( m_keys.at( 0 ) == 'T' ) {
2515  return motionToChar();
2516  }
2517  }
2518 
2519  // there was no previous t/f command
2520  return KateViRange::invalid();
2521 }
2522 
2523 // FIXME: should honour the provided count
2524 KateViRange KateViNormalMode::motionFindPrev()
2525 {
2526  QString pattern = m_viInputModeManager->getLastSearchPattern();
2527  bool backwards = m_viInputModeManager->lastSearchBackwards();
2528  const bool caseSensitive = m_viInputModeManager->lastSearchCaseSensitive();
2529  const bool placeCursorAtEndOfMatch = m_viInputModeManager->lastSearchPlacesCursorAtEndOfMatch();
2530 
2531  KateViRange match = findPatternForMotion( pattern, !backwards, caseSensitive, m_view->cursorPosition(), getCount() );
2532 
2533  if (!placeCursorAtEndOfMatch)
2534  {
2535  return KateViRange(match.startLine, match.startColumn, ViMotion::ExclusiveMotion);
2536  }
2537  else
2538  {
2539  return KateViRange(match.endLine, match.endColumn - 1, ViMotion::ExclusiveMotion);
2540  }
2541 }
2542 
2543 KateViRange KateViNormalMode::motionFindNext()
2544 {
2545  QString pattern = m_viInputModeManager->getLastSearchPattern();
2546  bool backwards = m_viInputModeManager->lastSearchBackwards();
2547  const bool caseSensitive = m_viInputModeManager->lastSearchCaseSensitive();
2548  const bool placeCursorAtEndOfMatch = m_viInputModeManager->lastSearchPlacesCursorAtEndOfMatch();
2549 
2550  KateViRange match = findPatternForMotion( pattern, backwards, caseSensitive, m_view->cursorPosition(), getCount() );
2551 
2552  if (!placeCursorAtEndOfMatch)
2553  {
2554  return KateViRange(match.startLine, match.startColumn, ViMotion::ExclusiveMotion);
2555  }
2556  else
2557  {
2558  return KateViRange(match.endLine, match.endColumn - 1, ViMotion::ExclusiveMotion);
2559  }
2560 }
2561 
2562 
2563 KateViRange KateViNormalMode::motionToLineFirst()
2564 {
2565  KateViRange r( getCount()-1, 0, ViMotion::InclusiveMotion );
2566  m_stickyColumn = -1;
2567 
2568  if ( r.endLine > doc()->lines() - 1 ) {
2569  r.endLine = doc()->lines() - 1;
2570  }
2571  r.jump = true;
2572 
2573  return r;
2574 }
2575 
2576 KateViRange KateViNormalMode::motionToLineLast()
2577 {
2578  KateViRange r( doc()->lines()-1, 0, ViMotion::InclusiveMotion );
2579  m_stickyColumn = -1;
2580 
2581  // don't use getCount() here, no count and a count of 1 is different here...
2582  if ( m_count != 0 ) {
2583  r.endLine = m_count-1;
2584  }
2585 
2586  if ( r.endLine > doc()->lines() - 1 ) {
2587  r.endLine = doc()->lines() - 1;
2588  }
2589  r.jump = true;
2590 
2591  return r;
2592 }
2593 
2594 KateViRange KateViNormalMode::motionToScreenColumn()
2595 {
2596  m_stickyColumn = -1;
2597 
2598  Cursor c( m_view->cursorPosition() );
2599 
2600  int column = getCount()-1;
2601 
2602  if ( doc()->lineLength( c.line() )-1 < (int)getCount()-1 ) {
2603  column = doc()->lineLength( c.line() )-1;
2604  }
2605 
2606  return KateViRange( c.line(), column, ViMotion::ExclusiveMotion );
2607 }
2608 
2609 KateViRange KateViNormalMode::motionToMark()
2610 {
2611  KateViRange r;
2612 
2613  m_stickyColumn = -1;
2614 
2615  QChar reg = m_keys.at( m_keys.size()-1 );
2616 
2617  // ` and ' is the same register (position before jump)
2618  if ( reg == '`' ) {
2619  reg = '\'';
2620  }
2621 
2622  Cursor c = m_view->getViInputModeManager()->getMarkPosition( reg );
2623  if ( c.isValid() ) {
2624  r.endLine = c.line();
2625  r.endColumn = c.column();
2626  } else {
2627  error(i18n("Mark not set: %1",m_keys.right( 1 ) ));
2628  r.valid = false;
2629  }
2630 
2631  r.jump = true;
2632 
2633  return r;
2634 }
2635 
2636 KateViRange KateViNormalMode::motionToMarkLine()
2637 {
2638  KateViRange r = motionToMark();
2639  r.endColumn = getFirstNonBlank(r.endLine);
2640 
2641  m_stickyColumn = -1;
2642 
2643  r.jump = true;
2644 
2645  return r;
2646 }
2647 
2648 KateViRange KateViNormalMode::motionToMatchingItem()
2649 {
2650  KateViRange r;
2651  int lines = doc()->lines();
2652 
2653  // If counted, then it's not a motion to matching item anymore,
2654  // but a motion to the N'th percentage of the document
2655  if( isCounted() ) {
2656  int count = getCount();
2657  if ( count > 100 ) {
2658  return r;
2659  }
2660  r.endLine = qRound(lines * count / 100.0) - 1;
2661  r.endColumn = 0;
2662  return r;
2663  }
2664 
2665  Cursor c( m_view->cursorPosition() );
2666 
2667  QString l = getLine();
2668  int n1 = l.indexOf( m_matchItemRegex, c.column() );
2669 
2670  m_stickyColumn = -1;
2671 
2672  if ( n1 < 0 ) {
2673  return KateViRange::invalid();
2674  }
2675 
2676  QRegExp brackets( "[(){}\\[\\]]" );
2677 
2678  // use Kate's built-in matching bracket finder for brackets
2679  if ( brackets.indexIn ( l, n1 ) == n1 ) {
2680  // findMatchingBracket requires us to move the cursor to the
2681  // first bracket, but we don't want the cursor to really move
2682  // in case this is e.g. a yank, so restore it to its original
2683  // position afterwards.
2684  c.setColumn( n1 + 1 );
2685  const Cursor oldCursorPos = m_view->cursorPosition();
2686  updateCursor(c);
2687 
2688  // find the matching one
2689  c = m_viewInternal->findMatchingBracket();
2690  if ( c > m_view->cursorPosition() ) {
2691  c.setColumn( c.column() - 1 );
2692  }
2693  m_view->setCursorPosition(oldCursorPos);
2694  } else {
2695  // text item we want to find a matching item for
2696  int n2 = l.indexOf( QRegExp( "\\b|\\s|$" ), n1 );
2697  QString item = l.mid( n1, n2 - n1 );
2698  QString matchingItem = m_matchingItems[ item ];
2699 
2700  int toFind = 1;
2701  int line = c.line();
2702  int column = n2 - item.length();
2703  bool reverse = false;
2704 
2705  if ( matchingItem.left( 1 ) == "-" ) {
2706  matchingItem.remove( 0, 1 ); // remove the '-'
2707  reverse = true;
2708  }
2709 
2710  // make sure we don't hit the text item we started the search from
2711  if ( column == 0 && reverse ) {
2712  column -= item.length();
2713  }
2714 
2715  int itemIdx;
2716  int matchItemIdx;
2717 
2718  while ( toFind > 0 ) {
2719  if ( reverse ) {
2720  itemIdx = l.lastIndexOf( item, column - 1 );
2721  matchItemIdx = l.lastIndexOf( matchingItem, column - 1 );
2722 
2723  if ( itemIdx != -1 && ( matchItemIdx == -1 || itemIdx > matchItemIdx ) ) {
2724  ++toFind;
2725  }
2726  } else {
2727  itemIdx = l.indexOf( item, column );
2728  matchItemIdx = l.indexOf( matchingItem, column );
2729 
2730  if ( itemIdx != -1 && ( matchItemIdx == -1 || itemIdx < matchItemIdx ) ) {
2731  ++toFind;
2732  }
2733  }
2734 
2735  if ( matchItemIdx != -1 || itemIdx != -1 ) {
2736  if ( !reverse ) {
2737  column = qMin( (unsigned int)itemIdx, (unsigned int)matchItemIdx );
2738  } else {
2739  column = qMax( itemIdx, matchItemIdx );
2740  }
2741  }
2742 
2743  if ( matchItemIdx != -1 ) { // match on current line
2744  if ( matchItemIdx == column ) {
2745  --toFind;
2746  c.setLine( line );
2747  c.setColumn( column );
2748  }
2749  } else { // no match, advance one line if possible
2750  ( reverse ) ? --line : ++line;
2751  column = 0;
2752 
2753  if ( ( !reverse && line >= lines ) || ( reverse && line < 0 ) ) {
2754  r.valid = false;
2755  break;
2756  } else {
2757  l = getLine( line );
2758  }
2759  }
2760  }
2761  }
2762 
2763  r.endLine = c.line();
2764  r.endColumn = c.column();
2765  r.jump = true;
2766 
2767  return r;
2768 }
2769 
2770 KateViRange KateViNormalMode::motionToNextBraceBlockStart()
2771 {
2772  KateViRange r;
2773 
2774  m_stickyColumn = -1;
2775 
2776  int line = findLineStartingWitchChar( '{', getCount() );
2777 
2778  if ( line == -1 ) {
2779  return KateViRange::invalid();
2780  }
2781 
2782  r.endLine = line;
2783  r.endColumn = 0;
2784  r.jump = true;
2785 
2786  if (motionWillBeUsedWithCommand())
2787  {
2788  // Delete from cursor (inclusive) to the '{' (exclusive).
2789  // If we are on the first column, then delete the entire current line.
2790  r.motionType = ViMotion::ExclusiveMotion;
2791  if (m_view->cursorPosition().column() != 0)
2792  {
2793  r.endLine--;
2794  r.endColumn = doc()->lineLength(r.endLine);
2795  }
2796  }
2797 
2798  return r;
2799 }
2800 
2801 KateViRange KateViNormalMode::motionToPreviousBraceBlockStart()
2802 {
2803  KateViRange r;
2804 
2805  m_stickyColumn = -1;
2806 
2807  int line = findLineStartingWitchChar( '{', getCount(), false );
2808 
2809  if ( line == -1 ) {
2810  return KateViRange::invalid();
2811  }
2812 
2813  r.endLine = line;
2814  r.endColumn = 0;
2815  r.jump = true;
2816 
2817  if (motionWillBeUsedWithCommand())
2818  {
2819  // With a command, do not include the { or the cursor position.
2820  r.motionType = ViMotion::ExclusiveMotion;
2821  }
2822 
2823  return r;
2824 }
2825 
2826 KateViRange KateViNormalMode::motionToNextBraceBlockEnd()
2827 {
2828  KateViRange r;
2829 
2830  m_stickyColumn = -1;
2831 
2832  int line = findLineStartingWitchChar( '}', getCount() );
2833 
2834  if ( line == -1 ) {
2835  return KateViRange::invalid();
2836  }
2837 
2838  r.endLine = line;
2839  r.endColumn = 0;
2840  r.jump = true;
2841 
2842  if (motionWillBeUsedWithCommand())
2843  {
2844  // Delete from cursor (inclusive) to the '}' (exclusive).
2845  // If we are on the first column, then delete the entire current line.
2846  r.motionType = ViMotion::ExclusiveMotion;
2847  if (m_view->cursorPosition().column() != 0)
2848  {
2849  r.endLine--;
2850  r.endColumn = doc()->lineLength(r.endLine);
2851  }
2852  }
2853 
2854  return r;
2855 }
2856 
2857 KateViRange KateViNormalMode::motionToPreviousBraceBlockEnd()
2858 {
2859  KateViRange r;
2860 
2861  m_stickyColumn = -1;
2862 
2863  int line = findLineStartingWitchChar( '}', getCount(), false );
2864 
2865  if ( line == -1 ) {
2866  return KateViRange::invalid();
2867  }
2868 
2869  r.endLine = line;
2870  r.endColumn = 0;
2871  r.jump = true;
2872 
2873  if (motionWillBeUsedWithCommand())
2874  {
2875  r.motionType = ViMotion::ExclusiveMotion;
2876  }
2877 
2878  return r;
2879 }
2880 
2881 KateViRange KateViNormalMode::motionToNextOccurrence()
2882 {
2883  QString word = getWordUnderCursor();
2884  KateGlobal::self()->viInputModeGlobal()->appendSearchHistoryItem("\\<" + word + "\\>");
2885  word.prepend("\\b").append("\\b");
2886 
2887  m_viInputModeManager->setLastSearchPattern( word );
2888  m_viInputModeManager->setLastSearchBackwards( false );
2889  m_viInputModeManager->setLastSearchCaseSensitive( false );
2890  m_viInputModeManager->setLastSearchPlacesCursorAtEndOfMatch( false );
2891 
2892  const KateViRange match = findPatternForMotion( word, false, false, getWordRangeUnderCursor().start(), getCount() );
2893  return KateViRange(match.startLine, match.startColumn, ViMotion::ExclusiveMotion);
2894 }
2895 
2896 KateViRange KateViNormalMode::motionToPrevOccurrence()
2897 {
2898  QString word = getWordUnderCursor();
2899  KateGlobal::self()->viInputModeGlobal()->appendSearchHistoryItem("\\<" + word + "\\>");
2900  word.prepend("\\b").append("\\b");
2901 
2902  m_viInputModeManager->setLastSearchPattern( word );
2903  m_viInputModeManager->setLastSearchBackwards( true );
2904  m_viInputModeManager->setLastSearchCaseSensitive( false );
2905  m_viInputModeManager->setLastSearchPlacesCursorAtEndOfMatch( false );
2906 
2907  // Search from the beginning of the word under the cursor, so that the current word isn't found
2908  // first.
2909  const KateViRange match = findPatternForMotion( word, true, false, getWordRangeUnderCursor().start(), getCount() );
2910  return KateViRange(match.startLine, match.startColumn, ViMotion::ExclusiveMotion);
2911 }
2912 
2913 KateViRange KateViNormalMode::motionToFirstLineOfWindow() {
2914  int lines_to_go;
2915  if (linesDisplayed() <= (unsigned int) m_viewInternal->endLine())
2916  lines_to_go = m_viewInternal->endLine() - linesDisplayed()- m_view->cursorPosition().line() + 1;
2917  else
2918  lines_to_go = - m_view->cursorPosition().line();
2919 
2920  KateViRange r = goLineUpDown(lines_to_go);
2921 
2922  r.endColumn = getFirstNonBlank(r.endLine);
2923  return r;
2924 }
2925 
2926 KateViRange KateViNormalMode::motionToMiddleLineOfWindow() {
2927  int lines_to_go;
2928  if (linesDisplayed() <= (unsigned int) m_viewInternal->endLine())
2929  lines_to_go = m_viewInternal->endLine() - linesDisplayed()/2 - m_view->cursorPosition().line();
2930  else
2931  lines_to_go = m_viewInternal->endLine()/2 - m_view->cursorPosition().line();
2932  KateViRange r = goLineUpDown(lines_to_go);
2933 
2934  r.endColumn = getFirstNonBlank(r.endLine);
2935  return r;
2936 }
2937 
2938 KateViRange KateViNormalMode::motionToLastLineOfWindow() {
2939  int lines_to_go;
2940  if (linesDisplayed() <= (unsigned int) m_viewInternal->endLine())
2941  lines_to_go = m_viewInternal->endLine() - m_view->cursorPosition().line();
2942  else
2943  lines_to_go = m_viewInternal->endLine() - m_view->cursorPosition().line();
2944 
2945  KateViRange r = goLineUpDown(lines_to_go);
2946 
2947  r.endColumn = getFirstNonBlank(r.endLine);
2948  return r;
2949 }
2950 
2951 KateViRange KateViNormalMode::motionToNextVisualLine() {
2952  return goVisualLineUpDown( getCount() );
2953 }
2954 
2955 KateViRange KateViNormalMode::motionToPrevVisualLine() {
2956  return goVisualLineUpDown( -getCount() );
2957 }
2958 
2959 KateViRange KateViNormalMode::motionToPreviousSentence()
2960 {
2961  Cursor c = findSentenceStart();
2962  int linenum = c.line(), column;
2963  const bool skipSpaces = doc()->line(linenum).isEmpty();
2964 
2965  if (skipSpaces) {
2966  linenum--;
2967  if (linenum >= 0) {
2968  column = doc()->line(linenum).size() - 1;
2969  }
2970  } else {
2971  column = c.column();
2972  }
2973 
2974  for (int i = linenum; i >= 0; i--) {
2975  const QString &line = doc()->line(i);
2976 
2977  if (line.isEmpty() && !skipSpaces) {
2978  return KateViRange(i, 0, ViMotion::InclusiveMotion);
2979  }
2980 
2981  if (column < 0 && line.size() > 0) {
2982  column = line.size() - 1;
2983  }
2984 
2985  for (int j = column; j >= 0; j--) {
2986  if (skipSpaces || QString::fromLatin1(".?!").indexOf(line.at(j)) != -1) {
2987  c.setLine(i);
2988  c.setColumn(j);
2989  updateCursor(c);
2990  c = findSentenceStart();
2991  return KateViRange(c.line(), c.column(), ViMotion::InclusiveMotion);
2992  }
2993  }
2994  column = line.size() - 1;
2995  }
2996  return KateViRange(0, 0, ViMotion::InclusiveMotion);
2997 }
2998 
2999 KateViRange KateViNormalMode::motionToNextSentence()
3000 {
3001  Cursor c = findSentenceEnd();
3002  int linenum = c.line(), column = c.column() + 1;
3003  const bool skipSpaces = doc()->line(linenum).isEmpty();
3004 
3005  for (int i = linenum; i < doc()->lines(); i++) {
3006  const QString &line = doc()->line(i);
3007 
3008  if (line.isEmpty() && !skipSpaces) {
3009  return KateViRange(i, 0, ViMotion::InclusiveMotion);
3010  }
3011 
3012  for (int j = column; j < line.size(); j++) {
3013  if (!line.at(j).isSpace()) {
3014  return KateViRange(i, j, ViMotion::InclusiveMotion);
3015  }
3016  }
3017  column = 0;
3018  }
3019 
3020  c = doc()->documentEnd();
3021  return KateViRange(c.line(), c.column(), ViMotion::InclusiveMotion);
3022 }
3023 
3024 KateViRange KateViNormalMode::motionToBeforeParagraph()
3025 {
3026  Cursor c( m_view->cursorPosition() );
3027 
3028  int line = c.line();
3029 
3030  m_stickyColumn = -1;
3031 
3032  for ( unsigned int i = 0; i < getCount(); i++ ) {
3033  // advance at least one line, but if there are consecutive blank lines
3034  // skip them all
3035  do {
3036  line--;
3037  } while (line >= 0 && getLine( line+1 ).length() == 0);
3038  while ( line > 0 && getLine( line ).length() != 0 ) {
3039  line--;
3040  }
3041  }
3042 
3043  if ( line < 0 ) {
3044  line = 0;
3045  }
3046 
3047  KateViRange r( line, 0, ViMotion::InclusiveMotion );
3048 
3049  return r;
3050 }
3051 
3052 KateViRange KateViNormalMode::motionToAfterParagraph()
3053 {
3054  Cursor c( m_view->cursorPosition() );
3055 
3056  int line = c.line();
3057 
3058  m_stickyColumn = -1;
3059 
3060  for ( unsigned int i = 0; i < getCount(); i++ ) {
3061  // advance at least one line, but if there are consecutive blank lines
3062  // skip them all
3063  do {
3064  line++;
3065  } while (line <= doc()->lines()-1 && getLine( line-1 ).length() == 0);
3066  while ( line < doc()->lines()-1 && getLine( line ).length() != 0 ) {
3067  line++;
3068  }
3069  }
3070 
3071  if ( line >= doc()->lines() ) {
3072  line = doc()->lines()-1;
3073  }
3074 
3075  // if we ended up on the last line, the cursor should be placed on the last column
3076  int column = (line == doc()->lines()-1) ? qMax( getLine( line ).length()-1, 0 ) : 0;
3077 
3078  KateViRange r( line, column, ViMotion::InclusiveMotion );
3079 
3080  return r;
3081 }
3082 
3083 KateViRange KateViNormalMode::motionToIncrementalSearchMatch()
3084 {
3085  return KateViRange(m_positionWhenIncrementalSearchBegan.line(),
3086  m_positionWhenIncrementalSearchBegan.column(),
3087  m_view->cursorPosition().line(),
3088  m_view->cursorPosition().column(), ViMotion::ExclusiveMotion);
3089 }
3090 
3092 // TEXT OBJECTS
3094 
3095 KateViRange KateViNormalMode::textObjectAWord()
3096 {
3097  Cursor c( m_view->cursorPosition() );
3098 
3099  Cursor c1 = c;
3100 
3101  bool startedOnSpace = false;
3102  if (doc()->character(c).isSpace())
3103  {
3104  startedOnSpace = true;
3105  }
3106  else
3107  {
3108  c1 = findPrevWordStart( c.line(), c.column()+1, true );
3109  if (!c1.isValid())
3110  {
3111  c1 = Cursor(0, 0);
3112  }
3113  }
3114  Cursor c2 = Cursor(c.line(), c.column() - 1);
3115  for (unsigned int i = 1; i <= getCount(); i++)
3116  {
3117  c2 = findWordEnd(c2.line(), c2.column());
3118  }
3119  if (!c1.isValid() || !c2.isValid())
3120  {
3121  return KateViRange::invalid();
3122  }
3123  // Adhere to some of Vim's bizarre rules of whether to swallow ensuing spaces or not.
3124  // Don't ask ;)
3125  const Cursor nextWordStart = findNextWordStart(c2.line(), c2.column());
3126  if (nextWordStart.isValid() && nextWordStart.line() == c2.line())
3127  {
3128  if (!startedOnSpace)
3129  {
3130  c2 = Cursor(nextWordStart.line(), nextWordStart.column() - 1);
3131  }
3132  }
3133  else
3134  {
3135  c2 = Cursor(c2.line(), doc()->lineLength(c2.line()) - 1);
3136  }
3137  bool swallowCarriageReturnAtEndOfLine = false;
3138  if (c2.line() != c.line() && c2.column() == doc()->lineLength(c2.line()) - 1)
3139  {
3140  // Greedily descend to the next line, so as to swallow the carriage return on this line.
3141  c2 = Cursor(c2.line() + 1, 0);
3142  swallowCarriageReturnAtEndOfLine = true;
3143  }
3144  const bool swallowPrecedingSpaces = (c2.column() == doc()->lineLength(c2.line()) - 1 && !doc()->character(c2).isSpace() ) || startedOnSpace || swallowCarriageReturnAtEndOfLine;
3145  if (swallowPrecedingSpaces)
3146  {
3147  if (c1.column() != 0)
3148  {
3149  const Cursor previousNonSpace = findPrevWordEnd(c.line(), c.column());
3150  if (previousNonSpace.isValid() && previousNonSpace.line() == c1.line())
3151  {
3152  c1 = Cursor(previousNonSpace.line(), previousNonSpace.column() + 1);
3153  }
3154  else if (startedOnSpace || swallowCarriageReturnAtEndOfLine)
3155  {
3156  c1 = Cursor(c1.line(), 0);
3157  }
3158  }
3159  }
3160 
3161  KateViRange r( c.line(), c.column(), !swallowCarriageReturnAtEndOfLine ? ViMotion::InclusiveMotion : ViMotion::ExclusiveMotion );
3162 
3163  r.startLine = c1.line();
3164  r.endLine = c2.line();
3165  r.startColumn = c1.column();
3166  r.endColumn = c2.column();
3167 
3168  return r;
3169 }
3170 
3171 KateViRange KateViNormalMode::textObjectInnerWord()
3172 {
3173  Cursor c( m_view->cursorPosition() );
3174 
3175  Cursor c1 = findPrevWordStart( c.line(), c.column()+1, true );
3176  if (!c1.isValid())
3177  {
3178  c1 = Cursor(0, 0);
3179  }
3180  // need to start search in column-1 because it might be a one-character word
3181  Cursor c2( c.line(), c.column()-1 );
3182 
3183  for ( unsigned int i = 0; i < getCount(); i++ ) {
3184  c2 = findWordEnd( c2.line(), c2.column(), true );
3185  }
3186 
3187  if (!c2.isValid())
3188  {
3189  c2 = doc()->documentEnd();
3190  }
3191 
3192  KateViRange r;
3193 
3194  // sanity check
3195  if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
3196  return KateViRange::invalid();
3197  } else {
3198  r.startLine = c1.line();
3199  r.endLine = c2.line();
3200  r.startColumn = c1.column();
3201  r.endColumn = c2.column();
3202  }
3203 
3204  return r;
3205 }
3206 
3207 KateViRange KateViNormalMode::textObjectAWORD()
3208 {
3209  Cursor c( m_view->cursorPosition() );
3210 
3211  Cursor c1 = c;
3212 
3213  bool startedOnSpace = false;
3214  if (doc()->character(c).isSpace())
3215  {
3216  startedOnSpace = true;
3217  }
3218  else
3219  {
3220  c1 = findPrevWORDStart( c.line(), c.column()+1, true );
3221  if (!c1.isValid())
3222  {
3223  c1 = Cursor(0, 0);
3224  }
3225  }
3226  Cursor c2 = Cursor(c.line(), c.column() - 1);
3227  for (unsigned int i = 1; i <= getCount(); i++)
3228  {
3229  c2 = findWORDEnd(c2.line(), c2.column());
3230  }
3231  if (!c1.isValid() || !c2.isValid())
3232  {
3233  return KateViRange::invalid();
3234  }
3235  // Adhere to some of Vim's bizarre rules of whether to swallow ensuing spaces or not.
3236  // Don't ask ;)
3237  const Cursor nextWordStart = findNextWordStart(c2.line(), c2.column());
3238  if (nextWordStart.isValid() && nextWordStart.line() == c2.line())
3239  {
3240  if (!startedOnSpace)
3241  {
3242  c2 = Cursor(nextWordStart.line(), nextWordStart.column() - 1);
3243  }
3244  }
3245  else
3246  {
3247  c2 = Cursor(c2.line(), doc()->lineLength(c2.line()) - 1);
3248  }
3249  bool swallowCarriageReturnAtEndOfLine = false;
3250  if (c2.line() != c.line() && c2.column() == doc()->lineLength(c2.line()) - 1)
3251  {
3252  // Greedily descend to the next line, so as to swallow the carriage return on this line.
3253  c2 = Cursor(c2.line() + 1, 0);
3254  swallowCarriageReturnAtEndOfLine = true;
3255  }
3256  const bool swallowPrecedingSpaces = (c2.column() == doc()->lineLength(c2.line()) - 1 && !doc()->character(c2).isSpace() ) || startedOnSpace || swallowCarriageReturnAtEndOfLine;
3257  if (swallowPrecedingSpaces)
3258  {
3259  if (c1.column() != 0)
3260  {
3261  const Cursor previousNonSpace = findPrevWORDEnd(c.line(), c.column());
3262  if (previousNonSpace.isValid() && previousNonSpace.line() == c1.line())
3263  {
3264  c1 = Cursor(previousNonSpace.line(), previousNonSpace.column() + 1);
3265  }
3266  else if (startedOnSpace || swallowCarriageReturnAtEndOfLine)
3267  {
3268  c1 = Cursor(c1.line(), 0);
3269  }
3270  }
3271  }
3272 
3273  KateViRange r( c.line(), c.column(), !swallowCarriageReturnAtEndOfLine ? ViMotion::InclusiveMotion : ViMotion::ExclusiveMotion );
3274 
3275  r.startLine = c1.line();
3276  r.endLine = c2.line();
3277  r.startColumn = c1.column();
3278  r.endColumn = c2.column();
3279 
3280  return r;
3281 }
3282 
3283 KateViRange KateViNormalMode::textObjectInnerWORD()
3284 {
3285  Cursor c( m_view->cursorPosition() );
3286 
3287  Cursor c1 = findPrevWORDStart( c.line(), c.column()+1, true );
3288  if (!c1.isValid())
3289  {
3290  c1 = Cursor(0, 0);
3291  }
3292  Cursor c2( c );
3293 
3294  for ( unsigned int i = 0; i < getCount(); i++ ) {
3295  c2 = findWORDEnd( c2.line(), c2.column(), true );
3296  }
3297 
3298  if (!c2.isValid())
3299  {
3300  c2 = doc()->documentEnd();
3301  }
3302 
3303  KateViRange r;
3304 
3305  // sanity check
3306  if ( c1.line() != c2.line() || c1.column() > c2.column() ) {
3307  return KateViRange::invalid();
3308  } else {
3309  r.startLine = c1.line();
3310  r.endLine = c2.line();
3311  r.startColumn = c1.column();
3312  r.endColumn = c2.column();
3313  }
3314 
3315  return r;
3316 }
3317 
3318 Cursor KateViNormalMode::findSentenceStart()
3319 {
3320  Cursor c(m_view->cursorPosition());
3321  int linenum = c.line(), column = c.column();
3322  int prev = column;
3323 
3324  for (int i = linenum; i >= 0; i--) {
3325  const QString &line = doc()->line(i);
3326  if (i != linenum) {
3327  column = line.size() - 1;
3328  }
3329 
3330  // An empty line is the end of a paragraph.
3331  if (line.isEmpty()) {
3332  return Cursor((i != linenum) ? i + 1 : i, prev);
3333  }
3334 
3335  prev = column;
3336  for (int j = column; j >= 0; j--) {
3337  if (line.at(j).isSpace()) {
3338  int lastSpace = j--;
3339  for (; j >= 0 && QString::fromLatin1("\"')]").indexOf(line.at(j)) != -1; j--);
3340  if (j >= 0 && QString::fromLatin1(".!?").indexOf(line.at(j)) != -1) {
3341  return Cursor(i, prev);
3342  }
3343  j = lastSpace;
3344  } else
3345  prev = j;
3346  }
3347  }
3348 
3349  return Cursor(0, 0);
3350 }
3351 
3352 Cursor KateViNormalMode::findSentenceEnd()
3353 {
3354  Cursor c(m_view->cursorPosition());
3355  int linenum = c.line(), column = c.column();
3356  int j = 0, prev = 0;
3357 
3358  for (int i = linenum; i < doc()->lines(); i++) {
3359  const QString &line = doc()->line(i);
3360 
3361  // An empty line is the end of a paragraph.
3362  if (line.isEmpty()) {
3363  return Cursor(linenum, j);
3364  }
3365 
3366  // Iterating over the line to reach any '.', '!', '?'
3367  for (j = column; j < line.size(); j++) {
3368  if (QString::fromLatin1(".!?").indexOf(line.at(j)) != -1) {
3369  prev = j++;
3370  // Skip possible closing characters.
3371  for (; j < line.size() && QString::fromLatin1("\"')]").indexOf(line.at(j)) != -1; j++);
3372 
3373  if (j >= line.size()) {
3374  return Cursor(i, j - 1);
3375  }
3376 
3377  // And hopefully we're done...
3378  if (line.at(j).isSpace()) {
3379  return Cursor(i, j - 1);
3380  }
3381  j = prev;
3382  }
3383  }
3384  linenum = i;
3385  prev = column;
3386  column = 0;
3387  }
3388 
3389  return Cursor(linenum, j - 1);
3390 }
3391 
3392 Cursor KateViNormalMode::findParagraphStart()
3393 {
3394  Cursor c(m_view->cursorPosition());
3395  const bool firstBlank = doc()->line(c.line()).isEmpty();
3396  int prev = c.line();
3397 
3398  for (int i = prev; i >= 0; i--) {
3399  if (doc()->line(i).isEmpty()) {
3400  if (i != prev) {
3401  prev = i + 1;
3402  }
3403 
3404  /* Skip consecutive empty lines. */
3405  if (firstBlank) {
3406  i--;
3407  for (; i >= 0 && doc()->line(i).isEmpty(); i--, prev--);
3408  }
3409  return Cursor(prev, 0);
3410  }
3411  }
3412  return Cursor(0, 0);
3413 }
3414 
3415 Cursor KateViNormalMode::findParagraphEnd()
3416 {
3417  Cursor c(m_view->cursorPosition());
3418  int prev = c.line(), lines = doc()->lines();
3419  const bool firstBlank = doc()->line(prev).isEmpty();
3420 
3421  for (int i = prev; i < lines; i++) {
3422  if (doc()->line(i).isEmpty()) {
3423  if (i != prev) {
3424  prev = i - 1;
3425  }
3426 
3427  /* Skip consecutive empty lines. */
3428  if (firstBlank) {
3429  i++;
3430  for (; i < lines && doc()->line(i).isEmpty(); i++, prev++);
3431  }
3432  int length = doc()->lineLength(prev);
3433  return Cursor(prev, (length <= 0) ? 0 : length - 1);
3434  }
3435  }
3436  return doc()->documentEnd();
3437 }
3438 
3439 KateViRange KateViNormalMode::textObjectInnerSentence()
3440 {
3441  KateViRange r;
3442  Cursor c1 = findSentenceStart();
3443  Cursor c2 = findSentenceEnd();
3444  updateCursor(c1);
3445 
3446  r.startLine = c1.line();
3447  r.startColumn = c1.column();
3448  r.endLine = c2.line();
3449  r.endColumn = c2.column();
3450  return r;
3451 }
3452 
3453 KateViRange KateViNormalMode::textObjectASentence()
3454 {
3455  int i;
3456  KateViRange r = textObjectInnerSentence();
3457  const QString &line = doc()->line(r.endLine);
3458 
3459  // Skip whitespaces and tabs.
3460  for (i = r.endColumn + 1; i < line.size(); i++) {
3461  if (!line.at(i).isSpace()) {
3462  break;
3463  }
3464  }
3465  r.endColumn = i - 1;
3466 
3467  // Remove preceding spaces.
3468  if (r.startColumn != 0) {
3469  if (r.endColumn == line.size() - 1 && !line.at(r.endColumn).isSpace()) {
3470  const QString &line = doc()->line(r.startLine);
3471  for (i = r.startColumn - 1; i >= 0; i--) {
3472  if (!line.at(i).isSpace()) {
3473  break;
3474  }
3475  }
3476  r.startColumn = i + 1;
3477  }
3478  }
3479  return r;
3480 }
3481 
3482 KateViRange KateViNormalMode::textObjectInnerParagraph()
3483 {
3484  KateViRange r;
3485  Cursor c1 = findParagraphStart();
3486  Cursor c2 = findParagraphEnd();
3487  updateCursor(c1);
3488 
3489  r.startLine = c1.line();
3490  r.startColumn = c1.column();
3491  r.endLine = c2.line();
3492  r.endColumn = c2.column();
3493  return r;
3494 }
3495 
3496 KateViRange KateViNormalMode::textObjectAParagraph()
3497 {
3498  Cursor original(m_view->cursorPosition());
3499  KateViRange r = textObjectInnerParagraph();
3500  int lines = doc()->lines();
3501 
3502  if (r.endLine + 1 < lines) {
3503  // If the next line is empty, remove all subsequent empty lines.
3504  // Otherwise we'll grab the next paragraph.
3505  if (doc()->line(r.endLine + 1).isEmpty()) {
3506  for (int i = r.endLine + 1; i < lines && doc()->line(i).isEmpty(); i++) {
3507  r.endLine++;
3508  }
3509  r.endColumn = 0;
3510  } else {
3511  Cursor prev = m_view->cursorPosition();
3512  Cursor c(r.endLine + 1, 0);
3513  updateCursor(c);
3514  c = findParagraphEnd();
3515  updateCursor(prev);
3516  r.endLine = c.line();
3517  r.endColumn = c.column();
3518  }
3519  } else if (doc()->lineLength(r.startLine) > 0) {
3520  // We went too far, but maybe we can grab previous empty lines.
3521  for (int i = r.startLine - 1; i >= 0 && doc()->line(i).isEmpty(); i--) {
3522  r.startLine--;
3523  }
3524  r.startColumn = 0;
3525  updateCursor(Cursor(r.startLine, r.startColumn));
3526  } else {
3527  // We went too far and we're on empty lines, do nothing.
3528  return KateViRange::invalid();
3529  }
3530  return r;
3531 }
3532 
3533 KateViRange KateViNormalMode::textObjectAQuoteDouble()
3534 {
3535  return findSurroundingQuotes( '"', false );
3536 }
3537 
3538 KateViRange KateViNormalMode::textObjectInnerQuoteDouble()
3539 {
3540  return findSurroundingQuotes( '"', true );
3541 }
3542 
3543 KateViRange KateViNormalMode::textObjectAQuoteSingle()
3544 {
3545  return findSurroundingQuotes( '\'', false );
3546 }
3547 
3548 KateViRange KateViNormalMode::textObjectInnerQuoteSingle()
3549 {
3550  return findSurroundingQuotes( '\'', true );
3551 }
3552 
3553 KateViRange KateViNormalMode::textObjectABackQuote()
3554 {
3555  return findSurroundingQuotes( '`', false );
3556 }
3557 
3558 KateViRange KateViNormalMode::textObjectInnerBackQuote()
3559 {
3560  return findSurroundingQuotes( '`', true );
3561 }
3562 
3563 
3564 KateViRange KateViNormalMode::textObjectAParen()
3565 {
3566 
3567  return findSurroundingBrackets( '(', ')', false, '(', ')' );
3568 }
3569 
3570 KateViRange KateViNormalMode::textObjectInnerParen()
3571 {
3572 
3573  return findSurroundingBrackets( '(', ')', true, '(', ')');
3574 }
3575 
3576 KateViRange KateViNormalMode::textObjectABracket()
3577 {
3578 
3579  return findSurroundingBrackets( '[', ']', false, '[', ']' );
3580 }
3581 
3582 KateViRange KateViNormalMode::textObjectInnerBracket()
3583 {
3584 
3585  return findSurroundingBrackets( '[', ']', true, '[', ']' );
3586 }
3587 
3588 KateViRange KateViNormalMode::textObjectACurlyBracket()
3589 {
3590 
3591  return findSurroundingBrackets( '{', '}', false, '{', '}' );
3592 }
3593 
3594 KateViRange KateViNormalMode::textObjectInnerCurlyBracket()
3595 {
3596  const KateViRange allBetweenCurlyBrackets = findSurroundingBrackets( '{', '}', true, '{', '}' );
3597  // Emulate the behaviour of vim, which tries to leave the closing bracket on its own line
3598  // if it was originally on a line different to that of the opening bracket.
3599  KateViRange innerCurlyBracket(allBetweenCurlyBrackets);
3600 
3601  if (innerCurlyBracket.startLine != innerCurlyBracket.endLine)
3602  {
3603  const bool openingBraceIsLastCharOnLine = innerCurlyBracket.startColumn == doc()->line(innerCurlyBracket.startLine).length();
3604  const bool stuffToDeleteIsAllOnEndLine = openingBraceIsLastCharOnLine &&
3605  innerCurlyBracket.endLine == innerCurlyBracket.startLine + 1;
3606  const QString textLeadingClosingBracket = doc()->line(innerCurlyBracket.endLine).mid(0, innerCurlyBracket.endColumn + 1);
3607  const bool closingBracketHasLeadingNonWhitespace = !textLeadingClosingBracket.trimmed().isEmpty();
3608  if (stuffToDeleteIsAllOnEndLine)
3609  {
3610  if (!closingBracketHasLeadingNonWhitespace)
3611  {
3612  // Nothing there to select - abort.
3613  return KateViRange::invalid();
3614  }
3615  else
3616  {
3617  // Shift the beginning of the range to the start of the line containing the closing bracket.
3618  innerCurlyBracket.startLine++;
3619  innerCurlyBracket.startColumn = 0;
3620  }
3621  }
3622  else
3623  {
3624  if (openingBraceIsLastCharOnLine && !closingBracketHasLeadingNonWhitespace)
3625  {
3626  innerCurlyBracket.startLine++;
3627  innerCurlyBracket.startColumn = 0;
3628  m_lastMotionWasLinewiseInnerBlock = true;
3629  }
3630  {
3631  // The line containing the end bracket is left alone if the end bracket is preceded by just whitespace,
3632  // else we need to delete everything (i.e. end up with "{}")
3633  if (!closingBracketHasLeadingNonWhitespace)
3634  {
3635  // Shrink the endpoint of the range so that it ends at the end of the line above,
3636  // leaving the closing bracket on its own line.
3637  innerCurlyBracket.endLine--;
3638  innerCurlyBracket.endColumn = doc()->line(innerCurlyBracket.endLine).length();
3639  }
3640  }
3641  }
3642 
3643  }
3644  return innerCurlyBracket;
3645 }
3646 
3647 KateViRange KateViNormalMode::textObjectAInequalitySign()
3648 {
3649 
3650  return findSurroundingBrackets( '<', '>', false, '<', '>' );
3651 }
3652 
3653 KateViRange KateViNormalMode::textObjectInnerInequalitySign()
3654 {
3655 
3656  return findSurroundingBrackets( '<', '>', true, '<', '>' );
3657 }
3658 
3659 KateViRange KateViNormalMode::textObjectAComma()
3660 {
3661  return textObjectComma(false);
3662 }
3663 
3664 KateViRange KateViNormalMode::textObjectInnerComma()
3665 {
3666  return textObjectComma(true);
3667 }
3668 
3669 // add commands
3670 // when adding commands here, remember to add them to visual mode too (if applicable)
3671 void KateViNormalMode::initializeCommands()
3672 {
3673  ADDCMD("a", commandEnterInsertModeAppend, IS_CHANGE );
3674  ADDCMD("A", commandEnterInsertModeAppendEOL, IS_CHANGE );
3675  ADDCMD("i", commandEnterInsertMode, IS_CHANGE );
3676  ADDCMD("<insert>", commandEnterInsertMode, IS_CHANGE );
3677  ADDCMD("I", commandEnterInsertModeBeforeFirstNonBlankInLine, IS_CHANGE );
3678  ADDCMD("gi", commandEnterInsertModeLast, IS_CHANGE );
3679  ADDCMD("v", commandEnterVisualMode, 0 );
3680  ADDCMD("V", commandEnterVisualLineMode, 0 );
3681  ADDCMD("<c-v>", commandEnterVisualBlockMode, 0 );
3682  ADDCMD("gv", commandReselectVisual, SHOULD_NOT_RESET );
3683  ADDCMD("o", commandOpenNewLineUnder, IS_CHANGE );
3684  ADDCMD("O", commandOpenNewLineOver, IS_CHANGE );
3685  ADDCMD("J", commandJoinLines, IS_CHANGE );
3686  ADDCMD("c", commandChange, IS_CHANGE | NEEDS_MOTION );
3687  ADDCMD("C", commandChangeToEOL, IS_CHANGE );
3688  ADDCMD("cc", commandChangeLine, IS_CHANGE );
3689  ADDCMD("s", commandSubstituteChar, IS_CHANGE );
3690  ADDCMD("S", commandSubstituteLine, IS_CHANGE );
3691  ADDCMD("dd", commandDeleteLine, IS_CHANGE );
3692  ADDCMD("d", commandDelete, IS_CHANGE | NEEDS_MOTION );
3693  ADDCMD("D", commandDeleteToEOL, IS_CHANGE );
3694  ADDCMD("x", commandDeleteChar, IS_CHANGE );
3695  ADDCMD("<delete>", commandDeleteChar, IS_CHANGE );
3696  ADDCMD("X", commandDeleteCharBackward, IS_CHANGE );
3697  ADDCMD("gu", commandMakeLowercase, IS_CHANGE | NEEDS_MOTION );
3698  ADDCMD("guu", commandMakeLowercaseLine, IS_CHANGE );
3699  ADDCMD("gU", commandMakeUppercase, IS_CHANGE | NEEDS_MOTION );
3700  ADDCMD("gUU", commandMakeUppercaseLine, IS_CHANGE );
3701  ADDCMD("y", commandYank, NEEDS_MOTION );
3702  ADDCMD("yy", commandYankLine, 0 );
3703  ADDCMD("Y", commandYankToEOL, 0 );
3704  ADDCMD("p", commandPaste, IS_CHANGE );
3705  ADDCMD("P", commandPasteBefore, IS_CHANGE );
3706  ADDCMD("gp", commandgPaste, IS_CHANGE );
3707  ADDCMD("gP", commandgPasteBefore, IS_CHANGE );
3708  ADDCMD("]p", commandIndentedPaste, IS_CHANGE );
3709  ADDCMD("[p", commandIndentedPasteBefore, IS_CHANGE );
3710  ADDCMD("r.", commandReplaceCharacter, IS_CHANGE | REGEX_PATTERN );
3711  ADDCMD("R", commandEnterReplaceMode, IS_CHANGE );
3712  ADDCMD(":", commandSwitchToCmdLine, 0 );
3713  ADDCMD("u", commandUndo, 0);
3714  ADDCMD("<c-r>", commandRedo, 0 );
3715  ADDCMD("U", commandRedo, 0 );
3716  ADDCMD("m.", commandSetMark, REGEX_PATTERN );
3717  ADDCMD(">>", commandIndentLine, IS_CHANGE );
3718  ADDCMD("<<", commandUnindentLine, IS_CHANGE );
3719  ADDCMD(">", commandIndentLines, IS_CHANGE | NEEDS_MOTION );
3720  ADDCMD("<", commandUnindentLines, IS_CHANGE | NEEDS_MOTION );
3721  ADDCMD("<c-f>", commandScrollPageDown, 0 );
3722  ADDCMD("<pagedown>", commandScrollPageDown, 0 );
3723  ADDCMD("<c-b>", commandScrollPageUp, 0 );
3724  ADDCMD("<pageup>", commandScrollPageUp, 0 );
3725  ADDCMD("<c-u>", commandScrollHalfPageUp, 0 );
3726  ADDCMD("<c-d>", commandScrollHalfPageDown, 0 );
3727  ADDCMD("z.", commandCenterViewOnNonBlank, 0);
3728  ADDCMD("zz", commandCenterViewOnCursor, 0);
3729  ADDCMD("z<return>", commandTopViewOnNonBlank, 0);
3730  ADDCMD("zt", commandTopViewOnCursor, 0);
3731  ADDCMD("z-", commandBottomViewOnNonBlank, 0);
3732  ADDCMD("zb", commandBottomViewOnCursor, 0);
3733  ADDCMD("ga", commandPrintCharacterCode, SHOULD_NOT_RESET );
3734  ADDCMD(".", commandRepeatLastChange, 0 );
3735  ADDCMD("==", commandAlignLine, IS_CHANGE );
3736  ADDCMD("=", commandAlignLines, IS_CHANGE | NEEDS_MOTION);
3737  ADDCMD("~", commandChangeCase, IS_CHANGE );
3738  ADDCMD("g~", commandChangeCaseRange, IS_CHANGE | NEEDS_MOTION );
3739  ADDCMD("g~~", commandChangeCaseLine, IS_CHANGE );
3740  ADDCMD("<c-a>", commandAddToNumber, IS_CHANGE );
3741  ADDCMD("<c-x>", commandSubtractFromNumber, IS_CHANGE );
3742  ADDCMD("<c-o>", commandGoToPrevJump, 0);
3743  ADDCMD("<c-i>", commandGoToNextJump, 0);
3744 
3745  ADDCMD("<c-w>h",commandSwitchToLeftView,0);
3746  ADDCMD("<c-w><c-h>",commandSwitchToLeftView,0);
3747  ADDCMD("<c-w><left>",commandSwitchToLeftView,0);
3748  ADDCMD("<c-w>j",commandSwitchToDownView,0);
3749  ADDCMD("<c-w><c-j>",commandSwitchToDownView,0);
3750  ADDCMD("<c-w><down>",commandSwitchToDownView,0);
3751  ADDCMD("<c-w>k",commandSwitchToUpView,0);
3752  ADDCMD("<c-w><c-k>",commandSwitchToUpView,0);
3753  ADDCMD("<c-w><up>",commandSwitchToUpView,0);
3754  ADDCMD("<c-w>l",commandSwitchToRightView,0);
3755  ADDCMD("<c-w><c-l>",commandSwitchToRightView,0);
3756  ADDCMD("<c-w><right>",commandSwitchToRightView,0);
3757  ADDCMD("<c-w>w",commandSwitchToNextView,0);
3758  ADDCMD("<c-w><c-w>",commandSwitchToNextView,0);
3759 
3760  ADDCMD("<c-w>s", commandSplitHoriz, 0);
3761  ADDCMD("<c-w>S", commandSplitHoriz, 0);
3762  ADDCMD("<c-w><c-s>", commandSplitHoriz, 0);
3763  ADDCMD("<c-w>v", commandSplitVert, 0);
3764  ADDCMD("<c-w><c-v>", commandSplitVert, 0);
3765 
3766  ADDCMD("gt", commandSwitchToNextTab,0);
3767  ADDCMD("gT", commandSwitchToPrevTab,0);
3768 
3769  ADDCMD("gqq", commandFormatLine, IS_CHANGE);
3770  ADDCMD("gq", commandFormatLines, IS_CHANGE | NEEDS_MOTION);
3771 
3772  ADDCMD("zo", commandExpandLocal, 0 );
3773  ADDCMD("zc", commandCollapseLocal, 0 );
3774  ADDCMD("za", commandToggleRegionVisibility, 0 );
3775  ADDCMD("zr", commandExpandAll, 0 );
3776  ADDCMD("zm", commandCollapseToplevelNodes, 0 );
3777 
3778  ADDCMD("q.", commandStartRecordingMacro, REGEX_PATTERN);
3779  ADDCMD("@.", commandReplayMacro, REGEX_PATTERN);
3780 
3781  ADDCMD("ZZ", commandCloseWrite, 0);
3782  ADDCMD("ZQ", commandCloseNocheck, 0);
3783 
3784  // regular motions
3785  ADDMOTION("h", motionLeft, 0 );
3786  ADDMOTION("<left>", motionLeft, 0 );
3787  ADDMOTION("<backspace>", motionLeft, 0 );
3788  ADDMOTION("j", motionDown, 0 );
3789  ADDMOTION("<down>", motionDown, 0 );
3790  ADDMOTION("<enter>", motionDownToFirstNonBlank, 0 );
3791  ADDMOTION("<return>", motionDownToFirstNonBlank, 0 );
3792  ADDMOTION("k", motionUp, 0 );
3793  ADDMOTION("<up>", motionUp, 0 );
3794  ADDMOTION("-", motionUpToFirstNonBlank, 0 );
3795  ADDMOTION("l", motionRight, 0 );
3796  ADDMOTION("<right>", motionRight, 0 );
3797  ADDMOTION(" ", motionRight, 0 );
3798  ADDMOTION("$", motionToEOL, 0 );
3799  ADDMOTION("<end>", motionToEOL, 0 );
3800  ADDMOTION("0", motionToColumn0, 0 );
3801  ADDMOTION("<home>", motionToColumn0, 0 );
3802  ADDMOTION("^", motionToFirstCharacterOfLine, 0 );
3803  ADDMOTION("f.", motionFindChar, REGEX_PATTERN );
3804  ADDMOTION("F.", motionFindCharBackward, REGEX_PATTERN );
3805  ADDMOTION("t.", motionToChar, REGEX_PATTERN );
3806  ADDMOTION("T.", motionToCharBackward, REGEX_PATTERN );
3807  ADDMOTION(";", motionRepeatlastTF, 0 );
3808  ADDMOTION(",", motionRepeatlastTFBackward, 0 );
3809  ADDMOTION("n", motionFindNext, 0 );
3810  ADDMOTION("N", motionFindPrev, 0 );
3811  ADDMOTION("gg", motionToLineFirst, 0 );
3812  ADDMOTION("G", motionToLineLast, 0 );
3813  ADDMOTION("w", motionWordForward, IS_NOT_LINEWISE );
3814  ADDMOTION("W", motionWORDForward, IS_NOT_LINEWISE );
3815  ADDMOTION("<c-right>", motionWordForward, IS_NOT_LINEWISE);
3816  ADDMOTION("<c-left>", motionWordBackward, IS_NOT_LINEWISE);
3817  ADDMOTION("b", motionWordBackward, 0 );
3818  ADDMOTION("B", motionWORDBackward, 0 );
3819  ADDMOTION("e", motionToEndOfWord, 0 );
3820  ADDMOTION("E", motionToEndOfWORD, 0 );
3821  ADDMOTION("ge", motionToEndOfPrevWord, 0 );
3822  ADDMOTION("gE", motionToEndOfPrevWORD, 0 );
3823  ADDMOTION("|", motionToScreenColumn, 0 );
3824  ADDMOTION("%", motionToMatchingItem, IS_NOT_LINEWISE );
3825  ADDMOTION("`[a-zA-Z^><\\.\\[\\]]", motionToMark, REGEX_PATTERN );
3826  ADDMOTION("'[a-zA-Z^><]", motionToMarkLine, REGEX_PATTERN );
3827  ADDMOTION("[[", motionToPreviousBraceBlockStart, IS_NOT_LINEWISE );
3828  ADDMOTION("]]", motionToNextBraceBlockStart, IS_NOT_LINEWISE );
3829  ADDMOTION("[]", motionToPreviousBraceBlockEnd, IS_NOT_LINEWISE );
3830  ADDMOTION("][", motionToNextBraceBlockEnd, IS_NOT_LINEWISE );
3831  ADDMOTION("*", motionToNextOccurrence, 0 );
3832  ADDMOTION("#", motionToPrevOccurrence, 0 );
3833  ADDMOTION("H", motionToFirstLineOfWindow, 0 );
3834  ADDMOTION("M", motionToMiddleLineOfWindow, 0 );
3835  ADDMOTION("L", motionToLastLineOfWindow, 0 );
3836  ADDMOTION("gj", motionToNextVisualLine, 0 );
3837  ADDMOTION("gk", motionToPrevVisualLine, 0 );
3838  ADDMOTION("(", motionToPreviousSentence, 0 );
3839  ADDMOTION(")", motionToNextSentence, 0 );
3840  ADDMOTION("{", motionToBeforeParagraph, 0 );
3841  ADDMOTION("}", motionToAfterParagraph, 0 );
3842 
3843  // text objects
3844  ADDMOTION("iw", textObjectInnerWord, 0 );
3845  ADDMOTION("aw", textObjectAWord, IS_NOT_LINEWISE );
3846  ADDMOTION("iW", textObjectInnerWORD, 0 );
3847  ADDMOTION("aW", textObjectAWORD, IS_NOT_LINEWISE );
3848  ADDMOTION("is", textObjectInnerSentence, IS_NOT_LINEWISE );
3849  ADDMOTION("as", textObjectASentence, IS_NOT_LINEWISE );
3850  ADDMOTION("ip", textObjectInnerParagraph, IS_NOT_LINEWISE );
3851  ADDMOTION("ap", textObjectAParagraph, IS_NOT_LINEWISE );
3852  ADDMOTION("i\"", textObjectInnerQuoteDouble, IS_NOT_LINEWISE );
3853  ADDMOTION("a\"", textObjectAQuoteDouble, IS_NOT_LINEWISE );
3854  ADDMOTION("i'", textObjectInnerQuoteSingle, IS_NOT_LINEWISE );
3855  ADDMOTION("a'", textObjectAQuoteSingle, IS_NOT_LINEWISE );
3856  ADDMOTION("i`", textObjectInnerBackQuote, IS_NOT_LINEWISE );
3857  ADDMOTION("a`", textObjectABackQuote, IS_NOT_LINEWISE );
3858  ADDMOTION("i[()b]", textObjectInnerParen, REGEX_PATTERN | IS_NOT_LINEWISE);
3859  ADDMOTION("a[()b]", textObjectAParen, REGEX_PATTERN | IS_NOT_LINEWISE);
3860  ADDMOTION("i[{}B]", textObjectInnerCurlyBracket, REGEX_PATTERN | IS_NOT_LINEWISE);
3861  ADDMOTION("a[{}B]", textObjectACurlyBracket, REGEX_PATTERN | IS_NOT_LINEWISE);
3862  ADDMOTION("i[><]", textObjectInnerInequalitySign, REGEX_PATTERN | IS_NOT_LINEWISE);
3863  ADDMOTION("a[><]", textObjectAInequalitySign, REGEX_PATTERN | IS_NOT_LINEWISE);
3864  ADDMOTION("i[\\[\\]]", textObjectInnerBracket, REGEX_PATTERN | IS_NOT_LINEWISE);
3865  ADDMOTION("a[\\[\\]]", textObjectABracket, REGEX_PATTERN | IS_NOT_LINEWISE);
3866  ADDMOTION("i,", textObjectInnerComma, IS_NOT_LINEWISE );
3867  ADDMOTION("a,", textObjectAComma, IS_NOT_LINEWISE);
3868 
3869  ADDMOTION("/<enter>", motionToIncrementalSearchMatch, IS_NOT_LINEWISE);
3870  ADDMOTION("?<enter>", motionToIncrementalSearchMatch, IS_NOT_LINEWISE);
3871 }
3872 
3873 QRegExp KateViNormalMode::generateMatchingItemRegex()
3874 {
3875  QString pattern("\\[|\\]|\\{|\\}|\\(|\\)|");
3876  QList<QString> keys = m_matchingItems.keys();
3877 
3878  for ( int i = 0; i < keys.size(); i++ ) {
3879  QString s = m_matchingItems[ keys[ i ] ];
3880  s = s.replace( QRegExp( "^-" ), QChar() );
3881  s = s.replace( QRegExp( "\\*" ), "\\*" );
3882  s = s.replace( QRegExp( "\\+" ), "\\+" );
3883  s = s.replace( QRegExp( "\\[" ), "\\[" );
3884  s = s.replace( QRegExp( "\\]" ), "\\]" );
3885  s = s.replace( QRegExp( "\\(" ), "\\(" );
3886  s = s.replace( QRegExp( "\\)" ), "\\)" );
3887  s = s.replace( QRegExp( "\\{" ), "\\{" );
3888  s = s.replace( QRegExp( "\\}" ), "\\}" );
3889 
3890  pattern.append( s );
3891 
3892  if ( i != keys.size()-1 ) {
3893  pattern.append( '|' );
3894  }
3895  }
3896 
3897  return QRegExp( pattern );
3898 }
3899 
3900 // returns the operation mode that should be used. this is decided by using the following heuristic:
3901 // 1. if we're in visual block mode, it should be Block
3902 // 2. if we're in visual line mode OR the range spans several lines, it should be LineWise
3903 // 3. if neither of these is true, CharWise is returned
3904 // 4. there are some motion that makes all operator charwise, if we have one of them mode will be CharWise
3905 OperationMode KateViNormalMode::getOperationMode() const
3906 {
3907  OperationMode m = CharWise;
3908 
3909  if ( m_viInputModeManager->getCurrentViMode() == VisualBlockMode ) {
3910  m = Block;
3911  } else if ( m_viInputModeManager->getCurrentViMode() == VisualLineMode
3912  || ( m_commandRange.startLine != m_commandRange.endLine
3913  && m_viInputModeManager->getCurrentViMode() != VisualMode )) {
3914  m = LineWise;
3915  }
3916 
3917  if ( m_commandWithMotion && !m_linewiseCommand )
3918  m = CharWise;
3919 
3920  if (m_lastMotionWasLinewiseInnerBlock)
3921  m = LineWise;
3922 
3923  return m;
3924 }
3925 
3926 bool KateViNormalMode::paste(PasteLocation pasteLocation, bool isgPaste, bool isIndentedPaste)
3927 {
3928  Cursor pasteAt( m_view->cursorPosition() );
3929  Cursor cursorAfterPaste = pasteAt;
3930  QChar reg = getChosenRegister( m_defaultRegister );
3931 
3932  OperationMode m = getRegisterFlag( reg );
3933  QString textToInsert = getRegisterContent( reg );
3934  const bool isTextMultiLine = textToInsert.split("\n").count() > 1;
3935 
3936  // In temporary normal mode, p/P act as gp/gP.
3937  isgPaste |= m_viInputModeManager->getTemporaryNormalMode();
3938 
3939  if ( textToInsert.isEmpty() ) {
3940  error(i18n("Nothing in register %1", reg ));
3941  return false;
3942  }
3943 
3944  if ( getCount() > 1 ) {
3945  textToInsert = textToInsert.repeated( getCount() ); // FIXME: does this make sense for blocks?
3946  }
3947 
3948 
3949  if ( m == LineWise ) {
3950  pasteAt.setColumn( 0 );
3951  if (isIndentedPaste)
3952  {
3953  // Note that this does indeed work if there is no non-whitespace on the current line or if
3954  // the line is empty!
3955  const QString leadingWhiteSpaceOnCurrentLine = doc()->line(pasteAt.line()).mid(0, doc()->line(pasteAt.line()).indexOf(QRegExp("[^\\s]")));
3956  const QString leadingWhiteSpaceOnFirstPastedLine = textToInsert.mid(0, textToInsert.indexOf(QRegExp("[^\\s]")));
3957  // QString has no "left trim" method, bizarrely.
3958  while (textToInsert[0].isSpace())
3959  {
3960  textToInsert = textToInsert.mid(1);
3961  }
3962  textToInsert.prepend(leadingWhiteSpaceOnCurrentLine);
3963  // Remove the last \n, temporarily: we're going to alter the indentation of each pasted line
3964  // by doing a search and replace on '\n's, but don't want to alter this one.
3965  textToInsert.chop( 1 );
3966  textToInsert.replace(QString('\n') + leadingWhiteSpaceOnFirstPastedLine, QString('\n') + leadingWhiteSpaceOnCurrentLine);
3967  textToInsert.append('\n'); // Re-add the temporarily removed last '\n'.
3968  }
3969  if (pasteLocation == AfterCurrentPosition)
3970  {
3971  textToInsert.chop( 1 ); // remove the last \n
3972  pasteAt.setColumn( doc()->lineLength( pasteAt.line() ) ); // paste after the current line and ...
3973  textToInsert.prepend( QChar( '\n' ) ); // ... prepend a \n, so the text starts on a new line
3974 
3975  cursorAfterPaste.setLine( cursorAfterPaste.line()+1 );
3976  }
3977  if (isgPaste)
3978  {
3979  cursorAfterPaste.setLine(cursorAfterPaste.line() + textToInsert.split("\n").length() - 1);
3980  }
3981  } else {
3982  if (pasteLocation == AfterCurrentPosition)
3983  {
3984  // Move cursor forward one before we paste. The position after the paste must also
3985  // be updated accordingly.
3986  if ( getLine( pasteAt.line() ).length() > 0 ) {
3987  pasteAt.setColumn( pasteAt.column()+1 );
3988  }
3989  cursorAfterPaste = pasteAt;
3990  }
3991  const bool leaveCursorAtStartOfPaste = isTextMultiLine && !isgPaste;
3992  if (!leaveCursorAtStartOfPaste)
3993  {
3994  cursorAfterPaste = cursorPosAtEndOfPaste(pasteAt, textToInsert);
3995  if (!isgPaste)
3996  {
3997  cursorAfterPaste.setColumn(cursorAfterPaste.column() - 1);
3998  }
3999  }
4000  }
4001 
4002  doc()->editBegin();
4003  if (m_view->selection())
4004  {
4005  pasteAt = m_view->selectionRange().start();
4006  doc()->removeText(m_view->selectionRange());
4007  }
4008  doc()->insertText( pasteAt, textToInsert, m == Block );
4009  doc()->editEnd();
4010 
4011  if (cursorAfterPaste.line() >= doc()->lines())
4012  {
4013  cursorAfterPaste.setLine(doc()->lines() - 1);
4014  }
4015  updateCursor( cursorAfterPaste );
4016 
4017  return true;
4018 }
4019 
4020 Cursor KateViNormalMode::cursorPosAtEndOfPaste(const Cursor& pasteLocation, const QString& pastedText)
4021 {
4022  Cursor cAfter = pasteLocation;
4023  const QStringList textLines = pastedText.split("\n");
4024  if (textLines.length() == 1)
4025  {
4026  cAfter.setColumn(cAfter.column() + pastedText.length());
4027  }
4028  else
4029  {
4030  cAfter.setColumn(textLines.last().length() - 0);
4031  cAfter.setLine(cAfter.line() + textLines.length() - 1);
4032  }
4033  return cAfter;
4034 }
4035 
4036 void KateViNormalMode::joinLines(unsigned int from, unsigned int to) const
4037 {
4038  // make sure we don't try to join lines past the document end
4039  if ( to >= (unsigned int)(doc()->lines()) ) {
4040  to = doc()->lines()-1;
4041  }
4042 
4043  // joining one line is a no-op
4044  if ( from == to ) return;
4045 
4046  doc()->joinLines( from, to );
4047 }
4048 
4049 void KateViNormalMode::reformatLines(unsigned int from, unsigned int to) const
4050 {
4051  joinLines( from, to );
4052  doc()->wrapText( from, to );
4053 }
4054 
4055 int KateViNormalMode::getFirstNonBlank(int line) const
4056 {
4057  if (line < 0) {
4058  line = m_view->cursorPosition().line();
4059  }
4060 
4061  // doc()->plainKateTextLine returns NULL if the line is out of bounds.
4062  Kate::TextLine l = doc()->plainKateTextLine(line);
4063  Q_ASSERT(l);
4064 
4065  int c = l->firstChar();
4066  return (c < 0) ? 0 : c;
4067 }
4068 
4069 // Tries to shrinks toShrink so that it fits tightly around rangeToShrinkTo.
4070 void KateViNormalMode::shrinkRangeAroundCursor(KateViRange& toShrink, const KateViRange& rangeToShrinkTo)
4071 {
4072  if (!toShrink.valid || !rangeToShrinkTo.valid)
4073  {
4074  return;
4075  }
4076  Cursor cursorPos = m_view->cursorPosition();
4077  if (rangeToShrinkTo.startLine >= cursorPos.line())
4078  {
4079  if (rangeToShrinkTo.startLine > cursorPos.line())
4080  {
4081  // Does not surround cursor; aborting.
4082  return;
4083  }
4084  Q_ASSERT(rangeToShrinkTo.startLine == cursorPos.line());
4085  if (rangeToShrinkTo.startColumn > cursorPos.column())
4086  {
4087  // Does not surround cursor; aborting.
4088  return;
4089  }
4090  }
4091  if (rangeToShrinkTo.endLine <= cursorPos.line())
4092  {
4093  if (rangeToShrinkTo.endLine < cursorPos.line())
4094  {
4095  // Does not surround cursor; aborting.
4096  return;
4097  }
4098  Q_ASSERT(rangeToShrinkTo.endLine == cursorPos.line());
4099  if (rangeToShrinkTo.endColumn < cursorPos.column())
4100  {
4101  // Does not surround cursor; aborting.
4102  return;
4103  }
4104  }
4105 
4106  if (toShrink.startLine <= rangeToShrinkTo.startLine)
4107  {
4108  if (toShrink.startLine < rangeToShrinkTo.startLine)
4109  {
4110  toShrink.startLine = rangeToShrinkTo.startLine;
4111  toShrink.startColumn = rangeToShrinkTo.startColumn;
4112  }
4113  Q_ASSERT(toShrink.startLine == rangeToShrinkTo.startLine);
4114  if (toShrink.startColumn < rangeToShrinkTo.startColumn)
4115  {
4116  toShrink.startColumn = rangeToShrinkTo.startColumn;
4117  }
4118  }
4119  if (toShrink.endLine >= rangeToShrinkTo.endLine)
4120  {
4121  if (toShrink.endLine > rangeToShrinkTo.endLine)
4122  {
4123  toShrink.endLine = rangeToShrinkTo.endLine;
4124  toShrink.endColumn = rangeToShrinkTo.endColumn;
4125  }
4126  Q_ASSERT(toShrink.endLine == rangeToShrinkTo.endLine);
4127  if (toShrink.endColumn > rangeToShrinkTo.endColumn)
4128  {
4129  toShrink.endColumn = rangeToShrinkTo.endColumn;
4130  }
4131  }
4132 }
4133 
4134 KateViRange KateViNormalMode::textObjectComma(bool inner)
4135 {
4136  // Basic algorithm: look left and right of the cursor for all combinations
4137  // of enclosing commas and the various types of brackets, and pick the pair
4138  // closest to the cursor that surrounds the cursor.
4139  KateViRange r(0, 0, m_view->doc()->lines(), m_view->doc()->line(m_view->doc()->lastLine()).length(), ViMotion::InclusiveMotion);
4140 
4141  shrinkRangeAroundCursor(r, findSurroundingQuotes( ',', inner ));
4142  shrinkRangeAroundCursor(r, findSurroundingBrackets( '(', ')', inner, '(', ')' ));
4143  shrinkRangeAroundCursor(r, findSurroundingBrackets( '{', '}', inner, '{', '}' ));
4144  shrinkRangeAroundCursor(r, findSurroundingBrackets( ',', ')', inner, '(', ')' ));
4145  shrinkRangeAroundCursor(r, findSurroundingBrackets( ',', ']', inner, '[', ']' ));
4146  shrinkRangeAroundCursor(r, findSurroundingBrackets( ',', '}', inner, '{', '}' ));
4147  shrinkRangeAroundCursor(r, findSurroundingBrackets( '(', ',', inner, '(', ')' ));
4148  shrinkRangeAroundCursor(r, findSurroundingBrackets( '[', ',', inner, '[', ']' ));
4149  shrinkRangeAroundCursor(r, findSurroundingBrackets( '{', ',', inner, '{', '}' ));
4150  return r;
4151 }
4152 
4153 void KateViNormalMode::updateYankHighlightAttrib()
4154 {
4155  if (!m_highlightYankAttribute)
4156  {
4157  m_highlightYankAttribute = new KTextEditor::Attribute;
4158  }
4159  const QColor& yankedColor = m_view->renderer()->config()->savedLineColor();
4160  m_highlightYankAttribute->setBackground(yankedColor);
4161  KTextEditor::Attribute::Ptr mouseInAttribute(new KTextEditor::Attribute());
4162  mouseInAttribute->setFontBold(true);
4163  m_highlightYankAttribute->setDynamicAttribute (KTextEditor::Attribute::ActivateMouseIn, mouseInAttribute);
4164  m_highlightYankAttribute->dynamicAttribute (KTextEditor::Attribute::ActivateMouseIn)->setBackground(yankedColor);
4165 }
4166 
4167 void KateViNormalMode::highlightYank(const KateViRange& range, const OperationMode mode)
4168 {
4169  clearYankHighlight();
4170 
4171  // current MovingRange doesn't support block mode selection so split the
4172  // block range into per-line ranges
4173  if (mode == Block)
4174  {
4175  for (int i = range.startLine; i <= range.endLine; i++)
4176  addHighlightYank( Range(i, range.startColumn, i, range.endColumn) );
4177  }
4178  else
4179  addHighlightYank( Range(range.startLine, range.startColumn, range.endLine, range.endColumn) );
4180 }
4181 
4182 void KateViNormalMode::addHighlightYank(const Range& yankRange)
4183 {
4184  KTextEditor::MovingRange *highlightedYank = m_view->doc()->newMovingRange(yankRange, Kate::TextRange::DoNotExpand);
4185  highlightedYank->setView(m_view); // show only in this view
4186  highlightedYank->setAttributeOnlyForViews(true);
4187  // use z depth defined in moving ranges interface
4188  highlightedYank->setZDepth (-10000.0);
4189  highlightedYank->setAttribute(m_highlightYankAttribute);
4190 
4191  highlightedYankForDocument().insert(highlightedYank);
4192 }
4193 
4194 void KateViNormalMode::clearYankHighlight()
4195 {
4196  QSet<KTextEditor::MovingRange *> &pHighlightedYanks = highlightedYankForDocument();
4197  qDeleteAll(pHighlightedYanks);
4198  pHighlightedYanks.clear();
4199 }
4200 
4201 void KateViNormalMode::aboutToDeleteMovingInterfaceContent()
4202 {
4203  QSet<KTextEditor::MovingRange *> &pHighlightedYanks = highlightedYankForDocument();
4204  // Prevent double-deletion in case this KateViNormalMode is deleted.
4205  pHighlightedYanks.clear();
4206 }
4207 
4208 QSet<KTextEditor::MovingRange *> &KateViNormalMode::highlightedYankForDocument()
4209 {
4210  // Work around the fact that both Normal and Visual mode will have their own m_highlightedYank -
4211  // make Normal's the canonical one.
4212  return m_viInputModeManager->getViNormalMode()->m_highlightedYanks;
4213 }
4214 
4215 bool KateViNormalMode::waitingForRegisterOrCharToSearch()
4216 {
4217  if (m_keys.size() != 1) {
4218  return false;
4219  }
4220 
4221  QChar lastChar = m_keys[0];
4222  return (lastChar == 'f' || lastChar == 't' || lastChar == 'F' || lastChar == 'T' || lastChar == 'r' || lastChar == 'q' || lastChar == '@');
4223 }
4224 
4225 void KateViNormalMode::textInserted(KTextEditor::Document* document, Range range)
4226 {
4227  Q_UNUSED(document);
4228  const bool isInsertMode = m_viInputModeManager->getCurrentViMode() == InsertMode;
4229  const bool continuesInsertion = range.start().line() == m_currentChangeEndMarker.line() && range.start().column() == m_currentChangeEndMarker.column();
4230  const bool beginsWithNewline = doc()->text(range)[0] == '\n';
4231  if (!continuesInsertion)
4232  {
4233  Cursor newBeginMarkerPos = range.start();
4234  if (beginsWithNewline && !isInsertMode)
4235  {
4236  // Presumably a linewise paste, in which case we ignore the leading '\n'
4237  newBeginMarkerPos = Cursor(newBeginMarkerPos.line() + 1, 0);
4238  }
4239  m_viInputModeManager->addMark(doc(), '[', newBeginMarkerPos, false);
4240  }
4241  m_viInputModeManager->addMark(doc(), '.', range.start());
4242  Cursor editEndMarker = range.end();
4243  if (!isInsertMode)
4244  {
4245  editEndMarker.setColumn(editEndMarker.column() - 1);
4246  }
4247  m_viInputModeManager->addMark(doc(), ']', editEndMarker);
4248  m_currentChangeEndMarker = range.end();
4249  if (m_isUndo)
4250  {
4251  const bool addsMultipleLines = range.start().line() != range.end().line();
4252  m_viInputModeManager->addMark(doc(), '[', Cursor(m_viInputModeManager->getMarkPosition('[').line(), 0));
4253  if (addsMultipleLines)
4254  {
4255  m_viInputModeManager->addMark(doc(), ']', Cursor(m_viInputModeManager->getMarkPosition(']').line() + 1, 0));
4256  m_viInputModeManager->addMark(doc(), '.', Cursor(m_viInputModeManager->getMarkPosition('.').line() + 1, 0));
4257  }
4258  else
4259  {
4260  m_viInputModeManager->addMark(doc(), ']', Cursor(m_viInputModeManager->getMarkPosition(']').line(), 0));
4261  m_viInputModeManager->addMark(doc(), '.', Cursor(m_viInputModeManager->getMarkPosition('.').line(), 0));
4262  }
4263  }
4264 }
4265 
4266 void KateViNormalMode::textRemoved(KTextEditor::Document* document , Range range)
4267 {
4268  Q_UNUSED(document);
4269  const bool isInsertMode = m_viInputModeManager->getCurrentViMode() == InsertMode;
4270  m_viInputModeManager->addMark(doc(), '.', range.start());
4271  if (!isInsertMode)
4272  {
4273  // Don't go resetting [ just because we did a Ctrl-h!
4274  m_viInputModeManager->addMark(doc(), '[', range.start());
4275  }
4276  else
4277  {
4278  // Don't go disrupting our continued insertion just because we did a Ctrl-h!
4279  m_currentChangeEndMarker = range.start();
4280  }
4281  m_viInputModeManager->addMark(doc(), ']', range.start());
4282  if (m_isUndo)
4283  {
4284  // Slavishly follow Vim's weird rules: if an undo removes several lines, then all markers should
4285  // be at the beginning of the line after the last line removed, else they should at the beginning
4286  // of the line above that.
4287  const int markerLineAdjustment = (range.start().line() != range.end().line()) ? 1 : 0;
4288  m_viInputModeManager->addMark(doc(), '[', Cursor(m_viInputModeManager->getMarkPosition('[').line() + markerLineAdjustment, 0));
4289  m_viInputModeManager->addMark(doc(), ']', Cursor(m_viInputModeManager->getMarkPosition(']').line() + markerLineAdjustment, 0));
4290  m_viInputModeManager->addMark(doc(), '.', Cursor(m_viInputModeManager->getMarkPosition('.').line() + markerLineAdjustment, 0));
4291  }
4292 }
4293 
4294 void KateViNormalMode::undoBeginning()
4295 {
4296  m_isUndo = true;
4297 }
4298 
4299 void KateViNormalMode::undoEnded()
4300 {
4301  m_isUndo = false;
4302 }
4303 
katevinormalmode.h
KateDocument::line
virtual QString line(int line) const
Definition: katedocument.cpp:447
KateViNormalMode::motionToLineLast
KateViRange motionToLineLast()
Definition: katevinormalmode.cpp:2576
KateDocument::align
void align(KateView *view, const KTextEditor::Range &range)
Definition: katedocument.cpp:2909
KateViRange::endLine
int endLine
Definition: katevirange.h:44
KateViNormalMode::motionLeft
KateViRange motionLeft()
Definition: katevinormalmode.cpp:2027
KateViNormalMode::commandFormatLines
bool commandFormatLines()
Definition: katevinormalmode.cpp:1922
KateDocument::insertLine
virtual bool insertLine(int line, const QString &s)
Definition: katedocument.cpp:701
InsertMode
Definition: kateviinputmodemanager.h:50
KateViNormalMode::textObjectInnerSentence
KateViRange textObjectInnerSentence()
Definition: katevinormalmode.cpp:3439
KateViInputModeManager::replayMacro
void replayMacro(QChar macroRegister)
Definition: kateviinputmodemanager.cpp:346
KateViInputModeManager::finishRecordingMacro
void finishRecordingMacro()
Definition: kateviinputmodemanager.cpp:334
KateViRange::jump
bool jump
Definition: katevirange.h:47
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KateViNormalMode::commandEnterInsertModeAppendEOL
bool commandEnterInsertModeAppendEOL()
start insert mode after the last character of the line
Definition: katevinormalmode.cpp:603
KateViNormalMode::commandEnterInsertModeAppend
bool commandEnterInsertModeAppend()
enter insert mode after the current character
Definition: katevinormalmode.cpp:577
KateViNormalMode::commandSetMark
bool commandSetMark()
Definition: katevinormalmode.cpp:1557
KateViNormalMode::paste
bool paste(KateViNormalMode::PasteLocation pasteLocation, bool isgPaste, bool isIndentedPaste)
Definition: katevinormalmode.cpp:3926
KateViModeBase::findWORDEnd
Cursor findWORDEnd(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:645
QKeyEvent::modifiers
Qt::KeyboardModifiers modifiers() const
kateviemulatedcommandbar.h
QString::append
QString & append(QChar ch)
Kate::Script::i18n
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
Definition: katescripthelpers.cpp:186
KateViInputModeManager::getTemporaryNormalMode
bool getTemporaryNormalMode()
Definition: kateviinputmodemanager.h:239
KateViModeBase::findPrevWORDStart
Cursor findPrevWORDStart(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:557
KateRenderer::Block
Definition: katerenderer.h:71
KateViNormalMode::commandTopViewOnCursor
bool commandTopViewOnCursor()
Definition: katevinormalmode.cpp:1696
KateViNormalMode::PasteLocation
PasteLocation
Definition: katevinormalmode.h:308
KateViNormalMode::commandAlignLine
bool commandAlignLine()
Definition: katevinormalmode.cpp:1768
QString::toUpper
QString toUpper() const
KateViNormalMode::addHighlightYank
void addHighlightYank(const Range &range)
Definition: katevinormalmode.cpp:4182
KateViModeBase::getRegisterFlag
OperationMode getRegisterFlag(const QChar &reg) const
Definition: katevimodebase.cpp:958
KateDocument::newMovingRange
virtual KTextEditor::MovingRange * newMovingRange(const KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors=KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::EmptyBehavior emptyBehavior=KTextEditor::MovingRange::AllowEmpty)
Create a new moving range for this document.
Definition: katedocument.cpp:4741
KateViNormalMode::reformatLines
void reformatLines(unsigned int from, unsigned int to) const
Definition: katevinormalmode.cpp:4049
KateViRange::normalize
void normalize()
Definition: katevirange.cpp:53
KateViNormalMode::initializeCommands
void initializeCommands()
Definition: katevinormalmode.cpp:3671
CharWise
Definition: katevimodebase.h:50
KateViModeBase::findSurroundingQuotes
KateViRange findSurroundingQuotes(const QChar &c, bool inner=false) const
Definition: katevimodebase.cpp:697
KateView::renderer
KateRenderer * renderer()
Definition: kateview.cpp:1664
KateViNormalMode::m_commandShouldKeepSelection
bool m_commandShouldKeepSelection
Definition: katevinormalmode.h:353
KateViNormalMode::commandPrintCharacterCode
bool commandPrintCharacterCode()
Definition: katevinormalmode.cpp:1732
KateViNormalMode::commandAbort
bool commandAbort()
Definition: katevinormalmode.cpp:1725
KateViNormalMode::motionToEndOfWORD
KateViRange motionToEndOfWORD()
Definition: katevinormalmode.cpp:2218
KateViNormalMode::commandUndo
bool commandUndo()
Definition: katevinormalmode.cpp:1524
KateViNormalMode::reset
virtual void reset()
Definition: katevinormalmode.cpp:479
katevivisualmode.h
KateDocument::editBegin
void editBegin()
Alias for editStart()
Definition: katedocument.h:213
KateViNormalMode::motionToNextBraceBlockEnd
KateViRange motionToNextBraceBlockEnd()
Definition: katevinormalmode.cpp:2826
KateViModeBase::getWordUnderCursor
const QString getWordUnderCursor() const
Definition: katevimodebase.cpp:141
KateViNormalMode::motionToIncrementalSearchMatch
KateViRange motionToIncrementalSearchMatch()
Definition: katevinormalmode.cpp:3083
KateViNormalMode::commandCenterViewOnNonBlank
bool commandCenterViewOnNonBlank()
Definition: katevinormalmode.cpp:1667
QList::length
int length() const
KateViModeBase::getCharUnderCursor
const QChar getCharUnderCursor() const
Definition: katevimodebase.cpp:128
KateViNormalMode::motionToNextBraceBlockStart
KateViRange motionToNextBraceBlockStart()
Definition: katevinormalmode.cpp:2770
KateViNormalMode::m_motionOperatorIndex
int m_motionOperatorIndex
Definition: katevinormalmode.h:341
KateViInputModeManager::addMark
void addMark(KateDocument *doc, const QChar &mark, const KTextEditor::Cursor &pos, const bool moveoninsert=true, const bool showmark=true)
Add a mark to the document.
Definition: kateviinputmodemanager.cpp:737
KateDocument::redo
void redo()
Definition: katedocument.cpp:1380
KateViNormalMode::commandIndentLine
bool commandIndentLine()
Definition: katevinormalmode.cpp:1567
KateViNormalMode::m_positionWhenIncrementalSearchBegan
Cursor m_positionWhenIncrementalSearchBegan
Definition: katevinormalmode.h:383
KateViNormalMode::findParagraphEnd
Cursor findParagraphEnd()
Definition: katevinormalmode.cpp:3415
KateViNormalMode::commandMakeUppercase
bool commandMakeUppercase()
Definition: katevinormalmode.cpp:864
KateViModeBase::m_currentMotionWasVisualLineUpOrDown
bool m_currentMotionWasVisualLineUpOrDown
Definition: katevimodebase.h:170
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KateViNormalMode::m_matchingCommands
QVector< int > m_matchingCommands
Definition: katevinormalmode.h:338
KateViModeBase::doc
KateDocument * doc() const
Definition: katevimodebase.h:172
KateViNormalMode::commandEnterVisualLineMode
bool commandEnterVisualLineMode()
Definition: katevinormalmode.cpp:641
KateView::setCaretStyle
void setCaretStyle(KateRenderer::caretStyles style, bool repaint=false)
Set the caret's style.
Definition: kateview.cpp:2413
QString::prepend
QString & prepend(QChar ch)
KateDocument::lineLength
virtual int lineLength(int line) const
Definition: katedocument.cpp:758
KateViNormalMode::motionToEOL
KateViRange motionToEOL()
Definition: katevinormalmode.cpp:2293
KateViNormalMode::commandScrollHalfPageDown
bool commandScrollHalfPageDown()
Definition: katevinormalmode.cpp:1644
KateViNormalMode::commandEnterVisualMode
bool commandEnterVisualMode()
Definition: katevinormalmode.cpp:696
KateCommandLineBar::setText
void setText(const QString &text, bool selected=true)
Definition: kateviewhelpers.cpp:839
QStack::push
void push(const T &t)
KateViNormalMode::waitingForRegisterOrCharToSearch
bool waitingForRegisterOrCharToSearch()
Definition: katevinormalmode.cpp:4215
KateViNormalMode::commandJoinLines
bool commandJoinLines()
Definition: katevinormalmode.cpp:1079
KateViNormalMode::motionWORDForward
KateViRange motionWORDForward()
Definition: katevinormalmode.cpp:2157
KateViModeBase::m_count
unsigned int m_count
Definition: katevimodebase.h:161
KateViNormalMode::generateMatchingItemRegex
QRegExp generateMatchingItemRegex()
Definition: katevinormalmode.cpp:3873
Kate::TextFolding::visibleLineToLine
int visibleLineToLine(int visibleLine) const
Convert a visible line number to a line number in the text buffer.
Definition: katetextfolding.cpp:422
KateViNormalMode::motionToMarkLine
KateViRange motionToMarkLine()
Definition: katevinormalmode.cpp:2636
KateViModeBase
Definition: katevimodebase.h:64
VisualMode
Definition: kateviinputmodemanager.h:51
KateViInputModeManager::setLastSearchBackwards
void setLastSearchBackwards(bool b)
set search direction of last search.
Definition: kateviinputmodemanager.h:229
QString::size
int size() const
KateViewInternal::pageUp
void pageUp(bool sel=false, bool half=false)
Definition: kateviewinternal.cpp:1544
KateViInputModeManager
Definition: kateviinputmodemanager.h:68
KateViNormalMode::textObjectAParagraph
KateViRange textObjectAParagraph()
Definition: katevinormalmode.cpp:3496
KateViNormalMode::textObjectAWord
KateViRange textObjectAWord()
Definition: katevinormalmode.cpp:3095
KateViNormalMode::executeCommand
void executeCommand(const KateViCommand *cmd)
Definition: katevinormalmode.cpp:511
KateViEmulatedCommandBar::Command
Definition: kateviemulatedcommandbar.h:44
KateViNormalMode::motionToBeforeParagraph
KateViRange motionToBeforeParagraph()
Definition: katevinormalmode.cpp:3024
KateView::showViModeEmulatedCommandBar
void showViModeEmulatedCommandBar()
Definition: kateview.cpp:1560
KateViNormalMode::commandEnterReplaceMode
bool commandEnterReplaceMode()
Definition: katevinormalmode.cpp:716
KateViNormalMode::textObjectAWORD
KateViRange textObjectAWORD()
Definition: katevinormalmode.cpp:3207
KateViNormalMode::commandBottomView
bool commandBottomView(bool onFirst)
Definition: katevinormalmode.cpp:1701
KateViNormalMode::textObjectAComma
KateViRange textObjectAComma()
Definition: katevinormalmode.cpp:3659
KateViInputModeManager::startRecordingMacro
void startRecordingMacro(QChar macroRegister)
Definition: kateviinputmodemanager.cpp:323
KateViNormalMode::textObjectInnerWORD
KateViRange textObjectInnerWORD()
Definition: katevinormalmode.cpp:3283
KateViRange::invalid
static KateViRange invalid()
Definition: katevirange.h:56
KateViKeyMapper::setDoNotMapNextKeypress
void setDoNotMapNextKeypress()
Definition: katevikeymapper.cpp:130
KateGlobal::self
static KateGlobal * self()
Kate Part Internal stuff ;)
Definition: kateglobal.cpp:465
KateViNormalMode::getFirstNonBlank
int getFirstNonBlank(int line=-1) const
Get the index of the first non-blank character from the given line.
Definition: katevinormalmode.cpp:4055
KateViNormalMode::m_pendingResetIsDueToExit
bool m_pendingResetIsDueToExit
Definition: katevinormalmode.h:370
NormalMode
Definition: kateviinputmodemanager.h:49
KateViNormalMode::findSentenceEnd
Cursor findSentenceEnd()
Definition: katevinormalmode.cpp:3352
QSet::insert
const_iterator insert(const T &value)
QString::remove
QString & remove(int position, int n)
KateViKeyParser::KeyEventToQChar
const QChar KeyEventToQChar(const QKeyEvent &keyEvent)
Definition: katevikeyparser.cpp:674
KateView::textFolding
Kate::TextFolding & textFolding()
Folding handler for this view.
Definition: kateview.h:574
KateView::setCursorPosition
bool setCursorPosition(KTextEditor::Cursor position)
Definition: kateview.cpp:2418
KateViNormalMode::motionToLineFirst
KateViRange motionToLineFirst()
Definition: katevinormalmode.cpp:2563
QString::chop
void chop(int n)
KateViModeBase::m_commandRange
KateViRange m_commandRange
Definition: katevimodebase.h:160
KateViRange::startColumn
int startColumn
Definition: katevirange.h:41
KateViNormalMode::commandgPasteBefore
bool commandgPasteBefore()
Definition: katevinormalmode.cpp:1344
KateViNormalMode::motionToPrevVisualLine
KateViRange motionToPrevVisualLine()
Definition: katevinormalmode.cpp:2955
KateDocument::plainKateTextLine
Kate::TextLine plainKateTextLine(uint i)
Definition: katedocument.cpp:4712
KateViNormalMode::commandReplayMacro
bool commandReplayMacro()
Definition: katevinormalmode.cpp:1944
KateDocument::indent
void indent(KTextEditor::Range range, int change)
Definition: katedocument.cpp:2899
KateViModeBase::getRange
const QString getRange(KateViRange &r, OperationMode mode=LineWise) const
Definition: katevimodebase.cpp:95
KateViNormalMode::m_commands
QVector< KateViCommand * > m_commands
Definition: katevinormalmode.h:336
KateViNormalMode::motionToFirstCharacterOfLine
KateViRange motionToFirstCharacterOfLine()
Definition: katevinormalmode.cpp:2318
KateViNormalMode::commandReplaceCharacter
bool commandReplaceCharacter()
Definition: katevinormalmode.cpp:1410
KateViNormalMode::textObjectInnerParagraph
KateViRange textObjectInnerParagraph()
Definition: katevinormalmode.cpp:3482
KateView::getViInputModeManager
KateViInputModeManager * getViInputModeManager()
Definition: kateview.cpp:1587
KateViNormalMode::commandRedo
bool commandRedo()
Definition: katevinormalmode.cpp:1542
QList::size
int size() const
KateViNormalMode::commandOpenNewLineOver
bool commandOpenNewLineOver()
Definition: katevinormalmode.cpp:1052
KateViNormalMode::commandCollapseLocal
bool commandCollapseLocal()
Definition: katevinormalmode.cpp:1974
KateViNormalMode::cursorPosAtEndOfPaste
Cursor cursorPosAtEndOfPaste(const Cursor &pasteLocation, const QString &pastedText)
Definition: katevinormalmode.cpp:4020
kateviewhelpers.h
KateViNormalMode::textObjectAInequalitySign
KateViRange textObjectAInequalitySign()
Definition: katevinormalmode.cpp:3647
katebuffer.h
KateViModeBase::isCounted
bool isCounted()
Definition: katevimodebase.h:138
KateViKeyMapper::isExecutingMapping
bool isExecutingMapping()
Definition: katevikeymapper.cpp:135
KateDocument::lastLine
int lastLine() const
gets the last line number (lines() - 1)
Definition: katedocument.h:691
KateViNormalMode::commandYankLine
bool commandYankLine()
Definition: katevinormalmode.cpp:1253
KateViNormalMode::motionPageDown
KateViRange motionPageDown()
Definition: katevinormalmode.cpp:2056
KateViNormalMode::commandToOtherEnd
bool commandToOtherEnd()
Definition: katevinormalmode.cpp:706
KateViVisualMode::goToPos
void goToPos(const Cursor &c)
Definition: katevivisualmode.cpp:229
QString::clear
void clear()
KateViNormalMode::commandChangeToEOL
bool commandChangeToEOL()
Definition: katevinormalmode.cpp:1172
AppendEOL
Definition: kateviinsertmode.h:42
KateViModeBase::goLineUpDown
KateViRange goLineUpDown(int lines)
method for moving up or down one or more lines note: the sticky column is always a virtual column ...
Definition: katevimodebase.cpp:998
KateViModeBase::m_oneTimeCountOverride
int m_oneTimeCountOverride
Definition: katevimodebase.h:162
KateView::selectionRange
virtual const KTextEditor::Range & selectionRange() const
Definition: kateview.cpp:2815
kateviinputmodemanager.h
KateViNormalMode::motionPageUp
KateViRange motionPageUp()
Definition: katevinormalmode.cpp:2070
ADDCMD
#define ADDCMD(STR, FUNC, FLGS)
Definition: katevinormalmode.cpp:47
KateViNormalMode::m_keys
QString m_keys
Definition: katevinormalmode.h:332
KateViNormalMode::commandChangeCaseRange
bool commandChangeCaseRange()
Definition: katevinormalmode.cpp:985
KateViInputModeManager::addJump
void addJump(KTextEditor::Cursor cursor)
Definition: kateviinputmodemanager.cpp:668
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
KateViModeBase::goVisualLineUpDown
KateViRange goVisualLineUpDown(int lines)
Definition: katevimodebase.cpp:1052
KateViNormalMode::commandIndentedPaste
bool commandIndentedPaste()
Definition: katevinormalmode.cpp:1349
KateViInsertMode::setBlockPrependMode
void setBlockPrependMode(KateViRange blockRange)
Definition: kateviinsertmode.cpp:585
QRegExp
KateViNormalMode::commandAddToNumber
bool commandAddToNumber()
Definition: katevinormalmode.cpp:1791
KateViModeBase::getLine
const QString getLine(int line=-1) const
Definition: katevimodebase.cpp:123
KateDocument::replaceText
virtual bool replaceText(const KTextEditor::Range &range, const QString &s, bool block=false)
Definition: katedocument.cpp:4686
KateViNormalMode::commandDeleteToEOL
bool commandDeleteToEOL()
Definition: katevinormalmode.cpp:760
KateViModeBase::findPrevWORDEnd
Cursor findPrevWORDEnd(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:456
QVector::clear
void clear()
KateDocument::insertText
virtual bool insertText(const KTextEditor::Cursor &position, const QString &s, bool block=false)
Definition: katedocument.cpp:530
katevikeymapper.h
KateViNormalMode::motionToScreenColumn
KateViRange motionToScreenColumn()
Definition: katevinormalmode.cpp:2594
KateViNormalMode::motionDownToFirstNonBlank
KateViRange motionDownToFirstNonBlank()
Definition: katevinormalmode.cpp:2084
QString::number
QString number(int n, int base)
KateViNormalMode::motionToNextVisualLine
KateViRange motionToNextVisualLine()
Definition: katevinormalmode.cpp:2951
QList::count
int count(const T &value) const
KateViNormalMode::highlightedYankForDocument
QSet< KTextEditor::MovingRange * > & highlightedYankForDocument()
Definition: katevinormalmode.cpp:4208
KateViModeBase::m_view
KateView * m_view
Definition: katevimodebase.h:172
KateViInputModeManager::getLastSearchPattern
const QString getLastSearchPattern() const
The current search pattern.
Definition: kateviinputmodemanager.cpp:422
KateViNormalMode::commandBottomViewOnNonBlank
bool commandBottomViewOnNonBlank()
Definition: katevinormalmode.cpp:1715
KateViNormalMode::commandSwitchToRightView
bool commandSwitchToRightView()
Definition: katevinormalmode.cpp:1873
KateViNormalMode::commandScrollPageDown
bool commandScrollPageDown()
Definition: katevinormalmode.cpp:1614
KateViModeBase::fillRegister
void fillRegister(const QChar &reg, const QString &text, OperationMode flag=CharWise)
Definition: katevimodebase.cpp:963
QChar::isSpace
bool isSpace() const
KateViNormalMode::motionUp
KateViRange motionUp()
Definition: katevinormalmode.cpp:2022
KateViNormalMode::commandCollapseToplevelNodes
bool commandCollapseToplevelNodes()
Definition: katevinormalmode.cpp:1928
KateViNormalMode::commandEnterInsertModeLast
bool commandEnterInsertModeLast()
enter insert mode at the last insert position
Definition: katevinormalmode.cpp:630
KateViNormalMode::commandSwitchToPrevTab
bool commandSwitchToPrevTab()
Definition: katevinormalmode.cpp:1903
KateRenderer::Underline
Definition: katerenderer.h:72
KateDocument::character
virtual QChar character(const KTextEditor::Cursor &position) const
Definition: katedocument.cpp:388
KateViRange
Definition: katevirange.h:33
KateDocument::wrapText
bool wrapText(int startLine, int endLine)
Remove a line.
Definition: katedocument.cpp:855
KateRenderer::config
KateRendererConfig * config() const
Configuration.
Definition: katerenderer.h:362
QSharedPointer
Up
Definition: katevimodebase.h:56
KateViRange::endColumn
int endColumn
Definition: katevirange.h:44
KateViModeBase::setCount
void setCount(unsigned int count)
Definition: katevimodebase.h:85
KateViRange::motionType
ViMotion::MotionType motionType
Definition: katevirange.h:45
KateRenderer::Half
Definition: katerenderer.h:73
KateViNormalMode::beginMonitoringDocumentChanges
void beginMonitoringDocumentChanges()
Definition: katevinormalmode.cpp:486
KateViNormalMode::motionToPreviousBraceBlockEnd
KateViRange motionToPreviousBraceBlockEnd()
Definition: katevinormalmode.cpp:2857
KateViEmulatedCommandBar::SearchBackward
Definition: kateviemulatedcommandbar.h:44
Left
Definition: katevimodebase.h:58
KateViNormalMode::textObjectInnerQuoteSingle
KateViRange textObjectInnerQuoteSingle()
Definition: katevinormalmode.cpp:3548
KateViNormalMode::textObjectComma
KateViRange textObjectComma(bool inner)
Definition: katevinormalmode.cpp:4134
KateViNormalMode::findParagraphStart
Cursor findParagraphStart()
Definition: katevinormalmode.cpp:3392
KateViNormalMode::textObjectInnerQuoteDouble
KateViRange textObjectInnerQuoteDouble()
Definition: katevinormalmode.cpp:3538
kateglobal.h
KateViModeBase::getNextJump
KTextEditor::Cursor getNextJump(KTextEditor::Cursor)
Definition: katevimodebase.cpp:974
KateViModeBase::scrollViewLines
void scrollViewLines(int l)
Definition: katevimodebase.h:129
KateViNormalMode::motionToEndOfPrevWORD
KateViRange motionToEndOfPrevWORD()
Definition: katevinormalmode.cpp:2267
KateViNormalMode::commandEnterInsertModeBeforeFirstNonBlankInLine
bool commandEnterInsertModeBeforeFirstNonBlankInLine()
Definition: katevinormalmode.cpp:614
KateViNormalMode::m_lastMotionWasLinewiseInnerBlock
bool m_lastMotionWasLinewiseInnerBlock
Definition: katevinormalmode.h:350
KateViewInternal
Definition: kateviewinternal.h:58
KateViModeBase::startReplaceMode
bool startReplaceMode()
Definition: katevimodebase.cpp:1199
ViMotion::MotionType
MotionType
Definition: katevirange.h:28
QString::isEmpty
bool isEmpty() const
KateViInputModeManager::keyMapper
KateViKeyMapper * keyMapper()
Definition: kateviinputmodemanager.cpp:913
KateViNormalMode::motionToPreviousSentence
KateViRange motionToPreviousSentence()
Definition: katevinormalmode.cpp:2959
KateViKeyParser::decodeKeySequence
const QString decodeKeySequence(const QString &keys) const
Definition: katevikeyparser.cpp:632
QString::trimmed
QString trimmed() const
KateViNormalMode::goToPos
virtual void goToPos(const KateViRange &r)
Definition: katevinormalmode.cpp:494
KateViModeBase::updateCursor
void updateCursor(const Cursor &c) const
Definition: katevimodebase.cpp:932
QVector::remove
void remove(int i)
QChar::isUpper
bool isUpper() const
KateViInputModeManager::getMarkPosition
KTextEditor::Cursor getMarkPosition(const QChar &mark) const
Definition: kateviinputmodemanager.cpp:781
KateViInputModeManager::getViNormalMode
KateViNormalMode * getViNormalMode()
Definition: kateviinputmodemanager.cpp:546
QKeyEvent::text
QString text() const
KateDocument::lines
virtual int lines() const
Definition: katedocument.cpp:753
KateViNormalMode::commandCenterViewOnCursor
bool commandCenterViewOnCursor()
Definition: katevinormalmode.cpp:1672
KateDocument::documentEnd
virtual KTextEditor::Cursor documentEnd() const
Definition: katedocument.cpp:4681
KateViNormalMode::m_isUndo
bool m_isUndo
Definition: katevinormalmode.h:381
KateView::cmdLineBar
KateCommandLineBar * cmdLineBar()
Definition: kateview.cpp:3013
KateViInputModeManager::setLastSearchPlacesCursorAtEndOfMatch
void setLastSearchPlacesCursorAtEndOfMatch(bool b)
Definition: kateviinputmodemanager.h:233
katecompletionwidget.h
KateViVisualMode
Definition: katevivisualmode.h:34
KateViModeBase::switchView
void switchView(Direction direction=Next)
Definition: katevimodebase.cpp:1416
KateViNormalMode::commandUnindentLines
bool commandUnindentLines()
Definition: katevinormalmode.cpp:1600
KateViEmulatedCommandBar::init
void init(Mode mode, const QString &initialText=QString())
Definition: kateviemulatedcommandbar.cpp:401
KateViNormalMode::commandCloseWrite
bool commandCloseWrite()
Definition: katevinormalmode.cpp:1968
QSet< KTextEditor::MovingRange * >
KateViNormalMode::m_lastTFcommand
QString m_lastTFcommand
Definition: katevinormalmode.h:345
KateViNormalMode::commandYank
bool commandYank()
Definition: katevinormalmode.cpp:1234
KateViModeBase::goLineDown
KateViRange goLineDown()
Definition: katevimodebase.cpp:984
ViMode
ViMode
The four vi modes supported by Kate's vi input mode.
Definition: kateviinputmodemanager.h:48
KateViNormalMode::commandScrollPageUp
bool commandScrollPageUp()
Definition: katevinormalmode.cpp:1624
KateViNormalMode::joinLines
void joinLines(unsigned int from, unsigned int to) const
Definition: katevinormalmode.cpp:4036
KateDocument::newLine
void newLine(KateView *view)
Definition: katedocument.cpp:2660
KateView::find
void find()
Definition: kateview.cpp:1597
QString
KateViModeBase::linesDisplayed
unsigned int linesDisplayed()
Definition: katevimodebase.h:128
QList< QString >
QColor
QChar::unicode
ushort unicode() const
KateViNormalMode::motionToEndOfPrevWord
KateViRange motionToEndOfPrevWord()
Definition: katevinormalmode.cpp:2240
KateViNormalMode::commandPasteBefore
bool commandPasteBefore()
Definition: katevinormalmode.cpp:1327
Next
Definition: katevimodebase.h:60
KateViNormalMode::commandExpandAll
bool commandExpandAll()
Definition: katevinormalmode.cpp:1984
kateviinsertmode.h
KateViNormalMode::motionRepeatlastTFBackward
KateViRange motionRepeatlastTFBackward()
Definition: katevinormalmode.cpp:2500
KateViModeBase::startInsertMode
bool startInsertMode()
Definition: katevimodebase.cpp:1190
KateViNormalMode::AtCurrentPosition
Definition: katevinormalmode.h:308
KateViNormalMode::motionFindPrev
KateViRange motionFindPrev()
Definition: katevinormalmode.cpp:2524
KateViModeBase::m_iscounted
bool m_iscounted
Definition: katevimodebase.h:163
KateViModeBase::m_stickyColumn
int m_stickyColumn
Definition: katevimodebase.h:168
KateViNormalMode::handleKeypress
bool handleKeypress(const QKeyEvent *e)
parses a key stroke to check if it's a valid (part of) a command
Definition: katevinormalmode.cpp:107
KateView::selection
virtual bool selection() const
Definition: kateview.cpp:2033
KateViModeBase::findWordEnd
Cursor findWordEnd(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:604
KateViNormalMode::commandIndentedPasteBefore
bool commandIndentedPasteBefore()
Definition: katevinormalmode.cpp:1354
KateViNormalMode::motionToChar
KateViRange motionToChar()
Definition: katevinormalmode.cpp:2398
QStringList
KateViNormalMode::textObjectASentence
KateViRange textObjectASentence()
Definition: katevinormalmode.cpp:3453
KateViVisualMode::setStart
void setStart(const Cursor &c)
Definition: katevivisualmode.h:50
KateViNormalMode::~KateViNormalMode
virtual ~KateViNormalMode()
Definition: katevinormalmode.cpp:96
QHash::keys
QList< Key > keys() const
KateView
Definition: kateview.h:77
QString::right
QString right(int n) const
KateView::align
void align()
Definition: kateview.cpp:2507
VisualBlockMode
Definition: kateviinputmodemanager.h:53
KateViModeBase::getCount
unsigned int getCount() const
Definition: katevimodebase.h:131
KateViModeBase::findNextWordStart
Cursor findNextWordStart(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:312
Kate::TextFolding::lineToVisibleLine
int lineToVisibleLine(int line) const
Convert a text buffer line to a visible line number.
Definition: katetextfolding.cpp:366
QString::toLower
QString toLower() const
KateViModeBase::startVisualLineMode
bool startVisualLineMode()
Definition: katevimodebase.cpp:1239
KateViModeBase::message
void message(const QString &msg)
Definition: katevimodebase.cpp:1269
KateViNormalMode::commandChangeLine
bool commandChangeLine()
Definition: katevinormalmode.cpp:1184
QKeyEvent::key
int key() const
LineWise
Definition: katevimodebase.h:51
KateViNormalMode::m_matchingMotions
QVector< int > m_matchingMotions
Definition: katevinormalmode.h:339
KateViNormalMode::motionWordForward
KateViRange motionWordForward()
Definition: katevinormalmode.cpp:2100
KateViModeBase::error
void error(const QString &errorMsg)
Definition: katevimodebase.cpp:1253
KateViNormalMode::commandSwitchToUpView
bool commandSwitchToUpView()
Definition: katevinormalmode.cpp:1868
KateViNormalMode::motionToNextOccurrence
KateViRange motionToNextOccurrence()
Definition: katevinormalmode.cpp:2881
KateViNormalMode::motionWORDBackward
KateViRange motionWORDBackward()
Definition: katevinormalmode.cpp:2179
KateViNormalMode::commandChangeCase
bool commandChangeCase()
Definition: katevinormalmode.cpp:911
QLatin1Char
KateDocument::setUndoMergeAllEdits
void setUndoMergeAllEdits(bool merge)
Definition: katedocument.cpp:4722
KateViewInternal::pageDown
void pageDown(bool sel=false, bool half=false)
Definition: kateviewinternal.cpp:1586
KateViNormalMode::m_isRepeatedTFcommand
bool m_isRepeatedTFcommand
Definition: katevinormalmode.h:346
KateViModeBase::startVisualBlockMode
bool startVisualBlockMode()
Definition: katevimodebase.cpp:1225
KateViewInternal::endLine
int endLine() const
Definition: kateviewinternal.cpp:307
QChar::toLower
QChar toLower() const
Down
Definition: katevimodebase.h:57
KateViNormalMode::commandSwitchToCmdLine
bool commandSwitchToCmdLine()
Definition: katevinormalmode.cpp:1462
KateViNormalMode::m_motions
QVector< KateViMotion * > m_motions
Definition: katevinormalmode.h:337
KateViNormalMode::commandDeleteChar
bool commandDeleteChar()
Definition: katevinormalmode.cpp:1359
KateDocument::kateTextLine
Kate::TextLine kateTextLine(uint i)
Definition: katedocument.cpp:4706
KateViNormalMode::m_commandWithMotion
bool m_commandWithMotion
Definition: katevinormalmode.h:349
KateView::pageUp
void pageUp()
Definition: kateview.cpp:2743
QWidget::repaint
void repaint()
VisualLineMode
Definition: kateviinputmodemanager.h:52
KateViNormalMode::motionToAfterParagraph
KateViRange motionToAfterParagraph()
Definition: katevinormalmode.cpp:3052
KateViNormalMode::motionToCharBackward
KateViRange motionToCharBackward()
Definition: katevinormalmode.cpp:2436
KateViNormalMode::motionToLastLineOfWindow
KateViRange motionToLastLineOfWindow()
Definition: katevinormalmode.cpp:2938
KateViModeBase::m_keysVerbatim
QString m_keysVerbatim
Definition: katevimodebase.h:166
KateViNormalMode::commandPrependToBlock
bool commandPrependToBlock()
Definition: katevinormalmode.cpp:1805
KateViNormalMode::motionDown
KateViRange motionDown()
Definition: katevinormalmode.cpp:2017
KateViNormalMode::KateViNormalMode
KateViNormalMode(KateViInputModeManager *viInputModeManager, KateView *view, KateViewInternal *viewInternal)
Definition: katevinormalmode.cpp:53
KateViNormalMode::commandSwitchToNextView
bool commandSwitchToNextView()
Definition: katevinormalmode.cpp:1878
KateView::cursorPosition
KTextEditor::Cursor cursorPosition() const
Definition: kateview.cpp:2423
KateViInputModeManager::lastSearchBackwards
bool lastSearchBackwards() const
get search direction of last search.
Definition: kateviinputmodemanager.h:224
KateViModeBase::findLineStartingWitchChar
int findLineStartingWitchChar(const QChar &c, unsigned int count, bool forward=true) const
Definition: katevimodebase.cpp:899
Append
Definition: kateviinsertmode.h:41
KateViNormalMode::m_awaitingMotionOrTextObject
QStack< int > m_awaitingMotionOrTextObject
Definition: katevinormalmode.h:340
ViMotion::ExclusiveMotion
Definition: katevirange.h:29
QString::replace
QString & replace(int position, int n, QChar after)
QKeyEvent
KateViNormalMode::commandReselectVisual
bool commandReselectVisual()
Definition: katevinormalmode.cpp:661
KateViNormalMode::highlightYank
void highlightYank(const KateViRange &range, const OperationMode mode=CharWise)
Definition: katevinormalmode.cpp:4167
KateViNormalMode::commandSearchForward
bool commandSearchForward()
Definition: katevinormalmode.cpp:1509
KateViNormalMode::textObjectABracket
KateViRange textObjectABracket()
Definition: katevinormalmode.cpp:3576
QVector::at
const T & at(int i) const
KateViInputModeManager::storeLastChangeCommand
void storeLastChangeCommand()
copy the contents of the key events log to m_lastChange so that it can be repeated ...
Definition: kateviinputmodemanager.cpp:279
KateGlobal::viInputModeGlobal
KateViGlobal * viInputModeGlobal()
vi input mode global
Definition: kateglobal.h:339
KateViNormalMode::commandSwitchToNextTab
bool commandSwitchToNextTab()
Definition: katevinormalmode.cpp:1893
KateViNormalMode::motionToMiddleLineOfWindow
KateViRange motionToMiddleLineOfWindow()
Definition: katevinormalmode.cpp:2926
KateViNormalMode::motionWillBeUsedWithCommand
bool motionWillBeUsedWithCommand()
Definition: katevinormalmode.h:341
KateViNormalMode::findSentenceStart
Cursor findSentenceStart()
Definition: katevinormalmode.cpp:3318
KateViNormalMode::commandExpandLocal
bool commandExpandLocal()
Definition: katevinormalmode.cpp:1992
KateViModeBase::goLineUp
KateViRange goLineUp()
Definition: katevimodebase.cpp:989
KateViNormalMode::commandMakeUppercaseLine
bool commandMakeUppercaseLine()
Definition: katevinormalmode.cpp:893
KateViModeBase::getChosenRegister
QChar getChosenRegister(const QChar &defaultReg) const
Definition: katevimodebase.cpp:940
QString::mid
QString mid(int position, int n) const
KateViNormalMode::commandAlignLines
bool commandAlignLines()
Definition: katevinormalmode.cpp:1778
KateViCommand
KateViNormalMode::m_currentChangeEndMarker
Cursor m_currentChangeEndMarker
Definition: katevinormalmode.h:379
KateViModeBase::yankToClipBoard
void yankToClipBoard(QChar chosen_register, QString text)
Definition: katevimodebase.cpp:54
KateViNormalMode::commandScrollHalfPageUp
bool commandScrollHalfPageUp()
Definition: katevinormalmode.cpp:1634
QChar::toUpper
QChar toUpper() const
QLatin1String
KateViInputModeManager::lastSearchCaseSensitive
bool lastSearchCaseSensitive()
Definition: kateviinputmodemanager.h:235
KateView::viModeEmulatedCommandBar
KateViEmulatedCommandBar * viModeEmulatedCommandBar()
Definition: kateview.cpp:3051
KateViNormalMode::commandDelete
bool commandDelete()
Definition: katevinormalmode.cpp:754
KateVi::EOL
const unsigned int EOL
Definition: kateviglobal.h:41
KateViKeyParser::encoded2qt
int encoded2qt(const QString &keypress) const
Definition: katevikeyparser.cpp:509
KateViNormalMode::m_findWaitingForChar
bool m_findWaitingForChar
Definition: katevinormalmode.h:334
KateViNormalMode::commandgPaste
bool commandgPaste()
Definition: katevinormalmode.cpp:1337
KateDocument::editEnd
void editEnd()
End a editor operation.
Definition: katedocument.cpp:796
KateViModeBase::deleteRange
bool deleteRange(KateViRange &r, OperationMode mode=LineWise, bool addToRegister=true)
Definition: katevimodebase.cpp:65
KateViModeBase::getPrevJump
KTextEditor::Cursor getPrevJump(KTextEditor::Cursor)
Definition: katevimodebase.cpp:979
KateViNormalMode::commandSwitchToDownView
bool commandSwitchToDownView()
Definition: katevinormalmode.cpp:1863
QString::at
const QChar at(int position) const
KateView::switchToCmdLine
void switchToCmdLine()
Definition: kateview.cpp:1652
KateViModeBase::m_viInputModeManager
KateViInputModeManager * m_viInputModeManager
Definition: katevimodebase.h:177
KateRendererConfig::savedLineColor
const QColor & savedLineColor() const
Definition: kateconfig.cpp:2666
KateViNormalMode::textObjectInnerInequalitySign
KateViRange textObjectInnerInequalitySign()
Definition: katevinormalmode.cpp:3653
KateViNormalMode::commandCloseNocheck
bool commandCloseNocheck()
Definition: katevinormalmode.cpp:1962
QList::last
T & last()
KateViEmulatedCommandBar::SearchForward
Definition: kateviemulatedcommandbar.h:44
KateViNormalMode::textObjectAQuoteDouble
KateViRange textObjectAQuoteDouble()
Definition: katevinormalmode.cpp:3533
KateViModeBase::m_extraWordCharacters
QString m_extraWordCharacters
Definition: katevimodebase.h:165
KateViInsertMode::setCountedRepeatsBeginOnNewLine
void setCountedRepeatsBeginOnNewLine(bool countedRepeatsBeginOnNewLine)
Definition: kateviinsertmode.h:81
KateViNormalMode::motionToColumn0
KateViRange motionToColumn0()
Definition: katevinormalmode.cpp:2309
KateViNormalMode::getOperationMode
OperationMode getOperationMode() const
Definition: katevinormalmode.cpp:3905
KateViNormalMode::textObjectInnerComma
KateViRange textObjectInnerComma()
Definition: katevinormalmode.cpp:3664
KateViNormalMode::textObjectAParen
KateViRange textObjectAParen()
Definition: katevinormalmode.cpp:3564
KateViNormalMode::commandSubtractFromNumber
bool commandSubtractFromNumber()
Definition: katevinormalmode.cpp:1798
OperationMode
OperationMode
Definition: katevimodebase.h:49
KateViewInternal::startLine
int startLine() const
Definition: kateviewinternal.h:126
KateViInputModeManager::isReplayingLastChange
bool isReplayingLastChange() const
Definition: kateviinputmodemanager.h:163
KateViNormalMode::m_deleteCommand
bool m_deleteCommand
Definition: katevinormalmode.h:355
KateViInputModeManager::isRecordingMacro
bool isRecordingMacro()
Definition: kateviinputmodemanager.cpp:341
KateViNormalMode::m_motionCanChangeWholeVisualModeSelection
bool m_motionCanChangeWholeVisualModeSelection
Definition: katevinormalmode.h:351
KateViNormalMode::textObjectInnerParen
KateViRange textObjectInnerParen()
Definition: katevinormalmode.cpp:3570
KateViNormalMode::AfterCurrentPosition
Definition: katevinormalmode.h:308
KateViNormalMode::commandEnterInsertMode
bool commandEnterInsertMode()
enter insert mode at the cursor position
Definition: katevinormalmode.cpp:566
KateViInputModeManager::setLastSearchPattern
void setLastSearchPattern(const QString &p)
Set the current search pattern.
Definition: kateviinputmodemanager.cpp:434
KateViNormalMode::commandFormatLine
bool commandFormatLine()
Definition: katevinormalmode.cpp:1913
QString::length
int length() const
KateDocument::text
virtual QString text(const KTextEditor::Range &range, bool blockwise=false) const
Definition: katedocument.cpp:337
KateViNormalMode::m_linewiseCommand
bool m_linewiseCommand
Definition: katevinormalmode.h:348
KateViModeBase::m_lastMotionWasVisualLineUpOrDown
bool m_lastMotionWasVisualLineUpOrDown
Definition: katevimodebase.h:169
KateViNormalMode::commandGoToNextJump
bool commandGoToNextJump()
Definition: katevinormalmode.cpp:1844
KateViInputModeManager::clearCurrentChangeLog
void clearCurrentChangeLog()
clear the key event log
Definition: kateviinputmodemanager.h:173
KateViNormalMode::commandYankToEOL
bool commandYankToEOL()
Definition: katevinormalmode.cpp:1273
KateViNormalMode::motionToEndOfWord
KateViRange motionToEndOfWord()
Definition: katevinormalmode.cpp:2201
KateViVisualMode::saveRangeMarks
void saveRangeMarks()
Definition: katevivisualmode.cpp:187
KateDocument::undo
void undo()
Definition: katedocument.cpp:1375
KateViNormalMode::motionToMark
KateViRange motionToMark()
Definition: katevinormalmode.cpp:2609
KateViNormalMode::commandRepeatLastChange
bool commandRepeatLastChange()
Definition: katevinormalmode.cpp:1753
KateViNormalMode::commandTopViewOnNonBlank
bool commandTopViewOnNonBlank()
Definition: katevinormalmode.cpp:1691
QString::left
QString left(int n) const
KateViNormalMode::m_countTemp
unsigned int m_countTemp
Definition: katevinormalmode.h:333
KateViVisualMode::switchStartEnd
void switchStartEnd()
Definition: katevivisualmode.cpp:219
QVector::push_back
void push_back(const T &value)
KateViNormalMode::commandDeleteCharBackward
bool commandDeleteCharBackward()
Definition: katevinormalmode.cpp:1384
KateViNormalMode::commandBottomViewOnCursor
bool commandBottomViewOnCursor()
Definition: katevinormalmode.cpp:1720
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KateViNormalMode::commandGoToPrevJump
bool commandGoToPrevJump()
Definition: katevinormalmode.cpp:1851
KateViNormalMode::motionToPreviousBraceBlockStart
KateViRange motionToPreviousBraceBlockStart()
Definition: katevinormalmode.cpp:2801
KateViModeBase::getRegisterContent
QString getRegisterContent(const QChar &reg)
Definition: katevimodebase.cpp:947
KateViNormalMode::commandUnindentLine
bool commandUnindentLine()
Definition: katevinormalmode.cpp:1576
kateundomanager.h
KateViNormalMode::motionFindChar
KateViRange motionFindChar()
Definition: katevinormalmode.cpp:2329
KateViModeBase::findSurroundingBrackets
KateViRange findSurroundingBrackets(const QChar &c1, const QChar &c2, bool inner, const QChar &nested1, const QChar &nested2) const
Definition: katevimodebase.cpp:764
KateViNormalMode::motionToMatchingItem
KateViRange motionToMatchingItem()
Definition: katevinormalmode.cpp:2648
KateViNormalMode::commandOpenNewLineUnder
bool commandOpenNewLineUnder()
Definition: katevinormalmode.cpp:1032
KateView::setBlockSelection
virtual bool setBlockSelection(bool on)
Definition: kateview.cpp:2226
KateViModeBase::findPrevWordEnd
Cursor findPrevWordEnd(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:416
KateViNormalMode::m_highlightedYanks
QSet< KTextEditor::MovingRange * > m_highlightedYanks
Definition: katevinormalmode.h:373
KateView::doc
KateDocument * doc()
accessor to katedocument pointer
Definition: kateview.h:553
KateViInputModeManager::getViInsertMode
KateViInsertMode * getViInsertMode()
Definition: kateviinputmodemanager.cpp:551
KateViVisualMode::getLastVisualMode
ViMode getLastVisualMode() const
Definition: katevivisualmode.h:55
KateViNormalMode::motionRight
KateViRange motionRight()
Definition: katevinormalmode.cpp:2041
KateViInputModeManager::repeatLastChange
void repeatLastChange()
repeat last change by feeding the contents of m_lastChange to feedKeys()
Definition: kateviinputmodemanager.cpp:315
KateViNormalMode::commandToggleRegionVisibility
bool commandToggleRegionVisibility()
Definition: katevinormalmode.cpp:2002
Block
Definition: katevimodebase.h:52
KateViNormalMode::textObjectInnerCurlyBracket
KateViRange textObjectInnerCurlyBracket()
Definition: katevinormalmode.cpp:3594
KateViModeBase::startVisualMode
bool startVisualMode()
Definition: katevimodebase.cpp:1208
KateViModeBase::getWordRangeUnderCursor
const Range getWordRangeUnderCursor() const
Definition: katevimodebase.cpp:147
KateViNormalMode::commandEnterVisualBlockMode
bool commandEnterVisualBlockMode()
Definition: katevinormalmode.cpp:651
KateViNormalMode::commandTopView
bool commandTopView(bool onFirst)
Definition: katevinormalmode.cpp:1677
KateViInputModeManager::getViVisualMode
KateViVisualMode * getViVisualMode()
Definition: kateviinputmodemanager.cpp:556
KateViNormalMode::commandSubstituteLine
bool commandSubstituteLine()
Definition: katevinormalmode.cpp:1228
KateViNormalMode::commandChangeCaseLine
bool commandChangeCaseLine()
Definition: katevinormalmode.cpp:1005
KateViNormalMode::shrinkRangeAroundCursor
void shrinkRangeAroundCursor(KateViRange &toShrink, const KateViRange &rangeToShrinkTo)
Definition: katevinormalmode.cpp:4070
KateViNormalMode::textObjectInnerWord
KateViRange textObjectInnerWord()
Definition: katevinormalmode.cpp:3171
KateViVisualMode::getStart
Cursor getStart()
Definition: katevivisualmode.h:51
QSet::clear
void clear()
KateViNormalMode::commandSplitVert
bool commandSplitVert()
Definition: katevinormalmode.cpp:1888
KateViNormalMode::commandPaste
bool commandPaste()
Definition: katevinormalmode.cpp:1321
KateDocument::editStart
void editStart()
Enclose editor actions with editStart() and editEnd() to group them.
Definition: katedocument.cpp:776
KateViNormalMode::motionFindNext
KateViRange motionFindNext()
Definition: katevinormalmode.cpp:2543
KateViNormalMode::m_matchingItems
QHash< QString, QString > m_matchingItems
Definition: katevinormalmode.h:364
KateViNormalMode::m_highlightYankAttribute
KTextEditor::Attribute::Ptr m_highlightYankAttribute
Definition: katevinormalmode.h:372
KateViInputModeManager::getCurrentViMode
ViMode getCurrentViMode() const
Definition: kateviinputmodemanager.cpp:451
KateViNormalMode::textObjectACurlyBracket
KateViRange textObjectACurlyBracket()
Definition: katevinormalmode.cpp:3588
KateViGlobal::appendSearchHistoryItem
void appendSearchHistoryItem(const QString &searchHistoryItem)
Definition: kateviglobal.cpp:257
KateViNormalMode::commandSplitHoriz
bool commandSplitHoriz()
Definition: katevinormalmode.cpp:1883
KateViNormalMode::commandDeleteLine
bool commandDeleteLine()
Definition: katevinormalmode.cpp:721
KateViNormalMode::commandCenterView
bool commandCenterView(bool onFirst)
Definition: katevinormalmode.cpp:1653
KateViNormalMode::motionUpToFirstNonBlank
KateViRange motionUpToFirstNonBlank()
Definition: katevinormalmode.cpp:2092
KateViNormalMode::commandMakeLowercaseLine
bool commandMakeLowercaseLine()
Definition: katevinormalmode.cpp:846
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVector::size
int size() const
KateViNormalMode::textObjectInnerBracket
KateViRange textObjectInnerBracket()
Definition: katevinormalmode.cpp:3582
KateViInputModeManager::lastSearchPlacesCursorAtEndOfMatch
bool lastSearchPlacesCursorAtEndOfMatch()
Definition: kateviinputmodemanager.h:237
KateViModeBase::findPrevWordStart
Cursor findPrevWordStart(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:493
KateViKeyParser::self
static KateViKeyParser * self()
Definition: katevikeyparser.cpp:38
KateViNormalMode::commandStartRecordingMacro
bool commandStartRecordingMacro()
Definition: katevinormalmode.cpp:1937
kateviglobal.h
KateViNormalMode::textObjectABackQuote
KateViRange textObjectABackQuote()
Definition: katevinormalmode.cpp:3553
kateconfig.h
KateViRange::valid
bool valid
Definition: katevirange.h:46
ViMotion::InclusiveMotion
Definition: katevirange.h:29
KateViNormalMode::commandAppendToBlock
bool commandAppendToBlock()
Definition: katevinormalmode.cpp:1820
KateDocument::joinLines
void joinLines(uint first, uint last)
Unwrap a range of lines.
Definition: katedocument.cpp:3497
KateViInputModeManager::setTemporaryNormalMode
void setTemporaryNormalMode(bool b)
Definition: kateviinputmodemanager.h:241
KateViNormalMode::motionRepeatlastTF
KateViRange motionRepeatlastTF()
Definition: katevinormalmode.cpp:2477
KateViNormalMode::commandSearchBackward
bool commandSearchBackward()
Definition: katevinormalmode.cpp:1494
KateViNormalMode::m_scroll_count_limit
uint m_scroll_count_limit
Definition: katevinormalmode.h:357
QString::repeated
QString repeated(int times) const
KateViNormalMode::motionToNextSentence
KateViRange motionToNextSentence()
Definition: katevinormalmode.cpp:2999
KateViNormalMode::motionWordBackward
KateViRange motionWordBackward()
Definition: katevinormalmode.cpp:2134
KateViRange::startLine
int startLine
Definition: katevirange.h:41
QChar::isLower
bool isLower() const
KateViInputModeManager::isAnyVisualMode
bool isAnyVisualMode() const
Definition: kateviinputmodemanager.cpp:461
KateViModeBase::m_viewInternal
KateViewInternal * m_viewInternal
Definition: katevimodebase.h:176
KateDocument::removeText
virtual bool removeText(const KTextEditor::Range &range, bool block=false)
Definition: katedocument.cpp:633
KateCommandLineBar::execute
void execute(const QString &text)
Definition: kateviewhelpers.cpp:847
KateViNormalMode::commandSwitchToLeftView
bool commandSwitchToLeftView()
Definition: katevinormalmode.cpp:1858
KateViNormalMode::commandChange
bool commandChange()
Definition: katevinormalmode.cpp:1133
KateViNormalMode::commandMakeLowercase
bool commandMakeLowercase()
Definition: katevinormalmode.cpp:821
KateViNormalMode::textObjectAQuoteSingle
KateViRange textObjectAQuoteSingle()
Definition: katevinormalmode.cpp:3543
KateViNormalMode::addCurrentPositionToJumpList
void addCurrentPositionToJumpList()
Definition: katevinormalmode.cpp:554
KateViModeBase::findNextWORDStart
Cursor findNextWORDStart(int fromLine, int fromColumn, bool onlyCurrentLine=false) const
Definition: katevimodebase.cpp:374
KateViNormalMode::motionToPrevOccurrence
KateViRange motionToPrevOccurrence()
Definition: katevinormalmode.cpp:2896
Right
Definition: katevimodebase.h:59
ADDMOTION
#define ADDMOTION(STR, FUNC, FLGS)
Definition: katevinormalmode.cpp:50
KateViNormalMode::motionToFirstLineOfWindow
KateViRange motionToFirstLineOfWindow()
Definition: katevinormalmode.cpp:2913
KateViNormalMode::commandIndentLines
bool commandIndentLines()
Definition: katevinormalmode.cpp:1585
KateViModeBase::addToNumberUnderCursor
void addToNumberUnderCursor(int count)
Definition: katevimodebase.cpp:1323
KateView::pageDown
void pageDown()
Definition: kateview.cpp:2753
KateViModeBase::findPatternForMotion
KateViRange findPatternForMotion(const QString &pattern, bool backwards, bool caseSensitive, const Cursor &startFrom, int count=1) const
Definition: katevimodebase.cpp:299
KateViInputModeManager::setLastSearchCaseSensitive
void setLastSearchCaseSensitive(bool caseSensitive)
Definition: kateviinputmodemanager.h:231
KateViewConfig::global
static KateViewConfig * global()
Definition: kateconfig.h:402
KateViNormalMode::m_matchItemRegex
QRegExp m_matchItemRegex
Definition: katevinormalmode.h:365
KateViNormalMode::textObjectInnerBackQuote
KateViRange textObjectInnerBackQuote()
Definition: katevinormalmode.cpp:3558
KateViInsertMode::setBlockAppendMode
void setBlockAppendMode(KateViRange blockRange, BlockInsert b)
Definition: kateviinsertmode.cpp:594
KateViewInternal::findMatchingBracket
KTextEditor::Cursor findMatchingBracket()
Definition: kateviewinternal.cpp:772
KateViNormalMode::motionFindCharBackward
KateViRange motionFindCharBackward()
Definition: katevinormalmode.cpp:2360
KateViNormalMode::commandSubstituteChar
bool commandSubstituteChar()
Definition: katevinormalmode.cpp:1216
KateViInsertMode::setCount
void setCount(int count)
Definition: kateviinsertmode.h:80
KateViModeBase::m_register
QChar m_register
Definition: katevimodebase.h:154
QStack::top
T & top()
KateViNormalMode::resetParser
void resetParser()
(re)set to start configuration.
Definition: katevinormalmode.cpp:453
KateViNormalMode::m_defaultRegister
QChar m_defaultRegister
Definition: katevinormalmode.h:360
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal