NAME
    Devel::PerlySense - IntelliSense for Perl

DESCRIPTION
    PerlySense is an IntelliSense style utility for editors.

    Conveniently navigate and browse the code and documentation of your
    project and Perl installation.

SYNOPSIS
  From Emacs
    C-p C-d -- Smart docs -- Show docs (POD/signature/etc) for the symbol
    (module/method/sub) at point. A doc hint is displayed in the message
    area (for methods and subs), or a new POD buffer is created (for
    modules).

    C-p C-g -- Smart go to -- Open file at proper location for module,
    method/sub declaration for the symbol (module/method/sub) at point. If
    no sub declaration is available (like for generated getters/setters),
    any appropriate POD is used instead.

    C-p m f -- Perl Module open File -- Open the source file of the module
    at point.

    As you can see, PerlySense duplicates some of the functionality in
    cperl-mode, and does more in certain areas.

  From the command line
    This is not very convenient unless you let your editor do it. See the
    "perly_sense" in bin script on how to do this.

    There is one useful command though; cache all the modules in @INC:

        perl perly_sense process_inc

  From other editors
    Any editor that is programmable and that can call a shell script could
    take advantage of PerlySense to implement something similar to the Emacs
    functionality. And most editors are programmable by the authors, if not
    by the users.

  From Perl
    See the source of the "perly_sense" in bin script, or the t directory.

INSTALLATION
    Install required modules from CPAN.

  Emacs installation
    Copy the file editors/emacs/perly-sense.el to your Emacs script dir
    (which should be in the load-path), and add this to the end of your
    .emacs config file:

      ; PerlySense
      (load "perly-sense")
      (global-unset-key "\C-p")
      (global-set-key (kbd "\C-p \C-d") 'perly-sense-smart-docs-at-point)
      (global-set-key (kbd "\C-p \C-g") 'perly-sense-smart-go-to-at-point)

    Adjust according to preference: the key mappings will replace the C-p
    command which may be really annoying for you if you don't use the arrow
    keys to move around. Suggestions welcome for other default key mappings.

GETTING STARTED WITH EMACS
    Open one of your Perl source files.

  Smart docs
    C-p C-d is the "Smart docs" command. It brings up documentation for
    what's at the point.

    Put the cursor on the "method" word of a $self->method call and press
    C-p C-d and wait until a documentation hint for the method call is
    displayed briefly in the message buffer. PerlySense will look in base
    classes if the method can't be found in the current class.

    Put the cursor on the "method" word of an $object->method call and press
    C-p C-d to see the docs hint. PerlySense will look through all your
    "use" modules (and their base classes) for the method call and try to
    identify the best match.

    Note! The first time each module is parsed this will take a second or
    two, and the very first time you run the command with lots of "use"
    modules it's bound to take longer than that.

    Put the cursor on a module name and press C-p C-d to bring up a new
    buffer with the POD for that module (this is similar to the cperl-mode
    feature, only a) not as good, but b) it works on Windows).

    Press C-p C-d with nothing under the cursor brings up a POD buffer for
    the current file.

  Smart go to
    C-p C-g is the "Smart go to" command. It's similar to Smart Docs, but
    instead of bringing the docs to you, it brings you to the definition of
    what's at the point.

    The definition can be either the sub declaration, or if the declaration
    can't be found (like for auto-generated getters/setters, autoloaded subs
    etc), the POD documentation for the sub.

*** THE FOLLOWING IS DEVELOPER DOCUMENTATION ***
PROPERTIES
  oCache
    Cache::Cache object, or undef if no cache is active.

    Default: undef

