GithubHelp home page GithubHelp logo

emacs-php / php-auto-yasnippets Goto Github PK

View Code? Open in Web Editor NEW
41.0 11.0 12.0 115 KB

Dynamically Generated YASnippets for PHP Code in GNU Emacs

License: GNU General Public License v3.0

PHP 41.63% Emacs Lisp 58.37%

php-auto-yasnippets's Introduction

Automatic YASnippets for PHP in Emacs

The php-auto-yasnippets package for GNU Emacs will automatically create ‘snippets’ for standard PHP functions. It defines these snippets using the YASnippet package, with optional support for auto-complete. For example, if you type the PHP function

implode

and press C-c C-y then php-auto-yasnippets will expand that into

implode($glue, $pieces)

with the cursor ready to overwrite $glue with the string you want to use. Pressing Tab will skip over to $pieces to do the same. This way you can be sure you not only have the correct number of arguments, but also that you have them in the correct order. PHP comes with a large standard library and functions that sound similar sometimes require arguments in contrasting orders. This package will help you avoid having to remember those corner cases.

If a function has any optional parameters then php-auto-yasnippets will wrap them in square braces. This is the same convention the PHP manual uses to indicate optional parameters. For example, php-auto-yasnippets will expand filter_input into this:

filter_input($type, $variable_name, [$filter], [$options])

If you do not need the optional parameters you can delete them by pressing C-d when you Tab over to them.

You can use the prefix command to expand method names. When you use the prefix, u.g. C-u C-c C-y, the package will ask you for the name of the class which implements that method. This information is necessary in order to generate the correct snippet.

Requirements

Installation

To use php-auto-yasnippets you need to do three things. First, place the package in your load-path (C-h v load-path for help) and load it from your Emacs configuration file by adding:

