Visual Studio:热键上下移动线,并移动最近的更改 [英] Visual Studio: hotkeys to move line up/down and move through recent changes

查看:311
本文介绍了Visual Studio:热键上下移动线,并移动最近的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从Eclipse移动到Visual Studio .NET,并发现除了两个以外我所爱的热键:




  • 在Eclipse中,你可以按 ALT - ALT - 访问您所做的最近更改,我经常使用的东西回到我在某个其他文件的地方,然后返回。显然在VS.NET中, CTRL - - CTRL - SHIFT - - 这样做,但它们似乎并不总是工作(例如在笔记本电脑上,可能是负数的numkey问题),似乎并不像我习惯于在Eclipse中使用与我在哪里相同的算法。有没有人得到这个工作,每天都依赖它等等。在Eclipse中

  • ,向上或向下移动一行你按 ALT - uparrow ALT - downarrow ,你只需要移动它通过代码,直到你到达你想要的地方,非常好。也可以复制一行,可以按 SHIFT - ALT - uparrow SHIFT - ALT - DownArrow中文。这两个热键甚至适用于您选择的行的块。有人在Visual Studio .NET中发现了这些热键功能吗?



ADDENDUM:



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


$ b $ (int i = 0; i <10; i ++){

}
Console.WriteLine(i); b

  

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

解决方案

答案提出了工作,但没有一个像日食一样好,关于他们保留现有的粘贴缓冲区,当前选定的字符,并且不允许用户对一系列行进行操作。这里是一个解决方案,我想出了保留粘贴缓冲区,当前的字符选择,并且可以使用或不选择(可能或可能不跨越多行):

 ''复制当前行(或选择行),并将副本
'一行置于当前光标位置之下或之上(基于参数)
Sub CopyLine(ByVal movingDown As Boolean)
DTE.UndoContext.Open(CopyLine)
Dim objSel As TextSelection = DTE.ActiveDocument.Selection

'存储原始选择和光标位置
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()

