Giter Club home page Giter Club logo

ede-php-autoload's Introduction

ede-php-autoload

http://melpa.org/packages/ede-php-autoload-badge.svg http://stable.melpa.org/packages/ede-php-autoload-badge.svg https://travis-ci.org/emacs-php/ede-php-autoload.svg

Description

This project simulates PHP autoloading system to use it in Semantic. It is composed of 3 parts:

  • An EDE project, ede-php-autoload, that defines autoloading configuration for a project. It is able to parse composer.json files to extract autoloading information from it
  • A SemanticDB backend that can find a tag by name using the autoload information of the current ede-php-autoload project
  • A minor mode, ede-php-autoload-mode, that enables the SemanticDB backend for a buffer.

Defining autoloads for a project

Let’s assume we have a project located at /home/me/my-project. It has 3 namespaces:

  • MyFirstNs, located at src/MyFirstNs, and uses the PSR-0 norm
  • MySecondNs, located at src/MySecondNs, and uses the PSR-4 norm
  • ThirdPartyNs, located at vendor/third-party/src, and uses the PSR-4 norm

Defining this project and its autoload information is done like this:

(ede-php-autoload-project "My project"
                          :file "/home/me/my-project/main.php"
                          :class-autoloads '(:psr-0 (("MyFirstNs" . "src/MyFirstNs"))
                                             :psr-4 (("MySecondNs" . "src/MySecondNs")
                                                     ("ThirdPartyNs" . "vendor/third-party/src"))))

If you have a composer.json at the root of your project, its autoload information (and also the one in the composer dependencies) will be merged with the information you put in :class-autoloads.

If your composer.json contains all the autoload information, and you have nothing to add in :class-autoloads, you don’t have to define an EDE project by hand. It will be automatically created when you visit a file in your project.

Enabling the SemanticDB backend in php buffers

(add-hook 'php-mode-hook #'ede-php-autoload-mode)

Commands

NameDescription
M-x ede-php-autoload-reload-autoloadsSimilar to the reindexation in IDEs. Use it when your composer configuration changed to reload the autoloads.

License

This project is released under the GPL v3 license. See GPL for details.

ede-php-autoload's People

Contributors

jcs090218 avatar jorissteyn avatar stevenremot avatar tarsius avatar xendk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ede-php-autoload's Issues

Transfer ownership to emacs-php

Following emacs-php/php-mode#235, the ownership of this package will be transfered to the @emacs-php group.

Tasks to perform:

  • Move the repository
  • Update the MELPA recipe
  • Ensure the CI works properly
  • Update references to the old repository URL to the new one

I would like to know if you see other tasks to do @zonuexe , either for ownership transferring, or for making it easy for others to contribute.

Support installer-paths

Drupal 8 (and I suspect other frameworks) uses https://github.com/composer/installers to relocate where the installed packages is placed.

The bad news is that composer basically allows composer plugins to mess with where packages are installed. The good news is that a large amount of frameworks uses composer/installers rather than their own custom one.

Sadly, composer doesn't note the installed path of a package in the lock file. That would have been too easy.

As I see it, what is needed is:

  1. Triggering on composer/installers being part of the dependencies.
  2. For each package discovered, check up on installer-paths to adjust its root path.

Each path can contain {$name}, {$vendor} and {$type}. Vendor can be taken from the package name, name is either taken from "installer-name" from the "extra" section of te packages composer.json, or the package name. Type is the "type" from the composer.json or "library"...

Each path points to an array of what to install there, which can be:

  1. A package name, ie. "drupal/core"
  2. A vendor: "vendor:my_organization"
  3. A package type: "type:drupal-module"

A bit fiddly, but not too bad...

This is step one in getting Drupal 8 working. Of course a solution that just hooks into ede-php-autoload and adjusts things for Drupal is also a possibility, but supporting composer/installers gives support for many more frameworks.

Problems with nested composer files

When opening files from a vendor package which has a composer.json, it creates a new ede project in the vendor project.

This causes the rest of the main project to become "invisible" to ede-php-autoload, which is a problem.

I've tried making ede-php-autoload-proj-root return the topmost composer.json, but it doesn't seem to be called (or somethings messing with me).

Or perhaps it's not creating a new project, but the vendor composer.json is confusing it somehow? (yeah, it's getting late here).

(side note, I've grown rather fond of https://github.com/jorgenschaefer/emacs-buttercup , so much that I've rewritten ede-php-autoload-drupals tests in it)

Support include-path and system-include-path

Despite earlier conversations about whether or not to support require/include directives, I kinda changed my mind on the subject. Altough not that useful on real-life projects, it just makes sense to implement this use-case, because it is simpler than the alternatives and gives us a good "base-line".

Anyway, what I'm missing in ede-php-autoload is the include-path and system-include-path properties. I currently work around it by using ede-cpp-project-root:

