Tmux/Vim plugin that shows a list of open files - vim

When I have many vim files open in different tmux panes, it becomes difficult to keep track of where they all are. I would love to see a list of open tmux panes labeled with the filename of the vim file being edited. Does such a plugin exist? Is it possible to create one?

For such a plugin to work you would need all your vim instances to run as servers on the same machine in order to query all the visible instances for their bufferlist. This sounds like a pathetically complex solution to a really dumb problem, IMO.
Unless you have a very specific need you shouldn't run multiple vim instances. Vim is perfectly able to deal with dozens of files and has many plugins designed to make buffer management easier.
Start with :help buffers.
Also, tmux is a fine piece of software but you should probably take a moment to weight the complexity it adds to your setup and workflow against its actual benefits.

tmux choose-window
will show the name of current directories of all buffers.
(0) 0: ssh "u35#localhost:~"
(1) 1: vim- "u0_a105#android:~/K/20081121"
(2) 2: vim "u0_a105#android:~/K/2014"
(3) 3: vim "u0_a105#android:~/K/20120430"
(4) 4: bash* "u0_a105#android:~/K/20081121"
I personnaly use
bind-key '"' choose-window
so that ^A" gives this list like screen did.
If you want to see the name of current file, you might configure vim to change the buffer name, as bash is doing.

Related

Is there a way to view the current input source in vim?

When using vim in a non-English language environment, mistakes in mis-entering command often occur.
To prevent this, is there a way to view the current input source on the statusline?
For example, EN or JP.
like MS word bottom bar
Vim doesn't have that information so it can't expose it, which is not exactly a problem since your desktop environment already does.
If you really want to duplicate that information in your Vim status line, then you will have to find what external command to call, and then find a way to consume the information that doesn't slow Vim to a crawl because the status line is refreshed several times per second.
Now, your question is really two questions:
How to get the information?
How to show it in the statusline?
The answer to the first question depends on your desktop environment, which you didn't disclose. You will have to look around on your own, on more specialised forums.
The answer to the second question is irrelevant without an answer to the first one but you can look up :help 'statusline' and :help system() if you are curious.
Anyway, you already have the information in your desktop environment's menu bar/task bar/whatever, so why bother?
Vim has modes. In Normal mode where it is supposed to stay most of the time all commands consist of latin letters by default. Therefore, using OS level keyboard layout switch cannot be recommended. Instead, Vim has a feature called "keymap". Vim keymap is only active in Insert or Command-line mode never affecting the Normal mode.
So, Vim never cares what is your active keyboard layout on OS level and you won't expect an easy way showing it. On the other side, Vim keymap name is accessible either as b:keymap_name variable or %k format specifier for the statusline option. So it is pretty easy to add it.

Selectively Enable/Replicate System Menu or Otherwise Show All MacVim Window Instances