'将每行从顶行复制到botto m行
Dim readLine As Long = lTopLine
Dim endLine As Long = lBottomLine + 1
Dim selectionPresent As Boolean =((lTopLine& lBottomLine)或(lTopColumn lBottomColumn)
If(selectionPresent And(lBottomColumn = 1))然后
'存在选择,但光标位于第一个字符前面
'在底线。从复制选择中排除那个底线。
endLine = lBottomLine
结束如果

'找出我们复制了多少行,我们可以在复制完成后重新定位
'我们的选择
Dim verticalOffset As Integer = 0
如果(movingDown)然后
verticalOffset = endLine - lTopLine
结束如果

'复制每一行,一次一个。
'Insert命令不能很好地处理多行,我们需要
'来使用Insert来避免自动完成
Dim insertLine As Long = endLine
While(readLine< endLine )
'移动读取位置,并读取当前行
objSel.MoveToLineAndOffset(readLine,1)
objSel.EndOfLine(True)'扩展为EOL
Dim lineTxt As String = objSel.Text.Clone
'移动到目标位置,并插入副本
objSel.MoveToLineAndOffset(insertLine,1)
objSel.Insert(lineTxt)
objSel.NewLine ()
'调整读取&插入点
readLine = readLine + 1
insertLine = insertLine + 1
End While

'将光标恢复到原始位置并选择
objSel.MoveToLineAndOffset (lBottomLine + verticalOffset,lBottomColumn)
objSel.MoveToLineAndOffset(lTopLine + verticalOffset,lTopColumn,True)
DTE.UndoContext.Close()
End Sub

'复制当前行(或选择行),并将副本
'在当前光标位置下方一行
Sub CopyLineDown()
CopyLine(True)
End Sub

''复制当前行(或选择行),并将副本
''放置在当前光标位置上方一行
Sub CopyLineUp()
CopyLine( False)
End Sub


'将选定的行上移一行。如果没有行被选中
'',则当前行被移动。
''
Sub MoveLineUp()
DTE.UndoContext.Open(MoveLineUp)
Dim objSel As TextSelection = DTE.ActiveDocument.Selection
'存储原始选择和光标位置
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

'如果选择多行,但底线不
'选择任何字符,请不要将其选为
Dim lEffectiveBottomLine = lBottomLine
如果((lBottomColumn = 1)And(lBottomLine<> lTopLine))然后
lEffectiveBottomLine = lBottomLine - 1
End If

'移到顶行上方的行
objSel.MoveToLineAndOffset(lTopLine - 1,1)
'并将其向下移动,直到其底线为底:
Do
DTE.ExecuteCommand(Edit.LineTranspose)
循环直到(objSel.BottomPoint.Line> = lEffectiveBottomLine)
'由于我们所在的行已经上升,我们在文件中的位置已更改:
lTopLine = lTopLine - 1
lBottomLine = lBottomLine - 1

IndentBlockAndRestoreSelection(objSel,lBottomLine,lBottomColumn,lTopLine,lTopColumn,indentChange)

DTE.UndoContext.Close()
End Sub

''移动选定的下线一行。如果没有行被选中
'',则当前行被移动。
''
Sub MoveLineDown()
DTE.UndoContext.Open(MoveLineDown)
Dim objSel As TextSelection = DTE.ActiveDocument.Selection
'存储原始选择和光标位置
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 lEffectiveBottomLine = lBottomLine
如果((lBottomColumn = 1)和(lBottomLine<> lTopLine))然后
lEffectiveBottomLine = lBottomLine - 1
End If

Dim textLineBelow As TextSelection = DTE.ActiveDocument.Selection
textLineBelow.MoveTo LineAndOffset(lEffectiveBottomLine + 1,1,False)
textLineBelow.MoveToLineAndOffset(lEffectiveBottomLine + 2,1,True)
Dim indentChange As Integer = CountIndentations(textLineBelow.Text)


'移动到底线
objSel.MoveToLineAndOffset(lEffectiveBottomLine,1)
'并将其向下移动,这有效地将其下方的行移动
'然后将光标向上移动,总是保持上行线上的一行
',并继续向上移动直到它的顶部行:
Dim lineCount As Long = lEffectiveBottomLine - lTopLine
Do
DTE.ExecuteCommand(Edit.LineTranspose)
objSel.LineUp(False,2)
lineCount = lineCount - 1
循环直到(lineCount< 0)
'由于我们所在的行已经下移,我们在文件中的位置已更改:
lTopLine = lTopLine + 1
lBottomLine = lBottomLine + 1

IndentBlockAndRestoreSelection(objSel,lBottomLine,lBottomColumn,lTopLine,lTopColumn,indentChange)

DTE.UndoContext.Close()
End Sub

''此方法需要关心通过indentChange参数
''缩进所选文本,然后将选择恢复为lTopLine:lTopColumn - lBottomLine:lBottomColumn参数。
将根据执行的indentChange调整这些值
Sub IndentBlockAndRestoreSelection(ByVal objSel As TextSelection,ByVal lBottomLine As Long,ByVal lBottomColumn As Long,ByVal lTopLine As Long,ByVal lTopColumn As Long,ByVal indentChange作为整数)
'将光标恢复到原始位置并选择
objSel.MoveToLineAndOffset(lBottomLine,lBottomColumn)
objSel.MoveToLineAndOffset(lTopLine,lTopColumn,True)
If(indentChange = 0)然后
'如果我们不更改缩进,我们完成
返回
结束如果

如果(lBottomLine = lTopLine)然后
if(indentChange> 0)Then
objSel.StartOfLine()
Else
objSel.StartOfLine()
objSel.WordRight()
End If
结束如果
objSel.Indent(indentChange)

'由于所选文本已更改列,因此调整列ngly:
'将光标恢复到原始位置并选择
Dim lNewBottomColumn As Long =(lBottomColumn + indentChange)
Dim lNewTopColumn As Long =(lTopColumn + indentChange)
'确保我们还在页面上
'如果我们处于行左边缘的或子句,我们将保留在左边缘。
如果((lNewBottomColumn <2)or(lBottomColumn = 1))然后
'单行选择或已经在1的bottomColumn可能仍然有一个新的BottomColumn为1
如果((lTopLine = lBottomLine)or(lBottomColumn = 1))然后
lNewBottomColumn = 1
Else
'如果我们选择了多行,不要让底部边缘触摸左列,
'或下一步将忽略该底线。
lNewBottomColumn = 2
End If
End If
如果((lNewTopColumn <2)或(lTopColumn = 1))然后
lNewTopColumn = 1
结束如果

'将选择恢复到修改的选择
objSel.MoveToLineAndOffset(lBottomLine,lNewBottomColumn)
objSel.MoveToLineAndOffset(lTopLine,lNewTopColumn,True)
End Sub


''该方法计算文本中作为参数
提供的缩进更改函数CountIndentations(ByVal text As String)As Integer
Dim indent As Integer = 0
While(Text.Length> 0)
If(Text.StartsWith(//))然后
Dim endOfLine As Integer = Text.IndexOf(\\\
2)
如果(等于(endOfLine,-1))然后
'剩余的文本全部在一行,所以'//'终止我们的搜索
'忽略其余的文本
退出而
结束如果
'继续查找行结束
Text = Text.Substring(endOfLine + 1)
如果

If(Text.StartsWith(/ *))然后
Dim endComment As Integer = Text.IndexOf(* /,2)
If(Equals(endComment,-1))然后
'这条线的长度。
'忽略文本的其余部分
退出While
结束如果
'继续查看此注释块的结尾
Text = Text.Substring(endComment + 1 )
如果

If(Text.StartsWith({))然后
indent = indent + 1
Else
If(Text.StartsWith (}))然后
indent = indent - 1
如果
结束If
Text = Text.Substring(1)
结束而
返回缩进
结束函数

我编辑这篇文章添加了UndoContext机制(由Nicolas建议Dorier)在MoveLineUp()和MoveLineDown()方法的开头,并将其关闭。
11/23/11 - 我再次更新,允许移动的行缩进自己,因为你跨支架边界


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

  • 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-uparrow or ALT-downarrow and 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-uparrow or SHIFT-ALT-downarrow. Both of these hotkeys even work for block of lines that you have selected.

Has anyone discovered these hotkey features in 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 (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-X and then move up and press CTRL-V.

解决方案

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):

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

这篇关于Visual Studio:热键上下移动线,并移动最近的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