Swiper/Ivy tip

Please install evil-escape at first.

When Swiper/Ivy candidate window pops up. You can press fd quickly to close the window.

fd is the default key binding from evil-escape. I changed it to kj instead.

I assign hotkey =,ii= to M-x counsel-imenu, and I can press kj to quit imenu popup. As you can see, I don't need move my fingers too much.

Use general.el to provide multiple leader key in evil-mode

General.el "provides a more convenient way to bind keys in emacs for both evil and non-evil users".

I have been using it for more than one month without any issue. I prefer general.el to evil-leader because I need both comma and space key as leader key.

Minimum setup is simple,

(require 'general)
(general-evil-setup t)
(nvmap :prefix ","
       "bb" 'back-to-previous-buffer
       "ww" 'save-buffer
       "oo" 'compile)

;; all keywords arguments are still supported
(nvmap :prefix "SPC"
       ; save windows layout
       "ss" 'wg-create-workgroup
       ;; load windows layout
       "ll" 'my-wg-switch-workgroup)

My real world setup is more complicated.

Use ivy to open recent directories

The recent directories include parent directories of opened files in Emacs and the directories accessed in Bash shell.

I used fasd to get the list of directories in shell. Fasd "offers quick access to files and directories for POSIX shells".

Here is my setup,

(require 'ivy) ; swiper 7.0+ should be installed

(defun counsel-goto-recent-directory ()
  "Open recent directory with dired"
  (interactive)
  (unless recentf-mode (recentf-mode 1))
  (let ((collection
         (delete-dups
          (append (mapcar 'file-name-directory recentf-list)
                  ;; fasd history
                  (if (executable-find "fasd")
                      (split-string (shell-command-to-string "fasd -ld") "\n" t))))))
    (ivy-read "directories:" collection :action 'dired)))

Screenshot:

ivy-recent-directory-nq8.png

Emacs vs Sublime Text on Salesforce development

Our client decided to move their legacy system to a cloud platform called salesforce.com. So I got a chance to investigate how to deploy code to the salesforce server inside Emacs and Sublime Text.

Salesforce provides a migration tool to deploy everything from the scratch which takes about 2 minutes. Basically makes it impossbile to be integrated with text editors.

Luckily, there is Force.com CLI which can upload single file in a few seconds. Both Sublime Text and Emacs use this tool.

Sublime Text

You need install sublime text plugin mavensmate. After installation, you need click Login menu at least once. Then when you save the code file, it's automatically deployed to the server.

For some reason, the logged in session will timeout after a couple minutes. So you need re-login. Sometimes deployment will fail, you could click the Fetch menu and fill in the component name into the popup window to confirm the fetch. Fetching will re-activate upload ability.

Mavensmate is actually just GUI wrapper of Force.com CLI,

  • When you click login, the command force login is executed
  • When saving file, force aura push or force push is executed
  • When fetching, force fetch is executed

Emacs

In Sublime Text I have to re-login and fetch from time to time. That get me distracted. I prefer executing only one commmand to upload the file in editing. That command should be always successful.

My solution is to combine "login/fetch/push" commnands into one liner which is stored in a file local variable compile-command. So when I execute M-x compile, the commands "login/fetch/push" in compile-command will all be executed sequentially. So I don't need care about login and fetch things any more.

Here is my setup,

(defun my-setup-develop-environment ()
  (interactive)
  (let (ffip-project-root)
    (setq ffip-project-root "~/projects/my-salesforce-project1")

    (when (memq major-mode '(web-mode js-mode js2-mode))
      (setq-local compile-command
                  (cond
                   ;; lightning controller javascript file
                   ((string-match "Controller\.js$" (buffer-file-name))
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && cp %s %s && force fetch -t Aura -n %s -d %s && mv %s %s && force aura push -f %s"
                            ffip-project-root
                            (buffer-file-name) (concat (buffer-file-name) ".bak")
                            (replace-regexp-in-string "Controller" "" (file-name-base (buffer-file-name)))
                            ffip-project-root
                            (concat (buffer-file-name) ".bak") (buffer-file-name)
                            (buffer-file-name)))
                   ;; ant build
                   ((string-match "build\.xml$" (buffer-file-name))
                    (format "cd %s && ant deployCode" ffip-project-root))
                   ;; lightning html view
                   ((string-match "\.cmp$" (buffer-file-name))
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && force aura push -f %s"
                            ffip-project-root
                            (buffer-file-name)))
                   ;; other salesforce pages
                   (t
                    (format "force login -i=test -u=username@salesforce.com -p=password1; cd %s && force push -f %s"
                            ffip-project-root
                            (buffer-file-name)))
                   )))
    ))

;; I use web-mode for html/xml
(add-hook 'web-mode-hook 'my-setup-develop-environment)
;; I use js2-mode for javascript
(add-hook 'js2-mode-hook 'my-setup-develop-environment)

How to be extremely efficient in Emacs

All you need to do is using keyfreq to measure how many time you execute commands.

The frequently used commands should be assigned efficient key bindings.

But you need exclude already optimized commands or commands which cannot be optimized before starting keyfreq.

For example, commands like next-line/previous-line/forward-char/backward-char could be excluded by tweaking variable keyfreq-excluded-commands.

The minimum keyfreq setup,

(require 'keyfreq)
(setq keyfreq-excluded-commands
      '(self-insert-command
        abort-recursive-edit
        forward-char
        backward-char
        previous-line
        next-line))
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)

My actual keyfreq setup is more complicated.

Below is the eight month keyfreq data of my office computer,

Times Percentage Command Key
4967 12.00% evilmi-jump-items %
2892 6.99% compile , o o
2178 5.26% find-file-in-project-by-selected , k k
1953 4.72% copy-to-x-clipboard , a a
1566 3.78% paste-from-x-clipboard , z z
1227 2.96% er/expand-region , x x
897 2.17% evil-repeat .
866 2.09% ido-find-file , x f, C-x C-f
819 1.98% toggle-full-window , f f
815 1.97% etags-select-find-tag-at-point C-], , h t
721 1.74% back-to-previous-buffer , b b
682 1.65% split-window-vertically , x 2
539 1.30% find-function , h f, C-h C-f
494 1.19% counsel-recentf-goto , r r
397 0.96% counsel-git-grep , g g
376 0.91% delete-other-windows , x 1, C-x 1
372 0.90% evilnc-comment-or-uncomment-lines , c i
351 0.85% eval-expression , e e, M-:
326 0.79% evilmi-select-items , s i
320 0.77% paredit-doublequote
307 0.74% evil-filepath-outer-text-object
300 0.72% steve-ido-choose-from-recentf
295 0.71% split-window-horizontally , x 3
283 0.68% git-add-current-file , x v a
279 0.67% winner-undo , x u, , s u, C-x 4 u
278 0.67% describe-function , h d, C-h f
278 0.67% evil-goto-mark-line '
269 0.65% ido-kill-buffer , x k, C-x k
254 0.61% evil-goto-definition g d
253 0.61% pop-tag-mark M-*
251 0.61% git-messenger:popup-message , x v b, C-x v p
246 0.59% my-goto-next-hunk , n n
237 0.57% evilnc-comment-operator , ,
235 0.57% flyspell-goto-next-error , f e, C-,
214 0.52% evil-exit-emacs-state
212 0.51% browse-kill-ring-forward
210 0.51% flyspell-buffer , f b
203 0.49% evil-ex-completion
195 0.47% narrow-or-widen-dwim , x n n
173 0.42% comint-send-input
173 0.42% beginning-of-defun , b f
170 0.41% evil-surround-region <visual-state> S
161 0.39% hippie-expand M-/
151 0.36% describe-key , h k, C-h k
149 0.36% evil-space–evil-next-visual-line SPC
139 0.34% gnus-topic-select-group
138 0.33% js2-print-json-path , j p p
132 0.32% goto-line M-g g, M-g M-g
132 0.32% evil-avy-goto-subword-1 ;
127 0.31% ibuffer-mark-for-delete
127 0.31% evil-inner-single-quote
126 0.30% isearch-other-meta-char
124 0.30% term-send-up
118 0.29% isearch-other-control-char
116 0.28% evil-set-marker m
115 0.28% browse-kill-ring M-y, , y y
114 0.28% counsel-git-grep-yank-line , g l
114 0.28% evil-window-down C-w j
112 0.27% evil-jump-backward C-o
108 0.26% evil-visual-block C-v
108 0.26% evil-space–evil-previous-visual-line S-SPC
107 0.26% comint-previous-input
98 0.24% gnus-summary-exit
98 0.24% evil-search-word-backward #
98 0.24% forward-button
96 0.23% evil-paste-pop-next
95 0.23% ediff-next-difference
95 0.23% ido-imenu , i i
92 0.22% my-wg-switch-workgroup , w g g
90 0.22% counsel-git-find-file , g f
90 0.22% evilmi-delete-items , d i
87 0.21% gnus-summary-extract-mail-address
87 0.21% cliphist-paste-item , h h
84 0.20% subword-backward-kill <C-backspace>
84 0.20% paredit-backslash
83 0.20% my-yas-reload-all , y c r
81 0.20% pwd
80 0.19% previous-complete-history-element
80 0.19% wg-create-workgroup , w g t
78 0.19% evil-forward-WORD-end E
77 0.19% gnus-summary-scroll-up
76 0.18% gnus-summary-extract-cc-and-to
75 0.18% compile-goto-error
73 0.18% evil-find-char-to t
72 0.17% evil-repeat-find-char
69 0.17% evil-window-up C-w k
67 0.16% eval-last-sexp , x e, C-x C-e
66 0.16% evil-complete-next-line
66 0.16% exchange-point-and-mark C-x C-x
63 0.15% direx:previous-item
61 0.15% ediff-jump-to-difference
60 0.14% diredp-next-line
58 0.14% evilmr-replace-in-buffer , r b
58 0.14% counsel-imenu-goto , i m
56 0.14% evil-goto-mark `
55 0.13% gnus-group-unsubscribe-current-group
55 0.13% ivy-bookmark-goto
55 0.13% evil-filepath-inner-text-object
54 0.13% describe-mode C-h m
54 0.13% recenter-top-bottom C-l
54 0.13% list-packages
52 0.13% gnus-topic-mark-topic
52 0.13% kill-line C-k, <deleteline>
51 0.12% find-and-ctags-update-all-tags-force
50 0.12% evil-paste-before P
49 0.12% execute-extended-command <execute>, C-x RET
49 0.12% etags-select-quit
49 0.12% evil-inner-WORD
48 0.12% find-tag g C-]
47 0.11% diredp-previous-line
46 0.11% paredit-close-square
44 0.11% paredit-open-square
44 0.11% evil-paste-last-insertion
42 0.10% evil-inner-double-quote
42 0.10% ivy-imenu-goto
40 0.10% counsel-git-find-my-file , g m
39 0.09% cp-filename-of-current-buffer , f n
39 0.09% gnus-article-read-summary-keys
39 0.09% isearch-nonincremental-exit-minibuffer
38 0.09% sh-assignment
38 0.09% mark-whole-buffer , x h, C-x h
38 0.09% evilmi-inner-text-object
36 0.09% evilnc-comment-or-uncomment-paragraphs , c p, C-c p
36 0.09% evil-toggle-input-method C-\
35 0.08% org2nikola-export-subtree
35 0.08% subword-forward M-f, ESC <right>
34 0.08% evil-open-above O
34 0.08% compose-mail C-x m
33 0.08% evil-inner-paren
33 0.08% term-send-raw-meta
33 0.08% evil-invert-char ~
32 0.08% evil-space–evil-repeat-find-char
32 0.08% httpd-restart-at-default-directory , w r d
32 0.08% cp-fullpath-of-current-buffer , f p
31 0.07% evil-forward-WORD-begin W
30 0.07% sort-lines , s l
30 0.07% bmkp-w3m-jump
30 0.07% evilnc-copy-and-comment-lines , c c, C-c c
29 0.07% toggle-company-ispell , t c i
29 0.07% top-level
28 0.07% package-menu-mark-upgrades
27 0.07% evil-numbers/dec-at-pt -
27 0.07% end-of-defun , e f, C-M-e
27 0.07% my-setup-develop-environment
26 0.06% evil-paste-pop
25 0.06% ediff-previous-difference
25 0.06% evil-backward-WORD-begin B
25 0.06% goto-char g o, M-g c
25 0.06% w3m-close-window
25 0.06% org-mime-htmlize
25 0.06% gnus-group-exit
24 0.06% git-gutter:toggle C-x C-g
23 0.06% my-gnus-group-list-subscribed-groups
23 0.06% find-directory-in-project-by-selected , f d
23 0.06% evil-inner-curly
22 0.05% org-edit-src-exit
22 0.05% string-edit-at-point , s e
22 0.05% package-menu-mark-delete
22 0.05% ido-magic-forward-char
22 0.05% run-js , r j s
22 0.05% git-gutter-reset-to-head-parent , g s h
21 0.05% counsel-read-history
21 0.05% rcirc-send-input
21 0.05% gnus-undo
21 0.05% subword-backward M-b
20 0.05% company-select-next
20 0.05% what-cursor-position g a, g 8, C-x =
20 0.05% my-grep , q q
20 0.05% hydra-gnus-summary/body
19 0.05% ansi-term
19 0.05% evil-window-right C-w l
19 0.05% debugger-jump
19 0.05% wg-switch-to-workgroup
19 0.05% yas-abort-snippet
19 0.05% tags-loop-continue M-,
19 0.05% swiper-the-thing , s s
18 0.04% my-wg-swich-to-workgroup
18 0.04% org-edit-special
17 0.04% lisp-complete-symbol
17 0.04% my-wg-switch-to-workgroup-at-index
17 0.04% test
17 0.04% ediff-scroll-vertically
16 0.04% w3m-view-previous-page
16 0.04% evil-window-left C-w h
16 0.04% isearch-yank-kill
16 0.04% my-goto-previous-hunk , p p
16 0.04% js-beautify , j b
16 0.04% hydra-launcher/body
16 0.04% read-only-mode C-x C-q
16 0.04% message-send-and-exit
16 0.04% etags-select-goto-tag
15 0.04% evil-next-match g n
15 0.04% js2r-kill , j j k
15 0.04% string-edit-conclude
15 0.04% delete-char
14 0.03% gnus-summary-limit-to-author
14 0.03% ediff-swap-buffers

Grab email address in Gnus

That's easy in Gnus.

I just re-use the mail sent from PM because she is good at the things.

Usage

  • Go to the Summary Buffer (press Enter on a mail folder).
  • Press `/ a PM-name Enter`
  • M-x gnus-summary-extract-mail-address, extracted mail addresses is inserted to kill ring

Code

Insert below code into ~/.emacs,

(defun gnus-summary-extract-mail-address(regexp)
  "Extract TO/CC/FROM fields from mails in current Gnus Summary Buffer.
REGEXP is pattern to exclude extracted address.  For example, 'Tom|gmail' excludes Tom or gmail.
Final result is inserted into kill-ring and returned."
  (interactive
   (let* ((regexp (read-regexp "Regex to exclude mail address (OPTIONAL):")))
     (list regexp)))

  (unless (featurep 'cl)
    (require 'cl))

  (let ((rlt "") (i 0))
    (dolist (d gnus-newsgroup-data)
      (let ((header (gnus-data-header d)) cc-to)
        (setq i (+ 1 i))
        (if (= (mod i 100) 0) (message "%s mails scanned ..." i))
        (when (vectorp header)
          (if (setq cc-to (mail-header-extra header))
              ;; (message "cc-to=%s cc=%s" cc-to (assoc 'Cc cc-to))
              (setq rlt (concat rlt
                                (cdr (assoc 'To cc-to))
                                ", "
                                (cdr (assoc 'Cc cc-to))
                                ", ")))
          (setq rlt (concat rlt (if (string= "" rlt) "" ", ") (mail-header-from header) ", "))
          )))
    ;; trim trailing ", "
    (setq rlt (split-string (replace-regexp-in-string (rx (* (any ", ")) eos)
                                                      ""
                                                      rlt) ", *"))

    ;; remove empty strings
    (setq rlt (delq nil (remove-if (lambda (s) (or (not s) (string= "" s)))
                               rlt)))
    ;; remove actually duplicated mails
    (setq rlt (delq nil (remove-duplicates rlt
                                 :test (lambda (x y)
                                         (let (x1 y1)
                                           ;; Tom W <tom.w@gmail.com> | tom.w@gmail.com (Tom W)
                                           (if (string-match "^[^<]*<\\([^ ]*\\)> *$" x)
                                               (setq x1 (match-string 1 x))
                                             (setq x1 (replace-regexp-in-string " *([^()]*) *" "" (if x x ""))))
                                           (if (string-match "^[^<]*<\\([^ ]*\\)> *$" y)
                                               (setq y1 (match-string 1 y))
                                             (setq y1 (replace-regexp-in-string " *([^ ]*) *" "" (if y y ""))))
                                           (string= x1 y1)))
                                 :from-end t)))
    ;; exclude mails
    (if (and regexp (not (string= regexp "")))
        (setq rlt (delq nil (remove-if (lambda (s)
                                         (string-match (concat "\\(" (replace-regexp-in-string "|" "\\\\|" regexp) "\\)") s))
                                       rlt))))
    (kill-new (mapconcat 'identity rlt ", "))
    (message "Mail addresses => kill-ring")
    rlt))

I tested on my office mail inbox. 8K+ mails is scanned in less than one minute.

Technical details

Global variable gnus-newsgroup-data contains the information of displayed mails in current folder. It's updated dynamically.

gnus-summary-extract-mail-address could also be used as an API. It return the list of mail addresses.

If you want to use it to update the BBDB database, study code from my project gmail2bbdb which use plain Lisp to insert Name and Mail Address into "~/.bbdb".

Diff regions in Emacs

CREATED: 2016-01-27

UPDATED: 2016-04-09 Sat

I know M-x ediff-regions-linewise.

But it's kind of too generic. I only want to view the different lines of two regions as quickly as possible.

So here is my code,

;; Diff two regions
;; Step 1: Select a region and `M-x diff-region-tag-selected-as-a'
;; Step 2: Select another region and `M-x diff-region-compare-with-b'
;; Press "q" in evil-mode or "C-c C-c" to exit the diff output buffer
(defun diff-region-format-region-boundary (b e)
  "Make sure lines are selected and B is less than E"
  (let (tmp rlt)
    ;; swap b e, make sure b < e
    (when (> b e)
      (setq tmp b)
      (setq b e)
      (set e tmp))

    ;; select lines
    (save-excursion
      ;; Another workaround for evil-visual-line bug:
      ;; In evil-mode, if we use hotkey V or `M-x evil-visual-line` to select line,
      ;; the (line-beginning-position) of the line which is after the last selected
      ;; line is always (region-end)! Don't know why.
      (if (and (> e b)
               (save-excursion (goto-char e) (= e (line-beginning-position)))
               (boundp 'evil-state) (eq evil-state 'visual))
          (setq e (1- e)))
      (goto-char b)
      (setq b (line-beginning-position))
      (goto-char e)
      (setq e (line-end-position)))
    (setq rlt (list b e))
    rlt))

(defun diff-region-exit ()
  (interactive)
  (bury-buffer "*Diff-region-output*")
  (winner-undo))

(defun diff-region-tag-selected-as-a ()
  "Select a region to compare"
  (interactive)
  (when (region-active-p)
    (let (tmp buf)
      ;; select lines
      (setq tmp (diff-region-format-region-boundary (region-beginning) (region-end)))
      (setq buf (get-buffer-create "*Diff-regionA*"))
      (save-current-buffer
        (set-buffer buf)
        (erase-buffer))
      (append-to-buffer buf (car tmp) (cadr tmp))))
  (message "Now select other region to compare and run `diff-region-compare-with-b`"))

(defun diff-region-compare-with-b ()
  "Compare current region with region selected by `diff-region-tag-selected-as-a' "
  (interactive)
  (if (region-active-p)
      (let (rlt-buf
            diff-output
            (fa (make-temp-file (expand-file-name "scor"
                                                  (or small-temporary-file-directory
                                                      temporary-file-directory))))
            (fb (make-temp-file (expand-file-name "scor"
                                                  (or small-temporary-file-directory
                                                      temporary-file-directory)))))
        ;;  save current content as file B
        (when fb
          (setq tmp (diff-region-format-region-boundary (region-beginning) (region-end)))
          (write-region (car tmp) (cadr tmp) fb))

        (setq rlt-buf (get-buffer-create "*Diff-region-output*"))
        (when (and fa (file-exists-p fa) fb (file-exists-p fb))
          ;; save region A as file A
          (save-current-buffer
            (set-buffer (get-buffer-create "*Diff-regionA*"))
            (write-region (point-min) (point-max) fa))
          ;; diff NOW!
          (setq diff-output (shell-command-to-string (format "diff -Nabur %s %s" fa fb)))
          ;; show the diff output
          (if (string= diff-output "")
              ;; two regions are same
              (message "Two regions are SAME!")
            ;; show the diff
            (save-current-buffer
              (switch-to-buffer-other-window rlt-buf)
              (set-buffer rlt-buf)
              (erase-buffer)
              (insert diff-output)
              (diff-mode)
              (if (fboundp 'evil-local-set-key)
                           (evil-local-set-key 'normal "q" 'diff-region-exit))
              (local-set-key (kbd "C-c C-c") 'diff-region-exit)
              )))

        ;; clean the temporary files
        (if (and fa (file-exists-p fa))
            (delete-file fa))
        (if (and fb (file-exists-p fb))
            (delete-file fb)))
    (message "Please select region at first!")))

Use ivy-mode to search bash history

(defun counsel-yank-bash-history ()
  "Yank the bash history"
  (interactive)
  (let (hist-cmd collection val)
    (shell-command "history -r") ; reload history
    (setq collection
          (nreverse
           (split-string (with-temp-buffer (insert-file-contents (file-truename "~/.bash_history"))
                                           (buffer-string))
                         "\n"
                         t)))
    (when (and collection (> (length collection) 0)
               (setq val (if (= 1 (length collection)) (car collection)
                           (ivy-read (format "Bash history:") collection))))
        (kill-new val)
        (message "%s => kill-ring" val))))

How to use Gnus Group Topics efficiently

Group Topics is used to manage Gnus groups.

For example, you can,

  • Place groups (mail folders) from Gmail into "gmail" topic
  • Place groups (mails folders) from Outlook.com into "hotmail" topic
  • Make "gmail" and "hotmail" belong to the root topic "Gnus"

Enable it is just one line,

(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)

Now comes the question how to delete/add/move the topics?

The official answer is to read its manual.

But there is a simpler solution. All you need to do is insert below code into ~/.emacs or ~/.gnus.el,

(eval-after-load 'gnus-topic
  '(progn
     (setq gnus-topic-topology '(("Gnus" visible)
                                 (("hotmail" visible nil nil))
                                 (("gmail" visible nil nil))))

     (setq gnus-topic-alist '(("hotmail" ; the key of topic
                               "nnimap+hotmail:Inbox"
                               "nnimap+hotmail:Drafts"
                               "nnimap+hotmail:Sent"
                               "nnimap+hotmail:Junk"
                               "nnimap+hotmail:Deleted")
                              ("gmail" ; the key of topic
                               "INBOX"
                               "[Gmail]/Sent Mail"
                               "[Gmail]/Trash"
                               "Drafts")
                              ("Gnus")))))

The management of topics is as easy as editing above code.

My setup always works no matter ~/.newsrc.eld is loaded or not.

BTW, "hotmail" and "gmail" are the keys you used when configuring IMAP accounts,

(setq gnus-select-method
             '(nnimap "gmail" ; key
                      (nnimap-address "imap.gmail.com")
                      (nnimap-server-port 993)
                      (nnimap-stream ssl)))
(add-to-list 'gnus-secondary-select-methods
             '(nnimap "hotmail" ; key
                      (nnimap-address "imap-mail.outlook.com")
                      (nnimap-server-port 993)
                      (nnimap-stream ssl)))

Git gutter tip

I use git-gutter.el everyday. It indicats "whether a line has been inserted, modified or deleted". You can jump to the inser/modified/deleted line easily.

But I usually need to know what line changed in latest commit.

So I designed `M-x git-gutter-reset-to-head-parent`,

(defun git-gutter-reset-to-head-parent()
  (interactive)
  (let (parent (filename (buffer-file-name)))
    (if (eq git-gutter:vcs-type 'svn)
        (setq parent "PREV")
      (setq parent (if filename (concat (shell-command-to-string (concat "git --no-pager log --oneline -n1 --pretty='format:%H' " filename)) "^") "HEAD^")))
    (git-gutter:set-start-revision parent)
    (message "git-gutter:set-start-revision HEAD^")))

(defun git-gutter-reset-to-default ()
  (interactive)
  (git-gutter:set-start-revision nil)
  (message "git-gutter reset"))

`M-x git-gutter-reset-to-default` compare you file under working directory with the latet version under VCS.

`M-x git-gutter:next-hunk` and `M-x git-gutter:previous-hunk` will jump to the deleted/modified/added line.