From: R. Steve McKown Date: Fri, 19 Jun 2015 15:25:39 +0000 (-0600) Subject: Initial commit X-Git-Url: https://oss.titaniummirror.com/gitweb?p=vim-mkbuild.git;a=commitdiff_plain;h=e1ebb294da0c4950b5c2a23224cec7b3b1273e55 Initial commit --- e1ebb294da0c4950b5c2a23224cec7b3b1273e55 diff --git a/doc/mkbuild.txt b/doc/mkbuild.txt new file mode 100644 index 0000000..4f658ff --- /dev/null +++ b/doc/mkbuild.txt @@ -0,0 +1,40 @@ +*mkbuild.txt* Plugin for integrating with mkbuild build system features + +Author: R. Steve McKown +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 e :call mkbuild#DmenuOpen('e') + +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 edit'. + +2. Any tags files found in &tags. The file is parsed to get filenames. + A tags file is set by mkbuild's 'make 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 index 0000000..fd92caa --- /dev/null +++ b/plugin/mkbuild.vim @@ -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