diff --git a/emacs/.emacs.d/qml-mode/LICENSE b/emacs/.emacs.d/qml-mode/LICENSE new file mode 100644 index 0000000..37def8a --- /dev/null +++ b/emacs/.emacs.d/qml-mode/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013, Kikuchi Motoki +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Kikuchi Motoki nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/emacs/.emacs.d/qml-mode/README.md b/emacs/.emacs.d/qml-mode/README.md new file mode 100644 index 0000000..ab34040 --- /dev/null +++ b/emacs/.emacs.d/qml-mode/README.md @@ -0,0 +1,14 @@ +qml-mode for GNU Emacs +============== +Major mode of Emacs for qt declarative (QML) markup. + +##Syntax Highlight +* Qt object declarations +* property and its declarations +* function and signal declarations +* import preprocessors (packages, directories, js resources) + +Not highlighting javascript codes. + +##Line Indentation +default indent offset is 2. diff --git a/emacs/.emacs.d/qml-mode/qml-mode.el b/emacs/.emacs.d/qml-mode/qml-mode.el new file mode 100644 index 0000000..e20d3c4 --- /dev/null +++ b/emacs/.emacs.d/qml-mode/qml-mode.el @@ -0,0 +1,249 @@ +;; -*- lexical-binding: nil; -*- +;; ^ How does this fix it?!?! +;; QML Mode + +(defvar qml-mode-hook nil) + +(let ((qml-highlight-blue "MediumBlue") ;#0000cd + (qml-highlight-orchid "DarkOrchid") ;#9932cc + (qml-highlight-olive "OliveDrab") ;#6b8e23 + (qml-highlight-red "red4") ;#8b0000 + (qml-highlight-violet "MediumPurple3") ;#8968cd + (qml-highlight-green "SeaGreen4") ;#698b69 + (qml-highlight-royal-blue "RoyalBlue2");#436eee + ) + + (defface qml-declaration-face + `((t :foreground ,qml-highlight-blue)) + "Face for element declaration.") + (defvar qml-declaration-face 'qml-declaration-face) + + (defface qml-preprocessor-face + `((t :foreground ,qml-highlight-orchid)) + "Face for preprocessor.") + (defvar qml-preprocessor-face 'qml-preprocessor-face) + + (defface qml-package-face + `((t :foreground ,qml-highlight-olive)) + "Face for package name.") + (defvar qml-package-face 'qml-package-face) + + (defface qml-package-version-face + `((t :foreground ,qml-highlight-red)) + "Face for package version.") + (defvar qml-package-version-face 'qml-package-version-face) + + (defface qml-property-def-keyword-face + `((t :foreground ,qml-highlight-violet)) + "Face for \"property\" keyword of peroperty definition.") + (defvar qml-property-def-keyword-face 'qml-property-def-keyword-face) + + (defface qml-basic-type-face + `((t :foreground ,qml-highlight-green)) + "Face for qml baic type.") + (defvar qml-basic-type-face 'qml-basic-type-face) + + (defface qml-function-keyword-face + `((t :foreground ,qml-highlight-royal-blue)) + "Face for qml function and signal keyword.") + (defvar qml-function-keyword-face 'qml-function-keyword-face) + ) + +(defvar qml-syntax-table + (let ((qml-st (make-syntax-table))) + (modify-syntax-entry ?/ ". 124b" qml-st) + (modify-syntax-entry ?* ". 23" qml-st) + (modify-syntax-entry ?\n "> b" qml-st) + (modify-syntax-entry ?' "\"" qml-st) + qml-st) + "Syntax table for qml-mode.") + +(defvar qml-font-lock-keywords + (let* ((separator "\\|") + (qml-directive-kwd + (mapconcat 'identity '("import" "using") separator)) + (qml-declaration "[A-Z][a-zA-Z0-9_]*") + (qml-package "[A-Z][a-zA-Z0-9_]*") + (qml-property "[a-z][a-zA-Z0-9_]*") + (qml-basic-type-kwd + (mapconcat 'identity + (list "int" "bool" "real" "double" "string" "url" "var" + "alias" "list" "enumeration" + "color" "font" "matrix4x4" "quaternion" "vector2d" + "vector3d" "vector4d" "date" "point" "size" "rect" + qml-declaration (concat qml-declaration "\\(?:." qml-declaration "\\)?")) + separator)) + ) + (list + ;; preprocessor + (list (concat "^[ \t]*\\(" qml-directive-kwd "\\)[ \t]+" + "\\(?:\\(?:" "\\(\\(?:\\(?:" qml-package "\\)\\.?\\)*\\(?:" qml-package "\\)\\)" ;; packages + "[ \t]+" + "\\(\\(?:\\(?:[0-9]+\\)\\.?\\)*\\(?:[0-9]+\\)\\)" ;; version + "\\|" + "\\(?:\"[^ \t].*\"\\)" ;; directory + "\\(?:[ \t]+as[ \t]+\\([a-zA-Z0-9_]+\\)\\)?" + "\\)" + "[ \t]*\\(?:as[ \t]+\\(" qml-package "\\)\\)?" + "\\)" + "[ \t]*;?$") + '(1 qml-preprocessor-face nil t) + '(2 qml-package-face nil t) + '(3 qml-package-version-face nil t) + '(4 qml-package-face nil t) ;; directory qualifier + '(5 qml-package-face nil t) ;; alias + ) + + ;; declarations + (list (concat "\\(?:^\\|\\*/\\|:[ \t]*\\)" + "[ \t]*" + "\\(" qml-declaration "\\.\\)?\\(" qml-declaration "\\)[ \t]*\\({\\|$\\)") + '(1 qml-declaration-face nil t) + '(2 qml-declaration-face nil t)) + + ;; properties + (list (concat "\\(?:^[ \t]*\\|;[ \t]*\\|{[ \t]*\\)" + "\\(?:\\([a-zA-Z][a-zA-Z0-9]*\\)\\.\\)?\\(" qml-property "\\)" + "[ \t]*[:{]") + '(1 font-lock-variable-name-face nil t) + '(2 font-lock-variable-name-face nil t)) + + ;; property definition + (list (concat "\\(?:^[ \t]*\\|;[ \t]*\\|{[ \t]*\\)" + "\\(?:\\(readonly\\|default\\)[ \t]+\\)?\\(property\\)[ \t]+" ;; keyword + "\\(?:\\(" qml-basic-type-kwd "\\)" ;; type + "\\|" + "\\(?:\\(" qml-declaration "\\)\\.\\(" qml-declaration "\\)\\)" ;; with qualifier + "\\|" + "\\(list\\)<\\(?:" ;; list + "\\(" qml-basic-type-kwd "\\)" + "\\|" + "\\(?:\\(" qml-declaration "\\)\\.\\(" qml-declaration "\\)\\)" + "\\)>\\)[ \t]+" ;; end - list + "\\([a-zA-Z0-9_]+\\)[ \t]*\\(?::[ \t]*[^ \t\n\\.=;:&|$#^/*+-].*\\)?$" ;; property name + ) + '(1 qml-property-def-keyword-face nil t) ;; keyword + '(2 qml-property-def-keyword-face nil t) ;; keyword + '(3 qml-basic-type-face nil t) ;; type + '(4 qml-basic-type-face nil t) ;; with qualifier + '(5 qml-basic-type-face nil t) ;; with qualifier + '(6 qml-basic-type-face nil t) ;; list + '(7 qml-basic-type-face nil t) ;; list + '(8 qml-basic-type-face nil t) ;; list + '(9 qml-basic-type-face nil t) ;; list + '(10 font-lock-variable-name-face nil t) ;; property name + ) + + ;; function definition + (list (concat "\\(^[ \t]*\\|:[ \t]*\\)" + "\\(function\\)" + "\\([ \t]+\\([a-zA-Z0-9_]+\\)\\)?[ \t]*?(" + ) + '(2 qml-function-keyword-face nil t) ;; keyword + ;;'(3 qml-basic-type-face nil t) ;; function name + ) + + ;; signal definition + (list (concat "\\(^[ \t]*\\|:[ \t]*\\)" + "\\(signal\\)[ \t]+" + "\\([a-zA-Z0-9_]+\\)" + ) + '(2 qml-function-keyword-face nil t) ;; keyword + ;;'(3 qml-basic-type-face nil t) ;; signal name + ) + ))) + +(defun qml-line-commentp (line) + (save-excursion + (goto-line line) + (string-match "^[ \t]*//" (buffer-substring (point) (point-at-eol))))) + +(defun qml-beginning-of-block-internal (prev cur) + "This function used in `qml-beginning-of-block' function. +If want the position of beginning of block, use it." + (if (not prev) nil + (let* ((prev1 + (save-excursion + (goto-char prev) + (if (search-backward-regexp "\\({\\|\\[\\)[ \t]*$" nil t) + (match-beginning 1) + nil))) + (end-of-prev1 (if prev1 + (condition-case nil + (save-excursion (goto-char prev1) + (forward-sexp) + (point)) + (error nil)) + nil))) + (if (not prev1) nil + (if (or (not end-of-prev1) + (and (not (qml-line-commentp (line-number-at-pos prev1))) + (> cur prev1) + (< (point-at-eol) end-of-prev1))) + prev1 + (qml-beginning-of-block-internal prev1 cur)))))) + +(defun qml-beginning-of-block (&optional cur) + "Get position of beginning of block. +Return the position of beginning parenthesis \"{\" if found it, otherwise return nil. +If CUR is nil, try find beginning of block from current position. +In the line CUR is in, an item is declared single line (like that +\"Item { id:item1 ... }\" is in a line.), return the position +of beginning of \"item1\"'s parent block." + (let* ((cur-point (if (numberp cur) cur (point))) + (qbob (qml-beginning-of-block-internal + (save-excursion (goto-char cur-point) (point-at-bol)) + cur-point))) + (if (not qbob) (message "Not found beginning of block")) + qbob)) + +(defvar qml-indent-offset 2) + +(defun line-emptyp (&optional n) + (string-match "^[ \t]+$" + (buffer-substring (point-at-bol n) (point-at-eol n)))) + +(defun qml-indent-line () + "Indent current line according to QML indentation rule." + (interactive) + (let* ((qbob (qml-beginning-of-block (point))) + (pi (if (not qbob) nil + (save-excursion + (goto-char qbob) + (current-indentation))))) + (if (not pi) (indent-line-to 0) + (let ((ni (+ pi qml-indent-offset)) + (ci (current-indentation))) + (if (not (eq ni ci)) (save-excursion (indent-line-to ni))) + (if (line-emptyp 0) (save-excursion + (beginning-of-line 0) + (indent-line-to 0))) + (let ((lbp (line-beginning-position))) + (if (< (- (point) lbp) ni) (goto-char (+ lbp ni)))))))) + +(defvar qml-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-") + (lambda () (interactive) (indent-region (point-min) (point-max)))) + map)) + +(define-derived-mode qml-mode fundamental-mode "QML" + "Mejor mode for Qt declarative UI (simple mode)" + (interactive) + (kill-all-local-variables) + (set-syntax-table qml-syntax-table) + (set (make-local-variable 'font-lock-defaults) '(qml-font-lock-keywords)) + (set (make-local-variable 'tab-width) qml-indent-offset) + (set (make-local-variable 'indent-line-function) 'qml-indent-line) + (set (make-local-variable 'comment-start) "//") + (use-local-map qml-mode-map) + (setq major-mode 'qml-mode) + (setq mode-name "QML") + (run-hooks 'qml-mode-hook) + ) + +(dolist (associattions (list (cons "\\.qml\\'" 'qml-mode) + (cons "\\.qmltypes\\'" 'qml-mode))) + (add-to-list 'auto-mode-alist associattions)) + +(provide 'qml-mode) diff --git a/emacs/.emacs.d/qml-mode/qml-tools.el b/emacs/.emacs.d/qml-mode/qml-tools.el new file mode 100644 index 0000000..5b39e4d --- /dev/null +++ b/emacs/.emacs.d/qml-mode/qml-tools.el @@ -0,0 +1,135 @@ +;; QML mark up supoprt tools +;; for Qt ver. 5.x + +;; QML preprocessors +;; +;; `qml-insert-preprocessors' function inserts preprocessors of importing +;; package (like "import QtQtuick 2.2") at current position. +;; +;; Preprocessors are defined by `qml-preprocessor-alist', +;; default values are below: +;; ("QtQuick" . "2.2") +;; ("QtQuick.Controls" . "1.1") +;; ("QtQuick.Layouts" . "1.1") +;; +;; (each element must be tuple) +;; +;; If you want to add a package, call `qml-add-preprocessor' function, +;; which require two arguments (package and version by string). +;; When called this, sorts `qml-preprocessor-alist' by package name with asc. +;; Also, want to remove one, call `qml-remove-preprocessor' function. +;; ex: +;; (qml-add-preprocessor "QtQuick.Controls.Styles" "1.1") +;; (qml-remove-preprocessor "QtQuick.Controls") +;; +;; Basic packages instead default: +;; QtQuick.Controls.Styles 1.1 +;; QtQuick.Dialogs 1.1 +;; QtQuick.Window 2.0 + +(defvar qml-preprocessor-alist '()) + +(defun qml-add-preprocessor (package version) + (let ((elm (cons package version))) + (if (and (stringp package) + (stringp version) + (not (member elm qml-preprocessor-alist))) + (setq qml-preprocessor-alist + (sort (add-to-list 'qml-preprocessor-alist elm) + (lambda (a b) + (string< (car a) (car b)))))))) + +(defun qml-remove-preprocessor (package) + (if (stringp package) + (setq qml-preprocessor-alist + (remove-if (lambda (p) + (string-equal (car p) package)) + qml-preprocessor-alist)))) + +(let ((preprocessor-list + (list + '("QtQuick" . "2.2") + '("QtQuick.Controls" . "1.1") + '("QtQuick.Layouts" . "1.1") + ))) + (mapcar (lambda (p) + (qml-add-preprocessor (car p) (cdr p))) + preprocessor-list)) + +(defun qml-insert-preprocessors (&optional not-sort) + (interactive) + (mapcar (lambda (preprocessor) + (insert (format "import %s %s\n" (car preprocessor) (cdr preprocessor)))) + qml-preprocessor-alist)) + + +;; QML Test +;; +;; Stabs for testing custom Qml type. +;; +;; Main use of interactive functions: +;; `qml-test-insert-test-function' +;; prompt: function name without "test_" prefix +;; +;; `qml-test-insert-signal-spy' +;; prompt: target object (id) and siganal name to spy +;; + +;; common - insert stab and indent region +(defun -insert-stab (stab) + (let ((begin (point))) + (insert stab) + (indent-region begin (point)))) + +(defvar qml-import-dir-list '()) + +;; common - reading string prompt which does not allow empty by default +(defun -string-prompt (prompt &optional allow-empty default-value) + (if allow-empty + (read-string prompt default-value) + (let ((cont t) (in) (prompt1 prompt)) + (while cont + (setq in (read-string prompt1 default-value)) + (if (setq cont (string-equal in "")) + (setq prompt1 (concat "Cannot set empty. " prompt)))) + in))) + +;; test function +(defun qml-test-function-stab (fun-name) + (concat (format "function test_%s() {\n" fun-name) + "setup()\n\n" + "teardown()\n}\n")) + +(defun qml-test-insert-test-function (&optional name) + "Snippet of QML test function. +If optional argument NAME is nil, prompt ask funtion name." + (interactive) + (-insert-stab (qml-test-function-stab + (if (stringp name) name + (-string-prompt "Function name (instead \"test_\" prefix): ")))) + (beginning-of-line -2) + (indent-for-tab-command)) + +;; signal spy +(defun qml-test-signal-spy-stab (target signal) + (concat "SignalSpy {\n" + (format "id: %s%sSpy\n" target + (concat (capitalize (substring signal 0 1)) + (if (> (length signal) 1) (substring signal 1) ""))) + (format "target: %s\n" target) + (format "signalName: \"%s\"\n}\n" signal))) + +(defun qml-test-insert-signal-spy (&optional target signal-name) + "Snippet of static declaration of signal spy. +If both optional arguments TARGET and SIGNAL-NAME are non-nil, +insert declaration without asking itsm, otherwise, ask target and signal name." + (interactive) + (let* ((tar (if (stringp target) target nil)) + (sig (if (stringp signal-name) signal-name nil)) + (tar-name (if (and tar sig) (cons tar sig) + (message "%s %s" tar sig) + (cons (-string-prompt "Taget: " nil tar) + (-string-prompt "Signal name: " nil sig))))) + (-insert-stab (qml-test-signal-spy-stab (car tar-name) (cdr tar-name))))) + +(provide 'qml-tools) diff --git a/emacs/.emacs.d/qml-mode/test.qml b/emacs/.emacs.d/qml-mode/test.qml new file mode 100644 index 0000000..66a2124 --- /dev/null +++ b/emacs/.emacs.d/qml-mode/test.qml @@ -0,0 +1,198 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 2.0 as L + +// insrted tabs +import Foo.Bar.Nee 12.345 + +import "../common/qml" +import "../custom/qml" as Custom +import "../private/qml" as private_1 + +import "../script/util.js" as Utility_Scripts + +Item { + id: item1 + + Layout.fillWidth: parent + longlonglonglonglonglonglonglonglonglongNameProperty: value + + property int prop1 : 123 + property bool prop2: true + property real prop3: 456.789 + property double prop4: 0.12345 + property string prop5: "string property" + property url prop6: "~/path/to/file" + property list prop7: [ + Item { }, + Item { }, + Item { } + ] + + property color prop_color + property font prop_font + property matrix4x4 prop_matrix4x4 + property quaternion prop_quaternion + property vector2d prop_vector2d + property vector3d prop_vector3d + property vector4d prop_vector4d + property date prop_date + property point prop_point + property size prop_size + property rect prop_rect + + property My.QmlType myType: My.QmlType { } + + property Type invalidPropDef: + property Type invalidPropDef: + property Type invalidPropDef: \\ + property Type invalidPropDef: . + property Type invalidPropDef: = + property Type invalidPropDef: ; + property Type invalidPropDef: : + property Type invalidPropDef: # + property Type invalidPropDef: $ + property Type invalidPropDef: | + property Type invalidPropDef: & + property Type invalidPropDef: ^ + property Type invalidPropDef: / + property Type invalidPropDef: * + property Type invalidPropDef: + + property Type invalidPropDef: - + + readonly property var prop8: function() { + return "this is a function property"; + } + + + // function foo () { + // } + + // comment (contains parenthesis) + Tex { + text: "text (parenthesis)" + } + + property alias binded: child.properyName + + default property int defaultProp + readonly property bool readonlyProp: true + readonly property real nonInit + + signal notifySignal() + + function execSomething(param1, param2) { + var x, y, z; + } + + Entity { id: a1; property string a1Str: "a1";property int number: 87654 } + + Under_Score { + id: unsco + under_score: "underscore" + } + + // line commnet ...... + // ...... + // ...... + + Rectangle { + // aaaa aA A */ Item { } + /* a*/ Item_after_comment { } + /* + multi + line + comment + */ Item { + a:b + items:[] + } + + // Item { + // Text { + // text: "line commont" + // } + // } + + /*Item { + Text { + text: "block commont" + // ...... + // ...... + } + }*/ + + /* + Item { + Text { + text: "block commont" + } + } + */ + + Custom.ErrorText { + property bool hasError: false + property list entityList: [ + Custom.Entity { value: v1 } + Custom.Entity { value: v2 } + Custom.Entity { value: v3 } + ] + } + + // invalid declaration + Custom ErrorText { + property bool hasError: false + property Custom.ErrorContent content: Custom.ErrorContent { + + } + } + + Rectangle + { + x : 120 // insrted tabs + y : 320 + + border { + width: 2 + color : "#ef4" + } + + Text { + function fun1() { + var x = (a + (b - (c * (d / (e + f))))); + var y = a ^ (b ^ c); + return a && (b || (c && d)); + } + + Component.onCompleted: { + var a = 10; + var b = 20; + console.log(a + b); + } + } + } + + Rectangle + { + border.width: 2 + border.color : "#ef4" + } + + Rectangle { border.width: 0; boder.color: "SteelBlue" } + + SingleLineDef { property real realValue: 1234567890 } + + Text { id:text2; width: 200; hitght: 23 ; text : "inline" } + } + + TextField { + validator: IntValidator { + bottom: -273 + top: 2349 + } + } + + TextField { + validator: RegExpValidator { regexp: "^[a-z_-\.]+$" } + } +} diff --git a/emacs/.emacs.d/qml-mode/tst_qml_test.qml b/emacs/.emacs.d/qml-mode/tst_qml_test.qml new file mode 100644 index 0000000..49e2109 --- /dev/null +++ b/emacs/.emacs.d/qml-mode/tst_qml_test.qml @@ -0,0 +1,50 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtTest 1.0 + +import "../my-qml-lib" +import "../external" + +MyQmlType { + id: testObj + + TestCase { + name: "QML Test Sample" + + property Deps deps + property var depsFactory: Qt.createComponent("Deps.qml") + + property QmlUtil util + property var utilFactory: Qt.createComponent("../external/QmlUtil.qml") + + SignalSpy { + id: depsCreatedSpy + target: deps + signalName: "created" + } + + function setup() { + if (deps != null) { + teardown() + } + verify(depsFactory != null) + compare(depsFactory.status, Component.Ready) + deps = depsFactory.createObject(this) + } + + function teardown() { + if (deps != null) { + deps.destroy() + deps = null + } + } + + function test_should_do_something() { + setup() + // test code (assertion......) + + compare(testObj.number, 17) + teardown() + } + } +}