(require 'php-auto-yasnippets)

Second, make sure the variable php-auto-yasnippet-php-program points to the program Create-PHP-YASnippet.php. That PHP program should have come with this package; if you do not have it then you can get it from the project website. By default php-auto-yasnippets will search for the PHP program in the same directory as the Elisp code, i.e. the php-auto-yasnippets.el. If you want to put the PHP program in another place then use setq in your configuration file to set the variable to the proper path, e.g:

(require 'php-auto-yasnippets)
(setq php-auto-yasnippet-php-program "~/path/to/Create-PHP-YASnippet.php")

Finally, bind the function yas/create-php-snippet to a key of your choice. You must do this because php-auto-yasnippets defines no key-bindings. And since the package requires php-mode, and is most useful when writing PHP code, you may want to use a key-binding that only works when using php-mode. For example:

(define-key php-mode-map (kbd "C-c C-y") 'yas/create-php-snippet)

Now if you type the name of a PHP function and press C-c C-y it will expand into a snippet containing all of the parameters, their names, any default values, et cetera.

auto-complete

With auto-complete support activated, it's even simpler:

imp

followed by Tab, then Return (to choose the first completion) expands the snippet to

implode($glue, $pieces)

First, install and configure auto-complete.

Add

(payas/ac-setup)

to your php-auto-yasnippets setup, and you should be good to go.

Note that auto-completion does not support user-defined functions or classes (it relies on auto-complete's php-mode dictionary of functions).

Loading User Code

This package can also generate snippets for user-defined functions and methods.

You can tell a buffer what files to load for function and class definitions by setting php-auto-yasnippet-required-files to a list of required paths.

If you use Composer, you might put something like this in ~/project/.dir-locals.el:

(php-mode . ((php-auto-yasnippet-required-files (list "~/project/vendor/autoload.php"))))

Now you can generate snippets for any classes Composer autoloads, in any PHP file in the project.

Contributors

Miscellaneous

This package uses Semantic Versioning.

License

GNU General Public License

Copyright 2013, 2014, 2015, 2016, 2017 Eric James Michael Ritz

php-auto-yasnippets's People

Contributors

amcorreia avatar bystrano avatar ejmr avatar glynnforrest avatar martango avatar nateeag avatar yasuyk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar

php-auto-yasnippets's Issues

Restrict payas/remove-extra-whitespace to PHP Mode Snippets

Right now the package sets payas/remove-extra-whitespace as a hook to run after expanding any snippet. That can cause problems with snippets written for other modes since the function expects to only ever deal with PHP code. Instead of being a global hook payas/remove-extra-whitespace should be restricted only to PHP Mode snippets.

Add support for end-user code? [idea]

I was thinking it might be useful to add support for snippets for end-user functions/methods.

Maybe something like:

  • Add a --require_once option to Create-PHP-Yasnippet.php that calls require_once for the passed path. It could be specified multiple times.
  • Add a list php-auto-yasnippet-requires (or something along those lines) to the elisp package, defaulting it to the empty list. Every path in it is passed to the PHP script via the new --require_once option.

Users could use .dir-locals (or other mechanisms) to set the php-auto-yasnippet-requires list for a given project.

A lot of modern PHP projects rely on autoloads, and even the ones that don't usually have some "include all the things" option, so this should be fairly usable in practice.

I verified that adding a require_once does let the code work with user code.

Does this sound like a worthwhile addition? If I got this working, do you think you'd merge it?

integration with auto-complete

php-auto-yasnippets looks like an awesome package - I'm always forgetting the order of args to PHP's numerous array functions. Thanks very much for writing it.

I took some time this weekend to try it out. It seems to work very nicely, and this coming week at work I'll be trying it out in-depth.

Being a lazy sort, after playing with it a bit, I thought, "It must be possible to auto-trigger the auto-snippets after auto-completing a function name."

After reading some code and playing, I came up with a working prototype. It's just an auto-complete source, based strongly on the yasnippet source that ships with auto-complete.

I tossed a demo video on my webserver if you'd like to see what it looks like.

The prototype code is in my .emacs.d repo.

Is this something you'd be interested in adding to php-auto-yasnippets? If so, what cleanup/improvements would be necessary?

If not, do you have any thoughts on how to make it available to anyone else who's interested?

Error with payas/ac-setup

When I add (payas/ac-setup) to my config, I get:

Debugger entered--Lisp error: (void-variable php-auto-yasnippets)
  payas/ac-setup()
  eval((payas/ac-setup) nil)
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Is this working for others?

support ~ for php-auto-yasnippet-php-program

As of 2.1.0 and using php-mode 2.12 the variable php-auto-yasnippet-php-program does not seem expanded (the ~ [tidla] isn't replaced by $HOME).
That brings spurious "Cannot run the program ~/.emacs.d/php/Create-PHP-YASnippet.php"

yas--all-parents: Lisp nesting exceeds `max-lisp-eval-depth'

When loading php-auto-yasnippets with my normal .emacs I get the above errors

  • "backtrace1" below if using M-x yas/create-php-snippet (I get wrong-type-argument stringp nil)
  • "backtrace2" below if using the keybinding (\C-C \C-Y)

But when running :
$ emacs -nw -D -Q --debug-init a.php
(load-file ~/.emacs.d/php-mode.el)
(load-file ~/.emacs.d/dropdown-list.el)
(load-file ~/.emacs.d/yasnippet.el)
(load-file ~/.emacs.d/php-auto-yasnippets.el)
M-: (setq php-auto-yasnippet-php-program "/tmp/Create-PHP-YASnippet.php")
M-: (define-key php-mode-map (kbd "C-c C-y") 'yas/create-php-snippet)

Then going on implode and for the example, putting my cursor after the "i" then M-x yas/create-php-snippet:

  • the status bar says : You can run the command yas/create-php-snippet' with C-c C-y`
  • a newline (nothing else) is inserted between the "i" and the "m"

My hypothesis is that it's not impossible that 2 bugs live here, one about the snippet builder itself (backtrace1) and another one about the interactive/non-interactive function call and empty argument (or something related).

  • backtrace 1 (using M-x yas/create-php-snippet)
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  string-match("[ \f    \n
]+" nil 0)
  split-string(nil)
  (let* ((input-chunks (split-string input)) (function-or-method-name (first input-chunks)) (class-name (or (second input-chunks) "")) (args (list php-executable nil (current-buffer) nil php-auto-yasnippet-php-program))) (setq command-args (list function-or-method-name class-name)) (progn (let ((--dolist-tail-- php-auto-yasnippet-required-files) elt) (while --dolist-tail-- (setq elt (car --dolist-tail--)) (setq command-args (cons elt command-args)) (setq command-args (cons "--require-once" command-args)) (setq --dolist-tail-- (cdr --dolist-tail--))) (setq elt nil) command-args)) (setq args (append args command-args)) (apply (quote call-process) args))
  (progn (let* ((input-chunks (split-string input)) (function-or-method-name (first input-chunks)) (class-name (or (second input-chunks) "")) (args (list php-executable nil (current-buffer) nil php-auto-yasnippet-php-program))) (setq command-args (list function-or-method-name class-name)) (progn (let ((--dolist-tail-- php-auto-yasnippet-required-files) elt) (while --dolist-tail-- (setq elt (car --dolist-tail--)) (setq command-args (cons elt command-args)) (setq command-args (cons "--require-once" command-args)) (setq --dolist-tail-- (cdr --dolist-tail--))) (setq elt nil) command-args)) (setq args (append args command-args)) (apply (quote call-process) args)))
  (unwind-protect (progn (let* ((input-chunks (split-string input)) (function-or-method-name (first input-chunks)) (class-name (or (second input-chunks) "")) (args (list php-executable nil (current-buffer) nil php-auto-yasnippet-php-program))) (setq command-args (list function-or-method-name class-name)) (progn (let ((--dolist-tail-- php-auto-yasnippet-required-files) elt) (while --dolist-tail-- (setq elt (car --dolist-tail--)) (setq command-args (cons elt command-args)) (setq command-args (cons "--require-once" command-args)) (setq --dolist-tail-- (cdr --dolist-tail--))) (setq elt nil) command-args)) (setq args (append args command-args)) (apply (quote call-process) args))) (set-match-data save-match-data-internal (quote evaporate)))
  (let ((save-match-data-internal (match-data))) (unwind-protect (progn (let* ((input-chunks (split-string input)) (function-or-method-name (first input-chunks)) (class-name (or (second input-chunks) "")) (args (list php-executable nil (current-buffer) nil php-auto-yasnippet-php-program))) (setq command-args (list function-or-method-name class-name)) (progn (let ((--dolist-tail-- php-auto-yasnippet-required-files) elt) (while --dolist-tail-- (setq elt ...) (setq command-args ...) (setq command-args ...) (setq --dolist-tail-- ...)) (setq elt nil) command-args)) (setq args (append args command-args)) (apply (quote call-process) args))) (set-match-data save-match-data-internal (quote evaporate))))
  payas/create-template(nil)
  (let ((exit-code (payas/create-template input))) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list (yas--parse-template))))
  (progn (let ((exit-code (payas/create-template input))) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list (yas--parse-template)))))
  (unwind-protect (progn (let ((exit-code (payas/create-template input))) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list (yas--parse-template))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((exit-code (payas/create-template input))) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list (yas--parse-template))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((exit-code (payas/create-template input))) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list (yas--parse-template))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (if (yas--get-template-by-uuid (quote php-mode) input) nil (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((exit-code ...)) (if (/= exit-code 0) (payas/report-error exit-code input)) (yas-define-snippets (quote php-mode) (list ...)))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))
  payas/define-template(nil)
  (if class (payas/define-template (concat function " " class)) (payas/define-template function))
  (let ((function (thing-at-point (quote symbol))) (class (if prefix (read-from-minibuffer "Class: ")))) (if class (payas/define-template (concat function " " class)) (payas/define-template function)) (setq php-auto-yasnippet-executing t) (yas-expand))
  yas/create-php-snippet(nil)
  call-interactively(yas/create-php-snippet record nil)
  command-execute(yas/create-php-snippet record)
  execute-extended-command(nil "yas/create-php-snippet")
  call-interactively(execute-extended-command nil nil)

Error while configuring user-defined function (composer)

Following the guide for getting user-defined functions via Composer to work. I have created a .dir-locals.el file at the root of the project with the following content.

((php-mode . ((php-auto-yasnippet-required-files (list "~/project/vendor/autoload.php")))))

When I do a M-x yas/create-php-snippet I get the following error.
Wrong type argument: stringp, (list "~/project/vendor/autoload.php")

Probably a syntax error, any ideas?

`Wrong type argument: stringp, nil` while in class method

It looks like somehow, (thing-at-point 'sexp) is returning nil when I call (yas/create-php-snippet) inside a class method. If I bring the cursor out of the method, then the function works correctly.
Is this a problem with thing-at-point or php-auto-yasnippets? (Calling (thing-at-point 'string) is also returning nil).
I'm not sure.

Click for error.
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  string-match("[ \f	\n
�]+" nil 0)
  split-string(nil)
  payas/create-template(nil)
  payas/define-template(nil)
  yas/create-php-snippet(nil)
  funcall-interactively(yas/create-php-snippet nil)
  call-interactively(yas/create-php-snippet nil nil)
  command-execute(yas/create-php-snippet)

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.