branch: elpa/scala-mode commit e6a2755547146791d9b9869caeb0462701ede3e2 Author: Ivan Malison <ivanmali...@gmail.com> Commit: Ivan Malison <ivanmali...@gmail.com>
Add stuff to readme. Small fixes. got rid fo whitespace changes. --- README.md | 39 ++++++++++++++++++++++++++++++++++++--- scala-mode2-imenu.el | 13 ++++++++++++- scala-mode2-syntax.el | 29 +++++++++++++++++++---------- scala-mode2.el | 16 ++++++++-------- 4 files changed, 75 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index df0ec19..796b5d3 100644 --- a/README.md +++ b/README.md @@ -428,9 +428,39 @@ Very complex scala files may need the following in your emacs init (.emacs, etc) (setq max-specpdl-size 5000) ``` +## `beginning-of-defun` and `end-of-defun` + +scala-mode2 defines `scala-syntax:beginning-of-definition` and +`scala-syntax:end-of-definition` which move the cursor forward and +backward over class, trait, object, def, val, var, and type. These +functions are assigned to the buffer local variables +`beginning-of-defun-function` and `end-of-defun-function` which makes +it so that the `beginning-of-defun` and `end-of-defun` functions behave +in a way that is appropriate to scala. Because of the relatively complex +nature of scala definitions, these functions are not currently able to +support some of the more advanced scala definition types. +Multiple assignment to variables e.g. + +```scala +val a, b = (1, 2) +``` + +are among the assignment types that are not currently supported. + +## imenu + +scala-mode2 supports imenu, a library for accessing locations in documents that +is included in emacs 24. The custom variable `scala-imenu:should-flatten-index` +controls whether or not the imenu index will be hierarchical or completely flat. +The current iMenu implementation only goes one level deep i.e. nested classes are +not traversed. scala-mode2's imenu support depends heavily on the +`scala-syntax:end-of-definition` and `scala-syntax:beginning-of-definition` +functions, and as such, it shares their limitations. + ## Other features - highlights only properly formatted string and character constants - indenting a code line removes trailing whitespace +- imenu compatibility ## Known issues @@ -447,16 +477,19 @@ The indenter thinks the second occurrence of `foo` is the body of the while. To work around this, terminate the while with a semicolon, or put a blank line after it. +`scala-syntax:end-of-definition` `scala-syntax:beginning-of-definition` + ## Future work - syntax-begin-function for reliably fontifying elements which span multiple lines -- beginning-of-defun, end-of-defun -- movement commands to move to previous or next definition (val, - var, def, class, trait, object) - highlight headings and annotations inside Scaladoc specially (use underline for headings) - highlight variables in string interpolation (scala 2.10) +- Improve `end-of-defun` and `beginning-of-defun`. In particular, + figure out why `end-of-defun` sometimes skips defintions + even though `scala-syntax:end-of-definition` does not and add + support for obscure types of val declarations. All suggestions and especially pull requests are welcomed in github https://github.com/hvesalai/scala-mode2 diff --git a/scala-mode2-imenu.el b/scala-mode2-imenu.el index 29b0c22..658e629 100644 --- a/scala-mode2-imenu.el +++ b/scala-mode2-imenu.el @@ -4,13 +4,16 @@ (require 'scala-mode2-syntax) +(defcustom scala-imenu:should-flatten-index nil + "Controls whether or not the imenu index is flattened or hierarchical.") + (defun scala-imenu:create-index () (interactive) (let ((class nil) (index nil)) (goto-char (point-max)) (while (setq class (scala-imenu:previous-class)) (setq index (cons class index))) - index)) + (if scala-imenu:should-flatten-index (scala-imenu:flatten-index index) index))) (defun scala-imenu:previous-class () (interactive) @@ -41,5 +44,13 @@ (scala-imenu:get-class-members stop-at-point))) nil))) +(defun scala-imenu:flatten-index (index) + (reduce #'append + (mapcar (lambda (class-info) + (let ((class-name (car class-info))) + (mapcar (lambda (member-info) `(,(concat class-name "." (car member-info)) . + ,(cdr member-info))) + (cdr class-info)))) index))) + (provide 'scala-mode2-imenu) diff --git a/scala-mode2-syntax.el b/scala-mode2-syntax.el index 1f7ce41..be79a8d 100644 --- a/scala-mode2-syntax.el +++ b/scala-mode2-syntax.el @@ -901,14 +901,18 @@ not. A list must be either enclosed in parentheses or start with ;; Functions to help with finding the beginning and end of scala definitions. +(defconst scala-syntax:modifiers-re + (regexp-opt '("override" "abstract" "final" "sealed" "implicit" "lazy" + "private" "protected" "case") 'words)) + (defconst scala-syntax:whitespace-delimeted-modifiers-re - (concat "\\(?:" scala-syntax:modifiers-unsafe-re "\\(?: *\\)" "\\)*")) + (concat "\\(?:" scala-syntax:modifiers-re "\\(?: *\\)" "\\)*")) (defconst scala-syntax:definition-words-re (regexp-opt '("class" "object" "trait" "val" "var" "def" "type") 'words)) (defun scala-syntax:build-definition-re (words-re) - (concat "[:space:]*" + (concat " *" scala-syntax:whitespace-delimeted-modifiers-re words-re "\\(?1: *\\)" @@ -920,6 +924,7 @@ not. A list must be either enclosed in parentheses or start with (scala-syntax:build-definition-re scala-syntax:definition-words-re)) ;; Functions to help with beginning and end of definitions. + (defun scala-syntax:backward-sexp-forcing () (condition-case ex (backward-sexp) ('error (backward-char)))) @@ -929,26 +934,31 @@ not. A list must be either enclosed in parentheses or start with (t (forward-sexp)))) (defun scala-syntax:beginning-of-definition () - "This function is not totally correct. Scala syntax is hard." + "This function may not work properly with certain types of scala definitions. +For example, no care has been taken to support multiple assignments to vals such as + +val a, b = (1, 2) +" (interactive) (let ((found-position (save-excursion - (funcall 'scala-syntax:backward-sexp-forcing) + (scala-syntax:backward-sexp-forcing) (scala-syntax:movement-function-until-re scala-syntax:all-definition-re - 'scala-syntax:backward-sexp-forcing)))) + 'scala-syntax:backward-sexp-forcing)))) (when found-position (progn (goto-char found-position) (back-to-indentation))))) (defun scala-syntax:end-of-definition () - "This function is not totally correct. Scala syntax is hard. -According to the documentation of end-of-defun it should be assumed that -beginning-of-defun was executed prior to the execution of this function." + "This function may not work properly with certain types of scala definitions. +For example, no care has been taken to support multiple assignments to vals such as + +val a, b = (1, 2) +" (interactive) (re-search-forward scala-syntax:all-definition-re) (scala-syntax:find-brace-equals-or-next) (scala-syntax:handle-brace-equals-or-next)) (defun scala-syntax:find-brace-equals-or-next () - (interactive) (scala-syntax:go-to-pos (save-excursion (scala-syntax:movement-function-until-cond-function @@ -957,7 +967,6 @@ beginning-of-defun was executed prior to the execution of this function." (lambda () (condition-case ex (scala-syntax:forward-sexp-or-next-line) ('error nil))))))) (defun scala-syntax:handle-brace-equals-or-next () - (interactive) (cond ((looking-at " *{") (forward-sexp)) ((looking-at " *=") (scala-syntax:forward-sexp-or-next-line) (scala-syntax:handle-brace-equals-or-next)) diff --git a/scala-mode2.el b/scala-mode2.el index 1b64fd5..cd88f61 100644 --- a/scala-mode2.el +++ b/scala-mode2.el @@ -69,17 +69,13 @@ If there is no plausible default, return nil." (scala-mode:make-local-variables 'syntax-propertize-function 'parse-sexp-lookup-properties - 'forward-sexp-function - 'beginning-of-defun-function - 'end-of-defun-function) + 'forward-sexp-function) (add-hook 'syntax-propertize-extend-region-functions 'scala-syntax:propertize-extend-region) (setq syntax-propertize-function 'scala-syntax:propertize parse-sexp-lookup-properties t - forward-sexp-function 'scala-mode:forward-sexp-function - beginning-of-defun-function 'scala-syntax:beginning-of-definition - end-of-defun-function 'scala-syntax:end-of-definition)) + forward-sexp-function 'scala-mode:forward-sexp-function)) ;;;###autoload (define-derived-mode scala-mode prog-mode "Scala" @@ -114,7 +110,9 @@ When started, runs `scala-mode-hook'. 'fixup-whitespace 'delete-indentation 'indent-tabs-mode - 'imenu-create-index-function) + 'imenu-create-index-function + 'beginning-of-defun-function + 'end-of-defun-function) (add-hook 'syntax-propertize-extend-region-functions 'scala-syntax:propertize-extend-region) @@ -147,7 +145,9 @@ When started, runs `scala-mode-hook'. indent-line-function 'scala-indent:indent-line fixup-whitespace 'scala-indent:fixup-whitespace delete-indentation 'scala-indent:join-line - indent-tabs-mode nil) + indent-tabs-mode nil + beginning-of-defun-function 'scala-syntax:beginning-of-definition + end-of-defun-function 'scala-syntax:end-of-definition) (set (make-local-variable 'imenu-create-index-function) #'scala-imenu:create-index) (use-local-map scala-mode-map) ;; add indent functionality to some characters