Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vim: support ":const" command which sets constants #2593

Merged
merged 1 commit into from
Jul 9, 2020
Merged

vim: support ":const" command which sets constants #2593

merged 1 commit into from
Jul 9, 2020

Conversation

lacygoill
Copy link
Contributor

This PR tries to add support for the Vim command :const. The latter is used in Vimscript to set a constant.


I did not try to create a new C function to parse the command because:

  1. that's above my level
  2. I don't think it's necessary. In Vim, :const is equivalent to :let followed by :lockvar; it's just a variable whose value is locked so that it can't change.

:const can be shortened into :cons, which is why I wrote 4 and not 5 here:

else if (wordMatchLen (line, "let", 3) || wordMatchLen (line, "const", 4))
                                                                       ^

I added a simple test consisting of an input file and an expected output tags file.
I made sure all the Vim tests passed:

make units LANGUAGES=Vim

@coveralls
Copy link

coveralls commented Jul 8, 2020

Coverage Status

Coverage increased (+0.0006%) to 86.778% when pulling b92362f on lacygoill:vim-const into 2a45704 on universal-ctags:master.

@codecov
Copy link

codecov bot commented Jul 8, 2020

Codecov Report

Merging #2593 into master will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #2593   +/-   ##
=======================================
  Coverage   86.67%   86.67%           
=======================================
  Files         183      183           
  Lines       38608    38610    +2     
=======================================
+ Hits        33462    33464    +2     
  Misses       5146     5146           
Impacted Files Coverage Δ
parsers/vim.c 99.59% <100.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 81a8999...b92362f. Read the comment docs.

@masatake
Copy link
Member

masatake commented Jul 8, 2020

that's above my level

I will asisst you. So the level is not a matter for us.

We know ctags. You know vim script. I know C. Your knowledge about vim script is very important.
See also #2494.

You reuse the code for handling "let". However, as far as my short study, let is for defining variables.
I think tagging a language object defined with :const as a variable is not good idea.
Instead, I think it should be tagged as a constant.

const s:CONSTANT = 42

=>

s:CONSTANT	input.vim	/^const s:CONSTANT = 42$/;"	v

Here v means a variable. I don't think s:CONSTANT is not a vairable.
How do you think?

@masatake
Copy link
Member

masatake commented Jul 8, 2020

I think ideal behavior is:

[jet@living]~/var/ctags% cat input.vim
cat input.vim
const s:CONSTANT = 42
[jet@living]~/var/ctags% ./ctags --list-kinds=Vim
./ctags --list-kinds=Vim
a  autocommand groups
c  user-defined commands
f  function definitions
m  maps
v  variable definitions
n  vimball filename
C  constant definitions
[jet@living]~/var/ctags% ./ctags -o - input.vim
./ctags -o - input.vim
s:CONSTANT	input.vim	/^const s:CONSTANT = 42$/;"	C

The change we need is for above result:

diff --git a/parsers/vim.c b/parsers/vim.c
index 0bdd1802..7ee767b6 100644
--- a/parsers/vim.c
+++ b/parsers/vim.c
@@ -46,7 +46,8 @@ typedef enum {
 	K_FUNCTION,
 	K_MAP,
 	K_VARIABLE,
-	K_FILENAME
+	K_FILENAME,
+	K_CONST,
 } vimKind;
 
 static kindDefinition VimKinds [] = {
@@ -56,6 +57,7 @@ static kindDefinition VimKinds [] = {
 	{ true,  'm', "map",      "maps" },
 	{ true,  'v', "variable", "variable definitions" },
 	{ true,  'n', "filename", "vimball filename" },
+	{ true,  'C', "constant", "constant definitions" },
 };
 
 /*
@@ -432,7 +434,7 @@ cleanUp:
 	return cmdProcessed;
 }
 
-static void parseLet (const unsigned char *line, int infunction)
+static void parseVariableOrConstant (const unsigned char *line, int infunction, int kindIndex)
 {
 	vString *name = vStringNew ();
 
@@ -482,7 +484,7 @@ static void parseLet (const unsigned char *line, int infunction)
 			vStringPut (name, (int) *cp);
 			++cp;
 		} while (isalnum ((int) *cp) || *cp == '_' || *cp == '#' || *cp == ':' || *cp == '$');
-		makeSimpleTag (name, K_VARIABLE);
+		makeSimpleTag (name, kindIndex);
 		vStringClear (name);
 	}
 
@@ -596,9 +598,12 @@ static bool parseVimLine (const unsigned char *line, int infunction)
 
 	else if (wordMatchLen (line, "let", 3))
 	{
-		parseLet (skipWord (line), infunction);
+		parseVariableOrConstant (skipWord (line), infunction, K_VARIABLE);
+	}
+	else if (wordMatchLen (line, "const", 4))
+	{
+		parseVariableOrConstant (skipWord (line), infunction, K_CONST);
 	}
-
 	return readNextLine;
 }

However, I don't know well about vim script. So, I would like to hear your comments.

@lacygoill
Copy link
Contributor Author

I agree with you; technically, a constant is not a variable since its value can't change.
It should probably have its own kind. c is already taken for commands, so C is the next best choice.

I've applied your patch, compiled and installed. All the Vim tests still pass, and the ctags(1) binary correctly generates tags for constants defined with the :const keyword. I haven't had the time to read all of #2494, but if I understand correctly, the purpose is to give advice on Vimscript. I'm no expert, but I think I can help. If you have any question regarding the Vimscript language, let me know.

@lacygoill
Copy link
Contributor Author

I made a mistake in the expected.tags file; I need to fix it.

parsers/vim.c Outdated
@@ -594,11 +596,14 @@ static bool parseVimLine (const unsigned char *line, int infunction)
parseAutogroup (skipWord (line));
}

else if (wordMatchLen (line, "let", 3))
else if (wordMatchLen (line, "let", 3) || wordMatchLen (line, "const", 4))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mathcing "const" is not needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I forgot to revert my old patch, sorry.

}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removng this empty line is not needed to support "const".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fixed; I added back the empty line.

@masatake masatake merged commit b9afa00 into universal-ctags:master Jul 9, 2020
@masatake
Copy link
Member

masatake commented Jul 9, 2020

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants