branch: elpa/raku-mode commit d62231e90216219e9a7b5f55893c9420f6bb3b5e Merge: 14073feeb0 588dc4417b Author: JJ Merelo <jjmer...@gmail.com> Commit: JJ Merelo <jjmer...@gmail.com>
Merge branch 'my-branch' of https://github.com/tbrowder/perl6-mode --- README.md | 1 - README.tmp-imenu-notes | 53 +++++++++++++++++++++++++ perl6-mode.el => nqp-mode.el | 6 +++ perl6-detect.el | 1 + perl6-imenu.el | 93 ++++++++++++++++++++++++++++++++++++++++++++ perl6-mode.el | 6 +++ perl6-unicode-menu.el | 30 ++++++++++++++ test/test-imenu.nqp | 24 ++++++++++++ test/test-imenu.p6 | 24 ++++++++++++ 9 files changed, 237 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c482b1f4f..77511adaff 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ This mode needs GNU Emacs 24.4. * Better indentation support * Help system * REPL interaction -* imenu support * ETags support * `find-file-at-point` for module names * Electricity (`electric-pair-mode` needs some context-sensitive help) diff --git a/README.tmp-imenu-notes b/README.tmp-imenu-notes new file mode 100644 index 0000000000..60d33741ac --- /dev/null +++ b/README.tmp-imenu-notes @@ -0,0 +1,53 @@ +major modes: + +The mode should specify how Imenu should find the definitions or +sections of a buffer, by setting up a buffer-local value for the +variable imenu-generic-expression, for the two variables +imenu-prev-index-position-function and +imenu-extract-index-name-function, or for the variable +imenu-create-index-function (see Imenu). + +Macro: defvar-local variable value &optional docstring + + This macro defines variable as a variable with initial value value + and docstring, and marks it as automatically buffer-local. It is + equivalent to calling defvar followed by + make-variable-buffer-local. variable should be an unquoted symbol. + +22.5 Imenu + +Imenu is a feature that lets users select a definition or section in +the buffer, from a menu which lists all of them, to go directly to +that location in the buffer. Imenu works by constructing a buffer +index which lists the names and buffer positions of the definitions, +or other named portions of the buffer; then the user can choose one of +them and move point to it. Major modes can add a menu bar item to use +Imenu using imenu-add-to-menubar. + +Command: imenu-add-to-menubar name + + This function defines a local menu bar item named name to run Imenu. + +The usual and simplest way is to set the variable imenu-generic-expression: + +Variable: imenu-generic-expression + + This variable, if non-nil, is a list that specifies regular + expressions for finding definitions for Imenu. Simple elements of + imenu-generic-expression look like this: + + (menu-title regexp index) + + Here, if menu-title is non-nil, it says that the matches for this + element should go in a submenu of the buffer index; menu-title + itself specifies the name for the submenu. If menu-title is nil, the + matches for this element go directly in the top level of the buffer + index. + + The second item in the list, regexp, is a regular expression (see + Regular Expressions); anything in the buffer that it matches is + considered a definition, something to mention in the buffer + index. + + The third item, index, is a non-negative integer that indicates + which subexpression in regexp matches the definition’s name. diff --git a/perl6-mode.el b/nqp-mode.el similarity index 88% copy from perl6-mode.el copy to nqp-mode.el index 67c5853a8d..d5b2d24e76 100644 --- a/perl6-mode.el +++ b/nqp-mode.el @@ -41,6 +41,7 @@ (require 'perl6-detect) (require 'perl6-font-lock) (require 'perl6-indent) +(require 'perl6-imenu) ;;;###autoload (define-derived-mode perl6-mode prog-mode "Perl6" @@ -50,6 +51,11 @@ (add-hook 'syntax-propertize-extend-region-functions #'syntax-propertize-multiline nil 'local) (setq-local font-lock-syntactic-face-function #'perl6-font-lock-syntactic-face) (setq-local font-lock-defaults '(perl6-font-lock-keywords nil nil)) + ;; Add imenu support for perl6-mode. Note that imenu-generic-expression + ;; is buffer-local, so we don't need a local-variable for it. + (add-hook 'perl6-mode-hook 'imenu-add-menubar-index) + (setq imenu-generic-expression perl6-imenu-generic-expression + imenu-case-fold-search nil) ;; Comments (setq-local comment-start "#") (setq-local comment-start-skip "#+ *") diff --git a/perl6-detect.el b/perl6-detect.el index 575ba64b5a..5753144b0a 100644 --- a/perl6-detect.el +++ b/perl6-detect.el @@ -14,6 +14,7 @@ ;;;###autoload (add-to-list 'auto-mode-alist '("\\.p[lm]?6\\'" . perl6-mode)) +(add-to-list 'auto-mode-alist '("\\.nqp\\'" . perl6-mode)) ;;;###autoload (defconst perl6-magic-pattern diff --git a/perl6-imenu.el b/perl6-imenu.el new file mode 100644 index 0000000000..075b6347a8 --- /dev/null +++ b/perl6-imenu.el @@ -0,0 +1,93 @@ +;;; perl6-imenu.el --- Imenu support Perl 6 -*- lexical-binding: t; -*- + +;; Imenu functions and variables are defined here. + +;; Definition of "identifiers" (names) from +;; https://docs.perl6.org/language/syntax#Identifiers +;; +;; Identifiers are a grammatical building block that occur in several +;; places. An identifier is a primitive name, and must start with an +;; alphabetic character (or an underscore), followed by zero or more +;; word characters (alphabetic, underscore or number). You can also +;; embed dashes - or single quotes ' in the middle, but not two in a +;; row, and only if followed immediately by an alphabetic character. +;; +;; For NQP names, no embedded hyphens or single quotes are allowed. + +;; Regex definitions: +(defvar perl6-name-regex + (concat + "[_[:alpha:]]" ; mandatory leading character + "\\(?:[-']?[[:alpha:]]\\|[_[:alnum:]]\\)*" ; rest of the name allowing embedded hyphens or single quotes + )) + +(defvar nqp-name-regex + (concat + "[_[:alpha:]]" ; mandatory leading character + "[_[:alnum:]]*" ; rest of the name (stricter than Perl 6 name) + )) + +(defvar perl6-vars-regex + (concat + "^\\s-*" ; leading ws allowed + "\\(?:my\\|our\\)\\s-+" ; scope of var, followed by mandatory ws + "\\(" ; start capture group 1 for the var name + "\\(?:\\$\\|@\\|%\\)" ; sigil for type of var + "\\(?:" ; start shy group for choice of one type name + perl6-name-regex + "\\|" + nqp-name-regex + "\\)" ; end shy group + "\\)" ; end of capture group 1 + )) + +(defvar perl6-subs-regex + (concat + "^\\s-*" ; leading ws allowed + "\\(?:my\\s-+\\|our\\s-+\\)?" ; optional specific scope followed by at least one space + ; must have one of the five type identifiers + ; followed by at least one space: + "\\(?:multi\\s-+sub\\|multi\\s-+method\\|sub\\|method\\|multi\\|proto\\)\\s-+" + "\\!?" ; optional private marker + "\\(" ; start capture group 1 for the sub name + perl6-name-regex + "\\|" + nqp-name-regex + "\\)" ; end of capture group 1 + )) + +(defvar perl6-classes-regex + (concat + "^\\s-*" ; leading ws allowed + ; must have one of the four type identifiers followed by at least one space: + "class\\s-+" + "\\(" ; start capture group 1 of the class name + perl6-name-regex + "\\|" + nqp-name-regex + "\\)" ; end of capture group 1 + )) + +(defvar perl6-imenu-generic-expression + `( + ;; the names are in reverse desired order since they are evaluated here last first + ("Classes" ,perl6-classes-regex 1) + ("Variables" ,perl6-vars-regex 1) + ("Subs/Methods" ,perl6-subs-regex 1) + ) + "Define interesting points in the Perl 6 buffer for `imenu'. + +This is used to set `imenu-generic-expression' when Perl 6 mode is +entered. Subsequent changes to `perl6-imenu-generic-expression' will +not affect existing Perl 6 buffers because imenu-generic-expression is +a local variable.") + +;;=========================== +(provide 'perl6-imenu) + +;; Local Variables: +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; perl6-imenu.el ends here diff --git a/perl6-mode.el b/perl6-mode.el index 67c5853a8d..d5b2d24e76 100644 --- a/perl6-mode.el +++ b/perl6-mode.el @@ -41,6 +41,7 @@ (require 'perl6-detect) (require 'perl6-font-lock) (require 'perl6-indent) +(require 'perl6-imenu) ;;;###autoload (define-derived-mode perl6-mode prog-mode "Perl6" @@ -50,6 +51,11 @@ (add-hook 'syntax-propertize-extend-region-functions #'syntax-propertize-multiline nil 'local) (setq-local font-lock-syntactic-face-function #'perl6-font-lock-syntactic-face) (setq-local font-lock-defaults '(perl6-font-lock-keywords nil nil)) + ;; Add imenu support for perl6-mode. Note that imenu-generic-expression + ;; is buffer-local, so we don't need a local-variable for it. + (add-hook 'perl6-mode-hook 'imenu-add-menubar-index) + (setq imenu-generic-expression perl6-imenu-generic-expression + imenu-case-fold-search nil) ;; Comments (setq-local comment-start "#") (setq-local comment-start-skip "#+ *") diff --git a/perl6-unicode-menu.el b/perl6-unicode-menu.el new file mode 100644 index 0000000000..b4a87e71d3 --- /dev/null +++ b/perl6-unicode-menu.el @@ -0,0 +1,30 @@ +;; Provide a menu bar item to ease insertion of Unicode characters. + + +;; Make a menu keymap (with a prompt string) +;; and make it the menu bar item’s definition. +;; put it at the end +(define-key global-map [menu-bar unicode] + (cons "Unicode" (make-sparse-keymap "Unicode"))) +;; Define specific subcommands in this menu. +(define-key global-map + [menu-bar unicode forward] + '("Forward word" . forward-word)) +(define-key global-map + [menu-bar unicode backward] + '("Backward word" . backward-word)) +(defvar menu-bar-final-items '(help-menu unicode-menu)) ;; doesn't work?? + + + + + +;;=========================== +(provide 'perl6-unicode-menu) + +;; Local Variables: +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; perl6-imenu.el ends here diff --git a/test/test-imenu.nqp b/test/test-imenu.nqp new file mode 100644 index 0000000000..307bd422b6 --- /dev/null +++ b/test/test-imenu.nqp @@ -0,0 +1,24 @@ +# file: test-imenu.p6 + +# Perl 6 syntax file for testing perl6-mode with imenu support, which is located at: +# +# https://github.com/tbrowder/perl6-mode [branch: "my-branch"] + +my $a; +my @b; +our %c; + +my $a-a; +my $a'a_3-z; + + sub a(){my @ze} + multi sub x() {} +method d() {} +my multi method z() {} +multi c() {} + +proto xx() {} + +class My-class1 {} +class My-class2{ + class doit () {} diff --git a/test/test-imenu.p6 b/test/test-imenu.p6 new file mode 100644 index 0000000000..5ec9e418bf --- /dev/null +++ b/test/test-imenu.p6 @@ -0,0 +1,24 @@ +# file: test-imenu.p6 + +# Perl 6 syntax file for testing perl6-mode with imenu support, which is located at: +# +# https://github.com/tbrowder/perl6-mode [branch: "my-branch"] + +my $a; +my @b; +our %c; + +my $a-a; +my $a'a_3-z; + + sub a(){my @ze} + multi sub x() {} +method d() {} +my multi method z() {} +multi c() {} +proto xx() {} +multi method !z-private() {} + +class My-class1 {} +class My-class2{ + class doit () {}