I have this in my '~/.vimrc' (among other things):
set guioptions += M
set guioptions -= m
to disable the menus in MacVim. I find that leaving out the '+=M' results in lots of keys being mapped (the menu hot keys etc.).
There is one facility provided by the system menu that I really would like: the ability to show all current MacVim "windows" (in the operating system sense, and not in the Vim sense of a "split"). For example, I could do something like this (perhaps in separate shells, at separate times):
$ mvim foo.txt
$ mvim bar.txt
$ mvim baz.txt
This will result in 3 separate MacVim "windows". With "set go=+M" not set, I can go to the "Windows" menu and see a these three instances listed and, optionally, select one of them.
Is there any way to do this without enabling the system menu, or at least the rest of it?
My motivation is this: after a while, I tend to end up with lots of different MacVim "windows" across multiple desktop spaces (I also tend to use a lot of desktop spaces). Sometimes I try to open, e.g., "foo.txt", only to get the notification that "foo.txt" is already open. Hunting down window in which it is open is a hassle. Yes, yes, I suppose I could change my entire way of dealing with this --- restricting myself to just one MacVim window, being disciplined about quitting files that I am not immediately working on etc. etc. But short of that, is there something else I could be doing?
I would also be happy if there was a command that I could issue either from the shell or from within Vim, that lists the windows and allowed me to activate one of my choice.
Edit
Turns out that MacVim has a ':macaction selectNextWindow:' command that at least allows me to cycle through the various instances:
nnoremap <silent> <M-`> :macaction selectNextWindow:<CR>
nnoremap <silent> <D-`> :macaction selectNextWindow:<CR>
nnoremap <silent> <M-S-`> :macaction selectPreviousWindow:<CR>
nnoremap <silent> <D-S-`> :macaction selectPreviousWindow:<CR>
I mapped both the command ('<D->') and meta ('<M->') because the former mapping only works with MacVim windows in the same desktop space. Weird. A partial solution in that I (eventually) find the window/instance I want, but at O(n) complexity. A window list would make it O(1).
It's generally possible to access menus from the command-line with a command like:
:amenu Edit
but adding M to 'guioptions' means that no menus are loaded whatsoever so :amenu is useless in your case.
Anyway, that window listing feature is provided by MacVim's Cocoa wrapper: it is part of the default functionalities any GUI application gets for free when created in XCode. MacVim doesn't appear to expose it to the Vim core, though, so you are kind of fucked:
the windows list is not available through :amenu,
set guioptions+=M gets rid of all menus, Vim-provided menus and Cocoa-provided menus.
There's another way to look at your problem: MacVim GUI windows are in fact separate Vim instances that all run as servers (see :help clientserver) and you can issue:
$ vim --serverlist
or:
:echo serverlist()
But I don't know of any high-level solution to manage separate servers and I have a feeling that it wouldn't be exactly trivial to come up with a solid solution.
Another way to look at your problem would be to selectively unmap all those undesired mappings without messing with the menus.
So yeah… my advice is to find another, more focused workflow.
If you use mvim often but don't want those menu-related mappings you might as well use mvim -v and work directly in your terminal which would almost certainly fix your mappings issue and your "same file opened in several instances" issue in one shot.

Open vim tab in new (GUI) window?

I'd like to move the current tab into a new (visual/real) window in MacVim.
It's probably difficult, as:
there is nothing in the vim help and only very few - not helpful - hits on google
MacVim does not support it (link, 2009)
So I am wondering if someone has found a way to achieve this?
The closest I think you can come is using mksession
This will have several drawbacks (like, initially the secondary session will open a few more buffers than ultimately desired).
However, it will preserve your mappings, settings, history, window layout (if you had multiple windows inside the current tab, they will all get cloned).
If this idea tickles your fancy, you could look at creating a script that will filter parts out of the session file (which is Yust Another Vim Text Script)
:mksession! $HOME/detach.vim
:tabclose
:silent! !gvim remote --servername Detach -nR +'silent! source H:\detach.vim' +tabonly
save all current windows, mappings, settings (:he mksession)
close the tab we are about to detach
clone the session (detach.vim) into a remote vim
:silent! (try not to talk too much)
!gvim remote --servername Detach; launch a new remote Vim server if it doesn't yet exist, or talk to the existing server named Detach
-nR TODO Fix This is here to avoid the use of swapfiles (because I found no way to suppress the dreaded ATTENTION messages[1]). However, this may be unsafe advice depending on your situation, which is why I also include -R for read-only mode
+'silent! source H:\detach.vim' +tabonly -- In the remote vim, source the session to clone, and keep only the active tab (that was already closed in step 1.)
A little rough around the edges, for sure, but quite close to what you intended, I feel.
If you are comfortable, you can drop the -nR flags and just click through a few annoying swapfile attention messages (keyboard: Q).
[1] :he ATTENTION
Post-scripts:
on windows you might want to use :silent! !start /b gvim .... in case you have terminal windows sticking around
also on windows, you might get annoying behaviour if the resulting gvim window is too small. The :simalt ~x sequence is one hacky way to maximize the window (assuming English UI, because x is the accelerator for Maximize)
as icing on the cake, vim 7.3 has 'persistent undo'. See e.g. :se undofile
I don't think this is possible because, when you open a new instance of (g)vim you don't have access to the undo-history of the previous vim instance. All you can do is (in command mode):
:!gvim %
It will open the current file in a new instance of gvim. At least this is all I could think of. I may be wrong

