NAME¶
Padre::Document - Padre Document API
DESCRIPTION¶
The
Padre::Document class provides a base class, default implementation
and API documentation for document type support in Padre.
As an API, it allows Padre developers and plug-in authors to implement extended
support for various document types in Padre, while ensuring that a naive
default document implementation exists that allows Padre to provide basic
support (syntax highlighting mainly) for many document types without the need
to install extra modules unless you need the extra functionality.
Document Type Registration¶
Padre uses MIME types as the fundamental identifier when working with documents.
Files are typed at load-time based on file extension (with a simple heuristic
fallback when opening files with no extension).
Many of the MIME types are unofficial X-style identifiers, but in cases without
an official type, Padre will try to use the most popular identifier (based on
research into the various language communities).
Each supported mime has a mapping to a Scintilla lexer (for syntax
highlighting), and an optional mapping to the class that provides enhanced
support for that document type.
Plug-ins that implement support for a document type provide a
"registered_documents" method that the plug-in manager will call as
needed.
Plug-in authors should
not load the document classes in advance, they
will be automatically loaded by Padre as needed.
Padre does
not currently support opening non-text files.
File to MIME type mapping¶
Padre has a built-in hash mapping the file extensions to MIME types. In certain
cases (.t, .pl, .pm) Padre also looks in the content of the file to determine
if the file is Perl 5 or Perl 6.
MIME types are mapped to lexers that provide the syntax highlighting.
MIME types are also mapped to modules that implement special features needed by
that kind of a file type.
Plug-ins can add further mappings.
Plan¶
Padre has a built-in mapping of file extension to either a single MIME type or
function name. In order to determine the actual MIME type Padre checks this
hash. If the key is a subroutine it is called and it should return the MIME
type of the file.
The user has a way in the GUI to add more file extensions and map them to
existing MIME types or functions. It is probably better to have a commonly
used name along with the MIME type in that GUI instead of the MIME type only.
I wonder if we should allow the users (and or plug-in authors) to change the
functions or to add new functions that will map file content to MIME type or
if we should just tell them to patch Padre. What if they need it for some
internal project?
A plug-in is able to add new supported MIME types. Padre should either check for
collisions if a plug-in wants to provide an already supported MIME type or
should allow multiple support modules with a way to select the current one.
(Again I think we probably don't need this. People can just come and add the
MIME types to Padre core.) (not yet implemented)
A plug-in can register zero or more modules that implement special features
needed by certain MIME types. Every MIME type can have only one module that
implements its features. Padre is checking if a MIME type already has a
registered module and does not let to replace it. (Special features such as
commenting out a few lines at once, auto-completion or refactoring tools).
Padre should check if the given MIME type is one that is in the supported MIME
type list. (TO DO)
Each MIME type is mapped to one or more lexers that provide the syntax
highlighting. Every MIME type has to be mapped to at least one lexer but it
can be mapped to several lexers as well. The user is able to select the lexer
for each MIME type. (For this each lexer should have a reasonable name too.)
(TO DO)
Every plug-in should be able to add a list of lexers to the existing MIME types
regardless if the plug-in also provides the class that implements the features
of that MIME type. By default Padre supports the built-in syntax highlighting
of Scintilla. Perl 5 currently has two PPI based syntax highlighter, Perl 6
can use the STD.pm or Rakudo/PGE for syntax highlighting but there are two
plug-ins - Parrot and Kate - that can provide syntax highlighting to a wide
range of MIME types.
"provided_highlighters()" returns a list of arrays like this:
['Module with a colorize function' => 'Human readable Name' => 'Long description']
"highlighting_mime_types()" returns a hash where the keys are module
names listed in "provided_highlighters", the values are array
references to MIME types:
'Module::A' => [ mime-type-1, mime-type-2]
The user can change the MIME type mapping of individual files and Padre should
remember this choice and allow the user to change it to another specific MIME
type or to set it to "Default by extension".
METHODS¶
new¶
my $doc = Padre::Document->new(
filename => $file,
);
$file is optional and if given it will be loaded in the document. MIME type is
defined by the "guess_mimetype" function.
error¶
$document->error( $msg );
Open an error dialog box with $msg as main text. There's only one OK button. No
return value.
load_file¶
$doc->load_file;
Loads the current file.
Sets the
Encoding bit using Encode::Guess and tries to figure out what
kind of newlines are in the file. Defaults to "utf-8" if it could
not figure out the encoding.
Returns true on success false on failure. Sets "$doc->errstr".
autocomplete_matching_char¶
The first argument needs to be a reference to the editor this method should work
on.
The second argument is expected to be a event reference to the event object
which is the reason why the method was launched.
This method expects a hash as the third argument. If the last key typed by the
user is a key in this hash, the value is automatically added and the cursor is
set between key and value. Both key and value are expected to be ASCII codes.
Usually used for brackets and text signs like:
$self->autocomplete_matching_char(
$editor,
$event,
39 => 39, # ' '
40 => 41, # ( )
);
Returns 1 if something was added or 0 otherwise (if anybody cares about this).
write¶
Writes the document to an arbitrary local file using the same semantics as when
we do a full file save.
reload¶
Reload the current file discarding changes in the editor.
Returns true on success false on failure. Error message will be in
"$doc->errstr".
TO DO: In the future it should backup the changes in case the user regrets the
action.
text_get¶
my $string = $document->text_get;
The "text_get" method returns the content of the document as a simple
plain scalar string.
text_length¶
my $chars = $document->GetLength;
The "text_length" method returns the size of the document in
characters.
Note that this is the character length of the document and not the byte size of
the document. The byte size of the file when saved is likely to differ from
the character size.
text_like¶
my $cool = $document->text_like( qr/(?:robot|ninja|pirate)/i );
The "text_like" method takes a regular expression and tests the
document to see if it matches.
Returns true if the document matches the regular express, or false if not.
text_set¶
$document->text_set("This is an\nentirely new document");
The "text_set" method takes a content string and does a complete
atomic replacement of the document with new and entirely different content.
It uses a simple and direct approach which is fast but is not aware of context
such as the current cursor position and the undo buffer.
As a result, it is only appropriate for use when a document is being changed for
new content that is completely and utterly different.
To change a document to a new version that is similar to the old one (such as
when you are doing refactoring tasks) the alternative "text_replace"
or ideally "text_delta" should be used instead.
text_replace¶
$document->text_replace("This is a\nmodified document");
The "text_replace" method takes content as a string and incrementally
modifies the current document to look like the new content.
The logic for this process is done with a Padre::Delta object created using
Algorithm::Diff and is run in the foreground. Because this blocks the entire
IDE it is considered relatively slow and expensive, and is particularly bad
for large documents.
But because it is by the most simple way of applying changes to a document and
does not require locks or background tasks, this method has a role to play in
early implementations of new logic.
Once functionality using "text_replace" has matured, you should
consider moving it into a background task which emits a Padre::Delta and then
use "text_delta" to apply the change to the editor in the
foreground.
Returns true if changes were made to the current document, or false if the new
document is identical to the existing one and no change was needed.
text_delta¶
The "text_delta" method takes a single Padre::Delta object as a
parameter and applies it to the current document.
Returns true if the document was changed, false if passed the null delta and no
changes were needed, or "undef" if not passed a Padre::Delta.
get_indentation_level_string¶
Calculates the string that should be used to indent a given number of levels for
this document.
Takes the indentation level as an integer argument which defaults to one. Note
that indenting to level 2 may be different from just concatenating the
indentation string to level one twice due to tab compression.
event_on_char¶
NOT IMPLEMENTED IN THE BASE CLASS
This method - if implemented - is called after any addition of a character to
the current document. This enables document classes to aid the user in the
editing process in various ways, e.g. by auto-pairing of brackets or by
suggesting usable method names when method-call syntax is detected.
Parameters retrieved are the objects for the document, the editor, and the
wxWidgets event.
Returns nothing.
Cf. "Padre::Document::Perl" for an example.
NOT IMPLEMENTED IN THE BASE CLASS
This method - if implemented - is called when a user triggers the context menu
(either by right-click or the context menu key or Shift+F10) in an editor
after the standard context menu was created and populated in the
"Padre::Wx::Editor" class. By manipulating the menu document classes
may provide the user with additional options.
Parameters retrieved are the objects for the document, the editor, the context
menu ("Wx::Menu") and the event.
Returns nothing.
event_on_left_up¶
NOT IMPLEMENTED IN THE BASE CLASS
This method - if implemented - is called when a user left-clicks in an editor.
This can be used to implement context-sensitive actions if the user presses
modifier keys while clicking.
Parameters retrieved are the objects for the document, the editor, and the
event.
Returns nothing.
project¶
my $project = $document->project;
The "project" method is used to discover which project a document is
part of. It uses a variety of methods to discover, scanning the file system if
needed to "intuit" the location and type of project.
Returns a Padre::Project object for the project, or "undef" if the
document is unsaved, anonymous, or not part of any type of project for some
other reason.
project_dir¶
my $path = $document->project_dir;
The "project_dir" method behaves similarly to "project", but
instead it returns a path to the root directory of the project for this
document.
Returns a directory as a string, or '' if the document is unsaved, anonymous, or
not part of any type of project for some other reason.
guess_indentation_style¶
Automatically infer the indentation style of the document using
Text::FindIndent.
Returns a hash reference containing the keys "use_tabs",
"tabwidth", and "indentwidth". It is suitable for passing
to "set_indendentation_style".
guess_filename¶
my $name = $document->guess_filename
When creating new code, one job that the editor should really be able to do for
you without needing to be told is to work out where to save the file.
When called on a new unsaved file, this method attempts to guess what the name
of the file should be based purely on the content of the file.
In the base implementation, this returns "undef" to indicate that the
method cannot make a reasonable guess at the name of the file.
Your MIME type specific document subclass should implement any file name
detection as it sees fit, returning the file name as a string.
guess_subpath¶
my $subpath = $document->guess_subpath;
When called on a new unsaved file, this method attempts to guess what the
sub-path of the file should be inside of the current project, based purely on
the content of the file.
In the base implementation, this returns a null list to indicate that the method
cannot make a reasonable guess at the name of the file.
Your MIME type specific document subclass should implement any file name
detection as it sees fit, returning the project-rooted sub-path as a list of
directory names.
These directory names do not need to exist, they only represent intent.