Sublime Forum

Modifying Sublime Merge key bindings

#1

I would like to modify sublime merge shortcuts, and make it like SublimeGit package of Sublime Text.

There is no command list available for Sublime Merge, so I don’t know how to add my own shortcuts.

So could anyone please help me to map these, we can make slightly different if necessary;

s = stage file/section
S = stage all unstaged files
ctrl+shift+s = stage all unstaged and untracked files
u = unstage file/section
U = unstage all files
backspace = discard file/section
shift+backspace = discard everything
c = commit
C = commit -a (add unstaged)
ctrl+shift+c = commit --amend (amend previous commit)
0 Likes

#2

Here are the key bindings you wanted. Please read the comments once. To use these, go to Preferences -> Edit Key Bindings ... from the main menu and paste.

[
	// This will stage a file when the focus is in a diff view.
	// s = stage file/section
	{
		"keys": ["s"],
		"command": "stage_file",
		"args": {
			"path": "$file"
		},
		"context": [
			{ "key": "is_diff", "operator": "equal", "operand": true },
		],
	},

	// This will unstage a file when the focus is in the staged file's diff view.
	// u = unstage file/section
	{
		"keys": ["u"],
		"command": "unstage_file",
		"args": {
			"path": "$file"
		},
		"context": [
			{ "key": "is_staged", "operator": "equal", "operand": true },
		],
	},

	// This will stage all unstaged files.
	// S = stage all unstaged files
	//
	// Currently, you can't type S in the commit message input, even though there is a context for it.
	// So not sure what's up with that.
	{
		"keys": ["S"],
		"command": "stage_all",
		"context": [
			{ "key": "is_editing_commit", "operator": "equal", "operand": false },
		],
	},

	// This will unstage all staged files.
	// U = unstage all files
	//
	// Same problem with the previous key binding. Not sure, how to deactivate it when in commit message input.
	{
		"keys": ["U"],
		"command": "unstage_all",
		"context": [
			{ "key": "has_staged", "operator": "equal", "operand": true },
		],
	},


	// Commit.
	//
	// Not sure why this doesn't work.
	{
		"keys": ["c"],
		"command": "commit",
		"context": [
			{ "key": "can_commit", "operator": "equal", "operand": true },
		],
	},

	// Amend the previous commit.
	// ctrl+shift+c = commit --amend (amend previous commit)
	{
		"keys": ["ctrl+shift+c"],
		"command": "commit",
		"args": {
			"mode": "commit --amend"
		},
	},

	// Automatically commit any modified/deleted files.
	// C = commit -a (add unstaged)
	//
	// This again doesn't work. Not sure.
	{
		"keys": ["C"],
		"command": "commit",
		"args": {
			"mode": "commit --all"
		},
	}
]

1 Like

#3

Thanks! But I have some issues. I would like to stage files while on the “files” tab. I think changing the context key will work, but what are the other context keys that I can use?

Edit: Ok I found it in here: https://www.sublimemerge.com/docs/key_bindings#context I will try now.

Edit2: Its triggered when context key is is_staged=false, but now $file variable doesn’t work. Is there any other variables that I can use? Check below.

  {
    "keys": ["s"],
    "command": "stage_file",
    "args": {
      "path": "$file"
    },
    "context": [
      { "key": "is_staged", "operator": "equal", "operand": false },
    ],
  },
0 Likes

#4

Hi @xmripper,

This should do what you want. You can see we use the control context key to check if we are focused on the table_of_contents (Files tab).

{
    "keys": ["s"],
    "command": "stage_file",
    "args": {"path":"$path"},
    "context":
    [
        {"key": "is_staged", "operand": false },
        { "key": "control", "operand": "table_of_contents table_of_contents_tree" }
    ],
},

Additionally, here are some commands you may find useful:
stage_file
unstage_file
discard_file
delete_file
stage_all
unstage_all
stage_all_modified
stage_all_untracked
discard_all_modified
discard_all_modified
commit (takes a mode argument which can accept "commit" or "commit --amend")

Hope this helps!

Kind regards,
- Dylan

3 Likes

#5

Just adding to this, if you’d like to get the names of specific UI controls to check for focus, you can set log_control_tree = true in the settings file (accessible via Preferences > Edit Settings...)

Once you’ve done this, you can use ctrl + alt + left click to print out the controls under the cursor. The output will then be displayed in the Sublime Merge console (access via Tools > Show Console) .

2 Likes

#6

That’s great! It worked well. Thanks for all the information.

Here is my final configuration, if anyone needs:

[
  // s = stage file
  {
    "keys": ["s"],
    "command": "stage_file",
    "args": {
      "path": "$file"
    },
    "context": [
      { "key": "is_editing_commit", "operator": "equal", "operand": false },
    ],
  },

  {
    "keys": ["s"],
    "command": "stage_file",
    "args": {
      "path": "$path"
    },
    "context": [
      { "key": "is_staged", "operand": false },
      { "key": "control", "operand": "table_of_contents table_of_contents_tree" }
    ],
  },

  // u = unstage file
  {
    "keys": ["u"],
    "command": "unstage_file",
    "args": {
      "path": "$file"
    },
    "context": [
      { "key": "is_editing_commit", "operator": "equal", "operand": false },
    ],
  },

  {
    "keys": ["u"],
    "command": "unstage_file",
    "args": {
      "path": "$path"
    },
    "context": [
      { "key": "is_staged", "operand": true },
      { "key": "control", "operand": "table_of_contents table_of_contents_tree" }
    ],
  },

  // S = stage all files
  {
    "keys": ["S"],
    "command": "stage_all",
    "context": [
      { "key": "is_editing_commit", "operator": "equal", "operand": false },
    ],
  },

  // U = unstage all files
  {
    "keys": ["U"],
    "command": "unstage_all",
    "context": [
      { "key": "is_editing_commit", "operator": "equal", "operand": false },
    ],
  },
]
0 Likes

#7

Glad it worked for you! One thing to note is that is_editing_commit is actually used to determine whether you’re editing an existing commit. It doesn’t actually correspond to whether the input focus is in the commit box.

I can’t think of a way off the top of my head to check this,
but I’ll get back to you on this. For the meantime, you could instead use ctrl + s for stage all (instead of stash).

Kind regards,
- Dylan

1 Like

#8

Thanks for pointing that. I thought it correspond to input focus.

0 Likes

#9

@djohnston Thanks for clarifying this ! I thought is_editing_commit actually corresponds to commit input focus.

0 Likes