What's the best (Linux-compatible) buffer/session manager for Vim?

Is there a good project / session manager for vim? A session (or project) is a named lists of files, e.g. "bitonic_sort" could identify files "~/A/bitonic_sort.sk", "~/B/bitonic_sort.smt2", etc.
(rationale) I have a project where I need to edit files from many different locations, and it is too cumbersome to open them manually each time I resume work. (so, it looks like things like nerdtree brought up at this sister question, Favorite (G)Vim plugins/scripts?, won't work). I also need separate sessions (i.e. lists of files) for different projects, not just a recent document list.
After all documents have been loaded as buffers, any enhancements to switching between them is a plus (e.g. start typing a name, and matching documents are displayed). Thanks in advance.
Vim has built-in session manager. To save your current session use:
:mks session1.vim
This basically create a Vim script named session1.vim, which will restore your opened file if you source it or start Vim like this:
vim -S session1.vim
To overwrite your saved sessions, use :mks! your_saved_session.vim. Combine with a custom key map and this will be the solution. For more about Vim session read :help :mks. Vim also has views manager which is quite similar. Read more from: :help :mkview
For switching between buffers, you can use FuzzyFinder; but I prefer this key map:
nmap <C-tab> :bn<CR>
imap <C-tab> <ESC>:bn<CR>i
Add it to .vimrc and I can use Ctrl + Tab to switch between buffers just like Firefox tabs. Hope this help.
I'm not sure exactly what you're asking for... but if you want to turn on tab-completion when opening files in vim, add this to your ~/.vimrc:
" Auto-complete file names after <TAB> like bash does.
set wildmode=longest,list
set wildignore=.svn,CVS,*.swp
Also, take a look at screen. From the man page:
When screen is called, it creates a single window with a shell in it (or the specified command) and
then gets out of your way so that you can use the program as you normally would. Then, at any time,
you can create new (full-screen) windows with other programs in them (including more shells), kill
existing windows, view a list of windows, turn output logging on and off, copy-and-paste text between
windows, view the scrollback history, switch between windows in whatever manner you wish, etc. All
windows run their programs completely independent of each other. Programs continue to run when their
window is currently not visible and even when the whole screen session is detached from the user's
terminal. When a program terminates, screen (per default) kills the window that contained it. If
this window was in the foreground, the display switches to the previous window; if none are left,
screen exits.
It's pretty much like having several xterms open, except unlike graphical xterms you can access your screen session if you access your machine remotely (e.g. by sshing to it). You could leave up several different instances of vim in separate screens with all the files you want open, and just never exit them.
The very basic setup I use is one vim window, one compile window, and one testing/debugging window.
And since we're talking about vim, check out this post: Post your Vim config. Lots of cool tweaks and spiffy stuff in there.
You can try the vim-workspace plugin, its session management features are automated and relatively simple (compared to vim-session): https://github.com/thaerkh/vim-workspace

Using Vim's tabs like buffers

I have looked at the ability to use tabs in Vim (with :tabe, :tabnew, etc.) as a replacement for my current practice of having many files open in the same window in hidden buffers.
I would like every distinct file that I have open to always be in its own tab. However, there are some things that get in the way of this. How do I fix these:
When commands like gf and ^] jump to a location in another file, the file opens in a new buffer in the current tab. Is there a way to have all of these sorts of commands open the file in a new tab, or switch to the existing tab with the file if it is already open?
When switching buffers I can use
:b <part of filename><tab>
and it will complete the names of files in existing buffers. <part of filename> can even be the middle of a filename instead of the beginning. Is there an equivalent for switching tabs?
Stop, stop, stop.
This is not how Vim's tabs are designed to be used. In fact, they're misnamed. A better name would be "viewport" or "layout", because that's what a tab is—it's a different layout of windows of all of your existing buffers.
Trying to beat Vim into 1 tab == 1 buffer is an exercise in futility. Vim doesn't know or care and it will not respect it on all commands—in particular, anything that uses the quickfix buffer (:make, :grep, and :helpgrep are the ones that spring to mind) will happily ignore tabs and there's nothing you can do to stop that.
Instead:
:set hidden
If you don't have this set already, then do so. It makes vim work like every other multiple-file editor on the planet. You can have edited buffers that aren't visible in a window somewhere.
Use :bn, :bp, :b #, :b name, and ctrl-6 to switch between buffers. I like ctrl-6 myself (alone it switches to the previously used buffer, or #ctrl-6 switches to buffer number #).
Use :ls to list buffers, or a plugin like MiniBufExpl or BufExplorer.
Bit late to the party here but surprised I didn't see the following in this list:
:tab sball - this opens a new tab for each open buffer.
:help switchbuf - this controls buffer switching behaviour, try :set switchbuf=usetab,newtab. This should mean switching to the existing tab if the buffer is open, or creating a new one if not.
Vim :help window explains the confusion "tabs vs buffers" pretty well.
A buffer is the in-memory text of a file.
A window is a viewport
on a buffer.
A tab page is a collection of windows.
Opening multiple files is achieved in vim with buffers. In other editors (e.g. notepad++) this is done with tabs, so the name tab in vim maybe misleading.
Windows are for the purpose of splitting the workspace and displaying multiple files (buffers) together on one screen. In other editors this could be achieved by opening multiple GUI windows and rearranging them on the desktop.
Finally in this analogy vim's tab pages would correspond to multiple desktops, that is different rearrangements of windows.
As vim help: tab-page explains a tab page can be used, when one wants to temporarily edit a file, but does not want to change anything in the current layout of windows and buffers. In such a case another tab page can be used just for the purpose of editing that particular file.
Of course you have to remember that displaying the same file in many tab pages or windows would result in displaying the same working copy (buffer).
Contrary to some of the other answers here, I say that you can use tabs however you want. vim was designed to be versatile and customizable, rather than forcing you to work according to predefined parameters. We all know how us programmers love to impose our "ethics" on everyone else, so this achievement is certainly a primary feature.
<C-w>gf is the tab equivalent of buffers' gf command. <C-PageUp> and <C-PageDown> will switch between tabs. (In Byobu, these two commands never work for me, but they work outside of Byobu/tmux. Alternatives are gt and gT.) <C-w>T will move the current window to a new tab page.
If you'd prefer that vim use an existing tab if possible, rather than creating a duplicate tab, add :set switchbuf=usetab to your .vimrc file. You can add newtab to the list (:set switchbuf=usetab,newtab) to force QuickFix commands that display compile errors to open in separate tabs. I prefer split instead, which opens the compile errors in a split window.
If you have mouse support enabled with :set mouse=a, you can interact with the tabs by clicking on them. There's also a + button by default that will create a new tab.
For the documentation on tabs, type :help tab-page in normal mode. (After you do that, you can practice moving a window to a tab using <C-w>T.) There's a long list of commands. Some of the window commands have to do with tabs, so you might want to look at that documentation as well via :help windows.
Addition: 2013-12-19
To open multiple files in vim with each file in a separate tab, use vim -p file1 file2 .... If you're like me and always forget to add -p, you can add it at the end, as vim follows the normal command line option parsing rules. Alternatively, you can add a bash alias mapping vim to vim -p.
I ran into the same problem. I wanted tabs to work like buffers and I never quite manage to get them to. The solution that I finally settled on was to make buffers behave like tabs!
Check out the plugin called Mini Buffer Explorer, once installed and configured, you'll be able to work with buffers virtaully the same way as tabs without losing any functionality.
This is an answer for those not familiar with Vim and coming from other text editors (in my case Sublime Text).
I read through all these answers and it still wasn't clear. If you read through them enough things begin to make sense, but it took me hours of going back and forth between questions.
The first thing is, as others have explained:
Tab Pages, sound a lot like tabs, they act like tabs and look a lot like tabs in most other GUI editors, but they're not. I think it's an a bad mental model that was built on in Vim, which unfortunately clouds the extra power that you have within a tab page.
The first description that I understood was from #crenate's answer is that they are the equivalent to multiple desktops. When seen in that regard you'd only ever have a couple of desktops open but have lots of GUI windows open within each one.
I would say they are similar to in other editors/browsers:
Tab groupings
Sublime Text workspaces (i.e. a list of the open files that you have in a project)
When you see them like that you realise the power of them that you can easily group sets of files (buffers) together e.g. your CSS files, your HTML files and your JS files in different tab pages. Which is actually pretty awesome.
Other descriptions that I find confusing
Viewport
This makes no sense to me. A viewport which although it does have a defined dictionary term, I've only heard referring to Vim windows in the :help window doc. Viewport is not a term I've ever heard with regards to editors like Sublime Text, Visual Studio, Atom, Notepad++. In fact I'd never heard about it for Vim until I started to try using tab pages.
If you view tab pages like multiple desktops, then referring to a desktop as a single window seems odd.
Workspaces
This possibly makes more sense, the dictionary definition is:
A memory storage facility for temporary use.
So it's like a place where you store a group of buffers.
I didn't initially sound like Sublime Text's concept of a workspace which is a list of all the files that you have open in your project:
the sublime-workspace file, which contains user specific data, such as the open files and the modifications to each.
However thinking about it more, this does actually agree. If you regard a Vim tab page like a Sublime Text project, then it would seem odd to have just one file open in each project and keep switching between projects. Hence why using a tab page to have open only one file is odd.
Collection of windows
The :help window refers to tab pages this way. Plus numerous other answers use the same concept. However until you get your head around what a vim window is, then that's not much use, like building a castle on sand.
As I referred to above, a vim window is the same as a viewport and quiet excellently explained in this linux.com article:
A really useful feature in Vim is the ability to split the viewable area between one or more files, or just to split the window to view two bits of the same file more easily. The Vim documentation refers to this as a viewport or window, interchangeably.
You may already be familiar with this feature if you've ever used Vim's help feature by using :help topic or pressing the F1 key. When you enter help, Vim splits the viewport and opens the help documentation in the top viewport, leaving your document open in the bottom viewport.
I find it odd that a tab page is referred to as a collection of windows instead of a collection of buffers. But I guess you can have two separate tab pages open each with multiple windows all pointing at the same buffer, at least that's what I understand so far.
You can map commands that normally manipulate buffers to manipulate tabs, as I've done with gf in my .vimrc:
map gf :tabe <cfile><CR>
I'm sure you can do the same with [^
I don't think vim supports this for tabs (yet). I use gt and gT to move to the next and previous tabs, respectively. You can also use Ngt, where N is the tab number. One peeve I have is that, by default, the tab number is not displayed in the tab line. To fix this, I put a couple functions at the end of my .vimrc file (I didn't paste here because it's long and didn't format correctly).
I use buffers like tabs, using the BufExplorer plugin and a few macros:
" CTRL+b opens the buffer list
map <C-b> <esc>:BufExplorer<cr>
" gz in command mode closes the current buffer
map gz :bdelete<cr>
" g[bB] in command mode switch to the next/prev. buffer
map gb :bnext<cr>
map gB :bprev<cr>
With BufExplorer you don't have a tab bar at the top, but on the other hand it saves space on your screen, plus you can have an infinite number of files/buffers open and the buffer list is searchable...
Looking at
:help tabs
it doesn't look like vim wants to work the way you do...
Buffers are shared across tabs, so it doesn't seem possible to lock a given buffer to appear only on a certain tab.
It's a good idea, though.
You could probably get the effect you want by using a terminal that supports tabs, like multi-gnome-terminal, then running vim instances in each terminal tab. Not perfect, though...
If you want buffers to work like tabs, check out the tabline plugin.
That uses a single window, and adds a line on the top to simulate the tabs (just showing the list of buffers). This came out a long time ago when tabs were only supported in GVim but not in the command line vim. Since it is only operating with buffers, everything integrates well with the rest of vim.
relevant:
Vim: can global marks switch tabs instead of the file in the current tab?
maybe useful to solve a little part of OP's problem:
nno \ <Cmd>call To_global_mark()<cr>
fun! To_global_mark()
-tab drop /tmp/useless.md
exe 'normal! `' .. toupper(input("To global mark: "))
endf

Resources