(ede-cpp-root-project "ZF1"
                      :file "/home/joris/repos/zf1/composer.json"
                      :include-path '("/home/joris/repos/zf1/library")
                      :system-include-path '("/usr/share/php"))

But in order to get the best of both, I'd like to use:

(ede-php-autoload-project "ZF1"
                           :file "/home/joris/repos/zf1/composer.json"
                           :include-path '("/home/joris/repos/zf1/library")
                           :system-include-path '("/usr/share/php"))

Is that a matter is changing the base class, or would it involve more work?

Cannot resolve file name for classes under PSR-0 + target-dir

I have written a function to open the source of a use statement that uses your function ede-php-autoload-find-class-def-file to get the file name.

I immediately noticed that it worked fine with Larave's PSR-4 Illuminate classes but not with earlier versions of components from both the Zend and Symfony frameworks.

Those packages still use the PSR-0 autoloader along with a target-dir declaration in the composer.json file [1,2, 3] and they all fail the file resolution with a resulting nil.

I have hacked the function to load those packages as well, but it's obviously far from acceptable, since the code is making assumptions about a non-standard structure that changes from package to package, and is untested.

I haven't had the time to work with the ede-php-autoload functions that operate on the composer file, but I think that a fix to this problem would involve using the target-dir attribute to reconstruct the path in ede-php-autoload-find-class-def-file.

As a sidenote, I wasn't able to run make test properly as it ends with an error, but them tests all pass when run interactively with ert.

Trouble Installing

Forgive me if this is a silly question, but I am trying to install this package and I cannot see it anywhere on (M)elpa. I have cloned the project and tried to load it like so:

(setq debug-on-error t)
(add-to-list 'load-path "~/.emacs.d/packages/ede-php-autoload/")
(load "ede-php-autoload")

However I am receiving an error when entering dired-mode and selecting a directory/file.

I receive the following log:

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  string-match("^/tmp_mnt/" nil)
  abbreviate-file-name(nil)
  locate-dominating-file(nil "composer.json")
  (let ((dominating-file (locate-dominating-file (buffer-file-name) ede-php-autoload-composer-file))) (if dominating-file (progn (file-name-directory dominating-file))))
  ede-php-autoload-proj-root()
  funcall(ede-php-autoload-proj-root)
  ede-project-autoload([object ede-project-autoload "php-autoload" "PHP AUTOLOAD" ede-php-autoload "composer.json" "" ede-php-autoload-proj-root nil ede-php-autoload-load ede-php-autoload-project nil nil t] "/home/elliot/Development/")
  apply(ede-project-autoload ([object ede-project-autoload "php-autoload" "PHP AUTOLOAD" ede-php-autoload "composer.json" "" ede-php-autoload-proj-root nil ede-php-autoload-load ede-php-autoload-project nil nil t] "/home/elliot/Development/"))
  eieio-generic-call-primary-only(ede-project-root-directory ([object ede-project-autoload "php-autoload" "PHP AUTOLOAD" ede-php-autoload "composer.json" "" ede-php-autoload-proj-root nil ede-php-autoload-load ede-php-autoload-project nil nil t] "/home/elliot/Development/"))
  ede-project-root-directory([object ede-project-autoload "php-autoload" "PHP AUTOLOAD" ede-php-autoload "composer.json" "" ede-php-autoload-proj-root nil ede-php-autoload-load ede-php-autoload-project nil nil t] "/home/elliot/Development/")
  #[(this dir) "\306�!�\307\n   \"�\310\n\311\"�\310\n\312\"�\f;\203#

This makes me think I am doing something wrong here? Are there any instructions or documentation on installing and loading this package?

Feature request: Local variable return type hints for semantic

Hi,
excellent work so far for navigating in a composer based application on the tracks of semanticdb. Since this works on top of the parser, i would like to propose for the typical php-project return type declaration method, which is mainly used in other IDEs. However, since PHP 7 adoption, which includes return type declarations officialy, will take its time in the frameworks and application out there, why not adopt the following common used method:

/** @var $myRepository Bundle\Package\ParentDir\SubDir\MyRepository */
$myRepository = $container->getMyRepository();

Is it possible to parser the above with your wisent-php package? It would a killer feature in my humble opinion, for navigation through and completion of larger codebases without php-lang-based return-type declarations. This kind of return type hint will stay a long time with us, i think. What's your opinion?

Weed out non-existent dirs?

Now that #19 merges paths, should there be a :late visitor that removes non-existent paths? They don't do much harm, but if composer/installers has relocated a lot of projects, it might be a bit ineffective to repeatedly check if classes exists in non-existing dirs.

Incompatibility with CEDET 2.0

ede-php-autoload doesn't work when using CEDET 2.0. If you remember this is most certainly down to the great changes that EIEIO has undergone.

This happens when I call (ede-php-autoload-find-class-def-file ..) from my code.

Debugger entered--Lisp error: (cl-no-applicable-method ede-php-autoload-find-class-def-file nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face)))
  signal(cl-no-applicable-method (ede-php-autoload-find-class-def-file nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face))))
  cl-no-applicable-method([cl-struct-cl--generic ede-php-autoload-find-class-def-file ((0 [cl-struct-cl--generic-generalizer 50 cl--generic-struct-tag #[257 "\2119\205*�\301�!\205*�\302�J!\205*�\211JG\303Y\205*�\211J\304H�>\205*�\305\306\307�J!\"\207" [cl-struct-eieio--class-tags boundp vectorp 12 0 mapcar eieio--class-name eieio--class-precedence-list] 5 "\n\n(fn TAG)"]] [cl-struct-cl--generic-generalizer 0 #[257 "\300\207" [nil] 2 "\n\n(fn NAME)"] #[257 "\300\207" [(t)] 2 "\n\n(fn TAG)"]])) ([cl-struct-cl--generic-method (ede-php-autoload-project) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\302\303�\304\" \"\207" [this class-name ede-php-autoload-find-class-def-file eieio-oref class-loader] 4 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-aggregate-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\304�\305\"\306�\211�\203��   \204��\307\n@�\"�\nA\211�\204�� *\207" [this class-def-file loaders class-name eieio-oref class-loaders nil ede-php-autoload-find-class-def-file] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr0-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "�\306H\307U\203���\310\311O\202����\312\313 !�\314\n\303\"�\311��\203H�\f\204H��@\315���\316��@�\"\203A�\317\320���@\"��A #��A�*\202��\f,\207" [class-name project-root this namespaces class-def-file candidate-file 0 92 1 nil ede-project-root-directory ede-current-project eieio-oref "" string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns pair] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr4-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\306\307 !�\310    \302\"�\311�\n\2031��\2041�\n@�\312\f@
\"\203*�\313\314
\f@\"\fA�#�\nA�)\202\f��+\207" [project-root this namespaces class-def-file pair class-name ede-project-root-directory ede-current-project eieio-oref nil string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\300\301!\207" [error "Method `ede-php-autoload-find-class-def-file' must be overriden"] 2 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]]) nil] nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face)))
  apply(cl-no-applicable-method [cl-struct-cl--generic ede-php-autoload-find-class-def-file ((0 [cl-struct-cl--generic-generalizer 50 cl--generic-struct-tag #[257 "\2119\205*�\301�!\205*�\302�J!\205*�\211JG\303Y\205*�\211J\304H�>\205*�\305\306\307�J!\"\207" [cl-struct-eieio--class-tags boundp vectorp 12 0 mapcar eieio--class-name eieio--class-precedence-list] 5 "\n\n(fn TAG)"]] [cl-struct-cl--generic-generalizer 0 #[257 "\300\207" [nil] 2 "\n\n(fn NAME)"] #[257 "\300\207" [(t)] 2 "\n\n(fn TAG)"]])) ([cl-struct-cl--generic-method (ede-php-autoload-project) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\302\303�\304\"   \"\207" [this class-name ede-php-autoload-find-class-def-file eieio-oref class-loader] 4 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-aggregate-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\304�\305\"\306�\211�\203��   \204��\307\n@�\"�\nA\211�\204�� *\207" [this class-def-file loaders class-name eieio-oref class-loaders nil ede-php-autoload-find-class-def-file] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr0-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "�\306H\307U\203���\310\311O\202����\312\313 !�\314\n\303\"�\311��\203H�\f\204H��@\315���\316��@�\"\203A�\317\320���@\"��A #��A�*\202��\f,\207" [class-name project-root this namespaces class-def-file candidate-file 0 92 1 nil ede-project-root-directory ede-current-project eieio-oref "" string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns pair] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr4-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\306\307 !�\310    \302\"�\311�\n\2031��\2041�\n@�\312\f@
\"\203*�\313\314
\f@\"\fA�#�\nA�)\202\f��+\207" [project-root this namespaces class-def-file pair class-name ede-project-root-directory ede-current-project eieio-oref nil string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[(this class-name) "\300\301!\207" [error "Method `ede-php-autoload-find-class-def-file' must be overriden"] 2 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]]) nil] (nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face))))
  #[128 "\301\302\300�#\207" [[cl-struct-cl--generic ede-php-autoload-find-class-def-file ((0 [cl-struct-cl--generic-generalizer 50 cl--generic-struct-tag #[257 "\2119\205*�\301�!\205*�\302�J!\205*�\211JG\303Y\205*�\211J\304H�>\205*�\305\306\307�J!\"\207" [cl-struct-eieio--class-tags boundp vectorp 12 0 mapcar eieio--class-name eieio--class-precedence-list] 5 "\n\n(fn TAG)"]] [cl-struct-cl--generic-generalizer 0 #[257 "\300\207" [nil] 2 "\n\n(fn NAME)"] #[257 "\300\207" [...] 2 "\n\n(fn TAG)"]])) ([cl-struct-cl--generic-method (ede-php-autoload-project) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\302\303�\304\"   \"\207" [this class-name ede-php-autoload-find-class-def-file eieio-oref class-loader] 4 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-aggregate-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\304�\305\"\306�\211�\203�� \204��\307\n@�\"�\nA\211�\204�� *\207" [this class-def-file loaders class-name eieio-oref class-loaders nil ede-php-autoload-find-class-def-file] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr0-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "�\306H\307U\203���\310\311O\202����\312\313 !�\314\n\303\"�\311��\203H�\f\204H��@\315���\316��@�\"\203A�\317\320���@\"��A   #��A�*\202��\f,\207" [class-name project-root this namespaces class-def-file candidate-file 0 92 1 nil ede-project-root-directory ede-current-project eieio-oref "" string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns pair] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr4-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\306\307 !�\310  \302\"�\311�\n\2031��\2041�\n@�\312\f@
\"\203*�\313\314
\f@\"\fA�#�\nA�)\202\f��+\207" [project-root this namespaces class-def-file pair class-name ede-project-root-directory ede-current-project eieio-oref nil string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\300\301!\207" [error "Method `ede-php-autoload-find-class-def-file' must be overriden"] 2 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]]) nil] apply cl-no-applicable-method] 5 "\n\n(fn &rest ARGS)"](nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face)))
  apply(#[128 "\301\302\300�#\207" [[cl-struct-cl--generic ede-php-autoload-find-class-def-file ((0 [cl-struct-cl--generic-generalizer 50 cl--generic-struct-tag #[257 "\2119\205*�\301�!\205*�\302�J!\205*�\211JG\303Y\205*�\211J\304H�>\205*�\305\306\307�J!\"\207" [cl-struct-eieio--class-tags boundp vectorp 12 0 mapcar eieio--class-name eieio--class-precedence-list] 5 "\n\n(fn TAG)"]] [cl-struct-cl--generic-generalizer 0 #[257 "\300\207" [nil] 2 "\n\n(fn NAME)"] #[257 "\300\207" [...] 2 "\n\n(fn TAG)"]])) ([cl-struct-cl--generic-method (ede-php-autoload-project) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\302\303�\304\" \"\207" [this class-name ede-php-autoload-find-class-def-file eieio-oref class-loader] 4 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-aggregate-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\304�\305\"\306�\211�\203�� \204��\307\n@�\"�\nA\211�\204�� *\207" [this class-def-file loaders class-name eieio-oref class-loaders nil ede-php-autoload-find-class-def-file] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr0-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "�\306H\307U\203���\310\311O\202����\312\313 !�\314\n\303\"�\311��\203H�\f\204H��@\315���\316��@�\"\203A�\317\320���@\"��A   #��A�*\202��\f,\207" [class-name project-root this namespaces class-def-file candidate-file 0 92 1 nil ede-project-root-directory ede-current-project eieio-oref "" string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns pair] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-psr4-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\306\307 !�\310  \302\"�\311�\n\2031��\2041�\n@�\312\f@
\"\203*�\313\314
\f@\"\fA�#�\nA�)\202\f��+\207" [project-root this namespaces class-def-file pair class-name ede-project-root-directory ede-current-project eieio-oref nil string-prefix-p ede-php-autoload--search-in-dirs ede-php-autoload--get-path-relative-to-ns] 4 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nReturn nil if no file has been found.\n\n(fn CL-CNM THIS CLASS-NAME)"]] [cl-struct-cl--generic-method (ede-php-autoload-class-loader) nil t #[385 "�\301\302\303\304\305��!\306\"\307$\310K\311K\301\302\312\304\305����\"\313\"\307$\216\310�M\210\311�M\210\314\300��\")\207" [#[... "\300\301!\207" [error "Method `ede-php-autoload-find-class-def-file' must be overriden"] 2 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces."] make-byte-code 0 "\301\300!\207" vconcat vector [cl--generic-isnot-nnm-p] 2 next-method-p call-next-method "\302\300M\210\303\301M\207" [next-method-p call-next-method] apply] 13 "Find the file in which CLASS-NAME is defined.\n\nCLASS-NAME must be the full name of the class, with all its parent namespaces.\n\n(fn CL-CNM THIS CLASS-NAME)"]]) nil] apply cl-no-applicable-method] 5 "\n\n(fn &rest ARGS)"] nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face)))
  ede-php-autoload-find-class-def-file(nil #("Officine\\Amaka\\ErrorReporting" 0 29 (fontified t face font-lock-type-face)))
  (let* ((class-name (replace-regexp-in-string "^\\\\" "" (thing-at-point (quote sexp)))) (class-file (ede-php-autoload-find-class-def-file (ede-current-project) class-name))) (if class-file (progn (xref-push-marker-stack) (find-file class-file))))

Feature request: support for completions

It would be very useful if the semanticdb backend supported the find-tags-for-completion-method-method. It could create faux tags based on the namespace/path mappings and the directory structure. It shouldn't actually parse any files.

Use cases:

new Symfony\Component\C[POINT]
  * User presses C-c , SPC
  * so semantic calls the find-tags-... method
  * ede-php determines the path of Symfony\Component
  * and returns faux tags for every file found in the directory, starting with C
  * perhaps recursively
new Sym[POINT]
  * User presses C-c , SPC
  * so semantic calls the find-tags-... method
  * ede-php matches the prefix (Sym) with all known namespace prefixes
  * and returns faux tags for the relevant prefixes (Symfony\Component, Symfony\Bridge)
new S[POINT]
  * A combination of above two cases, so classes in S*\* would be found

Symbol's value as variable is void: ede-php-autoload/class-loader

After installation with package-install, I get the following when starting emacs (after everything seems to have loaded normally):

Warning (initialization): An error occurred while loading `.../.emacs.d/init.el':

Symbol's value as variable is void: ede-php-autoload/class-loader

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the `--debug-init' option to view a complete error backtrace.

Starting with --debug-init gives the following bactrace (bt up to "(package-initialize)" in my init.el):

(void-variable ede-php-autoload-composer-file)
  (ede-project-autoload "php-autoload" :name "PHP AUTOLOAD" :file (quote ede-php-autoload) :proj-file ede-php-autoload-composer-file :proj-root (quote ede-php-autoload-proj-root) :load-type (function ede-php-autoload-load) :class-sym (quote ede-php-autoload-project) :new-p nil :safe-p t)
  (ede-add-project-autoload (ede-project-autoload "php-autoload" :name "PHP AUTOLOAD" :file (quote ede-php-autoload) :proj-file ede-php-autoload-composer-file :proj-root (quote ede-php-autoload-proj-root) :load-type (function ede-php-autoload-load) :class-sym (quote ede-php-autoload-project) :new-p nil :safe-p t) (quote unique))
  eval-buffer(#<buffer  *load*-510926> nil ".../.emacs.d/elpa/ede-php-autoload-20161018.436/ede-php-autoload-autoloads.el" nil t)  ; Reading at buffer position 1042
  load-with-code-conversion(".../.emacs.d/elpa/ede-php-autoload-20161018.436/ede-php-autoload-autoloads.el" ".../.emacs.d/elpa/ede-php-autoload-20161018.436/ede-php-autoload-autoloads.el" nil t)
  load(".../.emacs.d/elpa/ede-php-autoload-20161018.436/ede-php-autoload-autoloads" nil t)
  #[0 "\302\303\304\305\300\"\301\"\306\307#\207" [ede-php-autoload ".../.emacs.d/elpa/ede-php-autoload-20161018.436" load expand-file-name format "%s-autoloads" nil t] 5 "\n\n(fn)"]()
  funcall(#[0 "\302\303\304\305\300\"\301\"\306\307#\207" [ede-php-autoload ".../.emacs.d/elpa/ede-php-autoload-20161018.436" load expand-file-name format "%s-autoloads" nil t] 5 "\n\n(fn)"])
  package-activate-1([cl-struct-package-desc ede-php-autoload (20161018 436) "Simple EDE PHP Project" nil nil nil ".../.emacs.d/elpa/ede-php-autoload-20161018.436" ((:keywords "php" "project" "ede") (:url . "https://github.com/stevenremot/ede-php-autoload")) nil])
  package-activate(ede-php-autoload)
  package-initialize()

PSR0 support

Carrying over from #27 where I wrote:

I tried implementing the other completion, and it was going rather well, until I discovered that the PSR0 loader doesn't quite live up to the spec: http://www.php-fig.org/psr/psr-0/

It's only in class names that the underscores can be used as separator, so the original test that checks if Psr0Ns_T to Psr0Ns_TheClass is wrong. I then carried that misunderstanding on in the subdir handling.

Trying to fix that up gave me all kind of troubles, so before carrying on, I'd like to ask how important underscore completion is? Or could we get away with just always completing with backslashes? I mean, following the specs, Psr0Ns\TheS should offer both Psr0Ns\TheSubdir_ and Psr0Ns\TheSubdir\ as possible completions, and that's, IMHO, just ugly. And if you're using PSR4, backslashes should work just fine.

And @stevenremot wrote:

Ah, that's true. We can open another issue on that, but I think the impact is pretty limited because:

PSR-0 is deprecated
Most of the time, you use either namespaces or big class names, so there is not that much risk of mixing stuffs. At least that's my experience

Well, that's where I don't quite follow. I remember the big class names of yore and figured PSR0 tries to retain some compatibility with that, but according to the spec they still need to be prefixed by the vendor namespace.

So the file Dir/Sub_Dir/Class.php can be used as Vendor\Dir\Sub_Dir\Class or Vendor\Dir_Sub_Dir_Class or Vendor\Dir_Sub_Dir\Class or Vendor\Dir\Sub_Dir_Class, but not Vendor\Dir\Sub\Dir\Class or Vendor_Dir_Sub_Dir_Class.

Are you seeing different rules in the wild?

Whatever the case, it needs to match up with the classname actually used in the PHP file, but we can't read that.

In order to live up to the spec, as I see it, completion should simply offer subdirs as both SubDir\ and Subdir_, in order for PSR0 completion being able to provide whatever the user wants to use, and drop any other attempts at guessing. Though it will properly increase the number of completion steps (pressing tab, whatever) for the user, as each directory will basically appear twice. And leave it up to the developer to choose the one used in the PHP file.

Agree?

Double backslahses in features

Minor thing, but it bit me because I got burned on it in my own tests.

In features it's not necessary to double backslashes, but for the current tests it happens to work as the namespaces are toplevel.

Issues with autodetection

Seems that I've gotten somewhere with the completion code.

However, I ede-php-autoload doesn't seem to be able to detect a composer project automatically? It only wworks when I define it with ede-php-autoload-project.

What should I look for?

Question: inverse function to `ede-php-autoload-find-class-def-file`?

Hi Steven,

I'd like to write a skeleton to generate the following file template, where <namespace_name> is the path to the file converted to a fully qualified name via PSR-4, minus the class name, which will go into <class_name>.

<?php

namespace <namespace_name>;

class <class_name>
{
}

Is there already a function or a method that I can call from outside your package to obtain this information?

Thanks.

Error occurred while loading a composer project

Hi, I am not able to set up my project for EDE. Please can you help?

EDE settings for my project:

(ede-php-autoload-project "Store"
                      :file "~/Sites/store/README.md")

Below warning message shows when opening Emacs.

Warning (initialization): An error occurred while loading `/Users/foopang/.emacs.d/init.el':

Wrong type argument: characterp, lib

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the `--debug-init' option to view a complete error backtrace.

Debug message:

Debugger entered--Lisp error: (wrong-type-argument characterp "lib")
  concat("vendor/bradfeehan/desk-php/" ["lib" "tests"])
  (setq path (concat (file-name-as-directory base-dir) path))
  (progn (setq path (concat (file-name-as-directory base-dir) path)))
  (if (stringp base-dir) (progn (setq path (concat (file-name-as-directory base-dir) path))))
  (let* ((namespace (symbol-name (car pair))) (last-character (aref namespace (1- (length namespace)))) (path (cdr pair))) (if (member last-character (quote (92 95))) (progn (setq namespace (substring-no-properties namespace 0 (1- (length namespace)))))) (if (stringp base-dir) (progn (setq path (concat (file-name-as-directory base-dir) path)))) (if (string= "psr-0" standard) (progn (setq path (concat path namespace "/")))) (cons namespace path))
  ede-php-autoload--format-composer-pair((Desk . ["lib" "tests"]) "vendor/bradfeehan/desk-php" psr-0)
  (lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir (car autoload-part)))((Desk . ["lib" "tests"]))
  mapcar((lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir (car autoload-part))) ((Desk . ["lib" "tests"])))
  (setq key (intern (concat ":" (symbol-name (car autoload-part)))) spec (mapcar (function (lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir (car autoload-part)))) (cdr autoload-part)) base-spec (plist-get autoloads key))
  (progn (setq key (intern (concat ":" (symbol-name (car autoload-part)))) spec (mapcar (function (lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir (car autoload-part)))) (cdr autoload-part)) base-spec (plist-get autoloads key)) (setq autoloads (plist-put autoloads key (append base-spec spec))))
  (if (member (car autoload-part) (quote (psr-0 psr-4))) (progn (setq key (intern (concat ":" (symbol-name (car autoload-part)))) spec (mapcar (function (lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir (car autoload-part)))) (cdr autoload-part)) base-spec (plist-get autoloads key)) (setq autoloads (plist-put autoloads key (append base-spec spec)))))
  (while --dolist-tail-- (setq autoload-part (car --dolist-tail--)) (if (member (car autoload-part) (quote (psr-0 psr-4))) (progn (setq key (intern (concat ":" (symbol-name (car autoload-part)))) spec (mapcar (function (lambda (pair) (ede-php-autoload--format-composer-pair pair base-dir ...))) (cdr autoload-part)) base-spec (plist-get autoloads key)) (setq autoloads (plist-put autoloads key (append base-spec spec))))) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (let ((--dolist-tail-- composer-autoloads) autoload-part) (while --dolist-tail-- (setq autoload-part (car --dolist-tail--)) (if (member (car autoload-part) (quote (psr-0 psr-4))) (progn (setq key (intern (concat ":" (symbol-name ...))) spec (mapcar (function (lambda ... ...)) (cdr autoload-part)) base-spec (plist-get autoloads key)) (setq autoloads (plist-put autoloads key (append base-spec spec))))) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (let ((composer-autoloads (cdr (assoc (quote autoload) composer-data))) key spec base-spec) (let ((--dolist-tail-- composer-autoloads) autoload-part) (while --dolist-tail-- (setq autoload-part (car --dolist-tail--)) (if (member (car autoload-part) (quote (psr-0 psr-4))) (progn (setq key (intern (concat ":" ...)) spec (mapcar (function ...) (cdr autoload-part)) base-spec (plist-get autoloads key)) (setq autoloads (plist-put autoloads key (append base-spec spec))))) (setq --dolist-tail-- (cdr --dolist-tail--)))) autoloads)
  ede-php-autoload--merge-composer-autoloads(((autoload (psr-0 (Desk . ["lib" "tests"]))) (require-dev (seld/jsonlint . "~1.1.1") (squizlabs/php_codesniffer . "~1.5.0") (satooshi/php-coveralls . "~0.6.1") (mockery/mockery . "dev-master#3bd6f1712642838b4c0524d3a47359940df72e80") (phpunit/phpunit . "~4.1")) (require (bradfeehan/guzzle-modular-service-descriptions . "~1.1,>=1.1.1") (guzzle/guzzle . "~3.9.0") (php . ">=5.3")) (authors . [((email . "[email protected]") (name . "Brad Feehan"))]) (license . "MIT") (keywords . ["desk" "desk.com" "assistly" "assistly.com" "api" "guzzle"]) (description . "PHP client for Desk.com v2 API based on Guzzle") (name . "bradfeehan/desk-php")) (:psr-0 (("Sylius" . "vendor/sylius/sylius/src/Sylius/") ("Doctrine\\ORM" . "vendor/doctrine/orm/lib/Doctrine\\ORM/") ("Doctrine\\DBAL" . "vendor/doctrine/dbal/lib/Doctrine\\DBAL/") ("Money" . "vendor/mathiasverraes/money/libMoney/") ("DoctrineExtensions" . "vendor/beberlei/DoctrineExtensions/lib/DoctrineExtensions/") ("Symfony" . "vendor/symfony/symfony/src/Symfony/") ("Twig_Extensions" . "vendor/twig/extensions/lib/Twig_Extensions/") ("Pagerfanta" . "vendor/pagerfanta/pagerfanta/src/Pagerfanta/") ("Payum" . "vendor/payum/payum/src/Payum/") ("Jackalope" . "vendor/jackalope/jackalope-doctrine-dbal/src/Jackalope/") ("Hateoas" . "vendor/willdurand/hateoas/src/Hateoas/") ("Doctrine\\DBAL\\Migrations" . "vendor/doctrine/migrations/libDoctrine\\DBAL\\Migrations/") ("Zend_Locale" . "vendor/zf1/zend-locale/library/Zend_Locale/") ("OpenExchangeRates" . "vendor/dandelionmood/openexchangerates/lib/Dandelionmood/OpenExchangeRates/") ("Symm\\BitpayClient" . "vendor/symm/guzzle-bitpay/src/Symm\\BitpayClient/") ("Ddeboer\\DataImport" . "vendor/ddeboer/data-import/srcDdeboer\\DataImport/") ("Asm89\\Twig\\CacheExtension" . "vendor/asm89/twig-cache-extension/lib/Asm89\\Twig\\CacheExtension/")) :psr-4 (("FOS\\UserBundle" . "vendor/friendsofsymfony/user-bundle/") ("Symfony\\Bundle\\MonologBundle" . "vendor/symfony/monolog-bundle/") ("winzou\\Bundle\\StateMachineBundle" . "vendor/winzou/state-machine-bundle/") ("FOS\\ElasticaBundle" . "vendor/friendsofsymfony/elastica-bundle/"))) "vendor/bradfeehan/desk-php")
  (setq autoloads (ede-php-autoload--merge-composer-autoloads (ede-php-autoload--get-composer-data (expand-file-name dir project-dir)) autoloads dir))
  (while --dolist-tail-- (setq dir (car --dolist-tail--)) (setq autoloads (ede-php-autoload--merge-composer-autoloads (ede-php-autoload--get-composer-data (expand-file-name dir project-dir)) autoloads dir)) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (let ((--dolist-tail-- third-party-dirs) dir) (while --dolist-tail-- (setq dir (car --dolist-tail--)) (setq autoloads (ede-php-autoload--merge-composer-autoloads (ede-php-autoload--get-composer-data (expand-file-name dir project-dir)) autoloads dir)) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (let* ((root-data (ede-php-autoload--get-composer-data project-dir)) (third-party-dirs (ede-php-autoload--get-composer-third-party-dirs root-data))) (setq autoloads (ede-php-autoload--merge-composer-autoloads root-data autoloads nil)) (let ((--dolist-tail-- third-party-dirs) dir) (while --dolist-tail-- (setq dir (car --dolist-tail--)) (setq autoloads (ede-php-autoload--merge-composer-autoloads (ede-php-autoload--get-composer-data (expand-file-name dir project-dir)) autoloads dir)) (setq --dolist-tail-- (cdr --dolist-tail--)))) autoloads)
  ede-php-autoload--append-composer-autoload-data("~/Sites/store/" nil)
  (setq class-autoloads (ede-php-autoload--append-composer-autoload-data (file-name-directory (plist-get (car fields) :file)) class-autoloads))
  (let ((class-autoloads (plist-get (car fields) :class-autoloads))) (setq class-autoloads (ede-php-autoload--append-composer-autoload-data (file-name-directory (plist-get (car fields) :file)) class-autoloads)) (call-next-method this (list :file (plist-get (car fields) :file) :class-loader (ede-php-autoload-create-class-loader class-autoloads))))
  ede-php-autoload-project([object ede-php-autoload-project "store" nil "Untitled" "1.0" unbound unbound unbound nil nil unbound unbound unbound "" "" "" "" "" "" ("debug" "release") "debug" nil unbound] (:file "~/Sites/store/README.md"))
  apply(ede-php-autoload-project ([object ede-php-autoload-project "store" nil "Untitled" "1.0" unbound unbound unbound nil nil unbound unbound unbound "" "" "" "" "" "" ("debug" "release") "debug" nil unbound] (:file "~/Sites/store/README.md")))
  eieio-generic-call(initialize-instance ([object ede-php-autoload-project "store" nil "Untitled" "1.0" unbound unbound unbound nil nil unbound unbound unbound "" "" "" "" "" "" ("debug" "release") "debug" nil unbound] (:file "~/Sites/store/README.md")))
  initialize-instance([object ede-php-autoload-project "store" nil "Untitled" "1.0" unbound unbound unbound nil nil unbound unbound unbound "" "" "" "" "" "" ("debug" "release") "debug" nil unbound] (:file "~/Sites/store/README.md"))
  eieio-default-superclass(ede-php-autoload-project "store" :file "~/Sites/store/README.md")
  apply(eieio-default-superclass (ede-php-autoload-project "store" :file "~/Sites/store/README.md"))
  eieio-generic-call(constructor (ede-php-autoload-project "store" :file "~/Sites/store/README.md"))
  constructor(ede-php-autoload-project "store" :file "~/Sites/store/README.md")
  apply(constructor ede-php-autoload-project "store" (:file "~/Sites/store/README.md"))
  ede-php-autoload-project("store" :file "~/Sites/store/README.md")
  eval-buffer(#<buffer  *load*> nil "/Users/foopang/.emacs.d/init.el" nil t)  ; Reading at buffer position 4303
  load-with-code-conversion("/Users/foopang/.emacs.d/init.el" "/Users/foopang/.emacs.d/init.el" t t)
  load("/Users/foopang/.emacs.d/init" t t)
  #[0 "�\205\262�   \306=\203��\307�\310Q\202;� \311=\204��\307�\312Q\202;�\313\307\314\315#\203*�\316\202;�\313\307\314\317#\203:�\320\nB�\321\202;�\316\322�\323�\322\211#\210�\322=\203a�\324\325\326\307�\327Q!\"\323�\322\211#\210�\322=\203`���\210�\203\243�\330�!\331\232\203\243�\332�!\211\333P\334�!\203}�\211\202\210�\334�!\203\207��\202\210�\314\262��\203\241�\335��\"\203\237�\336\337��#\210\340\341!\210��\266�\f?\205\260�\314�\323\342\322\211#)\262�\207" [init-file-user system-type delayed-warnings-list user-init-file inhibit-default-init inhibit-startup-screen ms-dos "~" "/_emacs" windows-nt "/.emacs" directory-files nil "^\\.emacs\\(\\.elc?\\)?$" "~/.emacs" "^_emacs\\(\\.elc?\\)?$" (initialization "`_emacs' init file is deprecated, please use `.emacs'") "~/_emacs" t load expand-file-name "init" file-name-as-directory "/.emacs.d" file-name-extension "elc" file-name-sans-extension ".el" file-exists-p file-newer-than-file-p message "Warning: %s is newer than %s" sit-for 1 "default"] 7 "\n\n(fn)"]()
  command-line()
  normal-top-level()

This is the composer.json file cannot be parsed: https://github.com/bradfeehan/desk-php/blob/master/composer.json

Thanks!

ede-php-autoload-complete-type-name a bit odd

Trying to use ede-php-autoload-complete-type-name for completion is a bit of a challenge, for PSR-4 at least.

At first it returns full namespaces, but when traversing down, it only returns the last component. Instinctively, I'd expect it to either complete single components all the way, or return the full namespace (which is easier to deal with in a completion engine). Any objections against it returning the full name?

Secondly, I could use some information on the completions, whether its a directory or file, for colorization, later on, but I guess that's out of scope for ede-php-autoload-complete-type-name? Any tricks for how to determine whether a string would end in a class file, or require further expansion?

Get going problems

Hi,

I've been experimenting with @jorissteyn's semantic-php and ede-php-autoload to see how far I could push Emacs towards the next level in PHP development (we're a couple of Emacs heads defending our turf against the local PHPStorm users. My colleague is the drupal-mode maintainer, and now Drupal 8 is released we start missing better OO stuff).

semantic-php works for things in the same buffer, and as far as I understand, ede-php-autoload is the next step. But I can't really figure it out.

I have ede-php-autoload-mode activated, and a buffer from a simple composer project. As I understand it, it should sniff out where to find classes from the composer.json, but semantic-complete-analyze-inline doesn't "get" anything not defined in the same file. I've tried with master and the #5-type-completion-support branch, without much luck...

I'm a bit at a loss as to how to debug my troubles, or whether I'm just expecting something it can't do yet?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.