;;; alchemist-complete.el --- Complete functionality for Elixir source code -*- lexical-binding: t -*- ;; Copyright © 2014-2015 Samuel Tonini ;; Author: Samuel Tonini . ;;; Commentary: ;; Complete functionality for Elixir and Erlang source code. ;;; Code: (require 'cl-lib) (require 'dash) (require 'ansi-color) (require 'company-dabbrev-code) (require 'alchemist-utils) (defgroup alchemist-complete nil "Complete functionality for Elixir source code." :prefix "alchemist-complete-" :group 'alchemist) (defvar alchemist-company-last-completion nil) (defun alchemist-complete--concat-prefix-with-functions (prefix functions &optional add-prefix) (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) (candidates (-map (lambda (c) (concat prefix "." c)) (cdr functions)))) (if add-prefix (push prefix candidates) candidates))) (defun alchemist-complete--add-prefix-to-function (prefix function) (let* ((prefix (mapconcat 'concat (butlast (split-string prefix "\\.") 1) ".")) (candidate (concat prefix "." function))) candidate)) (defun alchemist-complete--build-candidates (a-list) (let* ((search-term (car a-list)) (candidates a-list) (candidates (-map (lambda (f) (let* ((candidate f) (meta (if (string-match-p "^.+/" f) (replace-regexp-in-string "^.+/" "/" f) ""))) (cond ((and (string-match-p "^:" search-term) (not (string-match-p "\\." search-term))) (unless (string= search-term candidate) (propertize (concat ":" candidate)) )) ((string-match-p "\\." search-term) (unless (string= search-term candidate) (propertize (alchemist-complete--add-prefix-to-function (concat (alchemist-scope-extract-module search-term) ".") (replace-regexp-in-string "/[0-9]$" "" candidate)) 'meta meta))) (t (propertize (replace-regexp-in-string "/[0-9]$" "" candidate) 'meta meta))))) candidates)) (candidates (-remove 'null candidates))) (cond ((and (string-match-p "\\.$" search-term) (not (string-match-p "\\.$" alchemist-company-last-completion))) (push (alchemist-utils-remove-dot-at-the-end search-term) candidates)) (t candidates)))) (defun alchemist-complete--build-help-candidates (a-list) (let* ((search-term (car a-list)) (candidates (cond ((> (alchemist-utils-count-char-occurence "\\." search-term) 1) (let ((search (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) (list (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "" search-term)) (list (alchemist-utils-remove-dot-at-the-end search-term)))) (candidates (-map (lambda (c) (if (string-match-p "\\.[a-z0-9_\?!]+$" search-term) (concat (replace-regexp-in-string "\\.[a-z0-9_\?!]+$" "." search-term) c) (concat search-term c))) (cdr a-list)))) (append search candidates))) ((string-match-p "\\.$" search-term) (alchemist-complete--concat-prefix-with-functions search-term a-list t)) ((string-match-p "\\.[a-z0-9_\?!]+$" search-term) (alchemist-complete--concat-prefix-with-functions search-term a-list)) (t a-list)))) (-distinct candidates))) (defun alchemist-complete--output-to-list (output) (let* ((output (split-string output))) (-remove 'null output))) (defun alchemist-complete--build-candidates-from-process-output (output) (let* ((output (alchemist-server-prepare-filter-output output)) (candidates (if (not (alchemist-utils-empty-string-p output)) (alchemist-complete--output-to-list (ansi-color-filter-apply output)) '())) (candidates (if candidates (alchemist-complete--build-candidates candidates) '()))) candidates)) (defun alchemist-complete--completing-prompt (initial completing-collection) (let* ((completing-collection (alchemist-complete--build-help-candidates completing-collection))) (cond ((equal (length completing-collection) 1) (car completing-collection)) (completing-collection (completing-read "Elixir help: " completing-collection nil nil (replace-regexp-in-string "\\.$" "" initial))) (t initial)))) (defun alchemsit-complete--dabbrev-code-candidates () "This function uses a piece of functionality of company-dabbrev-code backend. Please have a look at the company-dabbrev-code function for more detailed information." (let ((case-fold-search nil)) (-distinct (company-dabbrev--search (company-dabbrev-code--make-regexp alchemist-company-last-completion) company-dabbrev-code-time-limit (list major-mode) t)))) (provide 'alchemist-complete) ;;; alchemist-complete.el ends here