Visual Studio:热键来上下移动行,并通过最近的变化

我正在从Eclipse转移到Visual Studio .NET,并发现了所有我喜欢的热键,除了两个:

  • 在Eclipse中,您可以按ALTALT来访问您所做的最近的更改,我经常使用的东西返回到我在其他文件中的位置,然后返回。 显然在VS.NET中CTRL – 和CTRLSHIFT – 做到这一点,但他们似乎并不总是工作(例如,在笔记本电脑上,可能是减号numkey问题),似乎并没有遵循相同的algorithm就像我在Eclipse中习惯的“我在哪里”一样。 有没有人得到这个工作,并依靠它每天等?
  • 在Eclipse中,要向上或向下移动一行,请按ALTuparrowALT – 向下移动,然后在代码中移动它,直到将其放到所需的位置,非常好。 同样要制作一行的副本,可以按SHIFTALT向上SHIFTALT向下 。 这两个热键甚至适用于您select的线路块。

有没有人在Visual Studio .NET中发现这些热键function?

附录:

当你使用上述第二个特性的时候,一个例子是将这里的底线移到for循环中。 在Eclipse中,你可以把光标放在Console.WriteLine上,然后按下ALT-(uparrow),我就一直使用这个function:一个键盘上下移动一行。

for (int i = 0; i < 10; i++) { } Console.WriteLine(i); 

好的,推断查理的想法与不selectCTRL-Cselect一行,在Visual Studio中,你可以把光标放在Console.WriteLine,(不选)按CTRLX ,然后向上移动,然后按CTRLV。

