helm-ghq改

helm-ghq.elを作ってGO WAYに乗った / マスタカの ChangeLog メモ

改造点

  • ghq.root以下のみを表示(それまでのパスは見えないようにする)
  • レポジトリ選択後はリポジトリ内のファイルを開くようにする

ソース

(defun helm-ghq--open-dired (file)
  (dired (file-name-directory file)))

(defmacro helm-ghq--line-string ()
  `(buffer-substring-no-properties
    (line-beginning-position) (line-end-position)))

(defun helm-ghq--root ()
  (with-temp-buffer
    (unless (zerop (call-process "git" nil t nil "config" "ghq.root"))
      (error "Failed: Can't find ghq.root"))
    (goto-char (point-min))
    (expand-file-name (helm-ghq--line-string))))

(defun helm-ghq--list-candidates ()
  (with-temp-buffer
    (unless (zerop (call-process "ghq" nil t nil "list" "--full-path"))
      (error "Failed: ghq list --full-path'"))
    (let ((ghq-root (helm-ghq--root))
          paths)
      (goto-char (point-min))
      (while (not (eobp))
        (let ((path (helm-ghq--line-string)))
          (push (cons (file-relative-name path ghq-root) path) paths))
        (forward-line 1))
      (reverse paths))))

(defun helm-ghq--list-ls-files ()
  (with-current-buffer (helm-candidate-buffer 'global)
    (unless (zerop (call-process "git" nil t nil "ls-files"))
      (error "Failed: 'git ls-files'"))))

(defun helm-ghq--source (repo)
  (let ((name (file-name-nondirectory (directory-file-name repo))))
    `((name . ,name)
      (init . helm-ghq--list-ls-files)
      (candidates-in-buffer)
      (action . (("Open File" . find-file)
                 ("Open File other window" . find-file-other-window)
                 ("Open Directory" . helm-ghq--open-dired))))))

;;;###autoload
(defun helm-ghq-list ()
  (interactive)
  (let ((repo (helm-comp-read "ghq-list: "
                              (helm-ghq--list-candidates)
                              :name "ghq list"
                              :must-match t)))
    (let ((default-directory (file-name-as-directory repo)))
      (helm :sources (helm-ghq--source default-directory)
            :buffer "*helm-ghq-list*"))))

イメージ