Skip to content

Commit d809a1c

Browse files
Mike Sharpevim-scripts
Mike Sharpe
authored andcommittedNov 6, 2010
Version 2.13
Added new "AT" command which finds the alternate file and opens in a new tab. Similarly to the "A" and "AS" commands, if the buffer is already open it simply switches to that buffer in the corresponding tab/window. This script will only work with VIM7 from this version forward.
1 parent 8c86831 commit d809a1c

File tree

1 file changed

+144
-69
lines changed

1 file changed

+144
-69
lines changed
 

‎plugin/a.vim

+144-69
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
" Copyright (c) 1998-2004
1+
" Copyright (c) 1998-2006
22
" Michael Sharpe <feline@irendi.com>
33
"
44
" We grant permission to use, copy modify, distribute, and sell this
@@ -30,6 +30,10 @@ let loaded_alternateFile = 1
3030
" let g:alternateExtensions_{'aspx.cs'} = "aspx"
3131

3232

33+
" This variable will be increased when an extension with greater number of dots
34+
" is added by the AddAlternateExtensionMapping call.
35+
let s:maxDotsInExtension = 0
36+
3337
" Function : AddAlternateExtensionMapping (PRIVATE)
3438
" Purpose : simple helper function to add the default alternate extension
3539
" mappings.
@@ -51,6 +55,11 @@ function! <SID>AddAlternateExtensionMapping(extension, alternates)
5155
if (v:errmsg != "")
5256
let g:alternateExtensions_{a:extension} = a:alternates
5357
endif
58+
59+
let dotsNumber = strlen(substitute(a:extension, "[^.]", "", "g"))
60+
if s:maxDotsInExtension < dotsNumber
61+
let s:maxDotsInExtension = dotsNumber
62+
endif
5463
endfunction
5564

5665
" Add all the default extensions
@@ -204,7 +213,7 @@ endfunction
204213
" Returns : An expanded filename if found, the empty string otherwise
205214
" Author : Michael Sharpe (feline@irendi.com)
206215
" History : inline code written by Bindu Wavell originally
207-
function! <SID>FindFileInSearchPath(filename, pathList, relPathBase)
216+
function! <SID>FindFileInSearchPath(fileName, pathList, relPathBase)
208217
let filepath = ""
209218
let m = 1
210219
let pathListLen = strlen(a:pathList)
@@ -213,7 +222,7 @@ function! <SID>FindFileInSearchPath(filename, pathList, relPathBase)
213222
let pathSpec = <SID>GetNthItemFromList(a:pathList, m)
214223
if (pathSpec != "")
215224
let path = <SID>ExpandAlternatePath(pathSpec, a:relPathBase)
216-
let fullname = path . "/" . a:filename
225+
let fullname = path . "/" . a:fileName
217226
let foundMatch = <SID>BufferOrFileExists(fullname)
218227
if (foundMatch)
219228
let filepath = fullname
@@ -324,37 +333,21 @@ endfunction
324333
" variables echo the curly brace variable and look for an error
325334
" message.
326335
function! DetermineExtension(path)
327-
let extension = fnamemodify(a:path,":t:e")
328-
let v:errmsg = ""
329-
silent! echo g:alternateExtensions_{extension}
330-
if (v:errmsg != "")
331-
let extension = fnamemodify(a:path,":t:e:e")
332-
let v:errmsg = ""
333-
silent! echo g:alternateExtensions_{extension}
334-
if (v:errmsg != "")
335-
let extension = fnamemodify(a:path,":t:e:e:e")
336-
let v:errmsg = ""
337-
silent! echo g:alternateExtensions_{extension}
338-
if (v:errmsg != "")
339-
let extension = fnamemodify(a:path,":t:e:e:e:e")
340-
let v:errmsg = ""
341-
silent! echo g:alternateExtensions_{extension}
342-
if (v:errmsg != "")
343-
let extension = fnamemodify(a:path,":t:e:e:e:e:e")
344-
let v:errmsg = ""
345-
silent! echo g:alternateExtensions_{extension}
346-
if (v:errmsg != "")
347-
let extension = ""
348-
endif
349-
endif
350-
endif
351-
endif
352-
endif
353-
return extension
336+
let mods = ":t"
337+
let i = 0
338+
while i <= s:maxDotsInExtension
339+
let mods = mods . ":e"
340+
let extension = fnamemodify(a:path, mods)
341+
let v:errmsg = ""
342+
silent! echo g:alternateExtensions_{extension}
343+
if (v:errmsg == "")
344+
return extension
345+
endif
346+
let i = i + 1
347+
endwhile
348+
return ""
354349
endfunction
355350

356-
"source $HOME/vimscripts/plugin/Decho.vim
357-
358351
" Function : AlternateFile (PUBLIC)
359352
" Purpose : Opens a new buffer by looking at the extension of the current
360353
" buffer and finding the corresponding file. E.g. foo.c <--> foo.h
@@ -373,10 +366,6 @@ function! AlternateFile(splitWindow, ...)
373366
let baseName = substitute(expand("%:t"), "\." . extension . '$', "", "")
374367
let currentPath = expand("%:p:h")
375368