build议的答案工作,但没有一个像eclipse一样好,他们如何保留现有的粘贴缓冲区,当前选定的字符,他们不允许用户操作一系列的行。 下面是我提出的一个解决scheme,它保留了粘贴缓冲区,当前的字符select,并且可以使用或不使用select(可能或不可以跨越多行):

 '' Duplicates the current line (or selection of lines) and places the copy '' one line below or above the current cursor position (based upon the parameter) Sub CopyLine(ByVal movingDown As Boolean) DTE.UndoContext.Open("CopyLine") Dim objSel As TextSelection = DTE.ActiveDocument.Selection ' store the original selection and cursor position Dim topPoint As TextPoint = objSel.TopPoint Dim bottomPoint As TextPoint = objSel.BottomPoint Dim lTopLine As Long = topPoint.Line Dim lTopColumn As Long = topPoint.LineCharOffset Dim lBottomLine As Long = bottomPoint.Line Dim lBottomColumn As Long = bottomPoint.LineCharOffset() ' copy each line from the top line to the bottom line Dim readLine As Long = lTopLine Dim endLine As Long = lBottomLine + 1 Dim selectionPresent As Boolean = ((lTopLine <> lBottomLine) Or (lTopColumn <> lBottomColumn)) If (selectionPresent And (lBottomColumn = 1)) Then ' A selection is present, but the cursor is in front of the first character ' on the bottom line. exclude that bottom line from the copy selection. endLine = lBottomLine End If ' figure out how many lines we are copying, so we can re-position ' our selection after the copy is done Dim verticalOffset As Integer = 0 If (movingDown) Then verticalOffset = endLine - lTopLine End If ' copy each line, one at a time. ' The Insert command doesn't handle multiple lines well, and we need ' to use Insert to avoid autocompletions Dim insertLine As Long = endLine While (readLine < endLine) ' move to read postion, and read the current line objSel.MoveToLineAndOffset(readLine, 1) objSel.EndOfLine(True) 'extend to EOL Dim lineTxt As String = objSel.Text.Clone ' move to the destination position, and insert the copy objSel.MoveToLineAndOffset(insertLine, 1) objSel.Insert(lineTxt) objSel.NewLine() ' adjust the read & insertion points readLine = readLine + 1 insertLine = insertLine + 1 End While ' restore the cursor to original position and selection objSel.MoveToLineAndOffset(lBottomLine + verticalOffset, lBottomColumn) objSel.MoveToLineAndOffset(lTopLine + verticalOffset, lTopColumn, True) DTE.UndoContext.Close() End Sub '' Duplicates the current line (or selection of lines) and places the copy '' one line below the current cursor position Sub CopyLineDown() CopyLine(True) End Sub '' Duplicates the current line (or selection of lines) and places the copy '' one line above the current cursor position Sub CopyLineUp() CopyLine(False) End Sub '' Moves the selected lines up one line. If no line is '' selected, the current line is moved. '' Sub MoveLineUp() DTE.UndoContext.Open("MoveLineUp") Dim objSel As TextSelection = DTE.ActiveDocument.Selection ' store the original selection and cursor position Dim topPoint As TextPoint = objSel.TopPoint Dim bottomPoint As TextPoint = objSel.BottomPoint Dim lTopLine As Long = topPoint.Line Dim lTopColumn As Long = topPoint.LineCharOffset Dim lBottomLine As Long = bottomPoint.Line Dim lBottomColumn As Long = bottomPoint.LineCharOffset() Dim textLineAbove As TextSelection = DTE.ActiveDocument.Selection textLineAbove.MoveToLineAndOffset(lTopLine - 1, 1, False) textLineAbove.MoveToLineAndOffset(lTopLine, 1, True) Dim indentChange As Integer = CountIndentations(textLineAbove.Text) * -1 ' If multiple lines are selected, but the bottom line doesn't ' have any characters selected, don't count it as selected Dim lEffectiveBottomLine = lBottomLine If ((lBottomColumn = 1) And (lBottomLine <> lTopLine)) Then lEffectiveBottomLine = lBottomLine - 1 End If ' move to the line above the top line objSel.MoveToLineAndOffset(lTopLine - 1, 1) ' and move it down, until its below the bottom line: Do DTE.ExecuteCommand("Edit.LineTranspose") Loop Until (objSel.BottomPoint.Line >= lEffectiveBottomLine) ' Since the line we are on has moved up, our location in the file has changed: lTopLine = lTopLine - 1 lBottomLine = lBottomLine - 1 IndentBlockAndRestoreSelection(objSel, lBottomLine, lBottomColumn, lTopLine, lTopColumn, indentChange) DTE.UndoContext.Close() End Sub '' Moves the selected lines down one line. If no line is '' selected, the current line is moved. '' Sub MoveLineDown() DTE.UndoContext.Open("MoveLineDown") Dim objSel As TextSelection = DTE.ActiveDocument.Selection ' store the original selection and cursor position Dim topPoint As TextPoint = objSel.TopPoint Dim bottomPoint As TextPoint = objSel.BottomPoint Dim lTopLine As Long = topPoint.Line Dim lTopColumn As Long = topPoint.LineCharOffset Dim lBottomLine As Long = bottomPoint.Line Dim lBottomColumn As Long = bottomPoint.LineCharOffset() ' If multiple lines are selected, but the bottom line doesn't ' have any characters selected, don't count it as selected Dim lEffectiveBottomLine = lBottomLine If ((lBottomColumn = 1) And (lBottomLine <> lTopLine)) Then lEffectiveBottomLine = lBottomLine - 1 End If Dim textLineBelow As TextSelection = DTE.ActiveDocument.Selection textLineBelow.MoveToLineAndOffset(lEffectiveBottomLine + 1, 1, False) textLineBelow.MoveToLineAndOffset(lEffectiveBottomLine + 2, 1, True) Dim indentChange As Integer = CountIndentations(textLineBelow.Text) ' move to the bottom line objSel.MoveToLineAndOffset(lEffectiveBottomLine, 1) ' and move it down, which effectively moves the line below it up ' then move the cursor up, always staying one line above the line ' that is moving up, and keep moving it up until its above the top line: Dim lineCount As Long = lEffectiveBottomLine - lTopLine Do DTE.ExecuteCommand("Edit.LineTranspose") objSel.LineUp(False, 2) lineCount = lineCount - 1 Loop Until (lineCount < 0) ' Since the line we are on has moved down, our location in the file has changed: lTopLine = lTopLine + 1 lBottomLine = lBottomLine + 1 IndentBlockAndRestoreSelection(objSel, lBottomLine, lBottomColumn, lTopLine, lTopColumn, indentChange) DTE.UndoContext.Close() End Sub '' This method takes care of indenting the selected text by the indentChange parameter '' It then restores the selection to the lTopLine:lTopColumn - lBottomLine:lBottomColumn parameter. '' It will adjust these values according to the indentChange performed Sub IndentBlockAndRestoreSelection(ByVal objSel As TextSelection, ByVal lBottomLine As Long, ByVal lBottomColumn As Long, ByVal lTopLine As Long, ByVal lTopColumn As Long, ByVal indentChange As Integer) ' restore the cursor to original position and selection objSel.MoveToLineAndOffset(lBottomLine, lBottomColumn) objSel.MoveToLineAndOffset(lTopLine, lTopColumn, True) If (indentChange = 0) Then ' If we don't change the indent, we are done Return End If If (lBottomLine = lTopLine) Then If (indentChange > 0) Then objSel.StartOfLine() Else objSel.StartOfLine() objSel.WordRight() End If End If objSel.Indent(indentChange) ' Since the selected text has changed column, adjust the columns accordingly: ' restore the cursor to original position and selection Dim lNewBottomColumn As Long = (lBottomColumn + indentChange) Dim lNewTopColumn As Long = (lTopColumn + indentChange) ' ensure that we we still on the page. ' The "or" clause makes it so if we were at the left edge of the line, we remain on the left edge. If ((lNewBottomColumn < 2) Or (lBottomColumn = 1)) Then ' Single line selections, or a bottomColumn that is already at 1 may still have a new BottomColumn of 1 If ((lTopLine = lBottomLine) Or (lBottomColumn = 1)) Then lNewBottomColumn = 1 Else ' If we have multiple lines selected, don't allow the bottom edge to touch the left column, ' or the next move will ignore that bottom line. lNewBottomColumn = 2 End If End If If ((lNewTopColumn < 2) Or (lTopColumn = 1)) Then lNewTopColumn = 1 End If ' restore the selection to the modified selection objSel.MoveToLineAndOffset(lBottomLine, lNewBottomColumn) objSel.MoveToLineAndOffset(lTopLine, lNewTopColumn, True) End Sub '' This method counts the indentation changes within the text provided as the paramter Function CountIndentations(ByVal text As String) As Integer Dim indent As Integer = 0 While (Text.Length > 0) If (Text.StartsWith("//")) Then Dim endOfLine As Integer = Text.IndexOf("\n", 2) If (Equals(endOfLine, -1)) Then ' The remaining text is all on one line, so the '//' terminates our search ' Ignore the rest of the text Exit While End If ' continue looking after the end of line Text = Text.Substring(endOfLine + 1) End If If (Text.StartsWith("/*")) Then Dim endComment As Integer = Text.IndexOf("*/", 2) If (Equals(endComment, -1)) Then ' This comment continues beyond the length of this line. ' Ignore the rest of the text Exit While End If ' continue looking after the end of this comment block Text = Text.Substring(endComment + 1) End If If (Text.StartsWith("{")) Then indent = indent + 1 Else If (Text.StartsWith("}")) Then indent = indent - 1 End If End If Text = Text.Substring(1) End While Return indent End Function 

