How to create a centralized syntax file that be able to recognize multiple parts with different syntaxes? - vim

For i.e: I'd like to have a custom syntax file, may be called sugar.vim that includes multiple other syntax files(?) to have the ability to highlight, maybe a paragraph as python.vim and another paragraph as javascript.vim, may be separated by newline (paragraphs often distinct by newline)
The real case that I often catch myself writing a document (non-extension file) other than real config a specific filetype (specific extension file), but for clear readability in the document filetype (we called sugar above). I'm thinking about a mechanism to recognize and highlight different parts of a filetype as different syntaxes.
To narrow down this case. How would it be to have a syntax file called sugar.vim that would be able to recognize python syntax and javascript syntax in files that have an extension of .sugar then the recognized python text should have highlights applied as a normal python file, same for javascript part. All recognized text must be separated by newline (at least one before and one after that text)
Sample:
# this is a sample text for this question
# i'm writing a document that has an extension of `.sugar`
def py_func1(arg1, arg2) # python.vim and its highlights applied here.
print("bello world!")
square = function(x) { # javascript.vim and its highlights applied here.
return x * x;
};
System: gvim 8.1 / windows10
Thanks in advances.

Vim supports that with the :help :syn-include command. As it's intended for syntax script writers leveraging other syntaxes, its use is somewhat complicated, and it's not really suited for interactive, on-demand use.
My SyntaxRange plugin provides commands and functions to set up regions in the current buffer that either use a syntax different from the buffer's 'filetype', or completely ignore the syntax. With it, it's trivial to dynamically add a particular syntax highlighting for a range of lines, and public API functions also make the programmatic definition easier.

