How to debug broken vim completefunc in haml files? - ruby-on-rails

I'm using rails.vim and I love how you can use ctrl-x ctrl-u in insert mode to autocomplete long method names like distance_of_time_in_words and accepts_nested_attributes_for. But for some reason it doesn't work in haml files and I can't seem to figure out what's wrong or how to fix it.
:help i_CTRL-X_CTRL-U says the autocompletion is using completefunc. The haml file says its completefunc=syntaxcomplete#Complete (and it's the same in erb and helper files where ctrl-x ctrl-u works fine.) I can't find where the syntaxcomplete#Complete magic is defined, but presumably it has something to do with the filetype syntax. My .vim/syntax/haml.vim comes from vim-haml, so I tried removing it but the problem persists.
Commenting out my entire .vimrc didn't help either. What else can I try?
UPDATE: I searched my vim config files and the only place that looks like it's doing anything with syntaxcomplete#Complete is in autoload/rails.vim and looks like this:
function! s:resetomnicomplete()
if exists("+completefunc") && &completefunc == 'syntaxcomplete#Complete'
if exists("g:loaded_syntax_completion")
" Ugly but necessary, until we have our own completion
unlet g:loaded_syntax_completion
silent! delfunction syntaxcomplete#Complete
endif
endif
endfunction

Functions with # in name are defined in autoload scripts:
A function that can be autoloaded has a name
like this:
:call filename#funcname()
When such a function is called, and it is not defined yet, Vim will search the
"autoload" directories in 'runtimepath' for a script file called
"filename.vim". For example "~/.vim/autoload/filename.vim".
See :help autoload.

Looks like the file you're looking for is part of vim:
$ find /usr/share/vim/ -iname "syntaxcomplete.vim"
/usr/share/vim/vim72/autoload/syntaxcomplete.vim
There's a vim.org page with the latest version of the script.
If you want to customize the completion, you can just write your own completion function. See :help complete-functions
You can also use Ctrl+n to use vim's simple completion. It completes with text from any of the open files, but can be customized. (See :help 'complete')

Related

ocaml: Is there an environment variable to set the search path for #use and #load?

