diff --git a/autoload/plug.vim b/autoload/plug.vim
index 8be364c..b63d777 100644
--- a/autoload/plug.vim
+++ b/autoload/plug.vim
@@ -33,6 +33,7 @@
 "   " Unmanaged plugin (manually installed and updated)
 "   Plug '~/my-prototype-plugin'
 "
+"   " Add plugins to &runtimepath
 "   call plug#end()
 "
 " Then reload .vimrc and :PlugInstall to install plugins.
@@ -398,7 +399,7 @@ function! s:lod(names, types)
 endfunction
 
 function! s:lod_ft(pat, names)
-  call s:lod(a:names, ['plugin', 'after/plugin'])
+  call s:lod(a:names, ['plugin', 'after/plugin', 'syntax', 'after/syntax'])
   execute 'autocmd! PlugLOD FileType' a:pat
   if exists('#filetypeplugin#FileType')
     doautocmd filetypeplugin FileType
@@ -645,7 +646,7 @@ function! s:do(pull, force, todo)
     endif
     let installed = has_key(s:update.new, name)
     let updated = installed ? 0 :
-      \ (a:pull && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir)))
+      \ (a:pull && index(s:update.errors, name) < 0 && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir)))
     if a:force || installed || updated
       execute 'cd' s:esc(spec.dir)
       call append(3, '- Post-update hook for '. name .' ... ')
@@ -1049,17 +1050,17 @@ G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads'))
 G_STOP = thr.Event()
 G_THREADS = {}
 
-class BaseExc(Exception):
+class PlugError(Exception):
   def __init__(self, msg):
     self._msg = msg
   @property
   def msg(self):
     return self._msg
-class CmdTimedOut(BaseExc):
+class CmdTimedOut(PlugError):
   pass
-class CmdFailed(BaseExc):
+class CmdFailed(PlugError):
   pass
-class InvalidURI(BaseExc):
+class InvalidURI(PlugError):
   pass
 class Action(object):
   INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-']
@@ -1073,7 +1074,7 @@ class Buffer(object):
     self.maxy = int(vim.eval('winheight(".")'))
     self.num_plugs = num_plugs
 
-  def _where(self, name):
+  def __where(self, name):
     """ Find first line with name in current buffer. Return line num. """
     found, lnum = False, 0
     matcher = re.compile('^[-+x*] {0}:'.format(name))
@@ -1102,8 +1103,7 @@ class Buffer(object):
   def write(self, action, name, lines):
     first, rest = lines[0], lines[1:]
     msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)]
-    padded_rest = ['    ' + line for line in rest]
-    msg.extend(padded_rest)
+    msg.extend(['    ' + line for line in rest])
 
     try:
       if action == Action.ERROR:
@@ -1113,7 +1113,7 @@ class Buffer(object):
         self.bar += '='
 
       curbuf = vim.current.buffer
-      lnum = self._where(name)
+      lnum = self.__where(name)
       if lnum != -1: # Found matching line num
         del curbuf[lnum]
         if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]):
@@ -1127,56 +1127,73 @@ class Buffer(object):
       pass
 
 class Command(object):
-  def __init__(self, cmd, cmd_dir=None, timeout=60, ntries=3, cb=None, clean=None):
+  def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None):
     self.cmd = cmd
     self.cmd_dir = cmd_dir
     self.timeout = timeout
-    self.ntries = ntries
     self.callback = cb if cb else (lambda msg: None)
-    self.clean = clean
+    self.clean = clean if clean else (lambda: None)
+    self.proc = None
 
-  def attempt_cmd(self):
-    """ Tries to run the command, returns result if no exceptions. """
-    attempt = 0
-    finished = False
-    limit = self.timeout
+  @property
+  def alive(self):
+    """ Returns true only if command still running. """
+    return self.proc and self.proc.poll() is None
+
+  def execute(self, ntries=3):
+    """ Execute the command with ntries if CmdTimedOut.
+        Returns the output of the command if no Exception.
+    """
+    attempt, finished, limit = 0, False, self.timeout
 
     while not finished:
       try:
         attempt += 1
-        result = self.timeout_cmd()
+        result = self.try_command()
         finished = True
+        return result
       except CmdTimedOut:
-        if attempt != self.ntries:
-          for count in range(3, 0, -1):
-            if G_STOP.is_set():
-              raise KeyboardInterrupt
-            msg = 'Timeout. Will retry in {0} second{1} ...'.format(
-                count, 's' if count != 1 else '')
-            self.callback([msg])
-            time.sleep(1)
+        if attempt != ntries:
+          self.notify_retry()
           self.timeout += limit
-          self.callback(['Retrying ...'])
         else:
           raise
 
-    return result
+  def notify_retry(self):
+    """ Retry required for command, notify user. """
+    for count in range(3, 0, -1):
+      if G_STOP.is_set():
+        raise KeyboardInterrupt
+      msg = 'Timeout. Will retry in {0} second{1} ...'.format(
+            count, 's' if count != 1 else '')
+      self.callback([msg])
+      time.sleep(1)
+    self.callback(['Retrying ...'])
 
-  def timeout_cmd(self):
+  def try_command(self):
     """ Execute a cmd & poll for callback. Returns list of output.
-    Raises CmdFailed   -> return code for Popen isn't 0
-    Raises CmdTimedOut -> command exceeded timeout without new output
+        Raises CmdFailed   -> return code for Popen isn't 0
+        Raises CmdTimedOut -> command exceeded timeout without new output
     """
