Wed 20 August 2014

Inspiriert vom Idea-GitLab-Integration-Plugin, das ein open file in browser anbietet, habe ich das ganze mal für Emacs gebaut:

(require 'magit)

(setq git-browser-url-templates
      '(("bitbucket.org" . "https://bitbucket.org/{{repo}}/src/{{branch}}/{{file-name}}#cl-{{lineno}}")
     ("github.com" . "https://github.com/{{repo}}/blob/{{branch}}/{{file-name}}#L{{lineno}}")
     ("pwmt.org" . "https://git.pwmt.org/?p={{repo}}.git;a=blob;f={{file-name}};hb={{branch}}#l{{lineno}}")))

(defun format-gitviewer-url (template vars)
  (let ((expand (lambda (match)
               (let* ((name (substring match 2 -2))
                      (value (assoc name vars)))
                 (unless value
                   (error (format "Unknown variable %s" name)))
                 (cdr value)))))
    (replace-regexp-in-string "{{.+?}}" expand template)))


(defun git-open-in-browser ()
  (interactive)
  (let* ((remote (magit-get-remote nil))
      (remote-url (magit-get "remote" remote "url"))
      (branch (substring (magit-get-tracked-branch) (+ 1 (length remote))))
      (file-name (magit-file-relative-name (buffer-file-name)))
      (lineno (line-number-at-pos)))
    (unless (string-match "\\(@\\|://\\|^\\)\\([^:@/]+?\\)[:/]\\([^/].*?\\)\\(.git\\)?$" remote-url)
      (error "Could not find repo name"))
    (let* ((host-name (match-string 2 remote-url))
        (repo-name (match-string 3 remote-url))
        (url-template (assoc host-name git-browser-url-templates)))
      (unless url-template
     (error (format "Could not find URL template for host %s" host-name)))
      (browse-url (format-gitviewer-url (cdr url-template)
                                     (list
                                      (cons "repo" repo-name)
                                      (cons "branch" branch)
                                      (cons "file-name" file-name)
                                      (cons "lineno" (number-to-string lineno))))))))