I've never modified on an open source project before, but Notepad++ was pretty easy to get working with the Visual Studio files. The code is quite easy to read, even with minimal comments. Good job!
Anyway, I loved npp as a text editor, but the only thing missing for me was smart-indentation for programming. So I made a few modifications and it seems to work quite well. It only works with braces (so it won't work for def in Python, if/for/while statements without a {} block in C, html tags, etc), but for Perl and most cases in C/C++, Java, LISP, etc it works quite well.
Now I have a smart-indenting, code-folding, MDI text editor that's perfect for Perl scripts. UltraEdit had a few quirks in the syntax highlighting, and isn't freeware either, let alone open source. Thank you npp!
As you can probably tell, I leveraged the brace-matching code to get this to work. It's not rigourously tested, but for anyone else who's interested, here's what you need to do:
1. Add the private variable "bool _checkIndent;" to the Notepad_plus class
2. Modify the "MaintainIndentation(char ch)" function as follows:
void Notepad_plus::MaintainIndentation(char ch)
{
int eolMode = int(_pEditView->execute(SCI_GETEOLMODE));
int curLine = int(_pEditView->getCurrentLineNumber());
int lastLine = curLine - 1;
int indentAmount = 0;
// Flag the line to be checked for smart-indentation if this
// character closes a block and has no other text on the line
if (strchr("])}", ch)) {
int len = _pEditView->getLineLength(curLine) + 1;
char *line = new char[len];
_pEditView->execute(SCI_GETLINE, curLine, reinterpret_cast<LPARAM>(line));
_checkIndent = true;
for (int a = 0; a < len; a++)
if (strchr("\0\r\n\t ])}", line[a]) != NULL)
_checkIndent = false;
}
if (lastLine >= 0) {
indentAmount = _pEditView->getLineIndent(lastLine);
}
// Find the position of the previous character
int pos = _pEditView->execute(SCI_GETCURRENTPOS) - ((eolMode == SC_EOL_CRLF) ? 3 : 2);
// If an opening brace preceded the newline, smart-indent outwards
if ((pos > 0) && strchr("[({", ch = char(_pEditView->execute(SCI_GETCHARAT, pos))))
indentAmount += int(_pEditView->execute(SCI_GETTABWIDTH));
if (indentAmount > 0) {
_pEditView->setLineIndent(curLine, indentAmount);
}
}
}
3. Modify the "braceMatch()" function as follows:
void Notepad_plus::braceMatch()
{
int braceAtCaret = -1;
int braceOpposite = -1;
findMatchingBracePos(braceAtCaret, braceOpposite);
// If we're flagged as closing a block, adjust the indentation
// to match that of where the block opened
if (_checkIndent && (braceOpposite >= 0)) {
int curLine = int(_pEditView->getCurrentLineNumber());
int prevLine = int(_pEditView->execute(SCI_LINEFROMPOSITION, braceOpposite));
int indentAmount = _pEditView->getLineIndent(prevLine);
_pEditView->setLineIndent(curLine, indentAmount);
}
_checkIndent = false;
if (_pEditView->isShownIndentGuide())
{
int columnAtCaret = int(_pEditView->execute(SCI_GETCOLUMN, braceAtCaret));
int columnOpposite = int(_pEditView->execute(SCI_GETCOLUMN, braceOpposite));
_pEditView->execute(SCI_SETHIGHLIGHTGUIDE, (columnAtCaret < columnOpposite)?columnAtCaret:columnOpposite);
}
}
It might be useful to put a separate "Smart-Indentation" checkbox in the settings dialog, but I couldn't be bothered. Hopefully some of you will find this useful. I'll be happy to send a binary to anyone who wants it.
Enjoy!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I just tested your modification, the smart indentatation *for brace* works well. This feature will be included in the next release, and perhaps, I'll enhance it for "if", "while"... statement if I have the time.
Thank you.
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm actually working on a plugin to handle all this so it may not be necessary to include it, and it'll include language specific stuff as well.
I've been really busy for the past couple of weeks so I couldn't finish it, but I'll try again soon. I want to make a good framework that works for most languages and even identifies and handles multiline statements correctly. A bit tricky, but I think it's doable.
(BTW, isn't it a shame that the SourceForge forums don't supports tabs or fixed width font for code fragments?)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
I've never modified on an open source project before, but Notepad++ was pretty easy to get working with the Visual Studio files. The code is quite easy to read, even with minimal comments. Good job!
Anyway, I loved npp as a text editor, but the only thing missing for me was smart-indentation for programming. So I made a few modifications and it seems to work quite well. It only works with braces (so it won't work for def in Python, if/for/while statements without a {} block in C, html tags, etc), but for Perl and most cases in C/C++, Java, LISP, etc it works quite well.
Now I have a smart-indenting, code-folding, MDI text editor that's perfect for Perl scripts. UltraEdit had a few quirks in the syntax highlighting, and isn't freeware either, let alone open source. Thank you npp!
As you can probably tell, I leveraged the brace-matching code to get this to work. It's not rigourously tested, but for anyone else who's interested, here's what you need to do:
1. Add the private variable "bool _checkIndent;" to the Notepad_plus class
2. Modify the "MaintainIndentation(char ch)" function as follows:
void Notepad_plus::MaintainIndentation(char ch)
{
int eolMode = int(_pEditView->execute(SCI_GETEOLMODE));
int curLine = int(_pEditView->getCurrentLineNumber());
int lastLine = curLine - 1;
int indentAmount = 0;
// Flag the line to be checked for smart-indentation if this
// character closes a block and has no other text on the line
if (strchr("])}", ch)) {
int len = _pEditView->getLineLength(curLine) + 1;
char *line = new char[len];
_pEditView->execute(SCI_GETLINE, curLine, reinterpret_cast<LPARAM>(line));
_checkIndent = true;
for (int a = 0; a < len; a++)
if (strchr("\0\r\n\t ])}", line[a]) != NULL)
_checkIndent = false;
}
if (((eolMode == SC_EOL_CRLF || eolMode == SC_EOL_LF) && ch == '\n') ||
(eolMode == SC_EOL_CR && ch == '\r'))
{
while (lastLine >= 0 && _pEditView->getLineLength(lastLine) == 0)
lastLine--;
if (lastLine >= 0) {
indentAmount = _pEditView->getLineIndent(lastLine);
}
// Find the position of the previous character
int pos = _pEditView->execute(SCI_GETCURRENTPOS) - ((eolMode == SC_EOL_CRLF) ? 3 : 2);
// If an opening brace preceded the newline, smart-indent outwards
if ((pos > 0) && strchr("[({", ch = char(_pEditView->execute(SCI_GETCHARAT, pos))))
indentAmount += int(_pEditView->execute(SCI_GETTABWIDTH));
if (indentAmount > 0) {
_pEditView->setLineIndent(curLine, indentAmount);
}
}
}
3. Modify the "braceMatch()" function as follows:
void Notepad_plus::braceMatch()
{
int braceAtCaret = -1;
int braceOpposite = -1;
findMatchingBracePos(braceAtCaret, braceOpposite);
if ((braceAtCaret != -1) && (braceOpposite == -1))
{
_pEditView->execute(SCI_BRACEBADLIGHT, braceAtCaret);
_pEditView->execute(SCI_SETHIGHLIGHTGUIDE);
}
else
{
_pEditView->execute(SCI_BRACEHIGHLIGHT, braceAtCaret, braceOpposite);
// If we're flagged as closing a block, adjust the indentation
// to match that of where the block opened
if (_checkIndent && (braceOpposite >= 0)) {
int curLine = int(_pEditView->getCurrentLineNumber());
int prevLine = int(_pEditView->execute(SCI_LINEFROMPOSITION, braceOpposite));
int indentAmount = _pEditView->getLineIndent(prevLine);
_pEditView->setLineIndent(curLine, indentAmount);
}
_checkIndent = false;
if (_pEditView->isShownIndentGuide())
{
int columnAtCaret = int(_pEditView->execute(SCI_GETCOLUMN, braceAtCaret));
int columnOpposite = int(_pEditView->execute(SCI_GETCOLUMN, braceOpposite));
_pEditView->execute(SCI_SETHIGHLIGHTGUIDE, (columnAtCaret < columnOpposite)?columnAtCaret:columnOpposite);
}
}
enableCommand(IDM_SEARCH_GOTOMATCHINGBRACE, (braceAtCaret != -1) && (braceOpposite != -1), MENU | TOOLBAR);
}
It might be useful to put a separate "Smart-Indentation" checkbox in the settings dialog, but I couldn't be bothered. Hopefully some of you will find this useful. I'll be happy to send a binary to anyone who wants it.
Enjoy!
I just tested your modification, the smart indentatation *for brace* works well. This feature will be included in the next release, and perhaps, I'll enhance it for "if", "while"... statement if I have the time.
Thank you.
Don
Hi there,
is there now a way to activate smart-indent?
Andreas
Is this feature included? I can't seem to find anything about it.
Im trying to write a plugin that does this, which shouldnt take too long to make usable
One little correction:
You need "delete[] line;" in the "MaintainIndentation()" function, or there will be a memory leak. (Oops.)
You're welcome, Don.
I'm actually working on a plugin to handle all this so it may not be necessary to include it, and it'll include language specific stuff as well.
I've been really busy for the past couple of weeks so I couldn't finish it, but I'll try again soon. I want to make a good framework that works for most languages and even identifies and handles multiline statements correctly. A bit tricky, but I think it's doable.
(BTW, isn't it a shame that the SourceForge forums don't supports tabs or fixed width font for code fragments?)
I have just been goin through the code and I'm afraid it is not there as of 5.0.3.
Cheers
Fots