You're looking for :help :syn-include.
Excerpt from vim help :
If top-level syntax items in the included syntax file are to be
contained within a region in the including syntax, you can use the
":syntax include" command:
:sy[ntax] include [#{grouplist-name}] {file-name}
All syntax items declared in the included file will have the
"contained" flag added. In addition, if a group list is specified,
all top-level syntax items in the included file will be added to
that list. >
" In perl.vim:
:syntax include #Pod :p:h/pod.vim
:syntax region perlPOD start="^=head" end="^=cut" contains=#Pod
When {file-name} is an absolute path (starts with "/", "c:", "$VAR"
or "") that file is sourced. When it is a relative path
(e.g., "syntax/pod.vim") the file is searched for in 'runtimepath'.
All matching files are loaded. Using a relative path is
recommended, because it allows a user to replace the included file
with his own version, without replacing the file that does the ":syn
include".
As long as you can clearly define boundaries for your embedded language regions it is fairly straight forward to achieve this.
You can also refer to https://github.com/tpope/vim-markdown/blob/master/syntax/markdown.vim for reference on how tpope embeds other syntax definitions within the markdown syntax, driven by configuration to minimise the number of language syntax's that need embedding for optimal performance.

Related

In Vim how to know if function is defined

I am using Vim editor v7.4 .
I have a huge C Code library , and i make constant changes to it.
Is there a way ( before compilation) to know if a function i am adding to some file is defined for this file.
Thanks
I'm not sure to correctly understand your need. In my definition, when I add a function to a file, I add its definition, so it's defined. But when I'm using a function in a file, I only need its declaration. Then there is also the problem of being sure that a function defined in a translation unit is declared somewhere (privately in the same TU as a static function, or in a header file).
For the latter, I have a solution (that checks functions definitions and declarations are balanced in lh-cpp). For the case of being sure a function is declared in the UT it's used, it won't be that simple: we need to do the preprocessor work (and recursively follow includes) and search whether a function is indeed declared. It's not impossible, but it's best to have vim know the paths where header files are in order to look for them.
Look at a tool like exuberant ctags. It parses C-style files to find any identifier and store them in a tag file, so that each of them can be accessed quickly, inside Vim for example.
Once installed, in the shell command line, you have to create a tag file with this kind of command:
$ ctags *.c *.h
This will create an new file called tags, where all the c files and header files in the current directory are parsed. Please note that there are many options for this tool (like recursively include all lib headers, which can lead to a huge file, though), you may look at the doc for more details.
Once done, in Vim, there are several commands to use transparently the infos in this file. First check your current directory is the same as the tag file; then, to check if an identifier (like a function name) is already present in the tag file, you can use:
:ts myFunctionName
I don't think tag is a good enough solution to check whether function is defined. The flexibility of C syntax make it worse, because most tag tool is syntax-based other than semantics-based.
For example, at present, the most powerful code-completion plug-in for vim is
YouCompleteMe, which is semantic-based by virtue of Clang.
So IMHO, the answer to your question is: compile it!
In order to do compiling more convenience, you can add the following configuration in your .vimrc.
map <F6> :make install<CR>
After this, when you press F6, compiler will be launched to check your code.

vim syntax scripts "sourcing" another, but only for matching lines

I'm writing a vim syntax script and I want to be able to make lines matching a certain pattern, say, '^>', "source" or imitate the markdown syntax highlighting.
Is there a way to do this at the syntax script level? Do I need to just copy and paste it in manually and make the proper adjustments? Does this require a modeline on the actual file?
Thanks!
Have a look at :help :syn-include. It allows you to import an existing syntax (like e.g. markdown) into a syntax cluster in your own syntax, and then you can assign syntax regions (if I understand you correctly, that would be a region starting with /^>/ and ending at the end of the line /$/) to it.
Note that success isn't guaranteed; you need some collaboration from the included syntax. (For example, if the markdown syntax anchors its patterns at ^, but now it's included behind the > prefix, it won't match any more.) In the worst case, you have to modify the included syntax or copy it completely into your own syntax.

How to find all occurrences of a variable in Vim?

In vim, how to I find all occurrences of a variable in files under a certain directory?
I know vimgrep works sometimes, but it looks for text only and doesn't work if other classes have variables of the same name and I only want the variable under a specific class.
What should I do? Or should I get an IDE instead?
Why would you want to use another IDE when you already have one? Vim is an IDE that is configurable and usable for different languages..
You could use cscope to build a database of your code. This database
Allows searching code for:
all references to a symbol
global definitions
functions called by a function
functions calling a function
text string
regular expression pattern
a file
files including a file
Further features of Cscope:
Curses based (text screen)
An information database is generated for faster searches and later reference
The fuzzy parser supports C, but is flexible enough to be useful for C++ and Java, and for use as a generalized 'grep database' (use it to browse large text documents!)
Has a command line mode for inclusion in scripts or as a backend to a GUI/frontend
Runs on all flavors of Unix, plus most monopoly-controlled operating systems.
Once your database is created, you could browse through the usages of your variables, functions, etc.
Edit (slightly off-topic):
another cool thing that's quite handy when working with Vim on code is the taglist plugin that uses Ctags:
The "Tag List" plugin is a source code browser plugin for Vim and
provides an overview of the structure of source code files and allows
you to efficiently browse through source code files for different
programming languages.
cscope step by step example
Go to the base directory of your project, and run:
cscope -Rb
This generates a cscope.out file which contains the parsed information. Generation is reasonably fast, even for huge projects like the Linux kernel.
Note that cscope is not designed to work with other languages other than C. Sometimes it does work for other C-like syntax languages like Python, and you can force it to recognize those files with hacks such as cscope -Rb -s * and others mentioned at: Using cscope to browse Python code with VIM? but it won't work as well as for C.
Open vim, and run:
:cs add cscope.out
:cs find s my_func
s is a mnemonic for symbol. The other cscope provided queries are also possible.
The cscope interface (ouside Vim) also has a variable assignment query (subset of symbol occurrences) which Vim does not seem to offer (?)
This adds a list of the callers to the quickfix list, which you can open with:
:copen
Go to the line that interests you and hit enter to jump there.
See also:
automatically add the nearest database (parent directories) when you enter a file: how to auto load cscope.out in vim
for function calls: How to find the callers and callee of a function in C code in vi/vim?

Is there any vim plugin that could restrict spell check only in comment in c source code file?

I'd like to turn on spell check to avoid typos in comment, but in code those red underlines are really annoying...
Some file type plugins could do that for other languages, like Python, but I couldn't find any c plugins.
I tried c.vim but it doesn't work.
You should be able to modify the c syntax file to get the behavior you want. When you load a c file (or set a file to c filetype) the c syntax file is loaded from the /vimxx/syntax directory, it's the file there named c.vim. This file has all the various syntax statements that establish elements that can be highlighted.
You will notice several statements throughout the file that end with contains= and have #Spell among the groups that are "contained". If you remove #Spell from these statements (mostly string syntax items) and leave #Spell in the contains clause for "comment" elements (e.g., cComment) that should do what you want.
Be careful not to remove #Spell from any contains=ALLBUT, clauses, which, as you might guess, list syntax items that may not be contained in the given group.

In VIM: How to highlight "local variables" in a "C" file

I have highlighted all Symbols by using tags file & highlight option.
But I could not able to highlight my local variables.
I have an idea, that is, VIM already supports autocompletion of keywords for a current file, it does autocompletion of my local variable, so, if I get a list of keywords for my current file then I will highlight those keywords by using "highlight" vim command.
But problems is, I don't know, how to get a list of keywords for a current file.
You can highlight recognised names using the tags file as long as the tags file is generated with the --c-kinds=+l to ensure that it includes local variables. However, there is currently no realistic way to identify the scope of those variables (ctags does not provide much information), therefore Vim will not distinguish between variables in one function and another:
void main(void)
{
int MyVariable; // Highlighted
}
int MyFunction(void)
{
int MyFunctionVariable; // Highlighted
MyVariable = 1; // Syntax error, but still highlighted
}
It could be done by parsing the C file in a little more detail and creating syntax regions for each function, but it is far from easy (and it would be incompatible with plugins like rainbow.vim as Vim doesn't support overlapping regions).
On a related note, you may also be interested in my tag highlighting plugin available here. It will highlight local variables (if b:TypesFileIncludeLocals is set to 1 in the buffer open when running :UpdateTypesFile), but it doesn't deal with the scope of local variables. It does, however offer a lot more highlighting colour variations than the highlighting suggested in :help tag-highlight. Note that your colour scheme will have to have highlights defined for lots of extra groups (e.g. GlobalVariable, LocalVariable, DefinedName etc) to take full advantage of it.

Resources