vim-rails icon indicating copy to clipboard operation
vim-rails copied to clipboard

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

Open sadovnik opened this issue 7 years ago • 14 comments

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!.

sadovnik avatar Nov 26 '17 15:11 sadovnik

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

juanibiapina avatar Mar 15 '18 10:03 juanibiapina

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

tpope avatar Mar 15 '18 16:03 tpope

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 )

tap349 avatar May 08 '18 09:05 tap349

Any news about this feature?

Mehonoshin avatar Jun 11 '18 08:06 Mehonoshin

@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).

tap349 avatar Jun 11 '18 19:06 tap349

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

tpope avatar Jun 11 '18 20:06 tpope

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

igbanam avatar Mar 09 '19 11:03 igbanam

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

chalmagean avatar Mar 11 '20 08:03 chalmagean

looks like #135 is related

take avatar Apr 02 '20 06:04 take

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?

bmulholland avatar May 18 '21 10:05 bmulholland

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

otavioschwanck avatar Mar 21 '22 02:03 otavioschwanck

@otavioschwanck this code is very useful.

davidsilveira avatar Apr 13 '22 09:04 davidsilveira

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.

styrmis avatar Jun 17 '22 13:06 styrmis

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

jiz4oh avatar Nov 03 '22 03:11 jiz4oh