8

I'm having the following CSS class structure

.mAIcon
.mAIcon-reject
.mAIcon-edit
.mAIcon-accept
.event

and so on.

Inside my HTML files I want to autocomplete these class names.

But when I type

<span class="mAIcon mA|">

and I want to autocomplete the rest the only thing I get is

<span class="mAIcon mAIcon|">

To get what I really want I have to type an extra - and for example e and use the autocompletion again. But then I get everything that starts with an e, even the class event. This is really annoying and makes the autocompletion rather useless in this case.

I use Vim's generic keyword completion with the i_CTRL-N command and I don't have any additional completion plugins installed.

Is it possible to include the - to the detection of CSS class names for the autocompletion?

5
  • You say "autocomplete", does this mean you are using YouCompleteMe, neocomplete, or something similar? If so, this should be mentioned in your question. If not, then you must be issuing some kind of completion command, such as <c-x><c-n>, which should also be specified in your question. Jul 5, 2015 at 13:47
  • @KarlYngveLervåg thank you for your comment. Please take a look at my edit. Jul 5, 2015 at 15:15
  • 1
    Your edit confirmed my suspicion. First, IMHO autocompletion should be automatic, and as such the problem you are describing is not with autocompletion, but merely with completion. For autocompletion in Vim I recommend you look at neocomplete or YouCompleteMe. Second, You are using Vim's generic KEYWORD completion. A keyword is defined by the option 'iskeyword', and even though keywords are used also for other commands (side effects), this is still the correct way to achieve what you want without using other kinds of (auto)completion. Jul 5, 2015 at 18:02
  • @KarlYngveLervåg First I'm sorry for the misunderstanding. But I thought that autocompletion was the right term. Second could you then point me to something that solves my completion problem? As far as I can see YouCompleteMe and neocomplete don't change the completing behavior of the standard completion, they only add more "auto", which I don't need. I really thought this would be possible with Vim. Jul 5, 2015 at 19:02
  • 1
    I might be wrong, but tag completion might work in this case. I do not personally do much web development, and so I am not that familiar with Vim for html/css/..., but I think that ctags should be able to generate tags for your project. Then you can do tag completion with i_CTRL-X_CTRL-]. However, I see in the docs that tag completion also uses the iskeyword option, so I might be wrong. In any case, you probably want to read :h ins-completion. Jul 6, 2015 at 20:57

2 Answers 2

10

Yes, you can define what characters are considered part of keywords with the 'iskeyword' option:

setlocal iskeyword+=-

You can add the following snippet to your vimrc to restrict that option to CSS and HTML files:

augroup css
    autocmd!
    autocmd FileType css,html setlocal iskeyword+=-
augroup END
5
  • 5
    Note that modifying iskeyword has a lot of side-effects. For example dw on some-text will now delete some-text, instead of only some. Not necessarily a bad thing, but something to be aware of. Jul 3, 2015 at 9:59
  • Mhh this only seems to work inside of a CSS file, as soon as I switch to a different buffer (for example a HTML file) it only completes words with out the minus sign. Jul 5, 2015 at 7:10
  • @RaphaelAhrens, see my edit.
    – romainl
    Jul 5, 2015 at 7:51
  • @romainl I really appreciate your fast answer. But I'm sorry, I can't accept this answer since it will not scale with more file types and in addition it has the side-effects mentioned by Carpetsmoker. I hope you understand. Jul 5, 2015 at 11:34
  • 1
    I use this but I trigger on js and coffee files too. Because I find myself completing CSS classes often in Javascript, and I rarely have code that performs subtraction without a space. In code I edit, diff = foo - bar; is more common than diff=foo-bar; Oct 4, 2015 at 11:45
1

I solved the problem by writing a small python script that creates a tag file. The script searches for CSS classes and prints a tag line for every class.

At the moment I run the script by hand with

css_tags $file >> tags

which adds the files to the tags file. This works since tag completion isn't limited by the iskeyword setting.

Here is the contents of the script which is also available on GitHub.

#!/usr/bin/env python3

import argparse
import re

parser = argparse.ArgumentParser(description='CSStags.')
parser.add_argument('css_file', type=argparse.FileType('r'))


def create_tag(tag_name, filename, line):
    """
    Create a ctag line for the CSS class
    """
    print('%s\t%s\t/^%s$/;"\tc' % (tag_name, filename, line))


def main():
    args = parser.parse_args()

    class_regex = re.compile('^\.([\w-]+)\s*{')

    for line in args.css_file:
        class_match = class_regex.match(line)
        if class_match:
            create_tag(class_match.group(1), args.css_file.name, class_match.group(0))


if __name__ == '__main__':
    main()

Your Answer

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

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