我编辑了这个post,在MoveLineUp()和MoveLineDown()方法的开头添加了UndoContext机制(由Nicolas Dorierbuild议),并在最后closures它。 11/23/11 – 我再次更新了这个,让移动的线条在跨过括号边界时缩进自己

对于任何想在Visual Studio 2010中执行此操作的人,免费的Visual Studio 2010 Pro电动工具扩展程序都会增加上下移动行的function。

http://visualstudiogallery.msdn.microsoft.com/en-us/d0d33361-18e2-46c0-8ff2-4adea1e34fef

如果您还没有find它,这些键盘快捷键的设置位置在Tools |下 选项| 环境| 键盘。 通过浏览列表可以find许多方便的命令,但不幸的是我从来没有find任何描述每个命令打算做什么的好的参考。

至于具体的命令:

  • 我相信你所指的前进/后退导航命令是View.NavigateBackward和View.NavigateForward。 如果您的键盘不与VS键绑定配合,则可以将其重新映射到您的首选Eclipse键。 不幸的是,我不知道如何改变它用来确定去哪里的algorithm。

  • 我不认为有一个内置命令复制一行,但按Ctrl + C没有select文本将复制当前行到剪贴板。 鉴于此,下面是一个简单的macros,它复制下一行的当前行:

 Sub CopyLineBelow() DTE.ActiveDocument.Selection.Collapse() DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.Paste() End Sub Sub CopyLineAbove() DTE.ActiveDocument.Selection.Collapse() DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.LineUp() DTE.ActiveDocument.Selection.Paste() End Sub 
  • 为了移动一行文本,Edit.LineTranspose会将选中的行向下移动。 我不认为有排队的命令,但这是一个快速的macros:
 Sub MoveLineUp() DTE.ActiveDocument.Selection.Collapse() DTE.ActiveDocument.Selection.Cut() DTE.ActiveDocument.Selection.LineUp() DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.LineUp() End Sub 

