eclipse Visual Studio:用于向上/向下移动行并浏览最近更改的热键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/313462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 18:31:58  来源:igfitidea点击:

Visual Studio: hotkeys to move line up/down and move through recent changes

visual-studioeclipsehotkeys

提问by Edward Tanguay

I'm moving from Eclipse to Visual Studio .NET and have found all my beloved hotkeys except two:

我正在从 Eclipse 迁移到 Visual Studio .NET,并找到了除两个之外的所有我心爱的热键:

  • in Eclipse you can press ALT-and ALT-to visit recent changes you have made, something I use frequently to go back to where I was in some other file and then return. Apparently in VS.NET the CTRL--and CTRL-SHIFT--do this but they don't seem to always work (e.g. on laptop, may be a numkey issue with the minus) and don't seem to follow the same algorithm of "where I was" as I am used to in Eclipse. Has anyone gotten this to work and rely on it daily, etc.?
  • in Eclipse, to move a line up or down you press ALT-uparrowor ALT-downarrowand you just move it through the code until you get it to where you want it, very nice. Also to make a copy of a line, you can press SHIFT-ALT-uparrowor SHIFT-ALT-downarrow. Both of these hotkeys even work for block of lines that you have selected.
  • 在 Eclipse 中,您可以按ALT-ALT-访问您最近所做的更改,我经常使用它返回到我在其他文件中的位置然后返回。显然,在VS.NET的CTRL--CTRL- SHIFT--做到这一点,但他们似乎并不总是工作(如笔记本电脑,可能是一个numkey问题与负),似乎没有遵循“我在那里同样的算法“正如我在 Eclipse 中所习惯的那样。有没有人让它工作并每天依赖它等等?
  • 在 Eclipse 中,要向上或向下移动一行,您可以按ALT-uparrowALT-downarrow然后您只需在代码中移动它,直到将其移动到您想要的位置,非常好。同样要复制一行,您可以按SHIFT- ALT-uparrowSHIFT- ALT- downarrow。这两个热键甚至适用于您选择的行块。

Has anyone discovered these hotkey features in Visual Studio .NET?

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

A D D E N D U M :

附录:

An example of when you would use the second feature described above is to move the bottom line here up into the for loop. In Eclipse, you would put the cursor on the Console.WriteLine and then press ALT-(uparrow), I use that all the time: one key stroke to move lines up and down.

何时使用上述第二个功能的示例是将此处的底线向上移动到 for 循环中。在 Eclipse 中,您可以将光标放在 Console.WriteLine 上,然后按 ALT-(向上箭头),我一直使用它:一键上下移动行。

for (int i = 0; i < 10; i++) {

}
Console.WriteLine(i);

Ok, extrapolating Charlie's idea with no-selection-ctrl-c to select a line, in Visual Studio you could put your cursor on Console.WriteLine, (no selection) press CTRL-Xand then move up and press CTRL-V.

好的,用 no-selection-ctrl-c 推断 Charlie 的想法来选择一行,在 Visual Studio 中,您可以将光标放在 Console.WriteLine 上,(无选择)按CTRL-X然后向上移动并按CTRL- V

回答by Paul Ostrowski

The answers proposed work, but none of them are as nice as eclipse with regard to how they preserve the existing paste buffer, the currently selected characters, and they do not allow the user to operate upon a range of lines. Here is a solution I came up with that preserves the paste buffer, the current character selection, and works with or without a selection (that may or may not span multiple rows):

建议的答案是可行的,但在它们如何保留现有粘贴缓冲区、当前选定的字符以及它们不允许用户对一系列行进行操作方面,没有一个像 eclipse 一样好。这是我想出的一个解决方案,它保留了粘贴缓冲区、当前字符选择,并且可以使用或不使用选择(可能跨越多行,也可能不跨越多行):

'' 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

I edited this post to add the UndoContext mechanism (suggested by Nicolas Dorier) at the beginning of the MoveLineUp() and MoveLineDown() methods and closing it at their end. 11/23/11 - I updated this again to allow the moved lines to indent themselves as you cross bracket boundaries

我编辑了这篇文章,在 MoveLineUp() 和 MoveLineDown() 方法的开头添加了 UndoContext 机制(由 Nicolas Dorier 建议)并在它们的末尾关闭它。2011 年 11 月 23 日 - 我再次更新了这一点,以允许移动的行在跨越括号边界时缩进

回答by Polshgiant

For anyone looking for a way to do this in Visual Studio 2010, the free Visual Studio 2010 Pro Power Tools extension adds the capability to move lines up and down.

对于在 Visual Studio 2010 中寻找方法来执行此操作的任何人,免费的 Visual Studio 2010 Pro Power Tools 扩展添加了上下移动行的功能。

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

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

回答by Charlie

If you haven't already found it, the place where these keyboard shortcuts are setup is under Tools | Options | Environment | Keyboard. A lot of handy commands can be found just by browsing through the list, although unfortunately I've never found any good reference for describing what each command is intended to do.

如果您还没有找到,那么设置这些键盘快捷键的位置在工具 | 下。选项 | 环境 | 键盘。只需浏览列表即可找到许多方便的命令,但不幸的是,我从未找到任何好的参考资料来描述每个命令的用途。

As for specific commands:

