Sublimerge 3 documentation

Macros

Sublimerge comes with a few predefined Macros for Git, SVN and Mercurial users. Their implementation is stored in Preferences > Package Settings > Sublimerge > Macros - Default. Macros can be used for various scenarios and are not limited to Version Control Systems only. You can, for example, define one to compare local files with remote ones via (S)FTP.

Predefined Macros

Git Mercurial Subversion
Show Uncommited Changes... Show Uncommited Changes... Show Uncommited Changes...
Compare to Custom Git Command Output... Compare to Custom Hg Command Output... Compare to Custom SVN Command Output...
Compare to Other Branch... Compare to Named Branch...
Show Unpushed Changes...
Show Changes Between Current and Remote...
List and Resolve Conflicts...
Resolve Conflicts in Current File

Predefined variables

  • ${CONFIG:<config_key>} - returns a Sublimerge's configuration value for given key
  • ${CURRENT:FILE} - full path of active file, i.e. /Users/workspace/my_project/something.js
  • ${CURRENT:FILE_DIR} - full path of active file owning directory, i.e. /Users/workspace/my_project
  • ${CURRENT:FILE_NAME} - name of active file, i.e. something.js
  • ${CURRENT:REPO_ROOT} - root directory where .svn, .git or .hg is located for currently active file
  • ${ENV:TEMP_DIR} - path to system's temporary files directory
  • ${git} - path to git executable
  • ${svn} - path to svn executable
  • ${hg} - path to hg executable

Variables' modifiers

Modifiers allows you to transform value of the variable. You can chain modifiers using | operator, i.e. ${CURRENT:FILE|dirname|dirname|...}

  • ${variable|basename} - if variable contains filesystem path, will return only its base name
  • ${variable|dirname} - if variable contains filesystem path, will return only its directory path
  • ${variable|ext} - if variable contains filesystem path/file name, will return only file's extension
  • ${variable|repopath} - if variable contains filesystem path, will left-trim repository root (if applicable)

Directives

capture

Captures output from execute directive. If you want a step to run execute directive you must put it in capture.

  • name - if set, a variable containing captured output will be populated
  • regexp - if set, used to find and and parse matching output lines
  • value - if set, allows to format output line. Accepts @<number> placeholders for regexp
  • greedy - by default capture is not greedy and will stop on first (matching) line
  • empty_message - if set, empty capture will display a message and stop flow
  • continue_if_empty - if true, Macro execution will not be interrupted if captured output is empty. Applies only when empty_message is set.

capture {
    <execute> execute
    [, <string> name]
    [, <string> regexp]
    [, <string> value]
    [, <boolean> greedy=false]
    [, <string> empty_message]
    [, <boolean> continue_if_empty=false]
}

compare

Runs files comparison. Optionally can call a shell command given in execute statement just before comparison is run. For 2-way diff use left and right only. For 3-way diff use theirs, mine, base and merged only.

compare {
    [<left> left]
    [, <right> right]
    [, <theirs> theirs]
    [, <mine> mine]
    [, <base> base]
    [, <merged> merged]
    [, <execute> execute]
}

define

Allows to define variables to be used in next steps. Variable values may contain ${variable} placeholders to be replaced with previously declared variables' values.

define {
    <string> var_name_1: <string> var_value_1,
    ...
    <string> var_name_N: <string> var_value_N
}

execute

Executes given shell command in given directory. If you want a step to run execute directive you must put it in capture.

execute {
    <string> command,
    <string> directory
}

history_panel

Displays Quick Panel with list of commits for given file. When user selects a commit, variable defined by name is populated with commit number. If file is not versioned or does not exist, displays an error message and stops Macro execution. Works automatically for Git, SVN and Mercurial.

history_panel {
    <string> name,
    <string> file
}

item

Used by source directive to parse its execute output. Parsing is called for every output line. The regexp string argument defines regular expression to be used to parse a line. The caption argument, array of strings, is used to create each item which will be displayed in quick_panel. The value string argument sets item's value.

Both caption and value accepts @<number> placeholders for each regexp capturing group, i.e. @0, @1 and so on.

To make all items unique by their values, set unique argument to true.

item {
    <string> regexp,
    <array> caption,
    <string> value
    [, <boolean> unique=false]
}

left, right, theirs, mine, base, merged

Defines files for compare directive. The boolean temporary argument defines whether a file is temporary. Temporary files are read-only and are automatically removed after comparison is done. When title is provided then it is used for files' tab title. Defaults to file name.

left, right, theirs, mine, base, merged {
    <string> file,
    <boolean> temporary
    [, <string>] title
}

log

Prints debugging information into Sublime's console.

log {
    <string> text
}

ok_cancel_dialog

Displays ok/cancel dialog to let the user make a decision. The macro proceeds to next steps when all steps defined in on_ok are done. Pressing Cancel button stops Macro execution.

ok_cancel_dialog {
    <string> message,
    <array> on_ok
    [, <string> ok_title]
}

only, none

Controls how to filter data returned by source directive. You can pass one of the following arguments:

  • source - another source directive to fetch values, or
  • values - array of predefined string values.

Depending if used as only or none, works as follows:

  • only - return only items which value is listed
  • none - return only items which value is not listed

only, none {
    [<source> source]
    [, <array> values]
}

prompt

Displays a text box in the bottom of editor and populates a variable, defined by name with text entered by user. The caption string argument is used to display field's caption. The default string argument defines initial value displayed in field.

prompt {
    <string> name,
    <string> caption
    [, <string> default]
}

quick_panel

Displays Quick Panel (list menu) with data prepared by source directive. String argument name is used to populate a variable which will hold selected value.

quick_panel {
    <string> name,
    <source> source
}

source

