You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.4 KiB
154 lines
5.4 KiB
;;; ac-slim.el --- auto complete source for html tag and attributes |
|
|
|
;; Copyright (C) 2015 Zhang Kai Yu |
|
|
|
;; Author: Zhang Kai Yu <yeannylam@gmail.com> |
|
;; Keywords: html, auto-complete, slim, ruby |
|
|
|
;; 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 <http://www.gnu.org/licenses/>. |
|
|
|
;;; Commentary: |
|
|
|
;; Configuration: |
|
;; |
|
|
|
;;; Code: |
|
|
|
(require 'ac-html-core) |
|
|
|
(require 's) |
|
|
|
(defun ac-slim-inside-ruby-code () |
|
"Return t if inside ruby code." |
|
(let ((line (buffer-substring-no-properties (line-beginning-position) |
|
(line-end-position)))) |
|
(numberp (string-match-p "^[\t ]*[-=]" line)))) |
|
|
|
(defun ac-slim--line-leading-spaces () |
|
"Return leading space of current line." |
|
(let ((saved-point (point)) (number-of-spaces 0) (cur-point nil)) |
|
(goto-char (line-beginning-position)) |
|
(setq cur-point (point)) |
|
(while (-contains-p '(? ?\t) (char-after cur-point)) |
|
(setq number-of-spaces (1+ number-of-spaces)) |
|
(setq cur-point (1+ cur-point)) |
|
(goto-char cur-point)) |
|
(goto-char saved-point) |
|
number-of-spaces)) |
|
|
|
(defun ac-slim--line-is-block-indicator () |
|
"Return t if line indicate a non slim block." |
|
(let ((content-of-line (buffer-substring-no-properties |
|
(line-beginning-position) (line-end-position)))) |
|
(numberp (string-match-p |
|
"[ \t]*\\(ruby\\|javascript\\|coffee\\):[ \t]*" |
|
content-of-line)))) |
|
|
|
(defun ac-slim--line-is-empty () |
|
"Return t if line is empty." |
|
(s-matches-p "^[ \t]*$" (buffer-substring-no-properties |
|
(line-beginning-position) |
|
(line-end-position)))) |
|
|
|
(defun ac-slim-inside-non-slim-block () |
|
"Return t if inside ruby block, coffee block." |
|
(catch 'blk |
|
(save-excursion |
|
(let ((min-number-of-leading-spaces (ac-slim--line-leading-spaces))) |
|
(if (ac-slim--line-is-block-indicator) |
|
(throw 'blk t)) |
|
(while (not (or (= min-number-of-leading-spaces 0) |
|
(= 1 (line-number-at-pos)))) |
|
(forward-line -1) |
|
(if (ac-slim--line-is-empty) |
|
nil |
|
(if (< (ac-slim--line-leading-spaces) min-number-of-leading-spaces) |
|
(progn |
|
(setq min-number-of-leading-spaces (ac-slim--line-leading-spaces)) |
|
(if (ac-slim--line-is-block-indicator) |
|
(throw 'blk t)))))))))) |
|
|
|
(defun ac-slim-tag-prefix () |
|
(and (not (ac-slim-inside-ruby-code)) |
|
(not (ac-slim-inside-non-slim-block)) |
|
(save-match-data |
|
(save-excursion |
|
(re-search-backward "\\(^[\t ]*\\|:[\t ]*\\)\\([a-zA-Z]*\\)" nil t) |
|
(match-beginning 2))))) |
|
|
|
(defun ac-slim-attr-prefix () |
|
(and (not (ac-slim-inside-ruby-code)) |
|
(not (ac-slim-inside-non-slim-block)) |
|
(not (ac-slim-attrv-prefix)) |
|
(save-match-data |
|
(save-excursion |
|
(re-search-backward " \\(.*\\)" nil t) |
|
(match-beginning 1))))) |
|
|
|
(defun ac-slim-attrv-prefix () |
|
(and (not (ac-slim-inside-ruby-code)) |
|
(not (ac-slim-inside-non-slim-block)) |
|
(let (mb2 me2) |
|
(save-excursion |
|
(save-match-data |
|
(if (re-search-backward |
|
"\\w *= *[\"']\\([^\"']+[ ]\\|\\)\\([^\"']*\\)" |
|
(line-beginning-position) t) |
|
(progn |
|
(setq mb2 (match-beginning 2)) |
|
(setq me2 (match-end 2)))))) |
|
(if (and mb2 (>= me2 (point))) |
|
mb2)))) |
|
|
|
(defun ac-slim-class-prefix () |
|
(and (not (ac-slim-inside-ruby-code)) |
|
(not (ac-slim-inside-non-slim-block)) |
|
(save-match-data |
|
(save-excursion |
|
(re-search-backward "\\(^[\t ]*\\|:[\t ]*\\)\\([a-zA-Z0-9#.]*\\.\\)\\([a-zA-Z0-9]\\)" nil t) |
|
(match-beginning 3))))) |
|
|
|
(defun ac-slim-id-prefix () |
|
(and (not (ac-slim-inside-ruby-code)) |
|
(not (ac-slim-inside-non-slim-block)) |
|
(save-match-data |
|
(save-excursion |
|
(re-search-backward "\\(^[\t ]*\\|:[\t ]*\\)\\([a-zA-Z0-9.]*#\\)\\([a-zA-Z0-9]\\)" nil t) |
|
(match-beginning 3))))) |
|
|
|
(defun ac-slim-current-tag () |
|
"Return current slim tag user is typing on." |
|
(let* ((line (buffer-substring-no-properties (line-beginning-position) |
|
(line-end-position))) |
|
(match-result (s-match "\\(^[\t ]*\\|:[\t ]*\\)\\(\\w+\\)" line))) |
|
(if match-result |
|
(nth 2 match-result) |
|
"div"))) |
|
|
|
(defun ac-slim-current-attr () |
|
"Return current html tag's attribute user is typing on." |
|
(save-excursion (re-search-backward "[^a-z-]\\([a-z-]+\\) *=" nil t)) |
|
(match-string 1)) |
|
|
|
(ac-html-define-ac-source "slim" |
|
:tag-prefix ac-slim-tag-prefix |
|
:attr-prefix ac-slim-attr-prefix |
|
:attrv-prefix ac-slim-attrv-prefix |
|
:class-prefix ac-slim-class-prefix |
|
:id-prefix ac-slim-id-prefix |
|
:current-tag-func ac-slim-current-tag |
|
:current-attr-func ac-slim-current-attr) |
|
|
|
(provide 'ac-slim) |
|
;;; ac-slim.el ends here
|
|
|