void doxyItFunction() { std::string doc_block; int startLine, endLine; char *indent = NULL; if(!updateScintilla()) return; doc_block = Parse(); // Don't issue any warning messages, let Parse() handle that for us since it knows // about the error. Just return if it is a zero length string if(doc_block.length() == 0) return; // Keep track of where we started startLine = SendNpp(NPPM_GETCURRENTLINE); // Get the whitespace of the next line so we can insert it in front of // all the lines of the document block that is going to be inserted indent = getLineIndentStr(startLine + 1); SendScintilla(SCI_BEGINUNDOACTION); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) doc_block.c_str()); endLine = SendNpp(NPPM_GETCURRENTLINE); // get the end of the document block if(indent) insertBeforeLines(indent, startLine, endLine + 1); SendScintilla(SCI_ENDUNDOACTION); if(indent) delete[] indent; }
// 'update' causes the current parser pointer to be updated // else just return the currently cached parser const Parser *getCurrentParser(bool update) { static const Parser *current = NULL; if(update) { int lang_type; SendNpp(NPPM_GETCURRENTLANGTYPE, SCI_UNUSED, (LPARAM) &lang_type); if(lang_type == L_USER /* || lang_type == L_EXTERNAL */) { wchar_t *name = NULL; int len = 0; len = SendNpp(NPPM_GETLANGUAGENAME, lang_type, NULL) + 1; name = (wchar_t *) malloc(sizeof(wchar_t) * len); SendNpp(NPPM_GETLANGUAGENAME, lang_type, (LPARAM) name); for(unsigned int i = 0; i < parsers.size(); ++i) { // Use [6] because the name returned is "udl - mylangname" if(parsers[i]->language_name == &name[6]) { current = parsers[i]; free(name); return current; } } free(name); } else { for(unsigned int i = 0; i < parsers.size(); ++i) { if(parsers[i]->lang_type == lang_type) { current = parsers[i]; return current; } } } // Parser wasn't found for current language current = NULL; } return current; }
void getIniFilePath(wchar_t *iniPath, int size) { SendNpp(NPPM_GETPLUGINSCONFIGDIR, size, (LPARAM) iniPath); wcscat_s(iniPath, size, TEXT("\\")); wcscat_s(iniPath, size, NPP_PLUGIN_NAME); wcscat_s(iniPath, size, TEXT(".ini")); }
void FillExtraKeywords(Keywords &kw) { std::vector<std::string> filename; wchar_t fileName[MAX_PATH]; // Insert the current file name into the map SendNpp(NPPM_GETFILENAME, MAX_PATH, (LPARAM) fileName); filename.push_back(toString(fileName)); kw["$FILENAME"] = filename; }
// Get the current parser and text to parse std::string Parse(void) { std::string doc_block; const Parser *p; int found, curLine, foundLine; char *buffer; if(!(p = getCurrentParser())) { MessageBox(NULL, TEXT("Unrecognized language type."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); return std::string(""); } // External parsers are simple enough since they don't need any text to parse if(p->external) return FormatFunctionBlock(p, &p->ps, nullptr); // Get the text until a closing parenthesis. Find '(' first if((found = findNext("(")) == -1) { MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); return std::string(""); } // Do some sanity checking. Make sure curline <= found <= curline+2 curLine = SendNpp(NPPM_GETCURRENTLINE); foundLine = SendScintilla(SCI_LINEFROMPOSITION, found); if(foundLine < curLine || foundLine > curLine + 2) { MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); return std::string(""); } // Find the matching closing brace if((found = SendScintilla(SCI_BRACEMATCH, found, 0)) == -1) { MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); return std::string(""); } buffer = getRange(SendScintilla(SCI_GETCURRENTPOS), found + 1); doc_block = FormatFunctionBlock(p, &p->ps, buffer); delete[] buffer; // I don't think there is currently a case where callback() will return a zero length string, // but check it just in case we decide to for the future. if(doc_block.length() == 0) { MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); return std::string(""); } return doc_block; }
bool updateScintilla() { HWND curScintilla; // Get the current scintilla int which = -1; SendNpp(NPPM_GETCURRENTSCINTILLA, SCI_UNUSED, (LPARAM)&which); if(which == -1) return false; curScintilla = (which == 0) ? nppData._scintillaMainHandle : nppData._scintillaSecondHandle; // Get the function and pointer to it for more efficient calls pSciMsg = (SciFnDirect) SendMessage(curScintilla, SCI_GETDIRECTFUNCTION, 0, 0); pSciWndData = (sptr_t) SendMessage(curScintilla, SCI_GETDIRECTPOINTER, 0, 0); return true; }
void doxyItNewLine() { std::string indentation; const ParserSettings *ps; const char *eol; char *previousLine, *found = NULL; int curLine; if(!updateScintilla()) return; ps = getCurrentParserSettings(); if(!ps) return; eol = getEolStr(); curLine = SendNpp(NPPM_GETCURRENTLINE); previousLine = getLine(curLine - 1); // NOTE: we cannot use getLineIndentStr() because doc_start or doc_line may start with whitespace // which we don't want counted towards the indentation string. if(found = strstr(previousLine, ps->doc_line.c_str())) { indentation.append(previousLine, found - previousLine); // doc_line should have only whitespace in front of it if(isWhiteSpace(indentation)) { SendScintilla(SCI_BEGINUNDOACTION); SendScintilla(SCI_DELLINELEFT); // Clear any automatic indentation SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) indentation.c_str()); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) ps->doc_line.c_str()); SendScintilla(SCI_ENDUNDOACTION); SendScintilla(SCI_CHOOSECARETX); } } // If doc_start is relatively long we do not want the user typing the entire line, just the first 3 should suffice. // Also, if doc_end is found, this means a doc block was closed. This allows e.g. /** inline comments */ else if((found = strstr(previousLine, ps->doc_start.substr(0, 3).c_str())) && strstr(previousLine, ps->doc_end.c_str()) == 0) { indentation.append(previousLine, found - previousLine); if(isWhiteSpace(indentation)) { int pos; unsigned int i = 0; // Count the characters in common so we can add the rest while(i < ps->doc_start.length() && found[i] == ps->doc_start.at(i)) ++i; SendScintilla(SCI_BEGINUNDOACTION); SendScintilla(SCI_DELLINELEFT); // Clear any automatic indentation SendScintilla(SCI_DELETEBACK); // Clear the newline SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) &ps->doc_start.c_str()[i]); // Fill the rest of doc_start SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) eol); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) indentation.c_str()); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) ps->doc_line.c_str()); pos = SendScintilla(SCI_GETCURRENTPOS); // Save this position so we can restore it SendScintilla(SCI_LINEEND); // Skip any text the user carried to next line SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) eol); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) indentation.c_str()); SendScintilla(SCI_REPLACESEL, SCI_UNUSED, (LPARAM) ps->doc_end.c_str()); SendScintilla(SCI_ENDUNDOACTION); SendScintilla(SCI_CHOOSECARETX); // Restore the position SendScintilla(SCI_GOTOPOS, pos); } } delete[] previousLine; }
void activeCommenting() { do_active_commenting = !do_active_commenting; SendNpp(NPPM_SETMENUITEMCHECK, funcItem[3]._cmdID, (LPARAM) do_active_commenting); }