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

Smart tab completion not working

Open mattijsbliek opened this issue 9 years ago • 19 comments

I have smart tab completion enabled with the following line: imap <expr> <tab> emmet#expandAbbrIntelligent("\<tab>")

But if I type something Emmet doesn't recognise, for example whatever<tab> it expands it to:

whatever {

}

This prevents me from autocompleting my classes and mixins. Is this expected behaviour?

mattijsbliek avatar Aug 08 '14 09:08 mattijsbliek

What is your expected?

mattn avatar Aug 08 '14 09:08 mattn

That it Emmet ignores it and lets Vim autocomplete it. I think there's two cases, the first being something like this:

.selector {
  @include mixin-name();
}
.other-selector {
  @include mi<tab>
}

I would like Emmet to ignore this so Vim can autocomplete it to mixin-name.

The other case might not be a good default, but would work as a setting I think:

.block {}
.bl<tab>

I would rather have Vim autocomplete this to .block then have Emmet expand it to:

.bl {

}

But again this might be personal preference.

mattijsbliek avatar Aug 08 '14 10:08 mattijsbliek

I'm thinking it's not a task of emmet-vim. For example

.block-left {}
.block-right {}
.bl<tab>

Which you expect? Show candidates?

mattn avatar Aug 08 '14 10:08 mattn

Agreed, the autocompletion is not a task for emmet-vim. Therefore I would say it's best if Emmet ignores this case and lets Vim do whatever it would do if emmet-vim were not installed.

mattijsbliek avatar Aug 08 '14 10:08 mattijsbliek

Probably, you can use auto-completion plugin to complete candidates from buffer.

mattn avatar Aug 08 '14 10:08 mattn

Is there any way I can make emmet-vim only expand properties/values and nothing else?

mattijsbliek avatar Aug 08 '14 10:08 mattijsbliek

.foo
.bar
.f<tab>

When you want complete .foo from .f, you can use CTRL-X CTRL-L or CTRL-X CTRL-P.

mattn avatar Aug 08 '14 11:08 mattn

I am having this problem too, mainly for HTML files.

Let's say I type coconut. Is there a way for emmet not to consider it expandable and not to expand it to <coconut></coconut>? By modifying the emmet#isExpandable() function maybe?

jeromedalbert avatar Apr 29 '16 05:04 jeromedalbert

What is your expected?

mattn avatar Apr 29 '16 16:04 mattn

Initial config:

imap <expr> <tab> TabComplete()
smap <expr> <tab> TabComplete()
xmap <expr> <tab> TabComplete()

function! TabComplete()
  if neosnippet#expandable_or_jumpable()
    return "\<Plug>(neosnippet_expand_or_jump)"
  elseif &filetype =~ 'html\|css' && emmet#isExpandable()
    return "\<plug>(emmet-expand-abbr)"
  elseif pumvisible()
    return "\<c-n>"
  endif
endfunction

Current:

  1. Initial: coconut|
  2. Press tab
  3. Result:
    • in html file: <coconut>|</coconut>

    • in css file:

      coconut {
        |
      }
      

Expected:

  1. Initial: coconut|
  2. Press tab
  3. Result:
    • in html file: coconut|
    • in css file: coconut|

I expect this because coconut is not a real html tag and not a css element.

jeromedalbert avatar Apr 29 '16 17:04 jeromedalbert

Currently, no way to expand only tag name exists. So you need to do following.

imap <expr> <tab> TabComplete()
smap <expr> <tab> TabComplete()
xmap <expr> <tab> TabComplete()

let s:tags = ['!DOCTYPE','a','abbr','acronym','address','applet','area','article','aside','audio','b','base','basefont','bdi','bdo','big','blockquote','body','br','button','canvas','caption','center','cite','code','col','colgroup','datalist','dd','del','details','dfn','dialog','dir','div','dl','dt','em','embed','fieldset','figcaption','figure','font','footer','form','frame','frameset','h1','head','header','hr','html','i','iframe','img','input','ins','kbd','keygen','label','legend','li','link','main','map','mark','menu','menuitem','meta','meter','nav','noframes','noscript','object','ol','optgroup','option','output','p','param','pre','progress','q','rp','rt','ruby','s','samp','script','section','select','small','source','span','strike','strong','style','sub','summary','sup','table','tbody','td','textarea','tfoot','th','thead','time','title','tr','track','tt','u','ul','var','video','wbr']

