How to automatically name a file when saving in vim - vim

I'm trying to emulate in vim a behaviour similar to that of TextEdit.app.
As I work I often open a lot of files to take notes, and keep them there without saving them. When I restart the laptop, the TextEdit files will still be there and open thanks to AutoSave. If I do the same thing with vim (specifically MacVim) the files are (as expected) not saved and I lose their content.
My recipe for solving this problem has two bits. The first one is to automatically save the files when I'm not using them, so using a command like:
autocmd BufLeave,FocusLost * silent! wall
This works fine with files that have already been saved, but it ignores ones that have not yet been saved. This is where the second bit comes into play, I would like vim to automatically give these files a default name if it tries to save them and they don't already have a name. Possibly I would also like there to be a default save directory.
The ideal solution would be that when an unnamed file/buffer loses focus it gets saved as ~/Documents/notes/note_1.txt, the second one note_2.txt, etc etc.
I did look around for any pointers that could help in either direction (default name and default directory - the latter is not fundamental though), but couldn't find anything.
Can anybody help?

I don't like your idea, but it is doable.
You need a function:
function! SaveIt()
if bufname("%")==''
exec 'w /path/note_'.localtime()
else
w
endif
endfunction
and in your autocommand, just call the function. Some points you need to note:
the filename would be /path/note_( ms since 1970). your 1,2,3.. index will make vim check filesystem to find out the index. It could be a better name, e.g note_2013-09-11_11:11:11.233 You just change the localtime()
this may throw exception when you try to save a readonly buffer. (help, qf ...) You could check for them though.
Note that I didn't add the ! in w cmd.
it may not work for your autocmd wall. if you want to do it, you have to loop through all buffers, and for each buffer call the function.
after all the function shows the direction how it could be done, it (the quality) is still very far away from "production" level.

Related

How to save buffer (preferably if changed) and then close the buffer but not VIM?

So, I just realized I could use marks with capital letters to go to different files. That's great! However, I'm trying to find a way to close the buffer and return to the previous one. Say I go to my header file to change or add the declaration of the function I'm writing, and then I'd like to save the file, but only if there's changes to it, to go back to working on the contents of the function. How can I do this?
There's :x, but it also quits VIM
There's :bd!, but it doesnt save the changes
There's :bw, but that's even worse (unfortunately that's w[ipeout], not w[rite]...)
There's ctrl+O, but it doesnt seem to work when I edit the file (also, it doesnt actually close the buffer)
There's :up followed by :bd, but that's two commands and VIM's about efficiency, so I'd prefer a single command if it exists
There's a few other options and variants, but none that do what I wanted, afaik
It feels like this should be simple enough to do with one command, preferably without macros/plugins/functions/snippets/etc; as close to vanilla as possible. I get the feeling I'm missing something obvious.
You could concatenate commands like so:
:w|bd
I'd like to save the file, but only if there's changes to it
:up[date]
to go back to working on the contents of the function
Press Ctrl^, or enter the command :e[dit] #
I'd prefer a single command if it exists
Set an option :set autowrite and then Vim will save the current buffer on pressing Ctrl^ automatically.

Vim long file paths break/split over multiple lines in quickfix window

A long file paths is broken up over multiple lines in the Vim quickfix window which then for example does not allow to jump to the error location displayed in the qf.
The file (and the lines around) are diplayed in the quickfix window as (the example is the output from neomakes pdflatex)
|| Enter file name:
|| /long/path/to/file/.../loca
tionOfTexFiles/myTexFile.tex|144 error| Emergency stop.
|| read
to be able to follow to the file line by lnext/cnext I should have
/long/path/to/file/.../locationOfTexFiles/myTexFile.tex|144 error| Emergency stop.
For quickfix files I have the following relevant (in my view) settings which are set to:
setlocal nolinebreak
setlocal nowrap
setlocal textwidth=9999
So I am wondering how I can display the file path in one line within the quickfix window?
On :make, Vim invokes 'makeprg', captures the output, and then parses it according to 'errorformat'. The latter does support multi-line error messages (cp. :help errorformat-multi-line), but that is mostly for what I would call intentional linebreaks, as specified by the compiler. What you suffer from is unintentional linebreaks because of line wrapping (due to overly long paths).
Now, I don't know about "neomakes pdflatex", but it looks like that tool creates the linebreaks, whereas it shouldn't, as Vim is capturing the output, and there's no receiving terminal (or user). Investigating in that direction (or opening an issue at the project's tracker) might be helpful.
The mentioned Vim options ('linebreak', 'wrap', etc.) have nothing to do with it. They apply to normal buffers; the quickfix buffer as such is not modifiable.
Workarounds
A possible workaround might be to :cd first to a directory that is "closer" to the processed files (or even :set autochdir); this might avoid the long paths in the output.
Alternatively, you may "unmangle" the output by adding a sed stage after the compiler:
let &makeprg .= "| sed -e 's/.../...'"
If I'm not mistaken, the issue is on pdflatex side. The || mark is a good indication: you'll have one per output line -- in case filename and/or lines numbers are recognized, they'll be fed in between the bars.
So. This means you'll need a way to fix the path names. It'll be better to do it outside vim. I'm not saying this is trivial. I'm just saying that if you can have a program able to fix pdflatex outputs, you'll just be one pipe away from the solution (plus a correct forwarding of error codes...).
If you prefer to implement it in vim script, this is possible. But you'll experience side-effects. In my BuildToolsWrapper plugin I'm able to post-process compilation output in vim side, but the result is far from being perfect. I'm working on getqflist() result, and parse each line. When I found a line where I want to fix the filename, it's not simply about fixing the filename but also about assigning a valid buffer number to it. See this function where I can replace a filename with another one. The magic happens where lh#buffer#get_nr() is used. Still you'd need to implement a vim script able to merge split filenames.
IOW: my understanding is that vim is not involved. It could be used to fix the issue, but IMO this is not the easier path to undertake.

