devtools: vim: Port vim settings from factory repo

BUG=None
TEST=Make sure vim can recognize project-specific settings.

Change-Id: I98d452ca561f7ac4511a9a4c9c39d639d81b17cc
Reviewed-on: https://chromium-review.googlesource.com/912912
Commit-Ready: Shen-En Shih <petershih@chromium.org>
Tested-by: Shen-En Shih <petershih@chromium.org>
Reviewed-by: Yong Hong <yhong@google.com>
diff --git a/.local.vimrc b/.local.vimrc
new file mode 100644
index 0000000..ff08523
--- /dev/null
+++ b/.local.vimrc
@@ -0,0 +1,19 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+"
+" To load this file, You can symlink 'mk/vim/autoload/localrc.vim' to your
+" .vim/autoload folder, and add "call localrc#load()" to your vimrc.
+"
+" Or, you can source this file directly in your vimrc.
+"
+if exists('g:loaded_graphyte_localrc')
+  finish
+endif
+let g:loaded_graphyte_localrc = 1
+
+let g:localrc_project_root = expand('<sfile>:h')
+
+" Other files are placed under factory/devtools/vim
+exec 'set rtp^=' . join([g:localrc_project_root, 'devtools', 'vim'], '/')
+exec 'set rtp+=' . join([g:localrc_project_root, 'devtools', 'vim', 'after'], '/')
diff --git a/devtools/vim/README.md b/devtools/vim/README.md
new file mode 100644
index 0000000..8c16771
--- /dev/null
+++ b/devtools/vim/README.md
@@ -0,0 +1,29 @@
+<!--
+   -Copyright 2018 The Chromium OS Authors. All rights reserved.
+   -Use of this source code is governed by a BSD-style license that can be
+   -found in the LICENSE file.
+-->
+# Graphyte Developer VIM Plugins
+
+This folder contains VIM plugins that are useful for Graphyte development.
+
+## Installation
+
+Run `./setup.sh` to install script loader into your vim config.  If your `.vim`
+folder or `.vimrc` file is not in default location (`~/.vim` and `~/.vimrc`),
+you can use `DOT_VIM=... VIMRC=... ./setup.sh` to change it.
+
+## Plugins
+* `devtools/vim/ftplugin/python/sort_import.vim`
+    - sort python import lines
+* `devtools/vim/ftplugin/python/pylint.vim`
+    - config pylint arguments for
+    [scrooloose/syntastic](https://github.com/scrooloose/syntastic)
+* `devtools/vim/ftplugin/python/basic.vim`
+    - basic setup (indent, tabs, etc...)
+* `devtools/vim/plugin/add_pythonpath.vim`
+    - add Graphyte repositories into PYTHONPATH (for
+    [Valloric/YouCompleteMe](https://github.com/Valloric/YouCompleteMe) or
+    [davidhalter/jedi-vim](https://github.com/davidhalter/jedi-vim))
+* `devtools/vim/autoload/localrc.vim`
+    - `.local.vimrc` loader
diff --git a/devtools/vim/after/ftplugin/python/basic.vim b/devtools/vim/after/ftplugin/python/basic.vim
new file mode 100644
index 0000000..d8df9bd
--- /dev/null
+++ b/devtools/vim/after/ftplugin/python/basic.vim
@@ -0,0 +1,10 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+
+setlocal shiftwidth=2
+setlocal tabstop=2
+setlocal softtabstop=2
+setlocal expandtab
+setlocal textwidth=80
+setlocal wrap
diff --git a/devtools/vim/autoload/localrc.vim b/devtools/vim/autoload/localrc.vim
new file mode 100644
index 0000000..5c9a532
--- /dev/null
+++ b/devtools/vim/autoload/localrc.vim
@@ -0,0 +1,81 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+"
+" Find and source local vimrc files in each parent directory.  The order of
+" finding and sourcing files is from parent to child.  Therefore, if the
+" directory structure is:
+"
+"   project_root
+"   |-- a
+"   |   |-- b
+"   |   |   `-- .local.vimrc
+"   |   `-- .local.vimrc
+"   `-- .local.vimrc
+"
+" Then the order of loading .local.vimrc is::
+"
+"   source project_root/.local.vimrc
+"   source project_root/a/.local.vimrc
+"   source project_root/a/b/.local.vimrc
+"
+" To use this script, copy this script to .vim/autoload/localrc.vim
+" And in your vimrc, add::
+"
+"   call localrc#load()
+"
+let s:save_cpo = &cpo
+set cpo&vim
+
+let g:localrc_default_depth = -1  " unlimited
+let g:localrc_filename = '.local.vimrc'
+
+function! localrc#load(...)
+  " filename we would like to load
+  let fname = 1 <= a:0 ? a:1 : g:localrc_filename
+
+  " If starting point is not given, will use working directory
+  let search_dir = 2 <= a:0 ? a:2 : getcwd()
+
+  " If max search depth is not given, use the default one
+  let max_depth = 3 <= a:0 ? a:3 : g:localrc_default_depth
+
+  for filepath in s:search(fname, search_dir, max_depth)
+    source `=filepath`
+  endfor
+endfunction
+
+function! s:search(fname, current_dir, depth)
+  " expand to full path
+  let current_dir = fnamemodify(a:current_dir, ':p')
+
+  " maximum depth to search for a localrc
+  let depth = a:depth
+
+  " current path ends with '/', remove it
+  if current_dir =~ '\/$'
+    let current_dir = fnamemodify(current_dir, ':h')
+  endif
+
+  let found_files = []
+
+  while depth != 0
+    for fpath in split(globpath(current_dir, a:fname, 1), "\n")
+      if filereadable(fpath)
+        let found_files = [fpath] + found_files
+      endif
+    endfor
+
+    let depth -= 1
+    if current_dir == '/'
+      break
+    else
+      let current_dir = fnamemodify(current_dir, ':h')
+    endif
+  endwhile
+
+  return found_files
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
diff --git a/devtools/vim/ftplugin/python/pylint.vim b/devtools/vim/ftplugin/python/pylint.vim
new file mode 100644
index 0000000..8b5ad74
--- /dev/null
+++ b/devtools/vim/ftplugin/python/pylint.vim
@@ -0,0 +1,11 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+"
+
+if exists('g:loaded_syntastic_plugin')
+  " User is using syntastic
+  let pylintrc = join([g:localrc_project_root, 'pylintrc'],
+      \                '/')
+  let g:syntastic_python_pylint_args = '--rcfile=' . pylintrc
+endif
diff --git a/devtools/vim/ftplugin/python/sort_import.vim b/devtools/vim/ftplugin/python/sort_import.vim
new file mode 100644
index 0000000..3906f8d
--- /dev/null
+++ b/devtools/vim/ftplugin/python/sort_import.vim
@@ -0,0 +1,41 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+"
+" Sort python imports
+" we only care about python2
+"
+" According to python coding style, the import lines are sorted by package
+" path.
+if has('python')
+  command! -range -nargs=* VimPython <line1>,<line2>python <args>
+elseif has('python3')
+  command! -range -nargs=* VimPython <line1>,<line2>python3 <args>
+else
+  echoerr "sort_import plugin will not work because the version of vim" .
+      \ " supports neither python nor python3"
+  finish
+endif
+
+if !exists('g:vim_sort_import_map')
+  let g:vim_sort_import_map = '<Leader>si'
+endif
+
+if g:vim_sort_import_map != ''
+  execute "vnoremap <buffer>" g:vim_sort_import_map
+      \ ":VimPython SortImports()<CR>"
+endif
+
+VimPython <<EOF
+from __future__ import print_function
+import vim
+
+def SortImports():
+  text_range = vim.current.range
+
+  def _ImportLineToKey(line):
+    if line.startswith('import '):
+      return line.replace('import ', '').lower()
+    return line.replace('from ', '').replace(' import ', '.').lower()
+  text_range[:] = sorted(text_range, key=_ImportLineToKey)
+EOF
diff --git a/devtools/vim/plugin/add_pythonpath.vim b/devtools/vim/plugin/add_pythonpath.vim
new file mode 100644
index 0000000..817284d
--- /dev/null
+++ b/devtools/vim/plugin/add_pythonpath.vim
@@ -0,0 +1,13 @@
+" Copyright 2018 The Chromium OS Authors. All rights reserved.
+" Use of this source code is governed by a BSD-style license that can be
+" found in the LICENSE file.
+"
+" Add py_pkg to PYTHONPATH, so jedi and YCM could work.
+let py_pkg_dir = g:localrc_project_root
+if isdirectory(py_pkg_dir)
+  if empty($PYTHONPATH)
+    let $PYTHONPATH = py_pkg_dir
+  else
+    let $PYTHONPATH = py_pkg_dir . ':' . $PYTHONPATH
+  endif
+endif
diff --git a/devtools/vim/setup.sh b/devtools/vim/setup.sh
new file mode 100755
index 0000000..7b4c802
--- /dev/null
+++ b/devtools/vim/setup.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Usage: DOT_VIM=<path/to/.vim> VIMRC=<path/to/vimrc> ./setup.sh
+SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
+
+: ${DOT_VIM:="${HOME}/.vim"}
+DOT_VIM="$(readlink -f "${DOT_VIM}")"
+echo ".vim/ is: ${DOT_VIM}"
+mkdir -p "${DOT_VIM}/autoload"
+if [ -e "${DOT_VIM}/autoload/localrc.vim" ]; then
+  read -p \
+      "localrc.vim is already in .vim/, do you want to override it? [y/N] " \
+      answer
+else
+  read -p "Add localrc.vim to .vim/? [y/N] " answer
+fi
+if [ "${answer}" == "y" -o "${answer}" == "Y" ]; then
+  rm -f "${DOT_VIM}/autoload/localrc.vim"
+  ln -s "${SCRIPT_DIR}/autoload/localrc.vim" "${DOT_VIM}/autoload"
+else
+  echo "skipped..."
+fi
+
+: ${VIMRC:="${HOME}/.vimrc"}
+VIMRC="$(readlink -f "${VIMRC}")"
+echo ".vimrc is: ${VIMRC}"
+read -p "Can we add 'call localrc#load()' into your vimrc? [y/N] " answer
+if [ "${answer}" == "y" -o "${answer}" == "Y" ]; then
+  echo "call localrc#load()" >>"${VIMRC}"
+else
+  echo "skipped..."
+fi