├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── Commands └── Default.sublime-commands ├── Keymaps ├── Default (Linux).sublime-keymap ├── Default (OSX).sublime-keymap └── Default (Windows).sublime-keymap ├── LICENSE ├── Menus ├── Context.sublime-menu └── Main.sublime-menu ├── README.md ├── Settings └── Git blame.sublime-settings ├── boot.py ├── docs ├── packagecontrol_changelogs │ ├── 1.2.0.txt │ ├── 1.2.1.txt │ ├── 1.2.2.txt │ ├── 1.2.3.txt │ ├── 1.3.0.txt │ └── 1.3.1.txt ├── screenshot-blame-show.png ├── screenshot-blame.png ├── screenshot-blameall.png └── screenshot-palette.png ├── messages.json ├── src ├── base.py ├── blame.py ├── blame_all.py ├── blame_inline.py ├── blame_instadiff.py ├── settings.py └── templates.py └── tests └── test_parsing.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | * Sublime Text version: 13 | * [e.g. Build 3211] 14 | 15 | * How did you install this package?: 16 | * [e.g. via Package Control / Manually downloaded] 17 | 18 | * Operating System and version: 19 | * [e.g. macOS 10.15.6] 20 | 21 | * How did you install git itself? 22 | * [e.g. already came with my OS / via system package manager / Git-for-Windows] 23 | 24 | 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /Commands/Default.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Git Blame: Show", 4 | "command": "blame" 5 | }, 6 | { 7 | "caption": "Git Blame: Show All", 8 | "command": "blame_show_all" 9 | }, 10 | { 11 | "caption": "Git Blame: Erase All", 12 | "command": "blame_erase_all" 13 | }, 14 | { 15 | "caption": "Git Blame: Toggle Inline Blame", 16 | "command": "blame_toggle_inline" 17 | }, 18 | { 19 | "caption": "Git Blame: Instadiff", 20 | "command": "blame_instadiff" 21 | }, 22 | { 23 | "caption": "Git Blame: Settings", 24 | // TWIN: Entry in "Main.sublime-menu" 25 | "command": "edit_settings", 26 | "args": { 27 | "base_file": "${packages}/Git blame/Settings/Git blame.sublime-settings", 28 | "default": "{\n\t$0\n}\n" 29 | } 30 | }, 31 | { 32 | "caption": "Git Blame: Key Bindings", 33 | // TWIN: Entry in "Main.sublime-menu" 34 | "command": "edit_settings", 35 | "args": { 36 | "base_file": "${packages}/Git blame/Keymaps/Default (${platform}).sublime-keymap", 37 | "default": "[\n\t$0\n]\n" 38 | } 39 | } 40 | ] 41 | -------------------------------------------------------------------------------- /Keymaps/Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["ctrl+shift+q"], "command": "blame"}, 3 | {"keys": ["ctrl+shift+c"], "command": "blame_show_all"}, 4 | //{"keys": ["f5"], "command": "blame_toggle_inline"}, 5 | //{"keys": ["f8"], "command": "blame_instadiff"}, 6 | ] 7 | -------------------------------------------------------------------------------- /Keymaps/Default (OSX).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["ctrl+alt+b"], "command": "blame"}, 3 | {"keys": ["ctrl+alt+shift+b"], "command": "blame_show_all"}, 4 | //{"keys": ["f5"], "command": "blame_toggle_inline"}, 5 | //{"keys": ["f8"], "command": "blame_instadiff"}, 6 | ] 7 | -------------------------------------------------------------------------------- /Keymaps/Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | {"keys": ["ctrl+alt+b"], "command": "blame"}, 3 | {"keys": ["ctrl+alt+shift+b"], "command": "blame_show_all"}, 4 | // {"keys": ["f5"], "command": "blame_toggle_inline"}, 5 | // {"keys": ["f8"], "command": "blame_instadiff"}, 6 | ] 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Matt Smith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Menus/Context.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "blame", 4 | "caption": "Git Blame", 5 | "command": "blame" 6 | } 7 | ] -------------------------------------------------------------------------------- /Menus/Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "preferences", 4 | "children": [ 5 | { 6 | "id": "package-settings", 7 | "children": [ 8 | { 9 | "caption": "Git blame", 10 | "children": [ 11 | { 12 | "caption": "Settings", 13 | // TWIN: Entry in "Default.sublime-commands" 14 | "command": "edit_settings", 15 | "args": { 16 | "base_file": "${packages}/Git blame/Settings/Git blame.sublime-settings", 17 | "default": "{\n\t$0\n}\n" 18 | } 19 | }, 20 | { 21 | "caption": "Key Bindings", 22 | // TWIN: Entry in "Default.sublime-commands" 23 | "command": "edit_settings", 24 | "args": { 25 | "base_file": "${packages}/Git blame/Keymaps/Default (${platform}).sublime-keymap", 26 | "default": "[\n\t$0\n]\n" 27 | } 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | ] 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub release](https://img.shields.io/github/release/frou/st3-gitblame.svg)](https://github.com/frou/st3-gitblame/releases) 2 | [![GitHub contributors](https://img.shields.io/github/contributors/frou/st3-gitblame.svg)](https://github.com/frou/st3-gitblame/graphs/contributors) 3 | [![GitHub issues](https://img.shields.io/github/issues/frou/st3-gitblame.svg)](https://github.com/frou/st3-gitblame/issues) 4 | 5 | # Git blame - Package for Sublime Text 6 | 7 | This package enables you to query Git "blame" information for files while you are viewing/editing them in Sublime Text. 8 | 9 | Blame information tells you who last edited a line, when they did it, and which commit they did it in. You can then choose to show that commit in full including its commit message and diff. 10 | 11 | For this package to work, you must already have the `git` command-line tool installed, and be viewing/editing a file that is part of a Git repository on your hard drive. 12 | 13 | [View on the Package Control website](https://packagecontrol.io/packages/Git%20blame) 14 | 15 | This package was originally created by [@psykzz](https://github.com/psykzz) and is now maintained by [@frou](https://github.com/frou) 16 | 17 | ## How to use 18 | 19 | Place the text cursor on the line you are interested in, then press CtrlAltB (Mac/Windows) or CtrlShiftQ (Linux). 20 | 21 | (Instead of pressing the keyboard shortcut, you can alternatively right click and select *Git Blame* from the context menu) 22 | 23 | The blame information will appear: 24 | 25 | ![Screenshot](https://raw.githubusercontent.com/frou/st3-gitblame/master/docs/screenshot-blame.png) 26 | 27 | If you want, you can then click `[Show]` to show the commit in full: 28 | 29 | ![Screenshot](https://raw.githubusercontent.com/frou/st3-gitblame/master/docs/screenshot-blame-show.png) 30 | 31 | ...or click `[Copy]` to copy the Commit ID (aka SHA) to your clipboard. 32 | 33 | If the latest blame information was not as illuminating as you hoped for, click the `[Prev]` to step back through multiple previous commits that affected the line. 34 | 35 | To close the blame information, click the `×` icon, or press the keyboard shortcut again while the text cursor is still on the same line. 36 | 37 | ## Advanced use 38 | 39 | In combination with Sublime Text's *Multiple Selection* feature, you can query blame information for more than one line simultaneously by first placing a text cursor on each line you are interested in, and then running as described above. 40 | 41 | You can also query blame information for every line in the entire file simultaneously by pressing CtrlAltShiftB (Mac/Windows) or CtrlShiftC (Linux). Doing this shows blame information in a different style (it's located to the left of the content, and more compact, but with fewer features): 42 | 43 | ![Screenshot](https://raw.githubusercontent.com/frou/st3-gitblame/master/docs/screenshot-blameall.png) 44 | 45 | To close all of them, click the `×` icon on any one of them, or press the keyboard shortcut again. 46 | 47 | As well as via keyboard shortcuts, this package's commands are also made available in the *Command Palette*. Type "Git Blame" into it to find them: 48 | 49 | 55 | 56 | ![Screenshot](https://raw.githubusercontent.com/frou/st3-gitblame/master/docs/screenshot-palette.png) 57 | -------------------------------------------------------------------------------- /Settings/Git blame.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // Use this setting to supply additional flags to the git blame CLI program 3 | // when it gets invoked by this package. See `man git-blame`. 4 | // 5 | // Example values: 6 | // ["-M"] 7 | // ["-C", "-C"] 8 | // 9 | "custom_blame_flags": [], 10 | "inline_blame_enabled": false, 11 | "inline_blame_delay": 300 12 | } 13 | -------------------------------------------------------------------------------- /boot.py: -------------------------------------------------------------------------------- 1 | # Only .py files at the top-level of a Sublime package are considered "plugins". 2 | # Make Sublime aware of our *{Command,Listener,Handler} classes by importing them: 3 | from .src.blame import * # noqa: F401,F403 4 | from .src.blame_all import * # noqa: F401,F403 5 | from .src.blame_inline import * # noqa: F401,F403 6 | from .src.blame_instadiff import * # noqa: F401,F403 7 | 8 | # def plugin_loaded(): 9 | # pass 10 | 11 | # def plugin_unloaded(): 12 | # pass 13 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.2.0.txt: -------------------------------------------------------------------------------- 1 | -> 1.2.0 2 | 3 | NEW: 4 | 5 | - Added a [Prev] button to step back through multiple previous commits that affected a single line. Try this when the initial blame info is not as illuminating as you hoped for. 6 | 7 | - Added a Linux key binding (Ctrl-Shift-C) to show blame info for all lines. If you find that to be an unsuitable default, please comment here: https://github.com/frou/st3-gitblame/issues/49 8 | 9 | - Added entries for editing this package's Settings & Key Bindings to both the Preferences menu and the Command Palette. 10 | 11 | - Added the ability to set additional flags to be passed to the `git blame` CLI. See this package's Settings file. 12 | 13 | FIXED: 14 | 15 | - Fixed certain git configuration causing ANSI escape codes to be intermixed with the Diff when [Show]-ing a commit. Credit: https://github.com/james2doyle 16 | 17 | - Fixed caching issue that could cause incorrect blame info to be shown. 18 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.2.1.txt: -------------------------------------------------------------------------------- 1 | -> 1.2.1 2 | 3 | FIXED: 4 | 5 | - Fixed menu and command palette entries for editing package's Settings & Key Bindings using outdated paths. 6 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.2.2.txt: -------------------------------------------------------------------------------- 1 | -> 1.2.2 2 | 3 | FIXED: 4 | 5 | - Improved usability and reliability of [Prev] button that steps back through 6 | multiple previous commits that affected a single line. 7 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.2.3.txt: -------------------------------------------------------------------------------- 1 | -> 1.2.3 2 | 3 | FIXED: 4 | 5 | - Fixed [Prev] [Copy] [Show] buttons not appearing in the new Sublime Text beta. 6 | Credit: jtojnar https://github.com/frou/st3-gitblame/pull/56 7 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.3.0.txt: -------------------------------------------------------------------------------- 1 | -> 1.3.0 2 | 3 | NEW: 4 | 5 | - Commit author names are now shown in full regardless of their length or number 6 | of parts. 7 | 8 | - A view's "rulers" are now temporarily disabled while `Git Blame: Show All` 9 | information is being shown (their position doesn't make sense while your 10 | text/code is being horizontally offset). 11 | 12 | FIXED: 13 | 14 | - Fixed `Git Blame: Erase All` in the command palette causing the next 15 | activation of `Git Blame: Show All` to have to be done twice. 16 | 17 | - Fixed the viewport sometimes not being automatically scrolled all the way to 18 | the left when `Git Blame: Show All` was activated. 19 | -------------------------------------------------------------------------------- /docs/packagecontrol_changelogs/1.3.1.txt: -------------------------------------------------------------------------------- 1 | -> 1.3.1 2 | 3 | FIXED: 4 | 5 | - Fixed `Git Blame: Show All` information not displaying correctly in ST4 beta. 6 | -------------------------------------------------------------------------------- /docs/screenshot-blame-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frou/st3-gitblame/c44c0751dbf1ffdeeb050f6ef00762f8dec9e51c/docs/screenshot-blame-show.png -------------------------------------------------------------------------------- /docs/screenshot-blame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frou/st3-gitblame/c44c0751dbf1ffdeeb050f6ef00762f8dec9e51c/docs/screenshot-blame.png -------------------------------------------------------------------------------- /docs/screenshot-blameall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frou/st3-gitblame/c44c0751dbf1ffdeeb050f6ef00762f8dec9e51c/docs/screenshot-blameall.png -------------------------------------------------------------------------------- /docs/screenshot-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frou/st3-gitblame/c44c0751dbf1ffdeeb050f6ef00762f8dec9e51c/docs/screenshot-palette.png -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.2.0": "docs/packagecontrol_changelogs/1.2.0.txt", 3 | "1.2.1": "docs/packagecontrol_changelogs/1.2.1.txt", 4 | "1.2.2": "docs/packagecontrol_changelogs/1.2.2.txt", 5 | "1.2.3": "docs/packagecontrol_changelogs/1.2.3.txt", 6 | "1.3.0": "docs/packagecontrol_changelogs/1.3.0.txt", 7 | "1.3.1": "docs/packagecontrol_changelogs/1.3.1.txt" 8 | } 9 | -------------------------------------------------------------------------------- /src/base.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import subprocess 4 | import sys 5 | from abc import ABCMeta, abstractmethod 6 | from urllib.parse import parse_qs, urlparse 7 | 8 | import sublime 9 | 10 | from .settings import PKG_SETTINGS_KEY_CUSTOMBLAMEFLAGS, pkg_settings 11 | 12 | 13 | class BaseBlame(metaclass=ABCMeta): 14 | def run_git(self, view_file_path, cli_args): 15 | if sys.platform == "win32": 16 | startup_info = subprocess.STARTUPINFO() 17 | # Stop a visible console window from appearing. 18 | startup_info.dwFlags |= subprocess.STARTF_USESHOWWINDOW 19 | startup_info.wShowWindow = subprocess.SW_HIDE 20 | else: 21 | startup_info = None 22 | 23 | cmd_line = ["git"] + cli_args 24 | # print(cmd_line) 25 | 26 | return subprocess.check_output( 27 | cmd_line, 28 | cwd=os.path.dirname(os.path.realpath(view_file_path)), 29 | startupinfo=startup_info, 30 | stderr=subprocess.STDOUT, 31 | ).decode() 32 | 33 | def get_blame_text(self, path, **kwargs): 34 | cli_args = ["blame", "--show-name", "--minimal", "-w"] 35 | cli_args.extend(self.extra_cli_args(**kwargs)) 36 | cli_args.extend(pkg_settings().get(PKG_SETTINGS_KEY_CUSTOMBLAMEFLAGS, [])) 37 | cli_args.extend(["--", os.path.basename(path)]) 38 | return self.run_git(path, cli_args) 39 | 40 | def get_commit_fulltext(self, sha, path): 41 | cli_args = ["show", "--no-color", sha] 42 | return self.run_git(path, cli_args) 43 | 44 | def get_commit_message_subject(self, sha, path): 45 | cli_args = ["show", "--no-color", sha, "--pretty=format:%s", "--no-patch"] 46 | return self.run_git(path, cli_args) 47 | 48 | @classmethod 49 | def parse_line(cls, line): 50 | pattern = r"""(?x) 51 | ^ (?P\^?\w+) 52 | \s+ (?P[\S ]+) 53 | \s+ 54 | \( (?P.+?) 55 | \s+ (?P\d{4}-\d{2}-\d{2}) 56 | \s+ (?P