Skip to content

Instantly share code, notes, and snippets.

@Sidelobe
Forked from emotality/duplicate_line_xcode.md
Last active February 3, 2023 08:10
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Sidelobe/2e8c0244b91f9a41a148e5d419e49772 to your computer and use it in GitHub Desktop.
Save Sidelobe/2e8c0244b91f9a41a148e5d419e49772 to your computer and use it in GitHub Desktop.
Xcode - Duplicate Line key binding

Xcode line duplication (without overwriting your clipboard)

I find this shortcut extremely useful in Xcode: duplicate one or several lines without losing what you have on the clipboard.

Bind keys to duplicate lines in Xcode

  1. To add custom key bindings in Xcode, you have to edit this file (su privileges required): '/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/Current/Resources/IDETextKeyBindingSet.plist

I add the following new key at the bottom:

<key>Custom Commands</key>
<dict>
    <key>Duplicate Current Lines Down</key>
    <string>selectParagraph:, delete:, yank:, moveToBeginningOfParagraph:, yank:, moveUp:, moveToEndOfParagraph:</string>
</dict>
  1. Open Xcode and go to Xcode Preferences -> Key Bindings
  2. filter for Duplicate Current Lines Down, add a shortcut for it. I use the chord shift + ctrl + command + , which is not taken yet and reminds me of Eclipse ;-)

NOTE: you will have to do this every time Xcode is updated -- that's why you might as well write a shell script to automate most of it.

Automatization

NOTE: you will have to do this every time Xcode is updated -- that's why you might as well write a shell script to automate it.

I'm not doing a full automatization yet... I like doing the last step manually.

Save the following in bash shell script (I called it prepareXcodeKeybindingsForEditing.sh) and then call it from terminal with sudo sh prepareXcodeKeybindingsForEditing.sh everytime you update Xcode. It opens an editor (atom in my case, edit to your liking...) and prints the XML you need to copy-paste for you in terminal.

path='/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/Current/Resources/'
bindingsFile=$path'IDETextKeyBindingSet.plist'

sudo chmod 755 $path

if [ ! -f $bindingsFile ]; then
    echo "Bindings file doen't exist"
fi
sudo chmod 664 $bindingsFile
sudo open -a atom $bindingsFile

echo "Now paste the following:"
echo "<key>Custom Commands</key>
<dict>
    <key>Duplicate Current Lines Down</key>
    <string>selectParagraph:, delete:, yank:, moveToBeginningOfParagraph:, yank:, moveUp:, moveToEndOfParagraph:</string>
</dict>"
echo ""
@goldenlove
Copy link

Good job ~
I add this line before open editor, then just press ⌘ + v paste & enjoy. :)
echo "<key>Custom Commands</key><dict> ... </dict>" | pbcopy

@Sidelobe
Copy link
Author

Sidelobe commented May 4, 2020

Good job ~
I add this line before open editor, then just press ⌘ + v paste & enjoy. :)
echo "<key>Custom Commands</key><dict> ... </dict>" | pbcopy

Nice! I didn't know that command -- thanks!

@MrThiago
Copy link

Nice Work.

@lobodpav
Copy link

lobodpav commented Nov 18, 2020

Always hated doing stuff manually, so here goes the script which automates the addition of the custom command.

It is perfectly safe. The Apple's PlistBuddy tool is utilised to add the new dictionary. It will fail if the plist does not exist, or if the custom command is already there.

The only remaining manual step is assigning the command a keyboard shortcut.

#!/bin/bash

PLB="sudo /usr/libexec/PlistBuddy"
PLIST="/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/Current/Resources/IDETextKeyBindingSet.plist"

$PLB -c "Add :'Custom Commands':'Duplicate Current Lines Down' string 'selectParagraph:, delete:, yank:, moveToBeginningOfParagraph:, yank:, moveUp:, moveToEndOfParagraph:'" "$PLIST"

@Sidelobe
Copy link
Author

That looks great Pavel, thanks for sharing!
I was not aware of the PlistBuddy tool -- definitely a great idea to use that instead of digging around in the raw plist.
You learn something new every day :-)

@lobodpav
Copy link

That looks great Pavel, thanks for sharing!
I was not aware of the PlistBuddy tool -- definitely a great idea to use that instead of digging around in the raw plist.
You learn something new every day :-)

Glad I could help! I was just frustrated today when Xcode 12.2 got installed and the custom command stopped working again 😊

@tispokes
Copy link

tispokes commented Nov 26, 2020

Better than paste i use this in my shellscript:

ex /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist <<eof
5 insert
<key>Duplication</key>
        <dict>
            <key>Duplicate Current Line</key>
            <string>moveToBeginningOfLine:, deleteToEndOfLine:, yank:, insertNewline:, moveToBeginningOfLine:, yank:</string>
            <key>Duplicate Lines</key>
            <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:</string>
            <key>Delete Line</key>
            <string>selectLine:, deleteBackward:</string>
        </dict>
.
xit
eof

@ArthurBrum
Copy link

Hey guys!

Path for file has changed! I'm using Xcode 13.4.1 and this is the working path:
/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/

@Sidelobe
Copy link
Author

Sidelobe commented Feb 3, 2023

@ArthurBrum The path has not changed -- I'm at Xcode 14.1

Note that "Current" is an alias that points to "A" -- so you path is equivalent and also valid :-)

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment