Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
changelog.vim314 linesDownload Raw Back to ftplugin
1" Vim filetype plugin file2" Language:             generic Changelog file3" Maintainer:           Martin Florian <marfl@posteo.de>4" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>5" Latest Revision:      2021-10-176" Variables:7"   g:changelog_timeformat (deprecated: use g:changelog_dateformat instead) -8"       description: the timeformat used in ChangeLog entries.9"       default: "%Y-%m-%d".10"   g:changelog_dateformat -11"       description: the format sent to strftime() to generate a date string.12"       default: "%Y-%m-%d".13"   g:changelog_username -14"       description: the username to use in ChangeLog entries15"       default: try to deduce it from environment variables and system files.16" Local Mappings:17"   <Leader>o -18"       adds a new changelog entry for the current user for the current date.19" Global Mappings:20"   <Leader>o -21"       switches to the ChangeLog buffer opened for the current directory, or22"       opens it in a new buffer if it exists in the current directory.  Then23"       it does the same as the local <Leader>o described above.24" Notes:25"   run 'runtime ftplugin/changelog.vim' to enable the global mapping for26"   changelog files.27" TODO:28"  should we perhaps open the ChangeLog file even if it doesn't exist already?29"  Problem is that you might end up with ChangeLog files all over the place.30 31" If 'filetype' isn't "changelog", we must have been to add ChangeLog opener32if &filetype == 'changelog'33  if exists('b:did_ftplugin')34    finish35  endif36  let b:did_ftplugin = 137 38  let s:cpo_save = &cpo39  set cpo&vim40 41  " Set up the format used for dates.42  if !exists('g:changelog_dateformat')43    if exists('g:changelog_timeformat')44      let g:changelog_dateformat = g:changelog_timeformat45    else46      let g:changelog_dateformat = "%Y-%m-%d"47    endif48  endif49 50  function! s:username()51    if exists('g:changelog_username')52      return g:changelog_username53    elseif $EMAIL != ""54      return $EMAIL55    elseif $EMAIL_ADDRESS != ""56      return $EMAIL_ADDRESS57    endif58    let s:default_login = 'unknown'59 60    " Disabled by default for security reasons.61    if dist#vim#IsSafeExecutable('changelog', 'whoami')62      let login = s:login()63    else64      let login = s:default_login65    endif66    return printf('%s <%s@%s>', s:name(login), login, s:hostname())67  endfunction68 69  function! s:login()70    return s:trimmed_system_with_default('whoami', s:default_login)71  endfunction72 73  function! s:trimmed_system_with_default(command, default)74    return s:first_line(s:system_with_default(a:command, a:default))75  endfunction76 77  function! s:system_with_default(command, default)78    let output = system(a:command)79    if v:shell_error80      return a:default81    endif82    return output83  endfunction84 85  function! s:first_line(string)86    return substitute(a:string, '\n.*$', "", "")87  endfunction88 89  function! s:name(login)90    for name in [s:gecos_name(a:login), $NAME, s:capitalize(a:login)]91      if name != ""92        return name93      endif94    endfor95  endfunction96 97  function! s:gecos_name(login)98    for line in s:try_reading_file('/etc/passwd')99      if line =~ '^' . a:login . ':'100        return substitute(s:passwd_field(line, 5), '&', s:capitalize(a:login), "")101      endif102    endfor103    return ""104  endfunction105 106  function! s:try_reading_file(path)107    try108      return readfile(a:path)109    catch110      return []111    endtry112  endfunction113 114  function! s:passwd_field(line, field)115    let fields = split(a:line, ':', 1)116    if len(fields) < a:field117      return ""118    endif119    return fields[a:field - 1]120  endfunction121 122  function! s:capitalize(word)123    return toupper(a:word[0]) . strpart(a:word, 1)124  endfunction125 126  function! s:hostname()127    return s:trimmed_system_with_default('hostname', 'localhost')128  endfunction129 130  " Format used for new date entries.131  if !exists('g:changelog_new_date_format')132    let g:changelog_new_date_format = "%d  %u\n\n\t* %p%c\n\n"133  endif134 135  " Format used for new entries to current date entry.136  if !exists('g:changelog_new_entry_format')137    let g:changelog_new_entry_format = "\t* %p%c"138  endif139 140  " Regular expression used to find a given date entry.141  if !exists('g:changelog_date_entry_search')142    let g:changelog_date_entry_search = '^\s*%d\_s*%u'143  endif144 145  " Regular expression used to find the end of a date entry146  if !exists('g:changelog_date_end_entry_search')147    let g:changelog_date_end_entry_search = '^\s*$'148  endif149 150 151  " Substitutes specific items in new date-entry formats and search strings.152  " Can be done with substitute of course, but unclean, and need \@! then.153  function! s:substitute_items(str, date, user, prefix)154    let str = a:str155    let middles = {'%': '%', 'd': a:date, 'u': a:user, 'p': a:prefix, 'c': '{cursor}'}156    let i = stridx(str, '%')157    while i != -1158      let inc = 0159      if has_key(middles, str[i + 1])160        let mid = middles[str[i + 1]]161        let str = strpart(str, 0, i) . mid . strpart(str, i + 2)162        let inc = strlen(mid) - 1163      endif164      let i = stridx(str, '%', i + 1 + inc)165    endwhile166    return str167  endfunction168 169  " Position the cursor once we've done all the funky substitution.170  function! s:position_cursor()171    if search('{cursor}') > 0172      let lnum = line('.')173      let line = getline(lnum)174      let cursor = stridx(line, '{cursor}')175      call setline(lnum, substitute(line, '{cursor}', '', ''))176    endif177    startinsert178  endfunction179 180  " Internal function to create a new entry in the ChangeLog.181  function! s:new_changelog_entry(prefix)182    " Deal with 'paste' option.183    let save_paste = &paste184    let &paste = 1185    call cursor(1, 1)186    " Look for an entry for today by our user.187    let date = strftime(g:changelog_dateformat)188    let search = s:substitute_items(g:changelog_date_entry_search, date,189                                  \ s:username(), a:prefix)190    if search(search) > 0191      " Ok, now we look for the end of the date entry, and add an entry.192      call cursor(nextnonblank(line('.') + 1), 1)193      if search(g:changelog_date_end_entry_search, 'W') > 0194	let p = (line('.') == line('$')) ? line('.') : line('.') - 1195      else196        let p = line('.')197      endif198      let ls = split(s:substitute_items(g:changelog_new_entry_format, '', '', a:prefix),199                   \ '\n')200      call append(p, ls)201      call cursor(p + 1, 1)202    else203      " Flag for removing empty lines at end of new ChangeLogs.204      let remove_empty = line('$') == 1205 206      " No entry today, so create a date-user header and insert an entry.207      let todays_entry = s:substitute_items(g:changelog_new_date_format,208                                          \ date, s:username(), a:prefix)209      " Make sure we have a cursor positioning.210      if stridx(todays_entry, '{cursor}') == -1211        let todays_entry = todays_entry . '{cursor}'212      endif213 214      " Now do the work.215      call append(0, split(todays_entry, '\n'))216 217      " Remove empty lines at end of file.218      if remove_empty219        $-/^\s*$/-1,$delete220      endif221 222      " Reposition cursor once we're done.223      call cursor(1, 1)224    endif225 226    call s:position_cursor()227 228    " And reset 'paste' option229    let &paste = save_paste230  endfunction231 232  let b:undo_ftplugin = "setl com< fo< et< ai<"233 234  setlocal comments=235  setlocal formatoptions+=t236  setlocal noexpandtab237  setlocal autoindent238 239  if &textwidth == 0240    setlocal textwidth=78241    let b:undo_ftplugin .= " tw<"242  endif243 244  if !exists("no_plugin_maps") && !exists("no_changelog_maps") && exists(":NewChangelogEntry") != 2245    nnoremap <buffer> <silent> <Leader>o :<C-u>call <SID>new_changelog_entry('')<CR>246    xnoremap <buffer> <silent> <Leader>o :<C-u>call <SID>new_changelog_entry('')<CR>247    command! -buffer -nargs=0 NewChangelogEntry call s:new_changelog_entry('')248    let b:undo_ftplugin .= " | sil! exe 'nunmap <buffer> <Leader>o'" .249          \                " | sil! exe 'vunmap <buffer> <Leader>o'" .250          \                " | sil! delc NewChangelogEntry"251  endif252 253  let &cpo = s:cpo_save254  unlet s:cpo_save255else256  let s:cpo_save = &cpo257  set cpo&vim258 259  if !exists("no_plugin_maps") && !exists("no_changelog_maps")260    " Add the Changelog opening mapping261    nnoremap <silent> <Leader>o :call <SID>open_changelog()<CR>262    let b:undo_ftplugin .= " | silent! exe 'nunmap <buffer> <Leader>o"263  endif264 265  function! s:open_changelog()266    let path = expand('%:p:h')267    if exists('b:changelog_path')268      let changelog = b:changelog_path269    else270      if exists('b:changelog_name')271        let name = b:changelog_name272      else273        let name = 'ChangeLog'274      endif275      while isdirectory(path)276        let changelog = path . '/' . name277        if filereadable(changelog)278          break279        endif280        let parent = substitute(path, '/\+[^/]*$', "", "")281        if path == parent282          break283        endif284        let path = parent285      endwhile286    endif287    if !filereadable(changelog)288      return289    endif290 291    if exists('b:changelog_entry_prefix')292      let prefix = call(b:changelog_entry_prefix, [])293    else294      let prefix = substitute(strpart(expand('%:p'), strlen(path)), '^/\+', "", "")295    endif296 297    let buf = bufnr(changelog)298    if buf != -1299      if bufwinnr(buf) != -1300        execute bufwinnr(buf) . 'wincmd w'301      else302        execute 'sbuffer' buf303      endif304    else305      execute 'split' fnameescape(changelog)306    endif307 308    call s:new_changelog_entry(prefix)309  endfunction310 311  let &cpo = s:cpo_save312  unlet s:cpo_save313endif314 
codekingpro/portable-devtools · Team Ai