tpope / vim-rails

rails.vim: Ruby on Rails power tools
http://www.vim.org/scripts/script.php?script_id=1567
4.1k stars 383 forks source link

Create alternate or relative file if it's not found command #503

Open sadovnik opened 6 years ago

sadovnik commented 6 years ago

Hello!

Is there any command I can use to create an alternate or relative file if it's not created yet? If there isn't, it would be cool if you add some :A! command or something which will behave similar to :Emodel user!.

juanibiapina commented 6 years ago

This works with vim-projectionist already. I'm currently looking for an easy way to disabled alternation on vim-rails only.

tpope commented 6 years ago

There's an experimental feature where it will prompt you for the file to create with :set confirm.

tap349 commented 6 years ago

after updating the plugin set confirm no longer works :(

E345: Can't find file "<spec_file_path>" in path

UPDATE: this is because I created new Rails project with --no-skip-test which creates test directory instead of spec one. after renaming test to spec creating alternate file works as usual )

Mehonoshin commented 6 years ago

Any news about this feature?

tap349 commented 6 years ago

@Mehonoshin Even though Tim Pope says it's an experimental feature, :set confirm works for me (and it's been around for about 2 years already).

tpope commented 6 years ago

Yeah it does still work, but only for things defined as projections (which can be confusing, and why I still consider it experimental).

igbanam commented 5 years ago

I could understand that using :A could be some sort of magic if this file is not around.

Could this be a new command, like :C, which would require the explicit "projection"? — p.s: I do not know much about projections and projectionist, so if I am using this wrongly here, please correct me.

I was thinking the following :Cmodel car — creates a file at app/models/car.rb :Cspec models/car — creates a file at spec/models/car_spec.rb :Ccontroller :Clayout :Cview cars/index — creates a file at app/views/cars/index.html.erb

…and so on

chalmagean commented 4 years ago

I'd also to see this working. It's very useful to be able to create missing spec files, especially for long file names.

take commented 4 years ago

looks like #135 is related

bmulholland commented 3 years ago

I don't really care about what command does this, I just want to auto-create the spec - especially because I often make typos when creating those files (e.g. forgetting _spec).

I'm using a spec folder and :set confirm doesn't seem to work; when I try, I get the same E345 as before. That appears to be because the projection only goes in one direction, so a file in app can be created from a file in spec, but not vice versa.

Looks like this is something supported in vim-projectionist, but the vim-rails code is just too old to add it (and that was written 6 years ago!). Maybe someone will write a fresh code base now that Neovim is re-vitalizing things?

For now, seems like the only way to auto-create a spec is to add the projectionist plugin. I'm moving on to other work today, and will update with some setup steps & config if I get around to adding projectionist.

Writing out my debug steps here in case it helps others:

  1. Check :echo rails#buffer().alternate_candidates() - does it return a path?
  2. Does the folder structure in that path exist?
  3. Is there a projection for it?
  4. Is the projection in the correct direction?
otavioschwanck commented 2 years ago

i know this issue is old, but ill share my setup for this:

function OpenTestAlternateAndSplit()
  let win_count = winnr()
  let test_path = eval('rails#buffer().alternate()')

  execute "normal! \<C-w>o"

  execute "norm \<C-w>v"

  execute "call OpenTestAlternate()"

  if test_path =~ 'app/'
    execute "norm \<C-w>x"
  endif
endfunction

function OpenTestAlternate()
  let test_path = eval('rails#buffer().alternate()')

  execute "e " . test_path

  if !filereadable(test_path) && join(getline(1,'$'), "\n") == ''
    if test_path =~ "spec/"
      execute "norm itemplate_test\<Tab>"
    else
      execute "norm iminitest\<Tab>"
    endif
  endif
endfunction

nmap <leader>a :call OpenTestAlternate()<CR>
nmap <leader>A :call OpenTestAlternateAndSplit()<CR>

If you create an snippet called template_test for rspec and minitest for minitest, it automatically will expand a snippet for you.

To remove this behaviour, just remove this part:

  if !filereadable(test_path) && join(getline(1,'$'), "\n") == ''
    if test_path =~ "spec/"
      execute "norm itemplate_test\<Tab>"
    else
      execute "norm iminitest\<Tab>"
    endif
  endif

The snippets (Ultisnips format):

snippet minitest "minitest spec file" i
require 'test_helper'

class ${1:ClassName} < ActiveSupport::TestCase
  $0
end
endsnippet

snippet template_test "Rspec.describe Class, type: :model do ... end"
require 'rails_helper'

RSpec.describe ${1:Class}, type: :${2:model} do
  $0
end
endsnippet
davidsilveira commented 2 years ago

@otavioschwanck this code is very useful.

styrmis commented 2 years ago

I just wanted to have something incredibly basic, to avoid typing/typos when the alternate file didn't exist, so I have defined a single command in my vimrc:

command AC :execute "e " . eval('rails#buffer().alternate()')

So when :A complains about the file not existing, I run :AC and continue work from there.

jiz4oh commented 1 year ago
function! s:ac() abort
  let pre = &confirm
  try
    set confirm
    A
  finally
    let &confirm = pre
  endtry
endfunction

command! AC :call <SID>ac()

I defined this for myself