-    proc = None
     first_line = True
-    try:
-      tfile = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
-      proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile,
-          stderr=subprocess.STDOUT, shell=True, preexec_fn=os.setsid)
-      while proc.poll() is None:
-        # Yield this thread
-        time.sleep(0.2)
 
+    try:
+      tfile = tempfile.NamedTemporaryFile(mode='w+b')
+      self.proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile,
+                                   stderr=subprocess.STDOUT, shell=True,
+                                   preexec_fn=os.setsid)
+      thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,))
+      thrd.start()
+
+      thread_not_started = True
+      while thread_not_started:
+        try:
+          thrd.join(0.1)
+          thread_not_started = False
+        except RuntimeError:
+          pass
+
+      while self.alive:
         if G_STOP.is_set():
           raise KeyboardInterrupt
 
@@ -1190,23 +1207,24 @@ class Command(object):
         if time_diff > self.timeout:
           raise CmdTimedOut(['Timeout!'])
 
+        thrd.join(0.5)
+
       tfile.seek(0)
-      result = [line.decode().rstrip() for line in tfile]
+      result = [line.decode('utf-8', 'replace').rstrip() for line in tfile]
 
-      if proc.returncode != 0:
-        msg = ['']
-        msg.extend(result)
-        raise CmdFailed(msg)
+      if self.proc.returncode != 0:
+        raise CmdFailed([''] + result)
+
+      return result
     except:
-      if proc and proc.poll() is None:
-        os.killpg(proc.pid, signal.SIGTERM)
-      if self.clean:
-        self.clean()
+      self.terminate()
       raise
-    finally:
-      os.remove(tfile.name)
 
-    return result
+  def terminate(self):
+    """ Terminate process and cleanup. """
+    if self.alive:
+      os.killpg(self.proc.pid, signal.SIGTERM)
+    self.clean()
 
 class Plugin(object):
   def __init__(self, name, args, buf_q, lock):
@@ -1227,7 +1245,7 @@ class Plugin(object):
         self.install()
         with self.lock:
           thread_vim_command("let s:update.new['{0}'] = 1".format(self.name))
-    except (CmdTimedOut, CmdFailed, InvalidURI) as exc:
+    except PlugError as exc:
       self.write(Action.ERROR, self.name, exc.msg)
     except KeyboardInterrupt:
       G_STOP.set()
@@ -1252,11 +1270,18 @@ class Plugin(object):
     self.write(Action.INSTALL, self.name, ['Installing ...'])
     callback = functools.partial(self.write, Action.INSTALL, self.name)
     cmd = 'git clone {0} {1} --recursive {2} -b {3} {4} 2>&1'.format(
-        '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'], self.checkout, esc(target))
-    com = Command(cmd, None, G_TIMEOUT, G_RETRIES, callback, clean(target))
-    result = com.attempt_cmd()
+          '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'],
+          self.checkout, esc(target))
+    com = Command(cmd, None, G_TIMEOUT, callback, clean(target))
+    result = com.execute(G_RETRIES)
     self.write(Action.DONE, self.name, result[-1:])
 
+  def repo_uri(self):
+    cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url'
+    command = Command(cmd, self.args['dir'], G_TIMEOUT,)
+    result = command.execute(G_RETRIES)
+    return result[-1]
+
   def update(self):
     match = re.compile(r'git::?@')
     actual_uri = re.sub(match, '', self.repo_uri())
@@ -1277,18 +1302,12 @@ class Plugin(object):
               'git merge --ff-only {0}'.format(self.merge),
               'git submodule update --init --recursive']
       cmd = ' 2>&1 && '.join(cmds)
-      com = Command(cmd, self.args['dir'], G_TIMEOUT, G_RETRIES, callback)
-      result = com.attempt_cmd()
+      com = Command(cmd, self.args['dir'], G_TIMEOUT, callback)
+      result = com.execute(G_RETRIES)
       self.write(Action.DONE, self.name, result[-1:])
     else:
       self.write(Action.DONE, self.name, ['Already installed'])
 
-  def repo_uri(self):
-    cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url'
-    command = Command(cmd, self.args['dir'], G_TIMEOUT, G_RETRIES)
-    result = command.attempt_cmd()
-    return result[-1]
-
   def write(self, action, name, msg):
     self.buf_q.put((action, name, msg))
 
@@ -1325,7 +1344,7 @@ class RefreshThread(thr.Thread):
     while self.running:
       with self.lock:
         thread_vim_command('noautocmd normal! a')
-      time.sleep(0.2)
+      time.sleep(0.33)
 
   def stop(self):
     self.running = False
@@ -1343,7 +1362,7 @@ def esc(name):
 def nonblock_read(fname):
   """ Read a file with nonblock flag. Return the last line. """
   fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK)
-  buf = os.read(fread, 100000).decode()
+  buf = os.read(fread, 100000).decode('utf-8', 'replace')
   os.close(fread)
 
   line = buf.rstrip('\r\n')
@@ -1901,9 +1920,11 @@ function! s:preview_commit()
 
   execute 'pedit' sha
   wincmd P
-  setlocal filetype=git buftype=nofile nobuflisted
+  setlocal filetype=git buftype=nofile nobuflisted modifiable
   execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --pretty=medium' sha
   normal! gg"_dd
+  setlocal nomodifiable
+  nnoremap <silent> <buffer> q :q<cr>
   wincmd p
 endfunction