4

Recently I've started up with vuejs and I'm currently trying to set up my editor for using it. Vue uses a similar approach with React - keeping the HTML, Javascript & CSS in the same file - it does so by marking the various chunks of code with some XML tags. I'd like to change the filetype based on area of the file that I'm currently editing.

Long story short, given the anatomy of a .vue, file what I'd like to do is:

<template>
  <!-- 
    when the cursor is here, execute 
    :set ft=html
  -->
</template>

<script>
  /**
   * when the cursor is here, execute
   * :set ft=javascript
   */
</script>

<style>
  /**
   * when the cursor is here, execute
   * :set ft=css
   */
</style>

I know there's a plugin called vim-vue, which is awesome, but it only changes the syntax for correct highlighting, and I would like to change the filetype, so all other plugins (autocomplete with ternjs for javascript, linters, multi-line commenters, etc.) to work correctly in their respective areas.

I have to avenues of attacking this:

  1. using the aforementioned plugin and somehow monitor for changes of the syntax and update the filetype accordingly. AFAIK vim does not trigger an event when the syntax is changed.
  2. have something similar with syntax region but for filetype

But so far I could not find a solution. Any suggestions are welcome.

PS: I use neovim in CLI mode, but I don't think that's particularly relevant.

5

1 Answer 1

6

Regarding the proposal and links provided in comments you could define a function as follow:

function! s:setFileType()
  if searchpair('<script', '', '</script>', 'bnW')
    set ft=javascript
  elseif searchpair('<style', '', '</style>', 'bnW')
    set ft=css
  else
    set ft=html
endfunction

and bind it to CursorMoved autocommand in vue files:

augroup vueBinds
  au!
  au CursorMoved,CursorMovedI *.vue call s:setFileType()
augroup END

Now every time you cursor is moving in vue files base on where it is ( in between (<script,</script> or <style,</style> and ...) it sets the desired filetype and act as it.

But this approach has some major drawbacks:

  • syntax highlighting get disrupted every time you change the filetype
  • You missed your linters because linters normally check against the entire buffer
  • buffer local configurations remains active when you change filetype so you'll face some editing problems
  • and ...

Well, we can use a vue-linter(Does this ever exist?), confine beautifiers to regions, use more and more plugins But wait! Doesn't we done all of this for html, css, js and ... and all we're going to write is html, css, js code?!

So what's the solution. How can someone edit a filetype in another filetype with all the features of that filetype include: ftplugins, completions, linters, beautifiers and ...

All we need is a syntax-highlighting plugin and a feature called Narrowing the buffer!

vim-vue does highlighting But what about Narrowing?! Fortunately @Christian Brabandt has gracefully brings this emacs feature to vim throught: NrrwRgn plugin

Using this plugin and this tip from it's documentation you could choose to open region with desired filetype. for example in vue files you could visual select your script region and type:

:'<,'>NN javascript

command. it will open region and you could edit it with full javascript filetypes power.

Read Its Documentation and fine tune it to your needs.

1
  • Awesome answer, cheers mate!
    – motanelu
    Jan 2, 2017 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.