;;; ravi-init-vc.el --- vc control ;; Copyright (C) 2013 ;; Author: ;; Keywords: vc ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Version control initialization ;;; Code: (use-package vdiff :commands (vdiff-files vdiff-files3 vdiff-buffers vdiff-buffers3 vdiff-current-file vdiff-merge-conflict) :bind (:map vdiff-3way-mode-map ("M-r" . vdiff-hydra/body) :map vdiff-mode-map ("M-r" . vdiff-hydra/body))) ;; Git (use-package magit :bind (("" . magit-status) ("C-c g" . magit-dispatch) ("C-c M-g" . magit-file-dispatch)) :init (setq magit-define-global-key-bindings nil) :config (progn (setq-default magit-process-popup-time 10 magit-diff-refine-hunk t magit-completing-read-function (pcase ravi/use-selection-system ('helm #'helm--completing-read-default) ('ido #'magit-ido-completing-read) ('selectrum #'selectrum-completing-read) (_ #'magit-builtin-completing-read))) (setq magit-restore-window-configuration t) (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh) (defvar ravi/sync-top-level-host-extra-args "" "Extra arguments to rsync for `ravi/sync-top-level'") (defun ravi/sync-top-level () (when (and (boundp 'ravi/sync-top-level-host) (not (s-equals? (car (s-split-up-to "\\." (system-name) 1)) (car (s-split-up-to "\\." ravi/sync-top-level-host 1))))) (message "Synchronizing with %s" ravi/sync-top-level-host) (shell-command (concat "rsync -a " ravi/sync-top-level-host-extra-args " " (magit-toplevel) " " ravi/sync-top-level-host ":" (magit-toplevel))))) (add-hook 'magit-post-refresh-hook 'ravi/sync-top-level) (use-package vdiff-magit :commands (vdiff-magit vdiff-magit-dwim) :init (define-key magit-mode-map "e" 'vdiff-magit-dwim) (define-key magit-mode-map "E" 'vdiff-magit) (transient-suffix-put 'magit-dispatch "e" :description "vdiff (dwim)") (transient-suffix-put 'magit-dispatch "e" :command 'vdiff-magit-dwim) (transient-suffix-put 'magit-dispatch "E" :description "vdiff") (transient-suffix-put 'magit-dispatch "E" :command 'vdiff-magit)) ) :ensure t) (use-package forge :after magit) ;; Use 'git config --add magit.extension svn' in repository to enable ;; magit-svn for that repository (use-package magit-svn :after (magit)) (use-package git-modes :after (magit)) (use-package git-messenger :if window-system :bind ("C-x v p" . git-messenger:popup-message)) (use-package git-timemachine :bind ("C-x v t" . git-timemachine)) (use-package vc-git :bind ("C-x v f" . vc-git-grep) :ensure nil) (use-package git-link :bind (("C-x v N" . git-link) ("C-x v B" . ravi/git-link-in-browser)) :init ; init, not config, so that we have these in local.el (require 'subr-x) (require 's) (defun ravi/git-link-bitbucket-server-repo-name-format (hostname dirname) (when-let* ((reponame-parts (s-split "/" dirname)) (proj-name (nth-value 0 reponame-parts)) (repo-name (nth-value 1 reponame-parts))) (format "https://%s/projects/%s/repos/%s" hostname proj-name repo-name))) (defun ravi/git-link-bitbucket-server (hostname dirname filename branch commit start end) (let ((at-point (if (and git-link-use-commit commit) commit (or branch commit))) (repo-name (ravi/git-link-bitbucket-server-repo-name-format hostname dirname))) (format "%s/browse/%s" repo-name (concat filename (if at-point (format "?at=%s" at-point) "") (if start (if end (format "#%s-%s" start end) (format "#%s" start)) ""))))) (defun ravi/git-link-commit-bitbucket-server (hostname dirname commit) (format "%s/commits/%s" (ravi/git-link-bitbucket-server-repo-name-format hostname dirname) commit)) (defun ravi/git-link-bitbucket-server-enable (server-regexp) (add-to-list 'git-link-remote-alist (list server-regexp #'ravi/git-link-bitbucket-server)) (add-to-list 'git-link-commit-remote-alist (list server-regexp #'ravi/git-link-commit-bitbucket-server))) :config (defun ravi/git-link-in-browser () (interactive) (let ((git-link-open-in-browser t)) (call-interactively #'git-link)))) (use-package diff-hl :config (global-diff-hl-mode) (unless window-system (diff-hl-margin-mode))) ;; Stolen almost entirely from Fuco (Matus Goljer) (use-package ediff :hook (ediff-keymap-setup-hook . ravi/add-d-to-ediff-mode-map) :commands ravi/add-d-to-ediff-mode-map :config (defvar my-ediff-before-config nil "Window configuration before ediff.") (defvar my-ediff-after-config nil "Window configuration after ediff.") (unless window-system (setq ediff-split-window-function #'split-window-horizontally) (setq ediff-window-setup-function #'ediff-setup-windows-plain)) (defun my-ediff-before-setup () "Function to be called before any buffers or window setup for ediff." (setq my-ediff-before-config (current-window-configuration)) (set-register ?b (list my-ediff-before-config (point-marker)))) (defun my-ediff-after-setup () "Function to be called after buffers and window setup for ediff." (setq my-ediff-after-config (current-window-configuration)) (set-register ?e (list my-ediff-after-config (point-marker)))) (defun my-ediff-quit () "Function to be called when ediff quits." (when my-ediff-before-config (set-window-configuration my-ediff-before-config)) ;; clean up ediff bullshit (->> (buffer-list) (-map 'buffer-name) (--select (string-match-p "\\*[Ee]diff" it)) (-map 'kill-buffer))) ;; Copy both sides in a merge (defun ravi/ediff-copy-both-to-C () (interactive) (ediff-copy-diff ediff-current-difference nil 'C nil (concat (ediff-get-region-contents ediff-current-difference 'A ediff-control-buffer) (ediff-get-region-contents ediff-current-difference 'B ediff-control-buffer)))) (defun ravi/add-d-to-ediff-mode-map () (define-key ediff-mode-map "d" #'ravi/ediff-copy-both-to-C)) (add-hook 'ediff-before-setup-hook 'my-ediff-before-setup) (add-hook 'ediff-after-setup-windows-hook 'my-ediff-after-setup 'append) (add-hook 'ediff-quit-hook 'my-ediff-quit)) (use-package smerge-mode :config (defhydra unpackaged/smerge-hydra (:color pink :hint nil :post (smerge-auto-leave)) " ^Move^ ^Keep^ ^Diff^ ^Other^ ^^-----------^^-------------------^^---------------------^^------- _n_ext _b_ase _<_: upper/base _C_ombine _p_rev _u_pper _=_: upper/lower _r_esolve ^^ _l_ower _>_: base/lower _k_ill current ^^ _a_ll _R_efine ^^ _RET_: current _E_diff " ("n" smerge-next) ("p" smerge-prev) ("b" smerge-keep-base) ("u" smerge-keep-upper) ("l" smerge-keep-lower) ("a" smerge-keep-all) ("RET" smerge-keep-current) ("\C-m" smerge-keep-current) ("<" smerge-diff-base-upper) ("=" smerge-diff-upper-lower) (">" smerge-diff-base-lower) ("R" smerge-refine) ("E" smerge-ediff) ("C" smerge-combine-with-next) ("r" smerge-resolve) ("k" smerge-kill-current) ("ZZ" (lambda () (interactive) (save-buffer) (bury-buffer)) "Save and bury buffer" :color blue) ("q" nil "cancel" :color blue)) :hook (magit-diff-visit-file-hook . (lambda () (when smerge-mode (unpackaged/smerge-hydra/body))))) (provide 'ravi-init-vc) ;;; ravi-init-vc.el ends here