]> oss.titaniummirror.com Git - vim-mkbuild.git/commitdiff
Improve plugin; consolidate unite sources
authorR. Steve McKown <rsmckown@gmail.com>
Mon, 18 Jan 2016 21:04:10 +0000 (14:04 -0700)
committerR. Steve McKown <rsmckown@gmail.com>
Mon, 18 Jan 2016 21:04:10 +0000 (14:04 -0700)
autoload/unite/sources/mkbfiles.vim [deleted file]
autoload/unite/sources/mkbuild.vim [new file with mode: 0644]
autoload/unite/sources/xrefs.vim [deleted file]
plugin/mkbuild.vim

diff --git a/autoload/unite/sources/mkbfiles.vim b/autoload/unite/sources/mkbfiles.vim
deleted file mode 100644 (file)
index 1ff92b3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-" unite source: file selection for projects using mkbuild
-
-let s:save_cpo = &cpo
-set cpo&vim
-
-let s:source = {
-  \ 'name': 'mkbfiles',
-  \ 'description': 'select files in an mkbuild based project',
-  \ 'action_table': {
-  \   'open' : { 'is_selectable': 1 },
-  \ },
-  \ 'default_action': 'open'
-  \ }
-
-function! s:source.action_table.open.func(candidates)
-  for c in a:candidates
-    execute "e" c.word
-  endfor
-endfunction
-
-function! s:source.gather_candidates(args, context)
-  return map(split(mkbuild#filelist(), '\n'), '{ "word": v:val }')
-endfunction
-
-function! unite#sources#mkbfiles#define()
-  return s:source
-endfunction
-
-let &cpo = s:save_cpo
-unlet s:save_cpo
diff --git a/autoload/unite/sources/mkbuild.vim b/autoload/unite/sources/mkbuild.vim
new file mode 100644 (file)
index 0000000..0a293bd
--- /dev/null
@@ -0,0 +1,96 @@
+" unite mkbuild sources
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+let s:xref_source = {
+  \ 'name': 'mkbuild/xref',
+  \ 'description': 'select cross references built from an mkbuild build',
+  \ 'action_table': {
+  \   'setxrefs' : { 'is_selectable': 1 },
+  \ },
+  \ 'default_action': 'setxrefs'
+  \ }
+
+function! s:xref_source.action_table.setxrefs.func(candidates)
+  call s:select(a:candidates[0].word)
+endfunction
+
+function! s:xref_source.gather_candidates(args, context)
+  let cmd = 'find . -maxdepth 4 -type f -name tags -o -name cscope.out | ' .
+    \ 'while read f; do echo $(dirname $f); done | sort -u | sed -e "s|\./||"'
+  let xrefdirs = split(s:chompsys(cmd), '\n')
+
+  return map(xrefdirs, '{ "word": v:val }')
+endfunction
+
+function! s:select(dirname)
+  if empty(a:dirname)
+    return
+  endif
+  let file = a:dirname . "/tags"
+  let &tags=''
+  if filereadable(file)
+    let &tags = file
+  endif
+  if has('cscope')
+    let file = a:dirname . "/cscope.out"
+    execute 'cscope kill -1'
+    if filereadable(file)
+      execute 'cscope add ' . file
+    endif
+  endif
+endfunction
+
+" Return the results of a command without the ending newline
+function! s:chompsys(cmd)
+  return substitute(system(a:cmd), '\n$', '', '')
+endfunction
+
+
+let s:xfile_source = {
+  \ 'name': 'mkbuild/file_xref',
+  \ 'description': 'select files used in an mkbuild build',
+  \ 'action_table': {
+  \   'open' : { 'is_selectable': 1 },
+  \ },
+  \ 'default_action': 'open'
+  \ }
+
+function! s:xfile_source.action_table.open.func(candidates)
+  for c in a:candidates
+    execute 'e ' . c.word
+  endfor
+endfunction
+
+function! s:xfile_source.gather_candidates(args, context)
+  return map(mkbuild#buildFiles(), '{ "word": v:val }')
+endfunction
+
+
+let s:file_source = {
+  \ 'name': 'mkbuild/file',
+  \ 'description': 'select files in an mkbuild project',
+  \ 'action_table': {
+  \   'open' : { 'is_selectable': 1 },
+  \ },
+  \ 'default_action': 'open'
+  \ }
+
+function! s:file_source.action_table.open.func(candidates)
+  for c in a:candidates
+    execute 'e ' . c.word
+  endfor
+endfunction
+
+function! s:file_source.gather_candidates(args, context)
+  return map(mkbuild#allFiles(), '{ "word": v:val }')
+endfunction
+
+
+function! unite#sources#mkbuild#define()
+  return [s:xref_source, s:xfile_source, s:file_source]
+endfunction
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
diff --git a/autoload/unite/sources/xrefs.vim b/autoload/unite/sources/xrefs.vim
deleted file mode 100644 (file)
index 87f9b53..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-" unite source: tags file and/or cscope database selection for projects using
-" mkbuild
-
-let s:save_cpo = &cpo
-set cpo&vim
-
-let s:source = {
-  \ 'name': 'xrefs',
-  \ 'description': 'select cross references from a directory',
-  \ 'action_table': {
-  \   'setxrefs' : { 'is_selectable': 1 },
-  \ },
-  \ 'default_action': 'setxrefs'
-  \ }
-
-function! s:source.action_table.setxrefs.func(candidates)
-  call s:select(a:candidates[0].word)
-endfunction
-
-function! s:select(dirname)
-  if empty(a:dirname)
-    return
-  endif
-  let file = a:dirname . "/tags"
-  let &tags=''
-  if filereadable(file)
-    let &tags = file
-  endif
-  if has('cscope')
-    let file = a:dirname . "/cscope.out"
-    execute 'cscope kill -1'
-    if filereadable(file)
-      execute 'cscope add ' . file
-    endif
-  endif
-endfunction
-
-" Return the results of a command without the ending newline
-function! s:chompsys(cmd)
-  return substitute(system(a:cmd), '\n$', '', '')
-endfunction
-
-function! s:source.gather_candidates(args, context)
-  let cmd = 'find . -maxdepth 4 -type f -name tags -o -name cscope.out | ' .
-    \ 'while read f; do echo $(dirname $f); done | sort -u | sed -e "s|\./||"'
-  let xrefdirs = split(s:chompsys(cmd), '\n')
-
-  return map(xrefdirs, '{ "word": v:val }')
-endfunction
-
-function! unite#sources#xrefs#define()
-  return s:source
-endfunction
-
-let &cpo = s:save_cpo
-unlet s:save_cpo
index eb3fd2bd767cba259abe9a9ebbb991d4d82c3d48..6aac93653a0957447f03f2aa607767186429dce8 100644 (file)
@@ -5,48 +5,80 @@ 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 a list directories contained within an extrefs file at 'dir'.  Use
+" '.' as dir if wanting to find extrefs in the current directory.  The
+" returned list may be empty.  Directories returned are not validated.
+function! s:extrefs(dir)
+  let extdirs = []
+  let extrefs = a:dir . '/extrefs'
+  if filereadable(extrefs)
+    for e in split(s:chompsys(
+          \ "grep ^git " . extrefs . "| awk '{ print $3  }'"))
+      if !empty(e)
+        call add(extdirs, a:dir . '/' . e)
+      endif
+    endfor
+  endif
+  return extdirs
+endfunction
+
+" Return a list of files found using 'find', recursively, starting at 'dir'
+function s:filesFromFind(dir)
+  return split(s:chompsys("cd " . a:dir . " 2>/dev/null && find . -type f"),
+      \ '\n')
+endfunction
+
+" If 'dir' is empty, assume the current directory.  Assume 'dir' is within a
+" Git checkout.  If true, return a list of tracked files from the Get
+" repository.  Otherwise, return an empty string.
+function! s:gitTopLevel(dir)
     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 . "/|')"
+" 'dir' must either be an empty string or a directory within a Git checkout,
+" generally its top level directory.  Return a list of all tracked files
+" within the repository starting at 'dir'.
+function! s:filesFromGit(dir)
+  if empty(a:dir)
+    return []
+  else
+    return split(s:chompsys("git --git-dir=" . a:dir . "/.git ls-files | "
+        \ . "sed -e s'|^|" . a:dir . "/|'"), '\n')
+  endif
 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)
+" Return a list of files contained within the directory 'dir'.  If 'dir'
+" belongs to a Git working directory, return all tracked files in the
+" repository.  Otherwise, use find to return the files at the filesystem
+" subtree starting at 'dir'.
+"
+" Additionally, if 'dir' (or instead the Git top-level working directory),
+" contains an extrefs file, recursively include files from each of its listed
+" directories.
+function! s:filesFromDir(dir)
+  let dir = s:gitTopLevel(a:dir)
+  if !empty(dir)
+    let files = s:filesFromGit(dir)
   else
-    call add(dirs, topdir)
-    let extrefs = topdir . '/extrefs'
+    let dir = a:dir
+    let files = s:filesFromFind(dir)
+  endif
+  if !empty(files)
+    let extrefs = dir . '/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)
+        if !empty(e)
+          call extend(files, s:filesFromDir(dir . '/' . e))
         endif
       endfor
     endif
   endif
-  return dirs
+  return files
 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()
@@ -59,16 +91,16 @@ function! s:tagfiles()
   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)"
+" Return a list of files with full paths, parsed from the named tags (ctags)
+" file.
+function! s:filesFromTagsFile(tagfile)
+  return split(s:chompsys("grep -v \"!\" " . a:tagfile .
+      \ " | awk -F\\\t '{ print $2 }' | sort -u"), '\n')
 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()
+function! s:filelistfiles()
   let files = []
   for t in s:tagfiles()
     let f = substitute(t, '\c\(\.\/\)*tags.*$', 'filelist', '')
@@ -79,88 +111,39 @@ function! s:filelists()
   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 . ")"
+" Return a list of files with full paths, parsed from the named filelist file.
+function! s:filesFromFilelistFile(filelist)
+  return split(s:chompsys("cat " . a:filelist), '\n')
 endfunction
 
-" Generate a command to generate a list of files.  Return a dictionary
-" containing two entries:
-" source - The source of the files (generated by executing the sourcecmd)
-" sourcecmd - The system command to use to generate the list of files
-"
-" The source command returned will output files from one of 4 locations,
-" searched in priority order:
-" 1. All filelist files found in the same directory(ies) vim looks for tags
-"    files.  Files are extracted from the contents of these 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.
-" 4. Perform a 'find . -type f' in the current directory.
-function! mkbuild#flcmd()
-  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
-  return { 'source': source, 'sourcecmd': sourcecmd }
+" Return a list of all project files.  Where possible, use tracked files from
+" the project Git repository, else collect all files.  Also follow 'extrefs'
+" files to additional, external sources.
+function! mkbuild#allFiles()
+  return s:filesFromDir('.')
 endfunction
 
-" Generate a list of files using mkbuild#flcmd()
-function! mkbuild#filelist()
-  let flcmdres = mkbuild#flcmd()
-  return s:chompsys(flcmdres['sourcecmd'] . ' | cat')
-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"
+" Return the subset of project files used in the build referenced by the
+" directory defined in the 'tags' variable.  Use the mkbuild filelist, if
+" available, or fall back to extracting files from the tags file.  If no
+" source of filelist or tags files are available, revert to returning all
+" proejct files.
+function! mkbuild#buildFiles()
+  let files = []
+  let flfiles = s:filelistfiles()
+  if !empty(flfiles)
+    for f in flfiles
+      call extend(files, s:filesFromFilelistFile(f))
+    endfor
   else
-    let flcmdres = mkbuild#flcmd()
-    let source = flcmdres['source']
-    let sourcecmd = flcmdres['sourcecmd']
-    let fname = s:chompsys(sourcecmd . ' | dmenu -i -l 20 -p "' . source . '(' .
-        \ a:cmd . ')"')
-    if empty(fname)
-      return
+    let tagfiles = s:tagfiles()
+    if !empty(tagfiles)
+      for t in tags
+        call extend(files, s:filesFromTagsFile(t))
+      endfor
+    else
+      call extend(files, s:filesFromDir('.'))
     endif
-    execute a:cmd . " " . fname
   endif
+  return files
 endfunction