I've been wondering, if there is an environment variable to set the search path for #use and #load for the ocaml toplevel.
What I think I know so far:
I can use findlib instead of "raw" #use and #load. findlib looks at some environment variables for the search path.
I can set a search path with -I.
Experiments seem to indicate that CAML_LD_LIBRARY_PATH does not influence #use (script loading) and #load (byte code file loading).
(updated) I can use #directory to add the desired path - but unfortunately this only takes a string literal, so i can't pass something I read from the environment at run time. (Update: I forgot to mention #directory originally and why it doesn't fit my use case).
What I want to do:
Run ocaml programs as scripts
Point ocaml to script libraries and script fragments with an environment variable
Avoid, in some scenarios, to create a full findlib library.
Presently I'm not using ocaml as interpreter, but a wrapper that adds a path to the invocation. I want to avoid the wrapper.
(I hope the questions makes sense now, after you know my use case)
So: Is there an environment variable to set the search path for #use and #load without resorting to a wrapper?
More Details
What I'm currently doing:
#!/usr/bin/env oscript2
#use "MyScript"
#load "SomeModule.cmo"
(* ... more ocaml *)
oscript2 is a wrapper around ocaml that basically sets the search paths for #use and #load, but finally executes the toplevel ocaml withe something like
exec ocaml -I .... ...some-byte-code-modules... "$#"
MyScript and SomeModule.cmo live outside of the "normal" Ocaml search path. The actual location might change, but after login (and working through the profie scripts) there is an environment variable (today it's OSCRIPTLOAD_PATH) that tells me, where alle loadable byte code and ocaml script files might live.
This works well, a variant of that setup has been in use for years (at least 7).
The one thing that bothers me there, is: The wrapper, the simple fact of it's presence, looks homebrew, so I'd like to avoid it, to make a better impression on potential future users of the script collection. What I'd like to do
#!/usr/bin/env ocaml
#use "MyScript"
#load "SomeModule.cmo"
(* ... more ocaml *)
and have ocaml itself pick up the search path from some environment variable (I'm free to change the variable name, that is under my control, but I don't want to install script and byte code libs into the default search path, and, as already stated, I' asking if I can do that without findlib).
Basically (as already stated at the very beginning) I'm looking for an environment variable that controls the search path for #use and #load. I'm not looking for toplevel directives and not for wrappers that retrofit this feature. (Thanks everyone for those suggestions, but unfortunately I've already gone that road, it's feasible, but here I'm looking for an alternative purely for cosmetic reasons).
Recent research didn't bring up that such a variable exists, but I thought I'd be asking here, before giving up on it.
From inside the OCaml toplevel you can use the #directory "foo";; primitive to add an include directory.
Here's a shell script that runs the OCaml toplevel while adding a directory to the search path taken from an environment variable named EXTRA_OCAML_DIR.
#!/bin/sh
ocaml -I "$EXTRA_OCAML_DIR" "$#"
If you run this instead of ocaml, you will have a directory in the load path specified by an environment variable.
It seems a little obvious, but maybe it will spark an idea that is more helpful.

[perl]How to force perl use modules in my own path?

I want to let perl use the DBI module in my own path(suppose, /home/users/zdd/perl5/lib/DBI), but the sysem also has a DBI module which is /usr/lib/perl5/lib/DBI.
when I write the following code in my script, perl use the system path be default, how to force it use the one under my path?
use lib './perl5/lib/DBI';
use DBI;
sub test {
....
}
/usr/lib/perl5/lib/DBI was added to the PATH environment variable in my bash profile, it was used by many scripts, so I can't disable it.
The file for the main DBI module is in ./perl5/lib. So your path is not pointing to it.
The DBI folder contains sub-modules of DBI, e.g. DBI::Foo (the :: in module names is a representation of your module directory structure).
Try using ./perl5/lib as your library instead.
Also, using a relative path will fail if the current directory is not what you think it is. If you are in doubt, have your script call cwd to see what the current directory is.
For debugging purposes, it may be helpful to use:
no lib '[main Perl module library path here]';
That way you can be sure you are only using your custom module path. Any failure to find a module will cause an error, rather than silently using the system version.
Update: For more information, see Perldoc on use lib. Perl will use the library that you have specified first. If it does not, that indicates it is not actually finding the module in the location you have given.
In addition to what dan1111 suggested, I would also recommend you print out #INC (just before your use DBI statement) and dump %INC (just after your use DBI statement) to see what your script is doing. That may help you debug the issue.

Vim E854: path too long for completion

I have a Rails RSpec file which looks something like
require 'spec_helper'
describe "Something" do
...
end
When I try to use Ctrl+N to autocomplete anything in that file, I get:
Text version:
Scanning included file: spec_helper.rb
E854: path too long for completion
Press ENTER or type command to continue
If I Ctrl+C this, it completes my word perfectly.
To avoid Vim to autocomplete by using included files I can do:
:set complete-=i
But that's not the root of the issue.
How can I fix this?
Ok,
It results that I am using MacVim, and like romainl commented in the original post, the issue is related to a bug in ruby.vim. In this Stack Overflow post the third answer candidate actually suggests a possible cause (correctly), which is related to a bug in ruby.vim ( an old version is using a deprecated function ).
MacVim (Snapshot 64) is supplied with the old rails.vim, so to fix this I went into MacVim.app/Contents/Resources/vim/runtime/ftplugin and did wget to the raw file in the official rails.vim plug-in repo
This fixed the issue for me.

In rails.vim why do I get "E345 can't find file in path" errors?

I've been learning Ruby/Rails with vim. Tim Pope's rails.vim seems like a really good tool to traverse files with, but I keep getting these pesky "E345 can't find file in path" errors. I'm not vim expert yet, so the solution isn't obvious. Additionally, I've tried this and it doesn't apply to my problem.
As an example of the problem. I have a method format_name defined in app/helpers/application_helper.rb and it is used in app/helpers/messages_helper.rb. Within the latter file I put my cursor over the usage of format_name and then hit gf and I get that error. Similar disfunction with commands like ]f and [f
However, it works sometimes. I was able to gf from user to the app/models/user.rb
Ideas?
I think that is a limitation of rails.vim. It does not support “finding” bare methods. Supporting something like that would require one of the following:
an exhaustive search of all the source files for each “find” request
(which could be expensive with large projects),
“dumb” indexing of method names
(e.g. Exuberant Ctags and gControl-]; see :help g_CTRL-]), or
smart enough parsing of the code to make a good guess where the method might be defined
(which is hard to do properly).
If you know where the method is, you can extend many of the navigation commands with a method name:
:Rhelper application#format_name
But, you do not have to type all of that in. Assuming the cursor is on format_name you can probably just type:RhTabspaceappTab#Control-R Control-W (see :help c_CTRL-R_CTRL-W).

Vim html.erb snippets?? snipMate Need a vim tip

When I'm in an html.erb file, I get no snipMate snippets.
I would like both HTML and Ruby, or just HTML would be fine,
How would I do this?
Would I need to write a set of snippets?
If so, is there a way of pulling in existing snippets without copying them?
Is there a way of telling vim to go into html mode when it sees .html erb?
You can use an autocmd to set the filetype to html when opening a ".html.erb" file. This could have unwanted side effects for plugins that work for ".erb" files.
autocmd BufNewFile,BufRead *.html.erb set filetype=html
You can also load more than one set of snippets by using a dotted filetype:
autocmd BufNewFile,BufRead *.html.erb set filetype=html.eruby
See :help snippet-syntax in the snipMate help for more info.
Snippets are stored in directory called snippets somewhere in your ~/.vim folder.
If you look there, there is usually one file per filetype, there is a c.snippets, a ruby.snippets, so it seems what you have to do is to create an erb.snippets there with what you want.
Eventually you could copy the content of ruby.snippets and html.snippets into your new erb.snippets.
Alternatively you can search on github, some people have posted their own erb.snippets configuration. For example, there is a nice collection there :
https://github.com/scrooloose/snipmate-snippets
The best thing would to try first to open a snippet file and look at the syntax, it is pretty easy to create your own snippet depending on what you use the most.
I am currently on a promoting tour for UltiSnips on StackOverflow. UltiSnips supports extending other file types, your erb.snippets would look like this:
extends html, ruby, rails
snippet temp "A snippet only in Erb"
erb rules ${1}
endsnippet
A conversion script for snipMate snippets is shipped with UltiSnips, so switching is easy.
I used the autocommand method to the set the filetype, but then I got html syntax errors for things like this:
<%= image_tag("logo.png", :alt => "Sample App", :class => "round") %>
The last two angle brackets would be highlighted in red, which drove me bonkers. So, I created a symlink called eruby.snippets that points to html.snippets. That worked like a champ and now I don't have to make changes in two places. I also have an eruby-rails snippet directory for non-html eruby snippets.
This is on a Mac OS X system. Note that an alias won't work. You need to hit the terminal and use the ln command. Not sure about doing this on a Windoze system.
You can assign multiple snippets scopes to a single filetype. (I've found that altering the filetype tends to break some syntax highlighting).
You can check that the filetype for erb files is indeed 'eruby' with:
:set filetype?
If you're using the maintained fork of snipmate, it looks like you'll want both the eruby.snippets and eruby-rails.snippets from the snipmate-snippets repository (owned by honza, but I don't have enough reputation to link to it here) (see the INSTALL section of the snipmate README for proper setup).
If you are using the maintained fork, I believe setting g:snipMate.scope_aliases in your .vimrc with the following will work for your example:
let g:snipMate = {}
let g:snipMate.scope_aliases = {}
let g:snipMate.scope_aliases['eruby'] = 'eruby,eruby-rails'
I've added a pull request to snipmate to have their documentation updated.
Jumping on the UltiSnips bandwagon after trying SnipMate for a while. Like SirVer mentioned, having the html, ruby, etc snippets available within an *.erb file was as simple as adding the extend line to the eruby.snippets file.
With the original snipMate plugin, create a file ~/.vim/ftplugin/erb_snippets.vim and put the following into it:
silent call ExtractSnipsFile(g:snippets_dir . 'html.snippets', &l:filetype)
silent call ExtractSnipsFile(g:snippets_dir . 'ruby.snippets', &l:filetype)

Resources