python


13
May 09

PyPN Script Repository

Like the idea of using Python scripts to enhance Programmer’s Notepad but not sure where to start? James Yoneda has created the awesome ScriptShare website for exactly this purpose:

Scriptshare in Google Chrome

Scriptshare in Google Chrome

There are a bunch of scripts already there, and hopefully you will add yours too! We’re working on getting this moved over to pnotepad.org eventually.

My thanks to James for putting this effort in and creating such a useful site in such short time!


13
May 09

PyPN 0.10.973 Released

I’m happy to announce a minor bug fix release for PyPN, the Python extension for Programmer’s Notepad. This release fixes a PN crash if you tried to create a Scintilla object with no active document, and also the exception syntax problem preventing PyPN from working in Python 2.4-2.5.

Downloads


11
Feb 09

Programmer’s Notepad 2 0.9.921 Released

The latest testing release of Programmer’s Notepad 2 is finally out. There are plenty of fixes in this release, and a few minor new features too. Of particular note are the following:

  1. Updates to the extensions interface allowing extensions to create menu items
  2. International input fixed (I know this will please a whole bunch of users)
  3. Read only edit protection cleaned up
  4. More text transforms, also available from context menu
  5. Tab to space and vice versa conversions fixed
  6. Notepad’s .LOG feature natively supported
  7. Fix a problem using PN on the Windows 7 beta causing PN to hang on exit

Downloads

There is a new PyPN release supporting the updated plugin interface:

Thanks to all the users who have put time and effort into reporting and following up on bugs, testing, and contributing patches.


3
Jun 08

Line Movement Commands with PyPN

A bug on Google Code asked for an alternative to the built-in Transpose Lines command in Programmer’s Notepad, allowing a single command to move the current line up or down, allowing repeated use to shift a line through the current document.

To look at implementing this, I started with a python script – it’s so much quicker than writing C++ code to add these commands and going through compile/test for every change.

Here’s how to add these commands as a couple of scripts (which of course can have keyboard shortcuts):

import pn, scintilla, pypn.glue

@script("Move Line Up", "Text")
def MoveLineUp():
	s = scintilla.Scintilla(pn.CurrentDoc())
	l = s.LineFromPosition(s.CurrentPos)
	if (l == 0):
		return

	s.BeginUndoAction()
	s.LineTranspose()
	s.LineUp()
	s.EndUndoAction()

@script("Move Line Down", "Text")
def MoveLineDown():
	s = scintilla.Scintilla(pn.CurrentDoc())
	l = s.LineFromPosition(s.CurrentPos)
	if (l == (s.LineCount-1)):
		return

	s.BeginUndoAction()
	s.LineDown()
	s.LineTranspose()
	s.EndUndoAction()

Drop this in a file in your scripts directory to use it (remember you need PyPN installed), or wait for the next version of PN which has these commands built in.


28
May 08

Implementing Notepad’s .LOG Feature with PyPN

Notepad has a little-known feature where if you start a file with .LOG then every time the file is loaded the current date and time will be appended to the end of the file – allowing you to use a simple text file as a sort of diary.

A feature request came in for this and, pending a decision on whether to support it directly in Programmer’s Notepad, I decided to show how it could be implemented using the latest PyPN bits:

Updated: Fixed a couple of minor bugs thanks to Jeff Rivett:

import scintilla, pn, pypn.glue, time

oldDocLoad = pypn.glue.onDocLoad

def docLoad(doc):
    """ docLoad handler to implement notepad .LOG functionality"""

    # Get the edit component:
    s = scintilla.Scintilla(doc)

    # Get the first line:
    lineLength = s.LineLength(0)
    text = s.GetText(0, lineLength)

    # If we have .LOG then add a blank line and then the date and time
    if text.startswith(".LOG"):
        timestr = "\r\n\r\n" + time.asctime(time.localtime()) + "\r\n"
        s.AppendText(len(timestr), timestr)

        # Jump to the end of the document
        s.DocumentEnd()

    oldDocLoad(doc)

pypn.glue.onDocLoad = docLoad

Just drop this code in a file called dotlog.py under Programmer’s Notepad\scripts and you’ll have the .LOG functionality. This all uses the very latest 2.0.9 unstable bits and the related PyPN build.


24
Apr 08

Context-Sensitive Python Help

Over on the forums, Michel Claveau shows how he gets context-sensitive help for Python code in Programmer’s Notepad:

  1. Check where your python help file is (e.g. c:\python25\doc\Python25.chm)
  2. Install keyHH from http://www.keyworks.net/keyhh.htm
  3. Create a new tool in PN:
        – name: Python context Help
        – command: c:\windows\keyhh
        – parameters: -MyHelp -#klink “%w” c:\python25\doc\Python25.chm
        – shortcut: F1
  4. Use it!

Open a Python-source-file, click on the middle of a “strategic” word (examples: “time”, “sys”, “open”, etc.) or select the entire word, like “time.sleep”, and finally press [F1] and [Enter]