Parses output returned by command defined in execute directive. Returns parsed items to the parent quick_panel. If parsed output is empty, stops flow execution and optionally displays message defined by empty_message string argument. If alpha argument is true, then all items are sorted alphabetically. If reverse argument is true, items are sorted in reversed order. Can be used together with alpha. When none or only is set, then items are filtered against it. Arguments none and only must not be set together. Use only one of them.

source {
    <execute> execute,
    <item> item
    [, <boolean> alpha=false]
    [, <boolean> reverse=false]
    [, <only> only]
    [, <none> none]
    [, <string> empty_message]
}

sublime_command

Runs Sublime Text's built-in (or plugins-provided) command.

sublime_command {
    <string> command
    [, <object> args]
}

yes_no_cancel_dialog

Displays yes/no/cancel dialog to let the user make a decision. The macro proceeds to next steps when all steps defined in on_yes or on_no are done. Pressing Cancel button stops Macro execution.

yes_no_cancel_dialog {
    <string> message,
    <array> on_yes,
    <array> on_no
    [, <string> yes_title]
    [, <string> no_title]
}

Defining a Macro

To define a new Macro, you should edit Preferences / Package Settings / Sublimerge / Macros - User file. Your file should contain the following structure:

"macros_user": [
    //your Macros here
]

All user-defined Macros should be defined in Macros - User file to prevent them from being overridden each time Sublimerge is upgraded.

Structure

Macro is a JSON object with the following structure:

{
    "name": "Macro Name",
    "requires": null,
    "platform": null,
    "steps": [
        {
            //step 1
        },
        {
            //step 2
        },
        ...
        {
            //step N
        }
    ]
}
  • name - macro name as visible in Sublimerge's menu and Command Palette. Required.
  • requires - defines if Macro works only when VCS repository is present for current view.
    Available values: 'git', 'svn', 'hg' or null if VCS-independent. Optional, defaults to null.
  • platform - defines if Macro works only on a given platform. Possible values: 'osx', 'linux', 'windows', or an array of these values, or null if platform-independent. Optional, defaults to null.
  • steps - array of steps the Macro performs when executed. Required.

Defining a step

Each step consists of exactly one directive. The following directives are allowed to be used directly in a step:

Example

The code below is a working example from predefined ones. This Macro works for Git only. Its task is to list the files that are currently in conflict (during merge/rebase), open 3-way diff and allow the user to resolve the conflicts. Finally, depending on user's decision, it will mark the conflict as resolved after merge is completed.

{
    "name": "List and Resolve Conflicts",
    "requires": "git",
    "steps": [
        {
            "quick_panel": {
                "name": "conflicted_file",
                "source": {
                    "execute": {
                        "command": "${git} status --porcelain --untracked-files=no",
                        "directory": "${CURRENT:REPO_ROOT}"
                    },
                    "item": {
                        "regexp": "^UU\\s+\"?(.*?)\"?$",
                        "caption": ["@1"],
                        "value": "@1"
                    },
                    "empty_message": "There are no files in conflicted state"
                }
            }
        },
        {
            "capture": {
                "name": "base",
                "greedy": true,
                "regexp": "^\\d{6}\\s+([a-z0-9]+)\\s+1.*$",
                "value": "@1",
                "execute": {
                    "command": "${git} ls-files -u --full-name '${conflicted_file}'",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            }
        },
        {
            "capture": {
                "name": "theirs",
                "greedy": true,
                "regexp": "^\\d{6}\\s+([a-z0-9]+)\\s+2.*$",
                "value": "@1",
                "execute": {
                    "command": "${git} ls-files -u --full-name '${conflicted_file}'",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            }
        },
        {
            "capture": {
                "name": "mine",
                "greedy": true,
                "regexp": "^\\d{6}\\s+([a-z0-9]+)\\s+3.*$",
                "value": "@1",
                "execute": {
                    "command": "${git} ls-files -u --full-name '${conflicted_file}'",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            }
        },
        {
            "define": {
                "theirs_file": "${ENV:TEMP_DIR}/${theirs}${conflicted_file|ext}",
                "base_file": "${ENV:TEMP_DIR}/${base}${conflicted_file|ext}",
                "mine_file": "${ENV:TEMP_DIR}/${mine}${conflicted_file|ext}",
                "merged_file": "${CURRENT:REPO_ROOT}/${conflicted_file}"
            }
        },
        {
            "capture": {
                "execute": {
                    "command": "${git} show ${theirs} > ${theirs_file}",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            },
        },
        {
            "capture": {
                "execute": {
                    "command": "${git} show ${base} > ${base_file}",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            },
        },
        {
            "capture": {
                "execute": {
                    "command": "${git} show ${mine} > ${mine_file}",
                    "directory": "${CURRENT:REPO_ROOT}"
                }
            }
        },
        {
            "compare": {
                "theirs": {
                    "file": "${theirs_file}",
                    "temporary": true,
                    "title": "Theirs: ${conflicted_file}"
                },
                "base": {
                    "file": "${base_file}",
                    "temporary": true
                },
                "mine": {
                    "file": "${mine_file}",
                    "temporary": true,
                    "title": "Mine: ${conflicted_file}"
                },
                "merged": {
                    "file": "${merged_file}",
                    "temporary": false
                }
            }
        },
        {
            "ok_cancel_dialog": {
                "message": "${conflicted_file}\n\nMark as resolved?",
                "ok_title": "Resolved",
                "on_ok": [
                    {
                        "capture": {
                            "execute": {
                                "command": "${git} add '${conflicted_file}'",
                                "directory": "${CURRENT:REPO_ROOT}"
                            }
                        }
                    }
                ]
            }
        }
    ]
}
I serve cookies to improve your experience on this website. If you continue without changing your browser settings, I will assume that you accept the cookies. You can change your browser settings at any time.