我正在从Eclipse迁移到Visual Studio .NET,除了两个外,我找到了所有我心爱的热键:
有没有人在Visual Studio .NET中发现过这些热键功能?
A D D E N D U M:
使用上述第二个功能的一个示例是将底线向上移动到for循环中。在Eclipse中,您可以将光标放在Console.WriteLine上,然后按ALT-(向上箭头),我会一直使用它:一个键击可以上下移动线。
for (int i = 0; i < 10; i++) {
}
Console.WriteLine(i);
好的,通过no-selection-ctrl-c推断Charlie的想法来选择一行,在Visual Studio中你可以将光标放在Console.WriteLine上,(无选择)按 CTRL - X 然后向上移动并按 CTRL - V 。
答案 0 :(得分:50)
答案提出了工作,但是它们都没有像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
我编辑了这篇文章,在MoveLineUp()和MoveLineDown()方法的开头添加了UndoContext机制(由Nicolas Dorier建议)并在它们的末尾关闭它。 11/23/11 - 我再次对此进行了更新,以允许移动的线条在跨越支架边界时缩进
答案 1 :(得分:16)
对于在Visual Studio 2010中寻找方法的人来说,免费的Visual Studio 2010 Pro Power Tools扩展程序增加了上下移动行的功能。
http://visualstudiogallery.msdn.microsoft.com/en-us/d0d33361-18e2-46c0-8ff2-4adea1e34fef
答案 2 :(得分:14)
如果您还没有找到它,设置这些键盘快捷键的位置在工具|下选项|环境|键盘。通过浏览列表可以找到许多方便的命令,但不幸的是,我从来没有找到任何好的参考来描述每个命令的目的。
至于具体命令:
我相信你所指的前进/后退导航命令是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
Sub MoveLineUp()
DTE.ActiveDocument.Selection.Collapse()
DTE.ActiveDocument.Selection.Cut()
DTE.ActiveDocument.Selection.LineUp()
DTE.ActiveDocument.Selection.Paste()
DTE.ActiveDocument.Selection.LineUp()
End Sub
如果你还没有开始玩宏,它们真的很有用。工具|宏|宏IDE将带您进入编辑器,一旦定义它们,您就可以通过我上面提到的相同UI设置键盘快捷键。我使用非常方便的Record Temporary Macro命令生成了这些宏,也在Tools |下宏。此命令允许您录制一组键盘输入并重放它们任意次,这有助于构建高级编辑命令以及自动执行重复性任务(例如代码重新格式化)。
答案 3 :(得分:9)
我最近做了同样的事情,当我搬到一个新项目时,从Eclipse迁移到Visual Studio。 强烈推荐Resharper add in - 它增加了eclipse对VS的一些丰富的编辑,导航和重构功能。
Resharper还允许您使用与InteliJ非常相似的键盘映射方案。非常方便的Java逃脱者......
关于你的第二个问题,Resharper具有与eclipse相同的移动代码上/下功能,但有一些警告。首先,使用InteliJ键盘映射,键组合相当曲折。
向上移动代码: ctrl + shift + alt +向上光标
向下移动代码: ctrl + shift + alt +向下光标
其次,它并不总是仅移动一行,而是实际跳转代码块。所以它不能从if语句外部移动一行到它内部 - 它将所选行跳过if块。要做到这一点,你需要使用
移动“左”和“右”将代码移动到外部代码块中: ctrl + shift + alt + left cursor
将代码移动到下一个内部代码块: ctrl + shift + alt + right cursor
答案 4 :(得分:2)
在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
现在,您可以使用宏ide和键盘首选项将此宏映射到您喜欢的任何一组击键。
答案 5 :(得分:2)
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
答案 6 :(得分:1)
使用MoveLine extension在VS 2010/2012中向上或向下移动一行(或一组行)。
答案 7 :(得分:0)
我不知道VS是否支持您正在谈论的功能,但我知道resharper插件允许您使用CTRL + SHIFT + BACKSPACE转到之前的编辑。我不认为它支持上下移动一条线(不是我发现的那条)
答案 8 :(得分:0)
Paul Ostrowski我尝试了你的工具。它的工作原理很好。
eclipse所做的另一件事是将线移动到当前的缩进级别。
例如:
function test()
{
// do stuff
}
Console.WriteLine("test");
在console.writeline上进行升级会将其更改为
function test()
{
// do stuff
Console.WriteLine("test");
}
但您的工具似乎是这样做的:
function test()
{
// do stuff
Console.WriteLine("test");
}