Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions 4 Lib/idlelib/config-extensions.def
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ enable=True
enable_shell=False
enable_editor=True

[TrimExtension]
enable=True
enable_trim_on_save=True

[ScriptBinding]
enable=True
enable_shell=False
Expand Down
1 change: 1 addition & 0 deletions 1 Lib/idlelib/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,7 @@ def get_standard_extension_names(self):
'ParenMatch': 'parenmatch',
'RstripExtension': 'rstrip',
'ScriptBinding': 'runscript',
'TrimExtension': 'trim',
'ZoomHeight': 'zoomheight',
}

Expand Down
4 changes: 4 additions & 0 deletions 4 Lib/idlelib/idle_test/mock_tk.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ def _decode(self, index, endflag=0):
return lastline, len(self.data[lastline]) - 1
elif index == 'end':
return self._endex(endflag)
elif index.startswith('end-'):
a, b = index.split()
a = int(a[4: -1])
index = '%d.0' % (a + 1)

line, char = index.split('.')
line = int(line)
Expand Down
53 changes: 53 additions & 0 deletions 53 Lib/idlelib/idle_test/test_trim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import unittest
import idlelib.trim as trim
from test.support import requires
requires('gui')
from idlelib.editor import EditorWindow as Editor
from tkinter import Tk


class trimTest(unittest.TestCase):

def test_trim_line(self):
editor = Editor(root=Tk())
text = editor.text
do_trim = trim.TrimExtension(editor).do_trim

do_trim()
self.assertEqual(text.get('1.0', 'insert'), '')
text.insert('1.0', ' ')
do_trim()
self.assertEqual(text.get('1.0', 'insert'), '')
text.insert('1.0', ' \n')
do_trim()
self.assertEqual(text.get('1.0', 'insert'), '')

def test_trim_multiple(self):
editor = Editor(root=Tk())
text = editor.text
do_trim = trim.TrimExtension(editor).do_trim

original = (
"Line with an ending tab\t\n"
"Line ending in 5 spaces \n"
"Linewithnospaces\n"
" indented line\n"
" indented line with trailing space \n"
" \n"
"\n"
" \n"
"\n")
stripped = (
"Line with an ending tab\n"
"Line ending in 5 spaces\n"
"Linewithnospaces\n"
" indented line\n"
" indented line with trailing space\n")

text.insert('1.0', original)
do_trim()
self.assertEqual(text.get('1.0', 'insert'), stripped)


if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
13 changes: 13 additions & 0 deletions 13 Lib/idlelib/iomenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ def coding_spec(data):
return name


def strip_trailing_whitespace_and_blankline(f):
def _strip(self, event, *args, **kwargs):
if idleConf.GetOption('extensions', 'TrimExtension',
'enable_trim_on_save',
type='bool', default=False):
self.editwin.text.event_generate('<<do-trim>>')
return f(self, event, *args, **kwargs)
return _strip


class IOBinding:
# One instance per editor Window so methods know which to save, close.
# Open returns focus to self.editwin if aborted.
Expand Down Expand Up @@ -340,6 +350,7 @@ def maybesave(self):
self.text.focus_set()
return reply

@strip_trailing_whitespace_and_blankline
def save(self, event):
if not self.filename:
self.save_as(event)
Expand All @@ -353,6 +364,7 @@ def save(self, event):
self.text.focus_set()
return "break"

@strip_trailing_whitespace_and_blankline
def save_as(self, event):
filename = self.asksavefile()
if filename:
Expand All @@ -367,6 +379,7 @@ def save_as(self, event):
self.updaterecentfileslist(filename)
return "break"

@strip_trailing_whitespace_and_blankline
def save_a_copy(self, event):
filename = self.asksavefile()
if filename:
Expand Down
40 changes: 40 additions & 0 deletions 40 Lib/idlelib/trim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'Provides "Trim trailing whitespace and blank line" option'


class TrimExtension:

def __init__(self, editwin):
self.editwin = editwin
self.editwin.text.bind('<<do-trim>>', self.do_trim)

def do_trim(self, event=None):
text = self.editwin.text
undo = self.editwin.undo

undo.undo_block_start()

last = 0
end_line = int(float(text.index('end')))
for cur in range(1, end_line):
txt = text.get('%i.0' % cur, '%i.end' % cur)
raw = len(txt)
cut = len(txt.rstrip())

# Get the last non-blank line of code
if cut:
last = cur

# Since text.delete() marks file as changed, even if not,
# only call it when needed to actually delete something.
if cut < raw:
text.delete('%i.%i' % (cur, cut), '%i.end' % cur)

# Trim trailing blank line
text.delete('end-%ic linestart' % (end_line - last - 1), 'end')

undo.undo_block_stop()


if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_trim', verbosity=2, exit=False)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.