376-
"Decho "extension=".extension
377-
"Decho "baseName=".baseName
378-
"Decho "currentPath=".currentPath
379-
380369
if (a:0 != 0)
381370
let newFullname = currentPath . "/" . baseName . "." . a:1
382371
call <SID>FindOrCreateBuffer(newFullname, a:splitWindow)
@@ -386,9 +375,6 @@ function! AlternateFile(splitWindow, ...)
386375
let allfiles1 = EnumerateFilesByExtension(currentPath, baseName, extension)
387376
let allfiles2 = EnumerateFilesByExtensionInPath(baseName, extension, g:alternateSearchPath, currentPath)
388377

389-
"Decho "allfiles1=".allfiles1
390-
"Decho "allfiles2=".allfiles2
391-
392378
if (allfiles1 != "")
393379
if (allfiles2 != "")
394380
let allfiles = allfiles1 . ',' . allfiles2
@@ -432,6 +418,9 @@ endfunction
432418
comm! -nargs=? -bang A call AlternateFile("n<bang>", <f-args>)
433419
comm! -nargs=? -bang AS call AlternateFile("h<bang>", <f-args>)
434420
comm! -nargs=? -bang AV call AlternateFile("v<bang>", <f-args>)
421+
if v:version >= 700
422+
comm! -nargs=? -bang AT call AlternateFile("t<bang>", <f-args>)
423+
endif
435424

436425
" Function : BufferOrFileExists (PRIVATE)
437426
" Purpose : determines if a buffer or a readable file exists
@@ -442,17 +431,34 @@ comm! -nargs=? -bang AV call AlternateFile("v<bang>", <f-args>)
442431
" filename and not the path.
443432
function! <SID>BufferOrFileExists(fileName)
444433
let result = 0
445-
let bufName = fnamemodify(a:fileName,":t")
446-
let memBufName = bufname(bufName)
447-
if (memBufName != "")
448-
let memBufBasename = fnamemodify(memBufName, ":t")
449-
if (bufName == memBufBasename)
450-
let result = 2
434+
435+
let lastBuffer = bufnr("$")
436+
let i = 1
437+
while i <= lastBuffer
438+
if <SID>EqualFilePaths(expand("#".i.":p"), a:fileName)
439+
let result = 2
440+
break
441+
endif
442+
let i = i + 1
443+
endwhile
444+
445+
if (!result)
446+
let bufName = fnamemodify(a:fileName,":t")
447+
let memBufName = bufname(bufName)
448+
if (memBufName != "")
449+
let memBufBasename = fnamemodify(memBufName, ":t")
450+
if (bufName == memBufBasename)
451+
let result = 2
452+
endif
453+
endif
454+
455+
if (!result)
456+
let result = bufexists(bufName) || bufexists(a:fileName) || filereadable(a:fileName)
451457
endif
452458
endif
453459

454460
if (!result)
455-
let result = bufexists(bufName) || bufexists(a:fileName) || filereadable(a:fileName)
461+
let result = filereadable(a:fileName)
456462
endif
457463
return result
458464
endfunction
@@ -465,7 +471,7 @@ endfunction
465471
" not exist, it creates it.
466472
" Args : filename (IN) -- the name of the file
467473
" doSplit (IN) -- indicates whether the window should be split
468-
" ("v", "h", "n", "v!", "h!", "n!")
474+
" ("v", "h", "n", "v!", "h!", "n!", "t", "t!")
469475
" Returns : nothing
470476
" Author : Michael Sharpe <feline@irendi.com>
471477
" History : + bufname() was not working very well with the possibly strange
@@ -475,49 +481,98 @@ endfunction
475481
" Allow ! to be applied to buffer/split/editing commands for more
476482
" vim/vi like consistency
477483
" + implemented fix from Matt Perry
478-
function! <SID>FindOrCreateBuffer(filename, doSplit)
484+
function! <SID>FindOrCreateBuffer(fileName, doSplit)
479485
" Check to see if the buffer is already open before re-opening it.
480-
let bufName = bufname(a:filename)
481-
let bufFilename = fnamemodify(a:filename,":t")
482-
483-
if (bufName == "")
484-
let bufName = bufname(bufFilename)
485-
endif
486+
let FILENAME = a:fileName
487+
let bufNr = -1
488+
let lastBuffer = bufnr("$")
489+
let i = 1
490+
while i <= lastBuffer
491+
if <SID>EqualFilePaths(expand("#".i.":p"), a:fileName)
492+
let bufNr = i
493+
break
494+
endif
495+
let i = i + 1
496+
endwhile
497+
498+
if (bufNr == -1)
499+
let bufName = bufname(a:fileName)
500+
let bufFilename = fnamemodify(a:fileName,":t")
501+
502+
if (bufName == "")
503+
let bufName = bufname(bufFilename)
504+
endif
486505

