PyPN


13
Oct 08

Programmer’s Notepad 2 0.9.853

Turbo Pascal Preset  Read only, browser and open files 

Mark All

Today I released a new 0.9 build, here are the highlights:

  1. Create file backups when saving (option, defaulting to off)
  2. Updated some of the images in Find dialog and main UI, read only indicator now uses a tab image instead of text
  3. Extension configuration now stored in user settings directory, meaning this works on Vista without an admin prompt
  4. You can now choose to poll for updates of testing releases (like this one)
  5. Uncomment now works for multiple line-comment lines at once
  6. New keyboard shortcuts for line comments (if you haven’t customised your shortcuts, you’ll get Ctrl-, and Ctrl-. as defaults)
  7. Fixed a crash when going to the Advanced options page
  8. Added a new Turbo preset for Turbo Pascal lovers
  9. Improved the ZenBurn preset
  10. Default scheme font on Vista is now Consolas, still Lucida Console on XP and below

All that, and just since mid-September when .840 was released. If you missed that one, you missed all this:

  1. Allow opening workspace files
  2. Restore editor windows when jumping to a line or tag
  3. Improve regular expressions support (Xpressive now working just fine)
  4. Works on Win2k again
  5. Don’t hold directories open after selecting files
  6. Support explorer context menus in Browser, Open Files and Projects items
  7. Added Mark All (you can’t configure the colors yet, but that’s coming!)
  8. Find in all Project Files
  9. Find next across all open files

You didn’t think I’d been slacking did you?! There have also been lots of behind-the-scenes changes to improve stability and the quality of the code. Not too much more to go now before a new stable release is born. Then onwards with the push to 2.1.

You can download the latest bits here:

0.9.853 Installer

0.9.853 Portable

I’ve also updated PyPN to support Python 2.6 as well as 2.5 and 2.4:

PyPN 0.9.853 for Python 2.4

PyPN 0.9.853 for Python 2.5

PyPN 0.9.853 for Python 2.6


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.


28
May 08

Programmer’s Notepad 2 0.9.794 Released

It’s time for a second 0.9 unstable release, bringing a number of bug fixes and new features:

  • Automatic Update Check – at launch Programmer’s Notepad checks in the background whether there is an update available and shows you a message if there is one.
  • Vista open and save dialogs are now used throughout when you’re running Vista, previous OS versions should be unaffected
  • Programmer’s Notepad is now marked as Vista-aware, meaning that reads and writes to Program Files and similar locations are no longer redirected to the Virtual Store.
  • Find in Files can now search all open files
  • PyPN update 0.9 fixes a couple of event handlers

The update check is a very commonly requested feature. The system understands the difference between stable and unstable releases so most users will only ever see stable updates.

Currently there’s no UI option to enable unstable update checks (there will be!) but you can enable them for yourself by setting this registry value (assuming you’re using a default PN install):

Key: HKEY_CURRENT_USER\Software\Echo Software\PN2\General Settings
Value (REG_DWORD): CheckForUnstableUpdates = 1

209

What else is new in the 0.9 series?

  1. File browser window
  2. Open files window
  3. New, far better regular expressions support (multiline is coming)
  4. More colour schemes (I’m currently using ZenBurn) and the base styles adapt better with the colour schemes
  5. New PyPN release with more event hooks
  6. More Vista control styling dotted around (when running on Vista!)

Downloads

Installer: http://pnotepad.googlecode.com/files/pn209794.exe
Zip: http://pnotepad.googlecode.com/files/pn209794.zip
Portable Zip: http://pnotepad.googlecode.com/files/portable-pn209794.zip
PyPN for Python 2.4: http://pnotepad.googlecode.com/files/pypn-0.9.794-py24.zip
PyPN for Python 2.5: http://pnotepad.googlecode.com/files/pypn-0.9.794-py25.zip


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()

27
Mar 07

PyPN: Upload to FTP

Over in the forums, MurphyMc shows a sample bit of script that will upload your current file to FTP using Python via a PyPN script. It currently hard-codes site/user/pass etc. but these could easily be retrieved from elsewhere (potentially even project properties in the future).

Save To FTP Script

It’s easy to imagine how this could be extended in lots of directions, for example a script could retrieve a file from FTP, store it in a temporary location and then re-upload when the user is finished. That’s FTP integration done, what next!

Obviously I understand that many requests are for a fully-integrated FTP browser/editor, but this example really shows what can be achieved with the scripting integration.


27
Mar 07

PyPN: Validate Your Xml

Have you tried playing with PyPN and PN’s scripts system yet? If not, then perhaps you should. A large number of requests on PN’s Feature Requests tracker could be implemented as scripts. Some perhaps not so elegantly as if they were built in, others perfectly.

To start looking at ways that PyPN enhances Programmer’s Notepad, let’s look at a very early feature request: Validate XML.

Here is a simple PyPN script that does just this, adding a command to the scripts window called Validate in the XML group. This can, of course, be mapped to a keyboard shortcut.

The script simply runs the contents of your document through expat. When your Xml is valid no output is printed, where there’s an error the output window will show you the details.

To use this code, just drop it in a file called something like pnxml.py in the scripts directory. You’ll need PyPN installed, along with Python 2.4 and the PyXml package. As of Python 2.5 expat is bundled so the extra package won’t be necessary.


import pn
import scintilla
from pypn.decorators import script
import xml.parsers.expat as expat

@script("Validate", "Xml")
def ValidateXml():
	editor = scintilla.Scintilla(pn.CurrentDoc())
	text = editor.GetText(0, editor.Length)

	parser = expat.ParserCreate()

	try:
		parser.Parse(text, True)
	except expat.ExpatError, ex:
		pn.AddOutput("Error: " + str(ex))