Making AutoComplPop search entire project (or open buffers)?

I started using AutoComplPop for automatic code completions. It works great on the single file I am editing, but if file1 is making a reference to a method defined in file2, it doesn't find it.
The docs don't specify if there is a way to make it search a whole project directory, or even just all open buffers, so I can't tell if this is simply not something the plugin does, or if I need to enable something.
I was testing it out on two Ruby files, if that's relevant. Thanks!
Looks like that the cause of the problem is that ACP set the complete option for its purposes to .,w,b,k (see line #125 in autocomplpop/plugin/acp.vim),
call l9#defineVariableDefault('g:acp_completeOption', '.,w,b,k')
while the default value that is used when pressing \<C-n> is .,w,b,u,t,i. And it appears that the very last letter i actually makes the difference: for some reason vim would not use word from an include file opened in a buffer to complete words in another buffer. So, b option is not enough, i must also be included. Adding the following line into my .vimrc helped
let g:acp_completeOption = '.,w,b,u,t,i'
At least it worked for C++ files, but I'm not sure it fixes the problem for the case of Ruby scripts.
Depending on what is on the left of the cursor, ACP (like all the alternatives) decides what completion mechanism to use.
But ACP only uses Vim's default completion mechanisms: if <C-x><C-o> and <C-n>/<C-p> don't provide what you are looking for, ACP won't help. Try them out first.
Oh cool, this plugin looks a lot like neocomplcache but maybe cleaner...looks a little old. Little concerning that there are so many open tickets on that project and no updates in two years.
Anyway, according to the documentation it doesn't...really...say. Very likely its one of the following things:
Your pwd. If the root directory for your source is some/path then that should also be your current working directory. Try typing :cd some/path to see if that makes a difference.
The runtime path rtp. See if adding the directory with your source files to &rtp does the trick.
The path. Same deal as the &rtp setting.
Very likely this plugin is just falling back on the built in ruby omni completion functions bundled with vim. Try help ft-ruby-omni.
I just had the same problem, and I actually found a solution for this.
Apparently you have to set in your .vimrc file the following:
let g:acp_behaviorKeywordCommand = "\<C-x>\<C-i>"
This will make acp look in every file included by your source for completions, as if you were actually typing <C-p>. However, it is slow, after trying it I decided to revert using <C-p> when there are no matches and default behaviour in the other cases.

Ragtag apparently not working?

I am currently trying to use ragtag to close some of my html tags in ERB files. However, pressing something like (C-X)/ (which I interpret to be , "CONTROL" + "uppercase X" + "/") it just prints the / to the buffer. Any ideas?
Make sure you're in the correct mode. The (Ctrl-X) key mappings of ragtag.vim only work in "insert" mode, which is a bit non-intuitive since most text manipulation in Vim is done in "normal" mode.
First, make sure in your .vimrc file, you have the line
let g:ragtag_global_maps = 1
This gives you access to the ragtag key mappings as in <C-X>/ or <C-X><space>
Next, be sure to note that the available ragtag functions available to you depends on the type of file you're in. For instance, when you're in a standard .rb file, you only get a few features, whereas if you open an erb file, you get all the goodies.
Hope that helps.
Try modifying timeoutlen and ttimeoutlen to something bigger, or delete any lines you have set in your .vimrc. The default value should be sufficient for ragtag to work.

what function does vim call for completion with ctrl-n

My vim is throwing nasty errors 50% of the time when I use ctrl-n for completion
E854: path too long for completion
I really want to remap this, and call it with the :silent option to suppress the error, but I have no idea what function provides completion, so I can't remap it.
So my question is where can I find exactly what C-N calls when it is invoked in insert mode
Solution:
As mentioned in the comment on my accepted answer I found a way round this. Based off the instructions on building your own vim here : brilliantcorners.org/2011/02/building-vim-on-osx-snow-leopard
I grepped the source directory for E854 and it only comes up in 1 file. If you open that file you see it is only referenced twice. I just removed those error calls and built vim
This doesn't solve whatever the actual problem is, but it's the same effect as doing ignore. It works great now and doesn't throw any errors, I hope anyone else with this problem is helped by this.
In insert mode, <C-n> usually completes words with the content of your buffers. I don't know how it works internally but it may complain about a buffer's associated file's path length.
But I can't find a reference to E854 in Vim's :help, which can be normal if it comes from a plugin I don't have.
You could:
try :verbose imap <c-n> to locate its origin or
search the help for the tag E854, :help E854 or
search the help for the sting E854, :helpgrep E854 or
grep for E854 in your ~/.vim folder, $ grep -r E854 ~/.vim.
I had an issue like this similar. Turns out it was blowing up because the current ruby.vim that's distributed with Vim calls a deprecated Gem.all_load_paths which puts a nasty error in your path variable. Check out https://github.com/rubygems/rubygems/issues/161 and https://groups.google.com/forum/#!msg/vim_dev/wrouKpIDraU/xLxUuMT3_6QJ for a fix :)
My copy of the vim source code (obtained at some point using Mercurial and hg clone https://vim.googlecode.com/hg/) finds that error being thrown only in one spot, in the internal function vim_findfile_init():
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
...
/*
* copy wc_path and add restricts to the '**' wildcard.
* The octet after a '**' is used as a (binary) counter.
* So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
* or '**76' is transposed to '**N'( 'N' is ASCII value 76).
* For EBCDIC you get different character values.
* If no restrict is given after '**' the default is used.
* Due to this technique the path looks awful if you print it as a
* string.
*/
len = 0;
while (*wc_part != NUL)
{
if (len + 5 >= MAXPATHL)
{
EMSG(_(e_pathtoolong));
break;
}
...
So it looks like it's doing arbitrary-depth wildcard expansion. If I had to take a wild stab I'd say you have a path somewhere in the filesystem that has a circular symbolic link (say c -> a), so you end up doing path completion and getting /foo/bar/a/b/c/a/b/c/a/b/c/a/b/c/..... and the limit gets hit.
Edit
Scratch that last theory; based on actually reading the code, it looks like it's trying to find a tag file and blowing up. Can you post what you get when you do :set tags ?
Edit 2
Sigh, it's late... Here's the answer you originally wanted that I just found: do :help completefunc and :help completion-functions. completefunc is the one you want, if I (finally) understand your question.

Resources