diff --git a/python/src/META-INF/plugin.xml b/python/src/META-INF/plugin.xml
index 01608ed05b0b..afae9974faf8 100644
--- a/python/src/META-INF/plugin.xml
+++ b/python/src/META-INF/plugin.xml
@@ -29,5 +29,7 @@
+
+
diff --git a/python/src/com/jetbrains/python/editor/selectWord/PyStatementSelectionHandler.java b/python/src/com/jetbrains/python/editor/selectWord/PyStatementSelectionHandler.java
new file mode 100644
index 000000000000..a40553466cbb
--- /dev/null
+++ b/python/src/com/jetbrains/python/editor/selectWord/PyStatementSelectionHandler.java
@@ -0,0 +1,39 @@
+package com.jetbrains.python.editor.selectWord;
+
+import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandlerBase;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.jetbrains.python.psi.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public class PyStatementSelectionHandler extends ExtendWordSelectionHandlerBase {
+ public boolean canSelect(final PsiElement e) {
+ return e instanceof PyStringLiteralExpression || e instanceof PyCallExpression || e instanceof PyStatement ||
+ e instanceof PyStatementList || e instanceof PyFunction || e instanceof PyClass;
+ }
+
+ public List select(final PsiElement e, final CharSequence editorText, final int cursorOffset, final Editor editor) {
+ List result = new ArrayList();
+ PsiElement endElement = e;
+ while(endElement.getLastChild() != null) {
+ endElement = endElement.getLastChild();
+ }
+ if (endElement instanceof PsiWhiteSpace) {
+ final PsiElement prevSibling = endElement.getPrevSibling();
+ if (prevSibling != null) {
+ endElement = prevSibling;
+ }
+ }
+ result.addAll(expandToWholeLine(editorText, new TextRange(e.getTextRange().getStartOffset(),
+ endElement.getTextRange().getEndOffset())));
+
+ return result;
+ }
+}
diff --git a/python/src/com/jetbrains/python/editor/selectWord/PyWordSelectionHandler.java b/python/src/com/jetbrains/python/editor/selectWord/PyWordSelectionHandler.java
new file mode 100644
index 000000000000..38217089a896
--- /dev/null
+++ b/python/src/com/jetbrains/python/editor/selectWord/PyWordSelectionHandler.java
@@ -0,0 +1,14 @@
+package com.jetbrains.python.editor.selectWord;
+
+import com.intellij.codeInsight.editorActions.wordSelection.AbstractWordSelectioner;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.PyTokenTypes;
+
+/**
+ * @author yole
+ */
+public class PyWordSelectionHandler extends AbstractWordSelectioner {
+ public boolean canSelect(final PsiElement e) {
+ return e.getNode().getElementType() == PyTokenTypes.IDENTIFIER;
+ }
+}
diff --git a/python/testData/selectWord/word/after1.py b/python/testData/selectWord/word/after1.py
new file mode 100644
index 000000000000..786871240898
--- /dev/null
+++ b/python/testData/selectWord/word/after1.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testData/selectWord/word/after2.py b/python/testData/selectWord/word/after2.py
new file mode 100644
index 000000000000..8db61098735c
--- /dev/null
+++ b/python/testData/selectWord/word/after2.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testData/selectWord/word/after3.py b/python/testData/selectWord/word/after3.py
new file mode 100644
index 000000000000..8d4a9de28043
--- /dev/null
+++ b/python/testData/selectWord/word/after3.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testData/selectWord/word/after4.py b/python/testData/selectWord/word/after4.py
new file mode 100644
index 000000000000..ec3b6c795f0c
--- /dev/null
+++ b/python/testData/selectWord/word/after4.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testData/selectWord/word/after5.py b/python/testData/selectWord/word/after5.py
new file mode 100644
index 000000000000..e2dc9e6da996
--- /dev/null
+++ b/python/testData/selectWord/word/after5.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testData/selectWord/word/before.py b/python/testData/selectWord/word/before.py
new file mode 100644
index 000000000000..1e96862607d9
--- /dev/null
+++ b/python/testData/selectWord/word/before.py
@@ -0,0 +1,5 @@
+import os
+
+def f(arg):
+ print arg
+ print "a"
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/PySelectWordTest.java b/python/testSrc/com/jetbrains/python/PySelectWordTest.java
new file mode 100644
index 000000000000..2712bc1b5215
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/PySelectWordTest.java
@@ -0,0 +1,47 @@
+package com.jetbrains.python;
+
+import com.intellij.codeInsight.editorActions.SelectWordHandler;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * @author yole
+ */
+public class PySelectWordTest extends LightCodeInsightTestCase {
+ public void testWord() throws Exception {
+ doTest();
+ }
+
+ private void doTest() throws Exception {
+ @NonNls final String path = getTestName(true);
+ configureByFile(path + "/before.py");
+ int i = 1;
+ while (true) {
+ @NonNls String resultPath = path + "/after" + i + ".py";
+ if (new File(getTestDataPath() + resultPath).exists()) {
+ performAction();
+ //System.out.println("comparing with "+resultPath);
+ checkResultByFile("Step " + i, resultPath, false);
+ i++;
+ }
+ else {
+ break;
+ }
+ }
+ assertTrue(i>1);
+ }
+
+ private void performAction() {
+ SelectWordHandler action = new SelectWordHandler(null);
+ action.execute(getEditor(), DataManager.getInstance().getDataContext());
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PathManager.getHomePath() + "/plugins/python/testData/selectWord/";
+ }
+}