]> oss.titaniummirror.com Git - vim-mkbuild.git/commitdiff
Initial commit
authorR. Steve McKown <rsmckown@gmail.com>
Fri, 19 Jun 2015 15:25:39 +0000 (09:25 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Fri, 19 Jun 2015 15:43:46 +0000 (09:43 -0600)
doc/mkbuild.txt [new file with mode: 0644]
plugin/mkbuild.vim [new file with mode: 0644]

diff --git a/doc/mkbuild.txt b/doc/mkbuild.txt
new file mode 100644 (file)
index 0000000..4f658ff
--- /dev/null
@@ -0,0 +1,40 @@
+*mkbuild.txt*  Plugin for integrating with mkbuild build system features
+
+Author:  R. Steve McKown <rsmckown@gmail.com>
+License: Same terms as Vim itself (see |license|)
+
+This plugin is only available if 'compatible' is not set.
+
+INTRODUCTION                                    *mkbuild*
+
+This plugin provides features for working with code using the mkbuild build
+system.  The only tool currently available is a method to select files from
+the project using dmenu, which will also work without mkbuild.
+
+Map mkbuild#DmenuOpen(cmd) to some key, such as:
+nnoremap <leader>e :call mkbuild#DmenuOpen('e')<CR>
+
+The function will use dmenu to select a file to execute with provided
+argument.  If no file is selected by the user via dmenu, or if dmenu is not
+installed, no action is taken.  This idea was originally discovered at
+http://leafo.net/posts/using_dmenu_to_open_quickly.html.
+
+The list of files presented to dmenu comes from one of four places, in the
+following priority order:
+
+1. All filelist files found in the same directory(ies) vim looks for tags
+   files.  The filelist file is built by mkbuild and will be available to vim
+   sessions started via 'make <platform> edit'.
+
+2. Any tags files found in &tags.  The file is parsed to get filenames.
+   A tags file is set by mkbuild's 'make <platform> edit', but other tag files
+   created outside of mkbuild should be parseable as well.  This function does
+   not due the directory traversing than vim can normally do to find tag
+   files.
+
+3. The tracked files in the current git repository, and/or the tracked files
+   in those valid git repositories named in the 'extrefs' file, if present.
+
+3. Perform a 'find . -type f' in the current directory.
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/plugin/mkbuild.vim b/plugin/mkbuild.vim
new file mode 100644 (file)
index 0000000..fd92caa
--- /dev/null
@@ -0,0 +1,140 @@
+" Tools for use with the mkbuild build environment.
+
+" Return the results of a command without the ending newline
+function! s:chompsys(cmd)
+  return substitute(system(a:cmd), '\n$', '', '')
+endfunction
+
+" Return the top level working directory in a git checkout.  If dir is '',
+" start from the current directory, else start from dir.
+function! s:gittop(dir)
+  if empty(a:dir)
+    return s:chompsys('git rev-parse --show-toplevel 2>/dev/null')
+  else
+    return s:chompsys("cd " . a:dir .
+        \ " && git rev-parse --show-toplevel 2>/dev/null")
+endfunction
+
+" Return a shell segment that will output a list of files with full paths
+" parsed from working directory's tracked files.
+function! s:gitls(workdir)
+  return "(git --git-dir=" . a:workdir . "/.git ls-files | sed -e s'|^|" .
+      \ a:workdir . "/|')"
+endfunction
+
+" Return a list of git directories.  If the current directory is in a git
+" working directory, at least this one will be returned.  If the top level of
+" this directory has an extrefs file, then the valid git directories listed
+" therein are also added to the list.
+function! s:gitdirs()
+  let dirs = []
+  let topdir = s:gittop('')
+  if empty(topdir)
+  else
+    call add(dirs, topdir)
+    let extrefs = topdir . '/extrefs'
+    if filereadable(extrefs)
+      for e in split(s:chompsys(
+            \ "grep ^git " . extrefs . "| awk '{ print $3  }'"))
+        let dir = s:gittop(topdir . '/' . e)
+        if empty(dir)
+        else
+          call add(dirs, dir)
+        endif
+      endfor
+    endif
+  endif
+  return dirs
+endfunction
+
+" Return a list of readable tag files, as present in &tags.  This function
+" doesn't handle the sometimes-default 'tags:/' value I've seen.
+function! s:tagfiles()
+  let tags = []
+  for t in split(&tags, ',')
+    if filereadable(t)
+      call add(tags, t)
+    endif
+  endfor
+  return tags
+endfunction
+
+" Return a shell segment that will output a list of files with full paths
+" parsed from the named tags (ctags) file.
+function! s:tagls(tagfile)
+  return "(grep -v \"!\" " . a:tagfile . " | awk -F\\\t '{ print $2 }' | " .
+      \ "sort -u)"
+endfunction
+
+" Return a list of readable filelist files, which are looked for in the same
+" directories where &tags has vim looking for tags files.
+function! s:filelists()
+  let files = []
+  for t in s:tagfiles()
+    let f = substitute(t, '\c\(\.\/\)*tags.*$', 'filelist', '')
+    if filereadable(f)
+      call add(files, f)
+    endif
+  endfor
+  return files
+endfunction
+
+" Return a shell segment that will output a list of files with full paths
+" parsed from the named filelist file.
+function! s:filels(filelist)
+  return "(cat " . a:filelist . ")"
+endfunction
+
+" Use dmenu to select a file to execute with command 'cmd'.  If no file is
+" selected, no action is taken.  The list of files presented to dmenu comes
+" from one of four places, in the following priority order:
+" 1. All filelist files found in the same directory(ies) vim looks for tags
+"    files.
+" 2. Any tags files found in &tags.  The file is parsed to get filenames.
+" 3. The tracked files in the current git repository, and/or the tracked files
+"    in those valid git repositories named in the 'extrefs' file, if present.
+" 3. Perform a 'find . -type f' in the current directory.
+function! mkbuild#DmenuOpen(cmd)
+  if empty(system('which dmenu'))
+    echo "Dmenu is not installed"
+  else
+    let files = s:filelists()
+    if empty(files)
+      let tags = s:tagfiles()
+      if empty(tags)
+        let gitdirs = s:gitdirs()
+        if empty(gitdirs)
+          let source = 'find'
+          let sourcecmd = 'find . -type f'
+        else " gitdirs
+          let source = 'git|extrefs'
+          let sourcecmd = '(true'
+          for g in gitdirs
+            let sourcecmd = sourcecmd . '; ' . s:gitls(g)
+          endfor
+          let sourcecmd = sourcecmd . ')'
+        endif
+      else " tags
+        let source = 'tags'
+        let sourcecmd = '(true'
+        for t in tags
+          let sourcecmd = sourcecmd . '; ' . s:tagls(t)
+        endfor
+        let sourcecmd = sourcecmd . ')'
+      endif
+    else " filelists
+      let source = 'filelists'
+      let sourcecmd = '(true'
+      for f in files
+        let sourcecmd = sourcecmd . '; ' . s:filels(f)
+      endfor
+      let sourcecmd = sourcecmd . ')'
+    endif
+    let fname = s:chompsys(sourcecmd . ' | dmenu -i -l 20 -p "' . source . '(' .
+        \ a:cmd . ')"')
+    if empty(fname)
+      return
+    endif
+    execute a:cmd . " " . fname
+  endif
+endfunction