writing python doctests

Asked by reckoner

I would like a snippet to behave as shown:

>>> for i in range(3):
... print i
... print i*2

But the number of lines contained in the block can be arbitrary and there can be nested blocks such as

>>> for i in range(3):
... if i>0:
... print i

I am writing a lot of doctests in RST and this would help me a lot, especially with the nested indenting.

Question information

Language:
English Edit question
Status:
Answered
For:
UltiSnips Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
SirVer (sirver) said :
#1

I totally don't get what you want. I think UltiSnips can help you though :)

Please provide: keys you want to press -> result you want to get. Just read through what you've written and than image what I can make from this.

Revision history for this message
reckoner (reckoner) said :
#2

I can define a snippet like:

snippet dt "doctest" b
   >>> ${1:code}
   ... ${2:more_code}

$0
endsnippet

But, I would like an arbitrary number of lines instead of just two.
Also, it would be great to nest these blocks if possible.

Thanks!

On 8/25/2011 11:30 AM, SirVer wrote:
> Your question #169172 on UltiSnips changed:
> https://answers.launchpad.net/ultisnips/+question/169172
>
> Status: Open => Needs information
>
> SirVer requested more information:
> I totally don't get what you want. I think UltiSnips can help you though
> :)
>
> Please provide: keys you want to press -> result you want to get. Just
> read through what you've written and than image what I can make from
> this.
>

Revision history for this message
SirVer (sirver) said :
#3

Still don't get it:

snippet dt "doctest" b
>>> ${1:code ${2:and more code}}

$0
endsnippet

and you can of course expand new snippets inside of started snippets.

dt<tab>dt<tab>

no problem.

Revision history for this message
reckoner (reckoner) said :
#4

Your solution doesn't account for the "..." characters that you need in
a Python doctest. What I'm looking for is a way to handle multi-line
doctests using snippets.

So,

dt<TAB>

gives

>>> placeholder1
... placeholder2

where Ctrl+J moves to placeholder2 and so on. The trick is to let this
handle many more than to lines so that
subsequent Ctrl+J's move to further indented and "..." marked blocks.

Thanks!

I hope that made more sense.

On 8/25/2011 2:30 PM, SirVer wrote:
> Your question #169172 on UltiSnips changed:
> https://answers.launchpad.net/ultisnips/+question/169172
>
> Status: Open => Answered
>
> SirVer proposed the following answer:
> Still don't get it:
>
> snippet dt "doctest" b
>>>> ${1:code ${2:and more code}}
>
> $0
> endsnippet
>
> and you can of course expand new snippets inside of started snippets.
>
> dt<tab>dt<tab>
>
> no problem.
>

Revision history for this message
Ryan Wooden (ryan.wooden) said :
#5

This would be related to the idea of repeatable tabstops which has been talked about in the past but decided against. You could easily define a second snippet which inserts the "... " but it doesn't really seem worth it. With a minor change to UltiSnips (if SirVer wants to add it), you could do this:

snippet dt "doctest" !b
>>> $1`!p
if "lines" not in locals():
    lines = 0

newlines = t[1].count("\n")
if newlines > lines and len(t[1]) > 0 and t[1][-1] == "\n":
    t[1] += "... "
lines = newlines
`
$0
endsnippet

which would allow you to press <CR> and keep typing and it would automatically insert the "... ". But in order for this to work, UltiSnips needs to be modified to allow modification of tabstops from Python:

diff --git a/plugin/UltiSnips/TextObjects.py b/plugin/UltiSnips/TextObjects.py
index 05a7558..5a603ee 100644
--- a/plugin/UltiSnips/TextObjects.py
+++ b/plugin/UltiSnips/TextObjects.py
@@ -485,6 +485,11 @@ class _Tabs(object):
             return ""
         return ts.current_text

+ def __setitem__(self, no, value):
+ ts = self._to._get_tabstop(self._to, int(no))
+ if ts is not None:
+ ts.current_text = value
+
 class SnippetUtil(object):
     """ Provides easy access to indentation, etc.
     """

Revision history for this message
SirVer (sirver) said :
#6

Isn't this feature request redundant with comments+=s:>>> and set formatoptions+=r ?

Revision history for this message
reckoner (reckoner) said :
#7

Mysteriously, This isn't working for me. Furthermore, using this
approach, the first comment should be a '>>>' and then subsequent lines
should be prefixed with '...'.

I'm not sure how that works with your suggestion below.

Thanks!

On 8/26/2011 1:15 AM, SirVer wrote:
> Your question #169172 on UltiSnips changed:
> https://answers.launchpad.net/ultisnips/+question/169172
>
> Status: Open => Answered
>
> SirVer proposed the following answer:
> Isn't this feature request redundant with comments+=s:>>> and set
> formatoptions+=r ?
>

Revision history for this message
SirVer (sirver) said :
#8

Yep, I cannot get this to work with ... either. Strange enough; it works for >>> and for aaa for me. Seems like a vim thing. I then suggest going the route Ryan proposed.

@Ryan: are you willing to whip this patch in shape by adding a few tests and documentation?

Revision history for this message
reckoner (reckoner) said :
#9

Has this been resolved in the newest version of Ultisnips?

Thanks!

On Thu, Aug 25, 2011 at 4:25 PM, Ryan Wooden
<email address hidden> wrote:
> Your question #169172 on UltiSnips changed:
> https://answers.launchpad.net/ultisnips/+question/169172
>
> Ryan Wooden posted a new comment:
> This would be related to the idea of repeatable tabstops which has been
> talked about in the past but decided against. You could easily define a
> second snippet which inserts the "... " but it doesn't really seem worth
> it. With a minor change to UltiSnips (if SirVer wants to add it), you
> could do this:
>
> snippet dt "doctest" !b
>>>> $1`!p
> if "lines" not in locals():
>    lines = 0
>
> newlines = t[1].count("\n")
> if  newlines > lines and len(t[1]) > 0 and t[1][-1] == "\n":
>    t[1] += "... "
> lines = newlines
> `
> $0
> endsnippet
>
> which would allow you to press <CR> and keep typing and it would
> automatically insert the "... ". But in order for this to work,
> UltiSnips needs to be modified to allow modification of tabstops from
> Python:
>
> diff --git a/plugin/UltiSnips/TextObjects.py b/plugin/UltiSnips/TextObjects.py
> index 05a7558..5a603ee 100644
> --- a/plugin/UltiSnips/TextObjects.py
> +++ b/plugin/UltiSnips/TextObjects.py
> @@ -485,6 +485,11 @@ class _Tabs(object):
>             return ""
>         return ts.current_text
>
> +    def __setitem__(self, no, value):
> +        ts = self._to._get_tabstop(self._to, int(no))
> +        if ts is not None:
> +            ts.current_text = value
> +
>  class SnippetUtil(object):
>     """ Provides easy access to indentation, etc.
>     """
>
> --
> You received this question notification because you asked the question.

Revision history for this message
SirVer (sirver) said :
#10

Nope, no work has been done on this

Can you help with this problem?

Provide an answer of your own, or ask reckoner for more information if necessary.

To post a message you must log in.