API METHODS
  new()
    Create new PerlySense object.

  oDocumentParseFile($file)
    Parse $file into a new PerlySense::Document object.

    Return the new object.

    Die on errors (like if the file wasn't found).

  podFromFile(file => $file)
    Return the pod in $file as text, or die on errors.

    Die if $file doesn't exist.

  oLocationSmartGoTo(file => $fileOrigin, row => $row, col => $row)
    Look in $file at location $row/$col and determine what is there.
    Depending on what's there, find the source declaration/whatever, find it
    and return an Devel::PerlySense::Document::Location object.

    Currently supported:

      $self->method, look in current file and base classes. If no sub can
      be found, look for POD.

      $object->method, look in current file and used modules. If no sub
      can be found, look for POD.

      Module::Name (bareword)

      Module::Name (as the only contents of a string literal)

    If there's nothing at $row/col, or if the source can't be found, return
    undef.

    Die if $file doesn't exist, or on other errors.

  oLocationSmartDoc(file => $fileOrigin, row => $row, col => $row)
    Look in $file at location $row/$col and determine what is there.
    Depending on what's there, find the documentation for it and return a
    Document::Location object with the following rhProperty keys set:

      text - the docs text
      found - "method" | "module"
      docType - "hint" | "document"
      name - the name of the thing found

    Currently supported:

      Same as for oLocationSmartGoTo

    If there's nothing at $row/col, use the current document.

    Die if $file doesn't exist, or on other errors.

  classNameAt(file => $fileOrigin, row => $row, col => $row)
    Look in $file at location $row/$col and determine what class name that
    is.

    Return the class name or "" if it's package main.

    Die if $file doesn't exist, or on other errors.

  classAt(file => $fileOrigin, row => $row, col => $row)
    Look in $file at location $row/$col and determine what PerlySelse::Class
    that is.

    Return the Class object or undef if it's package main.

    Die if $file doesn't exist, or on other errors.

  fileFindModule(nameModule => $nameModule, dirOrigin => $dirOrigin)
    Find the file containing the $nameModule given the $dirOrigin.

    Return the absolute file name, or undef if none could be found. Die on
    errors.

  oDocumentFindModule(nameModule => $nameModule, dirOrigin => $dirOrigin)
    Find the file containing the $nameModule given the $dirOrigin.

    Return a parsed PerlySense::Document, or undef if none could be found.
    Die on errors.

IMPLEMENTATION METHODS
  fileFindLookingAround($fileModuleBase, $dirOrigin)
    Find the file containing the $nameModule given the $dirOrigin.

    Return the file name relative to $dirOrigin, or undef if none could be
    found. Die on errors.

  fileFindLookingInInc($fileModuleBase)
    Find the file containing the $nameModule in @INC.

    Return the absolute file name, or undef if none could be found. Die on
    errors.

  fileFromModule($nameModule)
    Return the $nameModule converted to a file name (i.e. with dirs and .pm
    extension).

  fileFoundInDir($dir, $fileModuleBase)
    Look if $fileModuleBase is located in $dir. If it is, return the file
    name relative to $dirOrigin.

    Return the absolute file name, or "" if not found at $dir.

  textFromPod($pod)
    Return $pod rendered as text, or die on errors.

  oLocationRenderPodToText($oLocation)
    Render the $oLocation->rhProperty->{pod} and put it in
    rhProperty->{text}.

    Return the same (modified) $oLocation object, or undef if no
    rhProperty->{pod} property ended up as text (after this operation, there
    is content in rhProperty->{text}).

    Return undef if $oLocation is undef.

    Die on errors.

  aDocumentFindModuleWithInterface(raNameModule => $raNameModule, raMethodRequired => $raMethodRequired, raMethodNice => $raMethodNice, dirOrigin => $dirOrigin)
    Return a list with Devel::PerlySense::Document objects that support all
    of the methods in $raMethodRequired and possibly the methods in
    $raMethodNice. Look in modules in $raNameModule.

    The list is sorted with the best match first.

    If the document APIs have one or more base classes, look in the @ISA
    (depth-first, just like Perl (see perldoc perltoot)).

    Warn on some failures to find the location. Die on errors.

  aApiOfClass(file => $fileOrigin, row => $row, col => $row)
    Look in $file at location $row/$col and determine what package is there.

    Return a two item array with (Package name,
    Devel::PerlySense::Document::Api object with the likely API of that
    class), or () if none was found.

    Die if $file doesn't exist, or on other errors.

CACHE METHODS
  cacheSet(file => $file, key => $key, value => $valuex)
    If the oCache isn't undef, store the $value in the cache under the total
    key of ($file, $file's timestamp, $key, and the PerlySense VERSION).

    $value should be a scalar or reference which can be freezed.

    $file must be an existing file.

    Return 1 if the $value was stored, else 0. Die on errors.

  cacheGet(file => $file, key => $key)
    If the oCache isn't undef, get the value in the cache under the total
    key of ($file, $file's timestamp, $key) and return it.

    $file must be an existing file.

    Return the value, or undef if the value could not be fetched. Die on
    errors.

  cacheKeyTotal($file, $key)
    If oCache is undef, return undef.

    Otherwise, return the total key of ($file, $file's timestamp, $key, and
    the PerlySense VERSION).

    $file must be an existing file.

    Die on errors.

ON PARSING PERL
    Oh, that old topic again...

    Well, since Perl is so dynamic, a perfect static analysis of the source
    is impossible. But not unusable.

    Because of this PerlySense is not about exact rules, but about
    heuristics and a 90% solution that isn't perfect, but good-enough. If it
    works for you, use it to be more productive. If not, well... let me
    know.

    PerlySense tries to take advantage of the fact that Perl code is more
    than the plain source. The source lives in a context of POD and a
    directory structure and... oher source code.

SEE ALSO
    sepia - similar effort

    PPI - excellent for parsing Perl

    CPANXR - also uses PPI for cross referencing the CPAN

    <http://www.DarSerMan.com/Perl/Oasis/> - Win32 class browser/IDE.
    Earlier (a lot) work by me.

AUTHOR
    Johan Lindstrm, "<johanl[T]DarSerMan.com>"

BUGS AND CAVEATS
  BUG REPORTS
    Please report any bugs or feature requests to
    "bug-devel-perlysense@rt.cpan.org", or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel-PerlySense>. I
    will be notified, and then you'll automatically be notified of progress
    on your bug as I make changes.

  CAVEATS
    Tab/space isn't supported by PPI yet, but it's supposed to be. So using
    Tab instead of spaces won't work properly.

  KNOWN BUGS
    PPI is kinda slow for large documents. Lots of objects being created
    etc.

    There are certainly edge cases. Bug reports with failing tests
    appreciated :)

ACKNOWLEDGEMENTS
    Peter Liljenberg for his elisp fu.

COPYRIGHT & LICENSE
    Copyright 2005 Johan Lindstrm, All Rights Reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