487-
if (bufName != "")
488-
let tail = fnamemodify(bufName, ":t")
489-
if (tail != bufFilename)
490-
let bufName = ""
506+
if (bufName != "")
507+
let tail = fnamemodify(bufName, ":t")
508+
if (tail != bufFilename)
509+
let bufName = ""
510+
endif
511+
endif
512+
if (bufName != "")
513+
let bufNr = bufnr(bufName)
514+
let FILENAME = bufName
491515
endif
492516
endif
493517

494518
let splitType = a:doSplit[0]
495519
let bang = a:doSplit[1]
496-
if (bufName == "")
520+
if (bufNr == -1)
497521
" Buffer did not exist....create it
498522
let v:errmsg=""
499523
if (splitType == "h")
500-
silent! execute ":split".bang." " . a:filename
524+
silent! execute ":split".bang." " . FILENAME
501525
elseif (splitType == "v")
502-
silent! execute ":vsplit".bang." " . a:filename
526+
silent! execute ":vsplit".bang." " . FILENAME
527+
elseif (splitType == "t")
528+
silent! execute ":tab split".bang." " . FILENAME
503529
else
504-
silent! execute ":e".bang." " . a:filename
530+
silent! execute ":e".bang." " . FILENAME
505531
endif
506532
if (v:errmsg != "")
507533
echo v:errmsg
508534
endif
509535
else
536+
537+
" Find the correct tab corresponding to the existing buffer
538+
let tabNr = -1
539+
" iterate tab pages
540+
for i in range(tabpagenr('$'))
541+
" get the list of buffers in the tab
542+
let tabList = tabpagebuflist(i + 1)
543+
let idx = 0
544+
" iterate each buffer in the list
545+
while idx < len(tabList)
546+
" if it matches the buffer we are looking for...
547+
if (tabList[idx] == bufNr)
548+
" ... save the number
549+
let tabNr = i + 1
550+
break
551+
endif
552+
let idx = idx + 1
553+
endwhile
554+
if (tabNr != -1)
555+
break
556+
endif
557+
endfor
558+
" switch the the tab containing the buffer
559+
if (tabNr != -1)
560+
execute "tabn ".tabNr
561+
endif
562+
510563
" Buffer was already open......check to see if it is in a window
511-
let bufWindow = bufwinnr(bufName)
564+
let bufWindow = bufwinnr(bufNr)
512565
if (bufWindow == -1)
513566
" Buffer was not in a window so open one
514567
let v:errmsg=""
515568
if (splitType == "h")
516-
silent! execute ":sbuffer".bang." " . bufName
569+
silent! execute ":sbuffer".bang." " . FILENAME
517570
elseif (splitType == "v")
518-
silent! execute ":vert sbuffer " . bufName
571+
silent! execute ":vert sbuffer " . FILENAME
572+
elseif (splitType == "t")
573+
silent! execute ":tab sbuffer " . FILENAME
519574
else
520-
silent! execute ":buffer".bang." " . bufName
575+
silent! execute ":buffer".bang." " . FILENAME
521576
endif
522577
if (v:errmsg != "")
523578
echo v:errmsg
@@ -529,11 +584,13 @@ function! <SID>FindOrCreateBuffer(filename, doSplit)
529584
" something wierd happened...open the buffer
530585
let v:errmsg=""
531586
if (splitType == "h")
532-
silent! execute ":split".bang." " . bufName
587+
silent! execute ":split".bang." " . FILENAME
533588
elseif (splitType == "v")
534-
silent! execute ":vsplit".bang." " . bufName
589+
silent! execute ":vsplit".bang." " . FILENAME
590+
elseif (splitType == "t")
591+
silent! execute ":tab split".bang." " . FILENAME
535592
else
536-
silent! execute ":e".bang." " . bufName
593+
silent! execute ":e".bang." " . FILENAME
537594
endif
538595
if (v:errmsg != "")
539596
echo v:errmsg
@@ -542,3 +599,21 @@ function! <SID>FindOrCreateBuffer(filename, doSplit)
542599
endif
543600
endif
544601
endfunction
602+
603+
" Function : EqualFilePaths (PRIVATE)
604+
" Purpose : Compares two paths. Do simple string comparison anywhere but on
605+
" Windows. On Windows take into account that file paths could differ
606+
" in usage of separators and the fact that case does not metter.
607+
" "c:\WINDOWS" is the same path as "c:/windows". has("win32unix") Vim
608+
" version does not count as one having Windows path rules.
609+
" Args : path1 (IN) -- first path
610+
" path2 (IN) -- second path
611+
" Returns : 1 if path1 is equal to path2, 0 otherwise.
612+
" Author : Ilya Bobir <ilya@po4ta.com>
613+
function! <SID>EqualFilePaths(path1, path2)
614+
if has("win16") || has("win32") || has("win64") || has("win95")
615+
return substitute(a:path1, "\/", "\\", "g") ==? substitute(a:path2, "\/", "\\", "g")
616+
else
617+
return a:path1 == a:path2
618+
endif
619+
endfunction

0 commit comments

Comments
 (0)
Failed to load comments.