[Forum Post]


27
Oct 07

Programmer’s Notepad – Calculator Part 2

This time we’re going to use a PyPN script to evaluate maths expressions. We’re cheating a little, because we’re just going to ask python to evaluate a string and get a number back out.

import pn, scintilla

@script("Calculator")
def DoMaths():
    s = scintilla.Scintilla(pn.CurrentDoc())

    if s.SelectionEnd - s.SelectionStart < 1:
        return

    sel = s.SelText

    i = eval(sel)
    if type(i) in [int, float, complex]:
        pn.AddOutput(str(i))

To use this, simply select an expression like “5+5″ in the editor, run the script, and the output window will contain the evaluation of the expression.

This script is very simple, and in fact could be generalised to a python expression evaluator, but it serves the intended purpose well. It could also be adapted to make sure that expressions are of the form "exp=" and then put the result after the = sign, or perhaps to replace the selected expression with the result. These changes are left as exercises for the reader!


26
Oct 07

Programmer’s Notepad – a Calculator?!

One of the recent feature requests for Programmer’s Notepad was to add the ability in PN to perform basic numeric conversions, e.g. decimal to hex. Also the ability to evaluate simple mathematical expressions like 2+3=.

With the PyPN extension this is very easy, and the required features can even be bound to keyboard shortcuts.

Number Conversions:

The first thing we might want to do is see hex, decimal, octal or even binary representations of a selected number. The following script plus helper functions does this for decimal or hex selections:

import pn, scintilla 

def hex2dec(s):
    """return the integer value of a hexadecimal string s"""
    return int(s, 16) 

def Denary2Binary(n):
    """convert denary integer n to binary string bStr"""
    bStr = ''
    if n < 0:
        raise ValueError, "must be a positive integer"
    if n == 0:
        return '0'
    while n > 0:
        bStr = str(n % 2) + bStr
        n = n >> 1
    return bStr 

@script("ConvertNumber")
def ConvertNumber():
    s = scintilla.Scintilla(pn.CurrentDoc())
    if s.SelectionEnd - s.SelectionStart < 1:
        return sel = s.SelText
    if sel.find('0x') != -1:
        sel = sel.replace("0x", "")
        sel = hex2dec(sel)
    else:
        sel = int(sel)
    pn.AddOutput("Dec: %d\n" % sel)
    pn.AddOutput("Hex: 0x%X\n" % sel)
    pn.AddOutput("Oct: %o\n" % sel)
    pn.AddOutput("Bin: %s" % Denary2Binary(sel))

In the next post we’ll look at evaluating simple math expressions.


17
Apr 07

Build 667 and PyPN 0.5

A new development build is available on Sourceforge, get it here:

Download PN 2.0.7.667

Also: Zip Distribution | Portable Edition Zip

This build introduces the global scheme management changes that have been promised for a long time. This means that (where the schemes have been updated already) you can change a single colour and have keywords, numbers, properties and the like use that colour in all schemes. It does need some schemes to be updated to work properly which is ongoing work.

Styles Options

The build also finally seperates HTML/PHP schemes from the original Hypertext and adds a PHP Script scheme for pure PHP files (i.e. ones with no <?php?>) in them.

Other changes are of more interest to extension developers. The tagging interface has been removed and a new one created within the standard extensions framework. The ctags tagger is now an extension – users should notice no difference.

There is a new extension discovery mechanism, simply run PN with the “–findexts” argument and config.xml will be updated with all found extensions.

Finally there are a couple of new extension points in the interface allowing extensions to respond to events when documents are saved and loaded (before and after respectively).

PyPN 0.5 has been released at the same time, providing compatibility with the new build along with some minor fixes and support for the new events.


10
Apr 07

Tabs to Spaces with PyPN

Want to convert your tabs to spaces and annoyed that your editor author hasn’t implemented that feature in a handy menu item yet?

Add a PyPN script to do it:

import pn
import scintilla
from pypn.decorators import script

def SetTarget(e, x, y):
	e.TargetStart = x
	e.TargetEnd = y

@script("Tabs to Spaces", "Text")
def TabsToSpaces():
	editor = scintilla.Scintilla(pn.CurrentDoc())

	tabSpaces = editor.TabWidth
	spaces = ""
	for x in range(tabSpaces):
		spaces = spaces + " "

	end = editor.Length

	SetTarget(editor, 0, end)
	editor.SearchFlags = 0
	editor.BeginUndoAction()

	pos = editor.SearchInTarget(1, "\t")

	while(pos != -1):
		l1 = editor.TargetEnd - editor.TargetStart
		editor.ReplaceTarget(tabSpaces, spaces)

		# adjust doc length
		end = end + tabSpaces - l1
		start = pos + tabSpaces

		if start >= end:
			pos = -1
		else:
			SetTarget(editor, start, end)
			pos = editor.SearchInTarget(1, "\t")

	editor.EndUndoAction()