function! s:realtag()
  return matchstr(getline('.')[:col('.')], '\(\S\+\)$')
endfunction

function! TabComplete()
  if neosnippet#expandable_or_jumpable()
    return "\<Plug>(neosnippet_expand_or_jump)"
  elseif &filetype =~ 'html\|css' && emmet#isExpandable() && index(s:tags, s:realtag()) != -1
    return "\<plug>(emmet-expand-abbr)"
  elseif pumvisible()
    return "\<c-n>"
  else
    return "\t"
  endif
endfunction

mattn avatar Apr 29 '16 19:04 mattn

Interesting start, but with this solution, some functionality is lost. Emmet HTML and CSS expression syntax do not work any more when you press tab.

For HTML I guess one could check if s:realtag() contains .#>+* etc, but I don't think this would work well for all cases. And this still won't work for CSS files (expanding things like dn to display: none;).

jeromedalbert avatar Apr 30 '16 17:04 jeromedalbert

Improving on @mattn's suggestion, and by looking at the s:emmet_settings variable in emmet-vim/autoload/emmet.vim, I made this snippet which satisfies most of my needs. It takes into account some basic Emmet expression syntax, html tags, and abbreviations like btn.

imap <expr> <tab> TabComplete()
smap <expr> <tab> TabComplete()
xmap <expr> <tab> TabComplete()

function! TabComplete()
  if neosnippet#expandable_or_jumpable()
    return "\<Plug>(neosnippet_expand_or_jump)"
  elseif &filetype =~ 'html\|css' && IsEmmetExpandable()
    return "\<plug>(emmet-expand-abbr)"
  elseif pumvisible()
    return "\<c-n>"
  else
    return "\<tab>"
  endif
endfunction

function! IsEmmetExpandable()
  if !emmet#isExpandable() | return 0 | endif
  if &filetype =~ 'css' | return 1 | endif

  let expr = matchstr(getline('.')[:col('.')], '\(\S\+\)$')
  return expr =~ '[.#>+*]' || index(s:emmetElements, expr) >= 0
endfunction

let s:emmetElements = ['a', 'abbr', 'acronym', 'address', 'applet', 'area', 'article', 'aside', 'audio', 'b', 'base', 'basefont', 'bdi', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']
      \ + ['emb', 'btn', 'sty', 'dlg', 'fst', 'fig', 'leg', 'tarea', 'hdr', 'cmd', 'colg', 'art', 'fset', 'src', 'prog', 'bq', 'kg', 'adr' , 'cap', 'datag', 'datal', 'sect', 'str', 'obj', 'ftr', 'optg', 'ifr', 'out', 'det', 'acr', 'opt']

There is a lot of room for improvement (especially the CSS part), but this should be enough to get me started. Having something like this built into emmet#isExpandable() would be nice though!

jeromedalbert avatar May 01 '16 06:05 jeromedalbert

@jeromedalbert * - mouse cursor (autocomple not working) index.html -> script tag -> $('succ*')

Error detected while processing function TabComplete[3]..IsEmmetExpandable[1]..emmet#isExpandable[8]..emmet#lang#html#findTokens:
line 19: E363: pattern uses more memory than 'maxmempattern'

D1mon avatar Mar 16 '18 15:03 D1mon

Looks like an emmet-vim bug on emmet#isExpandable()

jeromedalbert avatar Mar 16 '18 17:03 jeromedalbert

Could you please make small code to reproduce?

mattn avatar Mar 18 '18 11:03 mattn

filetype: html, htmldjango

<script type="text/javascript">                                                                                                                                                        
  $('suc')                                                                                                                                                                             
</script>

emmet plugin does not work with the function written above

D1mon avatar Mar 18 '18 15:03 D1mon

@D1mon Where is your cursor? and what key typed?

mattn avatar Mar 18 '18 16:03 mattn

Where is your cursor?

mouse cursor -> * $('suc*')

and what key typed?

Tab key

D1mon avatar Mar 18 '18 17:03 D1mon