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

Detecting conflicting snippet triggers #1506

Open
TryerGit opened this issue Nov 20, 2022 · 1 comment
Open

Detecting conflicting snippet triggers #1506

TryerGit opened this issue Nov 20, 2022 · 1 comment

Comments

@TryerGit
Copy link

Hello,

Is there a way to detect incompatible snippet triggers?

Say:

snippet st "superscript" iA
<---snippet body--->
endsnippet

vs

snippet bst "binary spanning tree data" iA
<---snippet body--->
endsnippet

vs

snippet bs "basis information" iA
<---snippet body--->
endsnippet

In the above case, bs would fire when bst is typed, so from the plugin POV there is no conflict, per se.

But from the user POV, bst will never fire. Is there a way to possibly call a function in UltiSnips that will detect and report such cases?

Thanks.

@TryerGit
Copy link
Author

One way to achieve this seems to be the following (seems a bit hackish so, perhaps there is a better way.)

Note that it is the snippets with A in their option list cause this problem. So, the following awk command processes the .snippets file and stores in a separate file the snippet triggers associated with option containing A:

awk '{if($1 == "snippet" && match($NF, "A"))printf ("%-50s\t%-d\n",$(2),NR)}' tex.snippets > keywords.txt

Then, it is a matter of processing these trigger keywords to see which pairs are subsets of each other. That can be accomplished via the following C++ code:

#include <string>
#include <vector>
#include <sstream>
#include <fstream>
std::vector<std::string> keywords;
std::vector<int> linenumbers;

// Returns -1 if s1 is not a substring of s2
int isSubstring(std::string s1, std::string s2)
{
	int M = s1.length();
	int N = s2.length();
  if (N < M)
    return -1;
    /* A loop to slide pat[] one by one */
	for (int i = 0; i <= N - M; i++) {
		int j;
		/* For current index i, check for
pattern match */
		for (j = 0; j < M; j++)
			if (s2[i + j] != s1[j])
				break;

		if (j == M)
			return i;
	}
	return -1;
}

int main() {
  std::ifstream ifile("keywords.txt");
  std::ofstream ofile("Processed_output.txt");
  std::string line;
  while (getline(ifile, line)) {
    std::istringstream ss(line);
      int lineno;
    while (!ss.eof()) {
      std::string hname;
      ss >> hname; 
      if (hname.length() > 0) {
        keywords.push_back(hname);
        ss >> lineno;
        linenumbers.push_back(lineno);
      }
    }
  }
  for (int i = 0; i < keywords.size(); i++) {
    for (int j = 0; j < keywords.size(); j++) {
      if (i == j)
        continue;
      if (isSubstring(keywords[i], keywords[j]) == -1) {
      }
      else {
        printf("Clash between %s [%d] and %s [%d]\n", keywords[i].c_str(), linenumbers[i], keywords[j].c_str(), linenumbers[j]);
        ofile << "Clash between " << keywords[i] << " ["<<linenumbers[i]<<"] and " << keywords[j] << " ["<<linenumbers[j]<<"]"<<std::endl; 
      }
    }
  }
  ifile.close();
  ofile.close();
}

This shows all the "clashes" for further analysis/correction.

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

No branches or pull requests

1 participant