Feature request
It would be great to have an option to remove trailing whitespace and tabs at end of line and also to remove superfluous newlines at end of file / ensure there is exactly a single newline at end of file.
This is some kind of standard for text only files like programming code and would be nice to have also for .tex files.
This is also something version control tools like GIT complain about and since working with .tex file plays nice with version control this would be very helpful in this case also.
Currently I use a simple script for this to achieve before adding my files to version control, but avoiding this extra post-processing step would be really great.
Btw.: I found a similar issue for this at sourceforge. Not sure which one is more recent. I.e. which tracker is really used by developers – GitHub or Sourceforge. Sorry if I duplicated it wrong.
you could make use of txs macro/script ability. I don‘t see a general demand for this.
I think it’s not very polite to instantly close this. Why don’t you leave this open for a while to give others a chance to add their opinion? I think is good practice for most open source projects.
see
https://github.com/texstudio-org/texstudio/wiki/Scripts#remove-whitespace-at-the-end-of-all-lines
not every functionality needs to be programmed in the core code, that is why we implemented all that nice scripting capabilities.
if you adapt above script to your needs, you can publish it in the wiki.
yet feature request could deserve some time for discussion. ;-)
I tried the script with the save trigger.
There is one problem: After saving the file and replacing all the text with the stripped text the editor pane scrolls to the first line.
I tried to fix this getting the cursor position before removing the space and resetting it afterwards using cursor.moveTo, however this has no effect on scrolling the editor pane.
I found no script commands for scrolling. I used this reference:
http://texstudio.sourceforge.net/manual/current/usermanual_en.html#SECTION33c
My version of the script
%SCRIPT
var tl = editor.document().textLines();
var r = cursor.lineNumber();
var c = cursor.columnNumber();
for (var i=tl.length-1;i>=0;i--)
tl[i] = tl[i].replace(/\s+$/, '');
editor.setText(tl.join("\n"));
cursor.moveTo(r, c);
Another super annoying thing about this solution: The save trigger is also triggered on each TeX run. This makes sense of course, but together with scrolling to the begin of the document it makes the script solution unusable because it breaks writing flow to scroll back on every preview.
Maybe this is something that should be natively programmed into the core editor code after all ;-)
And btw. I hope you don’t get me wrong nagging about this. TexStudio is great piece of software and I really love to work with it and value your work. I’m a developer too and know how much work this must have been. Tried some open source projects in my spare time myself and know how difficult it is to get something done in a very limited amount of spare time. So hope you don’t mind.
This seems to do the trick:
%SCRIPT
var tl = editor.document().textLines();
var r = cursor.lineNumber();
var c = cursor.columnNumber();
for (var i=tl.length-1;i>=0;i--) {
tl[i] = tl[i].replace(/\s+$/, '');
cursor.moveTo(i, 0);
cursor.movePosition(1, cursorEnums.EndOfLine, cursorEnums.KeepAnchor)
cursor.replaceSelectedText(tl[i]);
}
cursor.moveTo(r,c);
A small enhancement on the script:
%SCRIPT
var tl = editor.document().textLines();
var r = cursor.lineNumber();
var c = cursor.columnNumber();
for (var i=tl.length-1;i>=0;i--) {
var lineText = tl[i];
if (lineText.match(/\s+$/)) {
var lineTextFixed = lineText.replace(/\s+$/, '');
cursor.moveTo(i, 0);
cursor.movePosition(1, cursorEnums.EndOfLine, cursorEnums.KeepAnchor)
cursor.replaceSelectedText(lineTextFixed);
}
}
cursor.moveTo(r,c);
This only does the cursor magic when the line actually needs to be changed.
Want to note that I too thought this would be built in behavior, and found it strange I would have to copy paste a script off the internet to get this functionality. Grateful that works though
For newbies like me: The save trigger is ?save-file.
I made a version which also ensures that there is exactly one empty line at the end of the file and wraps the edits in {begin, end}EditBlock() so that changes can be undone all at once if necessary.
I agree with the previous posters, I thought this would be built in in the editor. Plus the script to obtain the right behaviour is not exactly straightforward, it would make sense to address this in the core code. But thanks for all your work in any case!
%SCRIPT
var tl = editor.document().textLines();
var r = cursor.lineNumber();
var c = cursor.columnNumber();
// Needs to detect if any edit was made, so that the save action can be retriggered.
var hasEdits = false;
function startEdits() {
if (!hasEdits) {
hasEdits = true;
cursor.beginEditBlock();
}
}
var processedLines = 0;
for (var i=tl.length-1;i>=0;i--) {
var lineText = tl[i];
if (lineText.match(/\s+$/)) {
startEdits();
lineText = lineText.replace(/\s+$/, '');
cursor.moveTo(i, 0);
cursor.movePosition(1, cursorEnums.EndOfLine, cursorEnums.KeepAnchor)
cursor.replaceSelectedText(lineText);
hasEdits = true;
}
if (processedLines == 0) {
if (lineText != '') {
startEdits();
cursor.moveTo(i, 0);
cursor.movePosition(1, cursorEnums.EndOfLine);
cursor.insertLine();
processedLines++;
}
processedLines++;
} else if (processedLines == 1) {
if (lineText == '') {
startEdits();
cursor.moveTo(i, 0);
cursor.eraseLine();
hasEdits = true;
} else {
processedLines++;
}
}
}
// If cursor was on a line that has been deleted
var lineCount = editor.document().lineCount();
if (r >= lineCount) {
r = lineCount - 1;
}
cursor.moveTo(r,c);
if (hasEdits) {
cursor.endEditBlock();
app.fileSave();
}
you can put the script either into wiki or texstudio-org/texstudio-macro
Most helpful comment
For newbies like me: The save trigger is
?save-file.