Add Cask configuration and fix some compilation warnings
ci/woodpecker/push/woodpecker Pipeline failed Details

WIP-cache
Hugo Thunnissen 9 months ago
parent 23245d0158
commit 2099abced8

@ -0,0 +1,4 @@
(source gnu)
(source melpa)
(package-file "phpinspect.el")

@ -0,0 +1,19 @@
export EMACS ?= $(shell which emacs)
CASK_DIR := $(shell cask package-directory)
$(CASK_DIR): Cask
cask install
@touch $(CASK_DIR)
.PHONY: cask
cask: $(CASK_DIR)
.PHONY: compile
compile: cask
cask emacs -batch -L . -L test \
-f batch-byte-compile $$(cask files); \
(ret=$$? ; cask clean-elc && exit $$ret)
.PHONY: test
test: compile
cask emacs --batch -L . -L test -l ./test/phpinspect-test.el e -f ert-run-tests-batch

@ -76,7 +76,8 @@ qualified names congruent with a bareword type name. Keyed by
bareword typenames."))
(defun phpinspect-make-autoload-definition-closure (project-root fs typehash)
"Create a closure that can be used to `maphash' the autoload section of a composer-json."
"Create a closure that can be used to `maphash' the autoload
section of a composer-json."
(lambda (type prefixes)
(let ((strategy))
(cond

@ -25,9 +25,16 @@
(require 'phpinspect-splayt)
(require 'phpinspect-meta)
(require 'phpinspect-changeset)
(require 'phpinspect-util)
(require 'compat)
(eval-when-compile
(defvar phpinspect-parse-context nil
"dummy for compilation")
(declare-function phpinspect-pctx-register-changeset "phpinspect-parse-context" (pctx changeset)))
(cl-defstruct (phpinspect-bmap (:constructor phpinspect-make-bmap))
(starts (make-hash-table :test #'eql
:size (floor (/ (point-max) 4))
@ -125,9 +132,9 @@
(declare (indent defun))
(let ((place (car place-and-bmap))
(bmap (gensym))
(_ignored (gensym)))
(ignored (gensym)))
`(let ((,bmap ,(cadr place-and-bmap)))
(maphash (lambda (,_ignored ,place)
(maphash (lambda (,ignored ,place)
,@body
(when (phpinspect-meta-overlay ,place)
(phpinspect-splayt-traverse (,place (phpinspect-meta-children ,place))
@ -172,6 +179,11 @@
(and (listp overlay)
(eq 'overlay (car overlay))))
(defsubst phpinspect-bmap-overlay-at-point (bmap point)
(let ((overlay (phpinspect-splayt-find-largest-before (phpinspect-bmap-overlays bmap) point)))
(when (and overlay (phpinspect-overlay-overlaps-point overlay point))
overlay)))
(cl-defmethod phpinspect-bmap-token-starting-at ((overlay (head overlay)) point)
(phpinspect-bmap-token-starting-at
(phpinspect-overlay-bmap overlay) (- point (phpinspect-overlay-delta overlay))))
@ -192,10 +204,6 @@
(phpinspect-bmap-tokens-ending-at overlay point)
(gethash point (phpinspect-bmap-ends bmap)))))
(defsubst phpinspect-bmap-overlay-at-point (bmap point)
(let ((overlay (phpinspect-splayt-find-largest-before (phpinspect-bmap-overlays bmap) point)))
(when (and overlay (phpinspect-overlay-overlaps-point overlay point))
overlay)))
(defsubst phpinspect-bmap-tokens-overlapping (bmap point)
(let ((tokens))
@ -212,6 +220,10 @@
(cl-defmethod phpinspect-bmap-token-meta ((overlay (head overlay)) token)
(phpinspect-bmap-token-meta (phpinspect-overlay-bmap overlay) token))
(defsubst phpinspect-probably-token-p (token)
(and (listp token)
(keywordp (car token))))
(cl-defmethod phpinspect-bmap-token-meta ((bmap phpinspect-bmap) token)
(unless (phpinspect-probably-token-p token)
(error "Unexpected argument, expected `phpinspect-token-p'. Got invalid token %s" token))
@ -226,10 +238,6 @@
(phpinspect-bmap-overlays bmap) (phpinspect-overlay-end overlay))
(throw 'found found?)))))))
(defsubst phpinspect-probably-token-p (token)
(and (listp token)
(keywordp (car token))))
(cl-defmethod phpinspect-bmap-last-token-before-point ((bmap phpinspect-bmap) point)
"Search backward in BMAP for last token ending before POINT."
(phpinspect-meta-find-child-before-recursively (phpinspect-bmap-root-meta bmap) point))

@ -23,7 +23,7 @@
;;; Code:
;;(require 'phpinspect-tree)
(require 'phpinspect-parser)
(require 'phpinspect-bmap)
(require 'phpinspect-edtrack)

@ -25,6 +25,7 @@
(require 'phpinspect-project)
(require 'phpinspect-autoload)
(require 'phpinspect-worker)
(cl-defstruct (phpinspect--cache (:constructor phpinspect--make-cache))
(projects (make-hash-table :test 'equal :size 10)

@ -0,0 +1,78 @@
;;; phpinspect-changeset.el --- Metadata changeset module -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc
;; Author: Hugo Thunnissen <devel@hugot.nl>
;; Keywords: php, languages, tools, convenience
;; Version: 0
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(define-inline phpinspect-make-changeset (meta)
(inline-letevals (meta)
(inline-quote
(list (phpinspect-meta-start ,meta) (phpinspect-meta-end ,meta)
(phpinspect-meta-parent ,meta) (phpinspect-meta-overlay ,meta)
(phpinspect-meta-parent-offset ,meta) ,meta))))
(define-inline phpinspect-changeset-start (set)
(inline-quote (car ,set)))
(define-inline phpinspect-changeset-end (set)
(inline-quote (cadr ,set)))
(define-inline phpinspect-changeset-parent (set)
(inline-quote (caddr ,set)))
(define-inline phpinspect-changeset-overlay (set)
(inline-quote (cadddr ,set)))
(define-inline phpinspect-changeset-parent-offset (set)
(inline-quote (car (cddddr ,set))))
(define-inline phpinspect-changeset-meta (set)
(inline-quote (car (nthcdr 5 ,set))))
(define-inline phpinspect-meta-with-changeset (meta &rest body)
(declare (indent 1))
(inline-letevals (meta)
(push 'progn body)
(inline-quote
(progn
(when phpinspect-parse-context
(phpinspect-pctx-register-changeset
phpinspect-parse-context (phpinspect-make-changeset ,meta)))
,body))))
(define-inline phpinspect-changeset-revert (changeset)
(inline-letevals (changeset)
(inline-quote
(progn
(setf (phpinspect-meta-parent (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-parent ,changeset))
(setf (phpinspect-meta-overlay (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-overlay ,changeset))
(setf (phpinspect-meta-absolute-start (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-start ,changeset))
(setf (phpinspect-meta-absolute-end (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-end ,changeset))
(setf (phpinspect-meta-parent-offset (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-parent-offset ,changeset))))))
(provide 'phpinspect-changeset)
;;; phpinspect-changeset.el ends here

@ -90,36 +90,21 @@ candidate. Candidates can be indexed functions and variables.")
(buffer nil
:type phpinspect-buffer))
(cl-defmethod phpinspect-completion-query-execute ((query phpinspect-completion-query))
"Execute QUERY.
Returns list of `phpinspect--completion'."
(let* ((buffer (phpinspect-completion-query-buffer query))
(point (phpinspect-completion-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point))
(completion-list (phpinspect--make-completion-list)))
(dolist (strategy phpinspect-completion-strategies)
(when (phpinspect-comp-strategy-supports strategy query rctx)
(phpinspect--log "Found matching completion strategy. Executing...")
(dolist (candidate (phpinspect-comp-strategy-execute strategy query rctx))
(phpinspect--completion-list-add
completion-list (phpinspect--make-completion candidate)))))
completion-list))
(cl-defgeneric phpinspect-comp-strategy-supports (strategy (query phpinspect-completion-query) (context phpinspect--resolvecontext))
"Should return non-nil if STRATEGY should be deployed for QUERY
and CONTEXT. All strategies must implement this method.")
(cl-defgeneric phpinspect-comp-strategy-execute (strategy (query phpinspect-completion-query) (context phpinspect--resolvecontext))
"Should return a list of objects for which `phpinspect--make-completion' is implemented.")
"Should return a list of objects for which
`phpinspect--make-completion' is implemented.")
(cl-defstruct (phpinspect-comp-sigil (:constructor phpinspect-make-comp-sigil))
"Completion strategy for the sigil ($) character.")
(cl-defmethod phpinspect-comp-strategy-supports
((strat phpinspect-comp-sigil) (q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
((_strat phpinspect-comp-sigil) (q phpinspect-completion-query)
(_rctx phpinspect--resolvecontext))
(and (= (phpinspect-completion-query-completion-point q)
(phpinspect-completion-query-point q))
(phpinspect-variable-p
@ -129,7 +114,7 @@ and CONTEXT. All strategies must implement this method.")
(phpinspect-completion-query-point q))))))
(cl-defmethod phpinspect-comp-strategy-execute
((strat phpinspect-comp-sigil) (q phpinspect-completion-query)
((_strat phpinspect-comp-sigil) (_q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
(phpinspect-suggest-variables-at-point rctx))
@ -137,12 +122,12 @@ and CONTEXT. All strategies must implement this method.")
"Completion strategy for object attributes")
(cl-defmethod phpinspect-comp-strategy-supports
((strat phpinspect-comp-attribute) (q phpinspect-completion-query)
((_strat phpinspect-comp-attribute) (_q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
(phpinspect-object-attrib-p (car (last (phpinspect--resolvecontext-subject rctx)))))
(cl-defmethod phpinspect-comp-strategy-execute
((strat phpinspect-comp-attribute) (q phpinspect-completion-query)
((_strat phpinspect-comp-attribute) (_q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
(phpinspect-suggest-attributes-at-point rctx))
@ -150,12 +135,12 @@ and CONTEXT. All strategies must implement this method.")
"Completion strategy for static attributes")
(cl-defmethod phpinspect-comp-strategy-supports
((strat phpinspect-comp-static-attribute) (q phpinspect-completion-query)
((_strat phpinspect-comp-static-attribute) (_q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
(phpinspect-static-attrib-p (car (last (phpinspect--resolvecontext-subject rctx)))))
(cl-defmethod phpinspect-comp-strategy-execute
((strat phpinspect-comp-static-attribute) (q phpinspect-completion-query)
((_strat phpinspect-comp-static-attribute) (_q phpinspect-completion-query)
(rctx phpinspect--resolvecontext))
(phpinspect-suggest-attributes-at-point rctx 'static))
@ -164,6 +149,23 @@ and CONTEXT. All strategies must implement this method.")
(phpinspect-make-comp-static-attribute))
"List of completion strategies that phpinspect can use.")
(cl-defmethod phpinspect-completion-query-execute ((query phpinspect-completion-query))
"Execute QUERY.
Returns list of `phpinspect--completion'."
(let* ((buffer (phpinspect-completion-query-buffer query))
(point (phpinspect-completion-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point))
(completion-list (phpinspect--make-completion-list)))
(dolist (strategy phpinspect-completion-strategies)
(when (phpinspect-comp-strategy-supports strategy query rctx)
(phpinspect--log "Found matching completion strategy. Executing...")
(dolist (candidate (phpinspect-comp-strategy-execute strategy query rctx))
(phpinspect--completion-list-add
completion-list (phpinspect--make-completion candidate)))))
completion-list))
(cl-defmethod phpinspect--make-completion
((completion-candidate phpinspect--function))
"Create a `phpinspect--completion` for COMPLETION-CANDIDATE."

@ -36,16 +36,6 @@
(buffer nil
:type phpinspect-buffer))
(cl-defmethod phpinspect-eldoc-query-execute ((query phpinspect-eldoc-query))
(let* ((buffer (phpinspect-eldoc-query-buffer query))
(point (phpinspect-eldoc-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point)))
(catch 'matched
(dolist (strategy phpinspect-eldoc-strategies)
(when (phpinspect-eld-strategy-supports strategy query rctx)
(phpinspect--log "Found matching eldoc strategy. Executing...")
(throw 'matched (phpinspect-eld-strategy-execute strategy query rctx)))))))
(cl-defgeneric phpinspect-eld-strategy-supports (strategy (query phpinspect-eldoc-query) (context phpinspect--resolvecontext))
"Should return non-nil if STRATEGY should be deployed for QUERY
@ -62,11 +52,11 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
"Eldoc strategy for object attributes.")
(cl-defmethod phpinspect-eld-strategy-supports
((strat phpinspect-eld-attribute) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
((_strat phpinspect-eld-attribute) (_q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(phpinspect-attrib-p (car (last (phpinspect--resolvecontext-subject rctx)))))
(cl-defmethod phpinspect-eld-strategy-execute
((strat phpinspect-eld-attribute) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
((_strat phpinspect-eld-attribute) (_q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(let ((attrib (car (last (phpinspect--resolvecontext-subject rctx))))
type-before)
(setf (phpinspect--resolvecontext-subject rctx) (butlast (phpinspect--resolvecontext-subject rctx)))
@ -77,9 +67,7 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(phpinspect--resolvecontext-project rctx)
type-before))
(attribute-name (cadadr attrib))
variable
method
result)
variable method result)
(when attribute-name
(cond ((phpinspect-static-attrib-p attrib)
(setq variable (phpinspect--class-get-variable class attribute-name))
@ -101,14 +89,15 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(setq method (phpinspect--class-get-method
class (phpinspect-intern-name attribute-name)))
(when method
(setq result (phpinspect-make-function-doc :fn method)))))))))))
(setq result (phpinspect-make-function-doc :fn method))))))
result)))))
(cl-defstruct (phpinspect-eld-function-args (:constructor phpinspect-make-eld-function-args))
"Eldoc strategy for function arguments.")
(cl-defmethod phpinspect-eld-strategy-supports
((strat phpinspect-eld-function-args) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
((_strat phpinspect-eld-function-args) (_q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(let ((parent-token (car (phpinspect--resolvecontext-enclosing-tokens rctx))))
;; When our subject is inside a list, it is probably an argument of a
;; function/method call, which is what this strategy provides information for.
@ -120,10 +109,9 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(car (last (phpinspect--resolvecontext-subject rctx)))))))
(cl-defmethod phpinspect-eld-strategy-execute
((strat phpinspect-eld-function-args) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
((_strat phpinspect-eld-function-args) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(phpinspect--log "Executing `phpinspect-eld-function-args' strategy")
(let* ((token-map (phpinspect-buffer-parse-map (phpinspect-eldoc-query-buffer q)))
(enclosing-token (car (phpinspect--resolvecontext-enclosing-metadata
(let* ((enclosing-token (car (phpinspect--resolvecontext-enclosing-metadata
rctx)))
(left-sibling )
(statement )
@ -239,6 +227,17 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
employ. Strategies are queried in the order of this list. See
also `phpinspect-eldoc-query-execute'.")
(cl-defmethod phpinspect-eldoc-query-execute ((query phpinspect-eldoc-query))
(let* ((buffer (phpinspect-eldoc-query-buffer query))
(point (phpinspect-eldoc-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point)))
(catch 'matched
(dolist (strategy phpinspect-eldoc-strategies)
(when (phpinspect-eld-strategy-supports strategy query rctx)
(phpinspect--log "Found matching eldoc strategy. Executing...")
(throw 'matched (phpinspect-eld-strategy-execute strategy query rctx)))))))
(defun phpinspect-eldoc-function ()
"An `eldoc-documentation-function` implementation for PHP files.

@ -61,13 +61,13 @@ thread, PREFER-ASYNC has no effect.")
(cl-defgeneric phpinspect-fs-directory-files (fs directory match))
(cl-defgeneric phpinspect-fs-directory-files-recursively (fs directory match))
(cl-defmethod phpinspect-fs-file-exists-p ((fs phpinspect-fs) file)
(cl-defmethod phpinspect-fs-file-exists-p ((_fs phpinspect-fs) file)
(file-exists-p file))
(cl-defmethod phpinspect-fs-file-exists-p ((fs phpinspect-virtual-fs) file)
(and (gethash file (phpinspect-virtual-fs-files fs)) t))
(cl-defmethod phpinspect-fs-file-directory-p ((fs phpinspect-fs) file)
(cl-defmethod phpinspect-fs-file-directory-p ((_fs phpinspect-fs) file)
(file-directory-p file))
(cl-defmethod phpinspect-fs-file-directory-p ((fs phpinspect-virtual-fs) file)
@ -86,14 +86,15 @@ thread, PREFER-ASYNC has no effect.")
(when file
(phpinspect-virtual-file-modification-time file))))
(cl-defmethod phpinspect-fs-file-modification-time ((fs phpinspect-fs) file)
(cl-defmethod phpinspect-fs-file-modification-time ((_fs phpinspect-fs) file)
(let ((attributes (file-attributes file)))
(when attributes
(file-attribute-modification-time attributes))))
(defsubst phpinspect--insert-file-contents-asynchronously (file)
"Inserts FILE contents into the current buffer asynchronously, while blocking the current thread.
"Inserts FILE contents into the current buffer asynchronously,
while blocking the current thread.
Errors when executed in main thread, as it should be used to make
background operations less invasive. Usage in the main thread can
@ -127,7 +128,7 @@ only be the result of a logic error."
(condition-wait condition)
(when err (error err)))))
(cl-defmethod phpinspect-fs-insert-file-contents ((fs phpinspect-fs) file &optional prefer-async)
(cl-defmethod phpinspect-fs-insert-file-contents ((_fs phpinspect-fs) file &optional prefer-async)
"Insert file contents from FILE. "
(if (and prefer-async (not (eq (current-thread) main-thread))
phpinspect--cat-executable)
@ -138,7 +139,7 @@ only be the result of a logic error."
(let ((file-obj (gethash file (phpinspect-virtual-fs-files fs))))
(when file (insert (or (phpinspect-virtual-file-contents file-obj) "")))))
(cl-defmethod phpinspect-fs-directory-files ((fs phpinspect-fs) directory &optional match)
(cl-defmethod phpinspect-fs-directory-files ((_fs phpinspect-fs) directory &optional match)
(directory-files directory t match t))
(cl-defmethod phpinspect-fs-directory-files ((fs phpinspect-virtual-fs) directory &optional match)
@ -154,7 +155,7 @@ only be the result of a logic error."
(phpinspect-virtual-fs-files fs))
files))
(cl-defmethod phpinspect-fs-directory-files-recursively ((fs phpinspect-fs) directory &optional match)
(cl-defmethod phpinspect-fs-directory-files-recursively ((_fs phpinspect-fs) directory &optional match)
(directory-files-recursively directory
match
t ;; Ignore directories that cannot be read

@ -25,6 +25,7 @@
(require 'phpinspect-util)
(require 'phpinspect-meta)
(require 'phpinspect-changeset)
(require 'phpinspect-bmap)
(defvar phpinspect-parse-context nil
@ -121,57 +122,6 @@ thrown.")
(setf (phpinspect-pctx-whitespace-before pctx) "")
whitespace))
(define-inline phpinspect-make-changeset (meta)
(inline-letevals (meta)
(inline-quote
(list (phpinspect-meta-start ,meta) (phpinspect-meta-end ,meta)
(phpinspect-meta-parent ,meta) (phpinspect-meta-overlay ,meta)
(phpinspect-meta-parent-offset ,meta) ,meta))))
(define-inline phpinspect-changeset-start (set)
(inline-quote (car ,set)))
(define-inline phpinspect-changeset-end (set)
(inline-quote (cadr ,set)))
(define-inline phpinspect-changeset-parent (set)
(inline-quote (caddr ,set)))
(define-inline phpinspect-changeset-overlay (set)
(inline-quote (cadddr ,set)))
(define-inline phpinspect-changeset-parent-offset (set)
(inline-quote (car (cddddr ,set))))
(define-inline phpinspect-changeset-meta (set)
(inline-quote (car (nthcdr 5 ,set))))
(define-inline phpinspect-meta-with-changeset (meta &rest body)
(declare (indent 1))
(inline-letevals (meta)
(push 'progn body)
(inline-quote
(progn
(when phpinspect-parse-context
(phpinspect-pctx-register-changeset
phpinspect-parse-context (phpinspect-make-changeset ,meta)))
,body))))
(define-inline phpinspect-changeset-revert (changeset)
(inline-letevals (changeset)
(inline-quote
(progn
(setf (phpinspect-meta-parent (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-parent ,changeset))
(setf (phpinspect-meta-overlay (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-overlay ,changeset))
(setf (phpinspect-meta-absolute-start (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-start ,changeset))
(setf (phpinspect-meta-absolute-end (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-end ,changeset))
(setf (phpinspect-meta-parent-offset (phpinspect-changeset-meta ,changeset))
(phpinspect-changeset-parent-offset ,changeset))))))
(defun phpinspect-pctx-cancel (pctx)
(phpinspect--log "Cancelling parse context")
(dolist (changeset (phpinspect-pctx-changesets pctx))

@ -204,7 +204,7 @@ apeared to be a little more performant than using `let'."
(phpinspect-splayt-node-rotate-left ,parent ,splayt)
(phpinspect-splayt-node-rotate-right ,parent ,splayt))
(t
(error "Failed in determining rotation strategy. (phpinspect-splayt-node-grandparent ,node): %s, parent: %s, ,node: %s")))
(error "Failed in determining rotation strategy.")))
;; Else
(if (eq ,node (phpinspect-splayt-node-left ,parent))

@ -1,10 +1,11 @@
; phpinspect.el --- PHP parsing and completion package -*- lexical-binding: t; -*-
;;; phpinspect.el --- PHP parsing and completion package -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc
;; Author: Hugo Thunnissen <devel@hugot.nl>
;; Keywords: php, languages, tools, convenience
;; Version: 0
;; Package-Requires: ((compat "29"))
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by

Loading…
Cancel
Save