如果你还没有开始玩macros,他们真的很有用。 工具| macros| macrosIDE将把你带到编辑器,一旦他们被定义,你可以通过我上面提到的相同的用户界面来设置键盘快捷键。 我使用令人难以置信的方便logging临时macros命令生成这些macros,也在工具|下 macros。 这个命令可以让你录制一组键盘input并重播它们,这对于构build高级编辑命令以及自动执行重复任务(例如代码重新格式化)非常有用。

我最近做了同样的事情,当我转移到一个新的项目时,从Eclipse转移到Visual Studio。 强烈build议使用Resharper插件 – 它增加了Eclipse中丰富的编辑,导航和重构function。

Resharper还允许您使用与InteliJ非常相似的keybaord映射scheme。 非常方便的Java逃生…

关于你的第二个问题,Resharper具有和eclipse一样的移动代码上/下函数, 但有一些注意事项 。 首先,使用InteliJ键盘映射,键组合是相当曲折的。

向上移动代码: ctrl + shift + alt +向上游标

向下移动代码: ctrl + shift + alt +向下游标

其次,它并不总是只移动一行,而是实际跳转代码块。 所以它不能从一个if语句之外的一行移动到它的内部 – 它将选中的行跳转到if块。 要做到这一点,你需要移动“左”和“右”使用

将代码移动到外部代码块: ctrl + shift + alt +向左游标

将代码移入下一个内部代码块: ctrl + shift + alt +右侧光标

在visual studio中录制一个macros来做alt-arrow的事情:

 ctrl-alt-r -- record mode ctrl-c -- copy a line up arrow -- go up a line home -- beginning of line (maybe there is a way to paste before the current line without this) ctrl-v -- paste ctrl-alt-r -- end record mode 

现在,您可以使用macroside和键盘首选项将此macros映射到任何您喜欢的按键。

Edit.LineTranspose,但这不起作用,以移动一条线…这是macros排列

 Sub LineTransposeUp() Dim offset As Integer Dim sel As TextSelection DTE.UndoContext.Open("LineTransposeUp") Try sel = DTE.ActiveDocument.Selection offset = sel.ActivePoint.LineCharOffset sel.LineUp() DTE.ExecuteCommand("Edit.LineTranspose") sel.LineUp() sel.MoveToLineAndOffset(sel.ActivePoint.Line, offset) Catch ex As System.Exception End Try DTE.UndoContext.Close() End Sub 

使用MoveLine扩展可以在VS 2010/2012中向上或向下移动一行(或一组行)。

我不知道VS是否支持你正在谈论的本地function,但是我知道resharper插件允许你使用CTRL + SHIFT + BACKSPACE去以前的编辑。 我不认为它支持上下移动一个线(好吧,我还没有find)

保罗·奥斯特罗夫斯基我试过你的工具。 它的工作大多是好的。

日食所做的另一件事是将行移到当前的缩进级别。

例如:

 function test() { // do stuff } Console.WriteLine("test"); 

在console.writeline上做一个改变会改变它

 function test() { // do stuff Console.WriteLine("test"); } 

但你的工具似乎这样做:

 function test() { // do stuff Console.WriteLine("test"); }