2008-11-24 33 views
40

我從Eclipse中移動到Visual Studio .NET,發現我所有心愛的熱鍵但有兩個:的Visual Studio:熱鍵移動線向上/向下,並通過最近的變化移動

  • 在Eclipse中你可以按ALT - ALT - 訪問所做最近的變化,我用頻繁地回到我在其他一些文件,其中,然後返回一些東西。顯然,在VS.NET的CTRL - -CTRL - SHIFT - -做到這一點,但他們似乎並不總是工作(如筆記本電腦,可能是一個numkey問題與負)並且似乎沒有遵循我在Eclipse中習慣的「我在哪裏」的相同算法。有沒有人得到這個工作,並依靠它每天等?
  • 在Eclipse中,以移動線向上或向下按ALT - UPARROWALT - DownArrow中文,你只要將它通過代碼,直到你得到它,你想要的話,很漂亮。也使一個行的副本,您可以按SHIFT - ALT - UPARROWSHIFT - ALT - DownArrow中文。這兩個熱鍵甚至適用於您選擇的線路塊。

有沒有人在Visual Studio .NET中發現這些熱鍵功能?

甲d d簡d U m的:

的時要使用上面描述的第二個特徵的一個例子是在這裏向上移動至底線到for循環。在Eclipse中,您可以將光標放在Console.WriteLine上,然後按ALT-(uparrow),我一直使用它:一次用於上下移動行的關鍵筆劃。

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

} 
Console.WriteLine(i); 

好吧,推斷查理的想法,沒有選擇,CTRL-C選擇線路,在Visual Studio中,你可以把你的Console.WriteLine光標(沒有選擇)按CTRL - X然後向上移動並按CTRL - V

+0

對不起,我錯誤地理解了線移動的東西,但我想我現在明白了。檢查編輯是否有這樣做的宏。 – Charlie 2008-11-24 05:41:58

回答

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 - 我再次更新了這一點,以允許移動的線條縮進自己,因爲你越過支架邊界

+0

太棒了。我希望我可以多次投票。做得好! – 2010-04-14 21:46:35

+4

這應該是答案,而不是米奇小麥的。做得好! – Borek 2010-06-07 22:09:05

+0

實際上,當我選擇「lazily」行時,這個腳本不起作用,即我從第1行中間的某處開始選擇,並在最後一行中間的某處結束。 Eclipse完美地處理這個 – Borek 2010-06-24 08:07:40

0

我不知道VS是否支持你在本地討論的功能,但我知道resharper插件可以讓你使用CTRL + SHIFT + BACKSPACE去以前的編輯。我不認爲它支持上下移動一行(不是我已經找到的)

+0

它有一種上下移動的快捷方式,但它在eclipse中不起作用 - 請參閱下面的答案。 – serg10 2008-11-24 13:10:59

14

如果您還沒有找到它,這些鍵盤快捷鍵的設置位置在Tools |選項|環境|鍵盤。通過瀏覽列表可以找到許多方便的命令,但不幸的是,我從來沒有找到任何描述每個命令打算做什麼的好參照。

至於具體的命令:

  • 我相信,前進/後退導航命令你指的是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 
  • 四處移動一行文本,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 

如果你還沒有開始與宏打,他們是真正有用的。工具|宏|宏IDE將帶你編輯器,一旦他們被定義,你可以通過我上面提到的相同的用戶界面來設置鍵盤快捷鍵。我使用令人難以置信的方便的Record Temporary Macro命令生成這些宏,同樣在Tools |下宏。該命令可讓您記錄一組鍵盤輸入並重播它們,這對於構建高級編輯命令以及自動執行重複性任務(例如代碼重新格式化)非常有用。

+2

CTRL-C,CTRL-V沒有選擇複製一行很不錯,不知道那個,謝謝。 – 2008-11-24 05:34:10

2

記錄在Visual Studio宏做ALT-箭頭的東西:

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和鍵盤偏好。

9

我最近做了同樣的事情,當我轉移到一個新項目時,從Eclipse轉移到Visual Studio。 Resharper add in強烈推薦 - 它增加了一些豐富的編輯,導航和重構功能,日食已與VS.

Resharper還允許您使用與InteliJ非常相似的密鑰映射方案。非常方便的Java逃生...

關於你的第二個問題,Resharper具有相同的移動代碼上/下功能日食,但有一些注意事項。首先,使用InteliJ鍵盤映射,鍵組合相當曲折。

代碼移動起來:CTRL + SHIFT + ALT +上箭頭

移動代碼下來:CTRL + SHIFT + ALT +下箭頭

其次,它並不總是隻移動一行,但實際上跳轉代碼塊。所以它不能將if語句之外的一行移動到if語句的內部 - 它將選中的行直接跳過if語句塊。要做到這一點,你需要移動「左」和「右」使用

代碼移動到外部代碼塊:CTRL + ALT +左光標

移動代碼轉移到下一個內碼塊: CTRL + SHIFT + ALT +右光標

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 
0

保羅·奧斯特洛夫斯基我想你的工具。它的工作主要是好的。

eclipse所做的另一件事是將行移動到當前縮進級別。

例如:

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

上做console.writeline升檔將其更改爲

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

,但你的工具,似乎要做到這一點:

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

使用MoveLine extension在VS 2010/2012中向上或向下移動一行(或一組行)。