至于具体的命令:

  • I believe the forward/backward navigation commands you're referring to are View.NavigateBackward and View.NavigateForward. If your keyboard isn't cooperating with the VS key bindings, you can remap them to your preferred Eclipse keys. Unfortunately, I don't know of a way to change the algorithm it uses to actually decide where to go.

  • I don't think there's a built-in command for duplicating a line, but hitting Ctrl+C with no text selected will copy the current line onto the clipboard. Given that, here's a simple macro that duplicates the current line on the next lower line:

  • 我相信您所指的向前/向后导航命令是 View.NavigateBackward 和 View.NavigateForward。如果您的键盘不与 VS 键绑定配合使用,您可以将它们重新映射到您首选的 Eclipse 键。不幸的是,我不知道有什么方法可以改变它用来实际决定去哪里的算法。

  • 我认为没有用于复制行的内置命令,但是在没有选择文本的情况下按 Ctrl+C 会将当前行复制到剪贴板上。鉴于此,这是一个简单的宏,它在下一行复制当前行:


    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
  • For moving a line of text around, Edit.LineTranspose will move the selected line down. I don't think there's a command for moving a line up, but here's a quick macro that does it:
  • 为了移动一行文本,Edit.LineTranspose 会将选定的行向下移动。我不认为有一个向上移动一行的命令,但这里有一个快速宏可以做到:

    Sub MoveLineUp()
        DTE.ActiveDocument.Selection.Collapse()
        DTE.ActiveDocument.Selection.Cut()
        DTE.ActiveDocument.Selection.LineUp()
        DTE.ActiveDocument.Selection.Paste()
        DTE.ActiveDocument.Selection.LineUp()
    End Sub

If you haven't yet started playing with macros, they are really useful. Tools | Macros | Macros IDE will take you the editor, and once they're defined, you can setup keyboard shortcuts through the same UI I mentioned above. I generated these macros using the incredibly handy Record Temporary Macro command, also under Tools | Macros. This command lets you record a set of keyboard inputs and replay them any number of times, which is good for building advanced edit commands as well as automating repetitive tasks (e.g. code reformatting).

如果您还没有开始使用宏,它们真的很有用。工具 | 宏 | 宏 IDE 将带您进入编辑器,一旦定义了它们,您就可以通过我上面提到的相同 UI 设置键盘快捷键。我使用非常方便的 Record Temporary Macro 命令生成了这些宏,也在 Tools | 下。宏。此命令允许您记录一组键盘输入并重放它们任意次数,这对于构建高级编辑命令以及自动执行重复性任务(例如代码重新格式化)非常有用。

回答by serg10

I have recently done the same thing and moved from Eclipse to Visual Studio when I moved onto a new project. The Resharper add inis highly recommended- it adds some of the rich editing, navigational and refactoring functionality that eclipse has to VS.

我最近做了同样的事情,当我转移到一个新项目时,我从 Eclipse 转移到了 Visual Studio。 强烈推荐使用Resharper 插件——它为 VS 添加了 eclipse 所具有的一些丰富的编辑、导航和重构功能。

Resharper also allows you to use a keybaord mapping scheme that is very simillar to InteliJ. Very handy for the Java escapees...

Resharper 还允许您使用与 InteliJ 非常相似的 keybaord 映射方案。对 Java 越狱者来说非常方便......

Regarding your second question, Resharper has the same move code up / down function as eclipse, but with some caveats. Firstly, using the InteliJ keyboard mappings, the key combination is rather tortuous.

关于您的第二个问题,Resharper 具有与 eclipse 相同的向上/向下移动代码功能,但有一些警告。首先,使用 InteliJ 键盘映射,组合键比较曲折。

Move code up: ctrl + shift + alt + up cursor

Move code down: ctrl + shift + alt + down cursor

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

下移代码:ctrl + shift + alt + 下光标

Secondly, it does not always move by just one line, but actually jumps code blocks. So it cannot move a line from outside an if statement to inside it - it jumps the selected line right over the if block. To do that you need to move "left" and "right" using

其次,它并不总是只移动一行,而是实际跳转代码块。所以它不能将一行从 if 语句的外部移动到它的内部 - 它会在 if 块的正上方跳过选定的行。为此,您需要使用“向左”和“向右”移动

Move code into outer code block: ctrl + shift + alt + left cursor

Move code into next inner code block: ctrl + shift + alt + right cursor

将代码移入外部代码块:ctrl + shift + alt + 左光标

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

回答by Nicolas Dorier

Edit.LineTranspose but this doesn't work to move a line up... Here is the macro to move line up

Edit.LineTranspose 但这对向上移动行不起作用...这是向上移动行的宏

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

回答by 1800 INFORMATION

Record a macro in visual studio to do the alt-arrow thing:

在visual studio中录制一个宏来做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

Now you can map this macro to any set of keystrokes you like using the macros ide and the keyboard preferences.

现在,您可以使用宏 ide 和键盘首选项将此宏映射到您喜欢的任何一组击键。

回答by Kevin Aenmey

Use the MoveLine extensionto move a line (or group of lines) up or down in VS 2010/2012.

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

回答by lomaxx

I don't know if VS supports the features you're talking about natively, but I know the resharper plugin allows you to go to the previous edits by using CTRL + SHIFT + BACKSPACE. I don't think it has support for moving a line up and down tho (well not that I've found yet)

我不知道 VS 是否支持您在本机谈论的功能,但我知道 resharper 插件允许您使用 CTRL + SHIFT + BACKSPACE 转到以前的编辑。我认为它不支持上下移动一条线(我还没有发现)

回答by jdeuce

Paul Ostrowski I tried your tool. It works mostly okay.

Paul Ostrowski 我试过你的工具。它的工作大部分没问题。

The other thing that eclipse does is move the line to the current indentation level.

eclipse 做的另一件事是将行移动到当前的缩进级别。

For example:

例如:

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

Doing a shift-up on console.writeline would change it to

在 console.writeline 上进行换档会将其更改为

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

but your tool seems to do this:

但您的工具似乎是这样做的:

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