Remove the very old lib dir
This commit is contained in:
parent
2fa1243482
commit
ba177678cc
|
@ -1,30 +0,0 @@
|
|||
;; Important Note: On linux you need to add your user to 'dialout' group
|
||||
;; OS reqyurements: You need to install these utilities:
|
||||
;; * arduino-mk
|
||||
;; * python-serial
|
||||
;; * avrdude
|
||||
;; * libdevice-serialport-perl
|
||||
;; * libyaml-perl
|
||||
;;
|
||||
;; You need following environments veriables:
|
||||
;; export ARDUINO_DIR=$HOME/bin/arduino-1.6.8
|
||||
;; export ARDMK_DIR=/usr/share/arduino
|
||||
;; export ARDMK_PATH=/usr/bin
|
||||
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/arduino/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'arduino-mode)
|
||||
(depends-on 'company-arduino)
|
||||
(depends-on 'mustache)
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension arduino
|
||||
:version "2.31"
|
||||
:on-initialize extensions/arduino-initialize)
|
||||
|
||||
(provide 'extensions/arduino)
|
||||
;;; arduino.el ends here
|
|
@ -1,10 +0,0 @@
|
|||
# If you didn't define these environment variables, uncomment these and fix the paths
|
||||
#ARDUINO_DIR=$HOME/bin/arduino-1.6.8
|
||||
#ARDMK_DIR=/usr/share/arduino
|
||||
#ARDMK_PATH=/usr/bin
|
||||
|
||||
BOARD_TAG=uno
|
||||
ARDUINO_PORT=/dev/ttyACM0
|
||||
ARDUINO_LIBS=
|
||||
|
||||
include $(ARDMK_DIR)/Arduino.mk
|
|
@ -1,67 +0,0 @@
|
|||
;;; Code:
|
||||
|
||||
;; Functions -------------------------------------------------
|
||||
|
||||
;;;###autoload
|
||||
(defun create-makefile ()
|
||||
"Create the arduino make file in the same directory as the ino file if doesn't exits."
|
||||
(let ((makefile (concat (file-name-directory buffer-file-name) "Makefile"))
|
||||
(makefile-src (concat fg42-home "/lib/extensions/arduino/Makefile")))
|
||||
(if (not (file-exists-p makefile))
|
||||
(progn (message "Creating arduino make file")
|
||||
(copy-file makefile-src makefile)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun arduino/compilation-finished (buffer result)
|
||||
(cond ((string-match "finished" result)
|
||||
(bury-buffer "*compilation*")
|
||||
(message "Compilation done."))
|
||||
(t
|
||||
(message "Compilation field."))))
|
||||
|
||||
;;;###autoload
|
||||
(defun arduino/compilation-and-upload-finished (buffer result)
|
||||
(cond ((string-match "finished" result)
|
||||
(bury-buffer "*compilation*")
|
||||
(message "Compilation done.")
|
||||
(message "Uploading")
|
||||
(arduino/upload))
|
||||
(t
|
||||
(message "Compilation field."))))
|
||||
|
||||
;;;###autoload
|
||||
(defun arduino/compile ()
|
||||
"Compile the current arduino project."
|
||||
(interactive)
|
||||
(let ((compilation-finish-functions 'arduino/compilation-finished))
|
||||
(recompile)))
|
||||
|
||||
|
||||
(defun arduino/upload ()
|
||||
(interactive)
|
||||
(let ((compile-command "make upload"))
|
||||
(recompile)))
|
||||
|
||||
;;;###autoload
|
||||
(defun arduino/compile-and-upload ()
|
||||
"Compile and upload the current arduino project."
|
||||
(interactive)
|
||||
(let ((compilation-finish-functions 'arduino/compilation-and-upload-finished))
|
||||
(recompile)))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/arduino-initialize ()
|
||||
"Arduino development plugin initialization."
|
||||
|
||||
(ability arduino-editor ('flycheck)
|
||||
"Gives FG42 the ability to edit arduino related contents."
|
||||
(add-hook 'arduino-mode-hook 'create-makefile)
|
||||
(setq auto-mode-alist (cons '("\\.\\(pde\\|ino\\)$" . arduino-mode) auto-mode-alist))
|
||||
|
||||
(global-set-key (kbd "C-c c") 'arduino/compile)
|
||||
(global-set-key (kbd "C-c u") 'arduino/upload)
|
||||
(autoload 'arduino-mode "arduino-mode" "Arduino editing mode." t))
|
||||
(message "'arduino' extension has been initialized."))
|
||||
|
||||
|
||||
(provide 'extensions/arduino/init)
|
|
@ -1,22 +0,0 @@
|
|||
;;; Auth --- Secret management extension for FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/auth/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'rcauth-notify)
|
||||
|
||||
(defun auth-doc ()
|
||||
"TBD"
|
||||
"TBD")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension auth
|
||||
:version "2.32"
|
||||
:on-initialize extensions/auth-initialize
|
||||
:docs "lib/extensions/auth/readme.org")
|
||||
|
||||
(provide 'extensions/auth)
|
||||
;;; auth.el ends here
|
|
@ -1,45 +0,0 @@
|
|||
;;; Auth --- Secret management extension for FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'auth-source)
|
||||
|
||||
(defvar auht/sources '((:sources "~/.authinfo.gpg")))
|
||||
|
||||
(defun auth/find-credential (host)
|
||||
"Find the credential for the given HOST.
|
||||
Return a list of credential pairs."
|
||||
(let (auth-list '())
|
||||
(dolist (cred (auth-source-search :host host
|
||||
:require '(:user :secret)))
|
||||
(let ((user (plist-get cred :user))
|
||||
(secret (plist-get cred :secret)))
|
||||
(add-to-list 'auth-list
|
||||
(list user
|
||||
(if (functionp secret)
|
||||
(funcall secret)
|
||||
secret)))))
|
||||
auth-list))
|
||||
|
||||
(defun utils/bold (text)
|
||||
"Make the TEXT appears in bold form."
|
||||
(propertize text 'face 'bold))
|
||||
|
||||
|
||||
(defun auth/credential-for (args host)
|
||||
"Return the credential for the given HOST.
|
||||
ARGS should be ignored."
|
||||
(interactive "P\nsHost: ")
|
||||
(dolist (pair (auth/find-credential host))
|
||||
(let* ((user (car pair))
|
||||
(pass (car (cdr pair)))
|
||||
(msg (concat "User: " (utils/bold user)
|
||||
" Passowrd: " (utils/bold pass))))
|
||||
(message msg))))
|
||||
|
||||
|
||||
(defun extensions/irc-initialize ()
|
||||
"Initialize the Auth extension."
|
||||
(setq auth-sources auth/sources))
|
||||
|
||||
(provide 'extensions/irc/init)
|
||||
;;; init.el ends here
|
|
@ -1,27 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/clojure/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'clojure-mode)
|
||||
(depends-on 'cider)
|
||||
(depends-on 'paredit)
|
||||
(depends-on 'flycheck)
|
||||
(depends-on 'flycheck-clojure)
|
||||
(depends-on 'clj-refactor)
|
||||
(depends-on 'let-alist)
|
||||
(depends-on 'clojure-mode-extra-font-locking)
|
||||
(depends-on 'flycheck-clj-kondo)
|
||||
;(depends-on 'core-async-mode)
|
||||
(depends-on 'yesql-ghosts)
|
||||
(depends-on 'rainbow-delimiters)
|
||||
|
||||
(defun clojure-doc ()
|
||||
"something fun")
|
||||
;; Extension -------------------------------------
|
||||
(extension clojure
|
||||
:version "2.32"
|
||||
:on-initialize extensions/clojure-initialize
|
||||
:docs "lib/extensions/clojure/readme.org")
|
||||
|
||||
(provide 'extensions/clojure)
|
|
@ -1,320 +0,0 @@
|
|||
(defun setup-keys ()
|
||||
(define-key clojure-mode-map (kbd "M-<right>") 'paredit-forward-slurp-sexp)
|
||||
(define-key clojure-mode-map (kbd "M-<left>") 'paredit-backward-slurp-sexp)
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-<right>") 'right-word)
|
||||
(define-key clojure-mode-map (kbd "C-<left>") 'left-word)
|
||||
(global-set-key (kbd "C-<right>") 'right-word)
|
||||
(global-set-key (kbd "C-<left>") 'left-word))
|
||||
|
||||
;; Add requires to blank devcards files
|
||||
(defun cljr--find-source-ns-of-devcard-ns (test-ns test-file)
|
||||
(let* ((ns-chunks (split-string test-ns "[.]" t))
|
||||
(test-name (car (last ns-chunks)))
|
||||
(src-dir-name (s-replace "devcards/" "src/" (file-name-directory test-file)))
|
||||
(replace-underscore (-partial 's-replace "_" "-"))
|
||||
(src-ns (car (--filter (or (s-prefix-p it test-name)
|
||||
(s-suffix-p it test-name))
|
||||
(-map (lambda (file-name)
|
||||
(funcall replace-underscore
|
||||
(file-name-sans-extension file-name)))
|
||||
(directory-files src-dir-name))))))
|
||||
(when src-ns
|
||||
(mapconcat 'identity (append (butlast ns-chunks) (list src-ns)) "."))))
|
||||
|
||||
(defun clj--find-devcards-component-name ()
|
||||
(or
|
||||
(ignore-errors
|
||||
(with-current-buffer
|
||||
(find-file-noselect (clj--src-file-name-from-cards (buffer-file-name)))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(search-backward "defcomponent ")
|
||||
(clojure-forward-logical-sexp)
|
||||
(skip-syntax-forward " ")
|
||||
(let ((beg (point))
|
||||
(end (progn (re-search-forward "\\w+")
|
||||
(point))))
|
||||
(buffer-substring-no-properties beg end)))))
|
||||
""))
|
||||
|
||||
(defun cljr--add-card-declarations ()
|
||||
(save-excursion
|
||||
(let* ((ns (clojure-find-ns))
|
||||
(source-ns (cljr--find-source-ns-of-devcard-ns ns (buffer-file-name))))
|
||||
(cljr--insert-in-ns ":require")
|
||||
(when source-ns
|
||||
(insert "[" source-ns " :refer [" (clj--find-devcards-component-name) "]]"))
|
||||
(cljr--insert-in-ns ":require")
|
||||
(insert "[devcards.core :refer-macros [defcard]]"))
|
||||
(indent-region (point-min) (point-max))))
|
||||
|
||||
(defun live-delete-and-extract-sexp ()
|
||||
"Delete the sexp and return it."
|
||||
(interactive)
|
||||
(let* ((begin (point)))
|
||||
(forward-sexp)
|
||||
(let* ((result (buffer-substring-no-properties begin (point))))
|
||||
(delete-region begin (point))
|
||||
result)))
|
||||
|
||||
(defun live-cycle-clj-coll ()
|
||||
"convert the coll at (point) from (x) -> {x} -> [x] -> (x) recur"
|
||||
(interactive)
|
||||
(let* ((original-point (point)))
|
||||
(while (and (> (point) 1)
|
||||
(not (equal "(" (buffer-substring-no-properties (point) (+ 1 (point)))))
|
||||
(not (equal "{" (buffer-substring-no-properties (point) (+ 1 (point)))))
|
||||
(not (equal "[" (buffer-substring-no-properties (point) (+ 1 (point))))))
|
||||
(backward-char))
|
||||
(cond
|
||||
((equal "(" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "{" (substring (live-delete-and-extract-sexp) 1 -1) "}"))
|
||||
((equal "{" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "[" (substring (live-delete-and-extract-sexp) 1 -1) "]"))
|
||||
((equal "[" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "(" (substring (live-delete-and-extract-sexp) 1 -1) ")"))
|
||||
((equal 1 (point))
|
||||
(message "beginning of file reached, this was probably a mistake.")))
|
||||
(goto-char original-point)))
|
||||
|
||||
|
||||
(defun my-toggle-expect-focused ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(search-backward "(expect" (cljr--point-after 'cljr--goto-toplevel))
|
||||
(forward-word)
|
||||
(if (looking-at "-focused")
|
||||
(paredit-forward-kill-word)
|
||||
(insert "-focused"))))
|
||||
|
||||
(defun my-remove-all-focused ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "(expect-focused" nil t)
|
||||
(delete-char -8))))
|
||||
|
||||
(defun clj-duplicate-top-level-form ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(cljr--goto-toplevel)
|
||||
(insert (cljr--extract-sexp) "\n")
|
||||
(cljr--just-one-blank-line)))
|
||||
|
||||
(defun clj-hippie-expand-no-case-fold ()
|
||||
(interactive)
|
||||
(let ((old-syntax (char-to-string (char-syntax ?/))))
|
||||
(modify-syntax-entry ?/ " ")
|
||||
(hippie-expand-no-case-fold)
|
||||
(modify-syntax-entry ?/ old-syntax)))
|
||||
|
||||
(defun nrepl-warn-when-not-connected ()
|
||||
(interactive)
|
||||
(message "Oops! You're not connected to an nREPL server. Please run M-x cider or M-x cider-jack-in to connect."))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun cljr-init ()
|
||||
(interactive)
|
||||
(require 'clj-refactor)
|
||||
|
||||
(clj-refactor-mode 1)
|
||||
|
||||
(setq cljr-magic-require-namespaces
|
||||
'(("io" . "clojure.java.io")
|
||||
("set" . "clojure.set")
|
||||
("str" . "clojure.string")
|
||||
("walk" . "clojure.walk")
|
||||
("zip" . "clojure.zip")
|
||||
("time" . "clj-time.core")
|
||||
("log" . "clojure.tools.logging")
|
||||
("json" . "cheshire.core")))
|
||||
|
||||
;; refer all from expectations
|
||||
(setq cljr-expectations-test-declaration "[expectations :refer :all]")
|
||||
|
||||
;; insert keybinding setup here
|
||||
(cljr-add-keybindings-with-prefix "C-c v")
|
||||
(setq cljr-favor-prefix-notation nil)
|
||||
(setq cljr-favor-private-functions nil)
|
||||
|
||||
;; Don't warn me about the dangers of clj-refactor, fire the missiles!
|
||||
(setq cljr-warn-on-eval nil)
|
||||
|
||||
(add-hook 'clojure-mode-hook #'yas-minor-mode)
|
||||
|
||||
;; no auto sort
|
||||
(setq cljr-auto-sort-ns nil)
|
||||
|
||||
;; do not prefer prefixes when using clean-ns
|
||||
(setq cljr-favor-prefix-notation nil)
|
||||
|
||||
(cljr-add-keybindings-with-modifier "C-s-")
|
||||
|
||||
(define-key clj-refactor-map (kbd "C-x C-r") 'cljr-rename-file)
|
||||
(define-key clojure-mode-map [remap paredit-forward] 'clojure-forward-logical-sexp)
|
||||
(define-key clojure-mode-map [remap paredit-backward] 'clojure-backward-logical-sexp)
|
||||
(define-key clojure-mode-map (kbd "C->") 'cljr-thread)
|
||||
(define-key clojure-mode-map (kbd "C-<") 'cljr-unwind)
|
||||
|
||||
(define-key clj-refactor-map
|
||||
(cljr--key-pairs-with-modifier "C-s-" "xf") 'my-toggle-expect-focused)
|
||||
(define-key clj-refactor-map
|
||||
(cljr--key-pairs-with-modifier "C-s-" "xr") 'my-remove-all-focused)
|
||||
|
||||
(defadvice cljr--add-ns-if-blank-clj-file (around add-devcards activate)
|
||||
(ignore-errors
|
||||
(when (and cljr-add-ns-to-blank-clj-files
|
||||
(cljr--clojure-ish-filename-p (buffer-file-name))
|
||||
(= (point-min) (point-max)))
|
||||
ad-do-it
|
||||
(when (clj--is-card? (buffer-file-name))
|
||||
(cljr--add-card-declarations)))))
|
||||
|
||||
(defadvice cljr-find-usages (before setup-grep activate)
|
||||
(window-configuration-to-register ?$)))
|
||||
|
||||
;;;###autoload
|
||||
(defun clojure-mode-init ()
|
||||
(interactive)
|
||||
|
||||
(require 'clojure-mode-extra-font-locking)
|
||||
(require 'cider)
|
||||
(require 'paredit)
|
||||
|
||||
;; indent [quiescent.dom :as d] specially
|
||||
(define-clojure-indent
|
||||
(d/a 1)
|
||||
(d/button 1)
|
||||
(d/div 1)
|
||||
(d/form 1)
|
||||
(d/h1 1)
|
||||
(d/h2 1)
|
||||
(d/h3 1)
|
||||
(d/h4 1)
|
||||
(d/h5 1)
|
||||
(d/hr 1)
|
||||
(d/img 1)
|
||||
(d/label 1)
|
||||
(d/li 1)
|
||||
(d/option 1)
|
||||
(d/p 1)
|
||||
(d/pre 1)
|
||||
(d/select 1)
|
||||
(d/small 1)
|
||||
(d/span 1)
|
||||
(d/strong 1)
|
||||
(d/ul 1)
|
||||
(d/svg 1)
|
||||
|
||||
;; Hafslund specifics
|
||||
(e/prose 1)
|
||||
(e/value 1)
|
||||
(e/section 1)
|
||||
(e/section-prose 1)
|
||||
(e/page 1)
|
||||
(e/instructions 1)
|
||||
(l/padded 1)
|
||||
(l/bubble-grid 1)
|
||||
(l/slider 1)
|
||||
(l/bottom-fixed 1)
|
||||
(c/box 1)
|
||||
(c/group 1)
|
||||
(c/list 1))
|
||||
|
||||
(defadvice clojure-test-run-tests (before save-first activate)
|
||||
(save-buffer))
|
||||
|
||||
(defadvice nrepl-load-current-buffer (before save-first activate)
|
||||
(save-buffer))
|
||||
|
||||
(setq cider-pprint-fn 'pprint)
|
||||
|
||||
(setq cider-repl-history-file (concat tmp-directory "/cider-repl-history"))
|
||||
|
||||
;; nice pretty printing
|
||||
(setq cider-repl-use-pretty-printing t)
|
||||
|
||||
;; nicer font lock in REPL
|
||||
(setq cider-repl-use-clojure-font-lock t)
|
||||
|
||||
;; result prefix for the REPL
|
||||
(setq cider-repl-result-prefix ";; => ")
|
||||
|
||||
;; never ending REPL history
|
||||
(setq cider-repl-wrap-history t)
|
||||
|
||||
;; looong history
|
||||
(setq cider-repl-history-size 3000)
|
||||
|
||||
|
||||
;; error buffer not popping up
|
||||
(setq cider-show-error-buffer nil)
|
||||
|
||||
;; Use figwheel for cljs repl
|
||||
(setq cider-cljs-lein-repl "(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")
|
||||
|
||||
;; Indent and highlight more commands
|
||||
(put-clojure-indent 'match 'defun)
|
||||
|
||||
;; Hide nrepl buffers when switching buffers (switch to by prefixing with space)
|
||||
(setq nrepl-hide-special-buffers t)
|
||||
|
||||
;; Enable error buffer popping also in the REPL:
|
||||
(setq cider-repl-popup-stacktraces t)
|
||||
|
||||
;; Specify history file
|
||||
(setq cider-history-file (concat (getenv "HOME") "/.tmp/nrepl-history"))
|
||||
|
||||
;; auto-select the error buffer when it's displayed
|
||||
(setq cider-auto-select-error-buffer t)
|
||||
|
||||
;; Prevent the auto-display of the REPL buffer in a separate window after connection is established
|
||||
(setq cider-repl-pop-to-buffer-on-connect nil)
|
||||
|
||||
;; Pretty print results in repl
|
||||
(setq cider-repl-use-pretty-printing t)
|
||||
|
||||
;; Don't prompt for symbols
|
||||
(setq cider-prompt-for-symbol nil)
|
||||
|
||||
;; eldoc for clojure
|
||||
(add-hook 'cider-repl-mode-hook #'paredit-mode)
|
||||
(setup-keys)
|
||||
(rainbow-delimiters-mode)
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-`") 'live-cycle-clj-coll)
|
||||
(define-key cider-repl-mode-map (kbd "<home>") nil)
|
||||
(define-key cider-repl-mode-map (kbd "C-,") 'complete-symbol)
|
||||
(define-key cider-mode-map (kbd "C-,") 'complete-symbol)
|
||||
(define-key cider-mode-map (kbd "C-c C-q") 'nrepl-close)
|
||||
(define-key cider-mode-map (kbd "C-c C-Q") 'cider-quit)
|
||||
(define-key clojure-mode-map (kbd "M-s-d") 'clj-duplicate-top-level-form)
|
||||
|
||||
(add-to-list 'cljr-project-clean-functions 'cleanup-buffer)
|
||||
|
||||
(define-key clojure-mode-map (kbd "s-j") 'clj-jump-to-other-file)
|
||||
;;(define-key clojure-mode-map (kbd "C-.") 'clj-hippie-expand-no-case-fold)
|
||||
(define-key clojure-mode-map (kbd "C-M-x") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-x C-e") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-e") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-l") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-r") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-z") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-k") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-n") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-q") 'nrepl-warn-when-not-connected)
|
||||
|
||||
(define-key clojure-mode-map (kbd "M-<right>") 'paredit-forward-slurp-sexp)
|
||||
(define-key clojure-mode-map (kbd "M-<left>") 'paredit-backward-slurp-sexp)
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-<right>") 'right-word)
|
||||
(define-key clojure-mode-map (kbd "C-<left>") 'left-word)
|
||||
(global-set-key (kbd "C-<right>") 'right-word)
|
||||
(global-set-key (kbd "C-<left>") 'left-word)
|
||||
|
||||
|
||||
(message "Clojure mode hook ran and initialized clojure-editor ability."))
|
||||
|
||||
(provide 'extensions/clojure/core)
|
|
@ -1,65 +0,0 @@
|
|||
(require 'extensions/clojure/core)
|
||||
|
||||
;;;###autoload
|
||||
(defun set-clojure-favorite-buffer ()
|
||||
"Set the favorite buffer to cider repl"
|
||||
(setq *favorite-buffer* "\*cider-repl\s.*\*"))
|
||||
|
||||
;;;###autoload
|
||||
(defun clojure-pretty-symbol ()
|
||||
(interactive)
|
||||
(setq prettify-symbols-alist
|
||||
'(
|
||||
("fn" . 955) ; λ
|
||||
("->" . 8594)))) ; →
|
||||
; ⇒
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/clojure-initialize ()
|
||||
; Clojure development initialization
|
||||
(ability clojure-editor ('flycheck)
|
||||
(require 'clojure-mode)
|
||||
(require 'flycheck-clj-kondo)
|
||||
(add-to-list 'auto-mode-alist '("\\.clj$" . clojure-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.cljc$" . clojurec-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.cljs$" . clojurescript-mode))
|
||||
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
(add-hook 'cider-mode-hook #'set-clojure-favorite-buffer)
|
||||
(add-hook 'clojure-mode-hook #'paredit-mode)
|
||||
(add-hook 'clojure-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(setq cider-cljs-lein-repl "(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")
|
||||
|
||||
(add-hook 'clojure-mode-hook 'clojure-mode-init)
|
||||
(setq tmp-directory (concat (getenv "HOME") "/.tmp")))
|
||||
|
||||
|
||||
(ability pretty-symbols ()
|
||||
(add-hook 'clojure-mode-hook 'clojure-pretty-symbol))
|
||||
|
||||
|
||||
(ability clojure-completion ('code-completion)
|
||||
;; company mode for completion
|
||||
(add-hook 'cider-repl-mode-hook #'company-mode)
|
||||
(add-hook 'cider-mode-hook #'company-mode))
|
||||
|
||||
(ability clojure-refactore ()
|
||||
(add-hook 'clojure-mode-hook 'cljr-init)))
|
||||
|
||||
;; (ability clojure-check ('flycheck)
|
||||
;; (require 'flycheck-clojure)
|
||||
;; (eval-after-load 'flycheck '(add-to-list 'flycheck-checkers 'clojure-cider-eastwood))
|
||||
;; (eval-after-load 'flycheck '(flycheck-clojure-setup))
|
||||
;; (add-hook 'after-init-hook #'global-flycheck-mode)
|
||||
;; ;; Set up linting of clojure code with eastwood
|
||||
|
||||
;; ;; Make sure to add [acyclic/squiggly-clojure "0.1.2-SNAPSHOT"]
|
||||
;; ;; to your :user :dependencies in .lein/profiles.clj
|
||||
|
||||
;; (add-hook 'cider-mode-hook
|
||||
;; '(lambda ()
|
||||
;; (message "Make sure to add [acyclic/squiggly-clojure \"0.1.2-SNAPSHOT\"] to your :user :dependencies in .lein/profiles.clj")))))
|
||||
|
||||
(provide 'extensions/clojure/init)
|
|
@ -1,6 +0,0 @@
|
|||
* Clojure Extension
|
||||
|
||||
This extension provides an integrated environment for developing clojure applications
|
||||
using FG42 on top of cider.
|
||||
|
||||
** Usage
|
|
@ -1,311 +0,0 @@
|
|||
(require 'clojure-mode)
|
||||
(require 'clojure-mode-extra-font-locking)
|
||||
|
||||
(defadvice clojure-test-run-tests (before save-first activate)
|
||||
(save-buffer))
|
||||
|
||||
(defadvice nrepl-load-current-buffer (before save-first activate)
|
||||
(save-buffer))
|
||||
|
||||
(require 'clj-refactor)
|
||||
|
||||
(setq cljr-favor-prefix-notation nil)
|
||||
(setq cljr-favor-private-functions nil)
|
||||
|
||||
(cljr-add-keybindings-with-modifier "C-s-")
|
||||
(define-key clj-refactor-map (kbd "C-x C-r") 'cljr-rename-file)
|
||||
|
||||
(define-key clojure-mode-map [remap paredit-forward] 'clojure-forward-logical-sexp)
|
||||
(define-key clojure-mode-map [remap paredit-backward] 'clojure-backward-logical-sexp)
|
||||
|
||||
(setq cider-pprint-fn 'pprint)
|
||||
|
||||
(require 'core-async-mode)
|
||||
|
||||
(defun enable-clojure-mode-stuff ()
|
||||
(clj-refactor-mode 1)
|
||||
(when (not (s-ends-with-p "/dev/user.clj" (buffer-file-name)))
|
||||
(core-async-mode 1)))
|
||||
|
||||
(add-hook 'clojure-mode-hook 'enable-clojure-mode-stuff)
|
||||
|
||||
(require 'symbol-focus)
|
||||
(define-key clojure-mode-map (kbd "M-s-f") 'sf/focus-at-point)
|
||||
|
||||
(defun clj-duplicate-top-level-form ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(cljr--goto-toplevel)
|
||||
(insert (cljr--extract-sexp) "\n")
|
||||
(cljr--just-one-blank-line)))
|
||||
|
||||
(define-key clojure-mode-map (kbd "M-s-d") 'clj-duplicate-top-level-form)
|
||||
|
||||
(add-to-list 'cljr-project-clean-functions 'cleanup-buffer)
|
||||
|
||||
(define-key clojure-mode-map (kbd "C->") 'cljr-thread)
|
||||
(define-key clojure-mode-map (kbd "C-<") 'cljr-unwind)
|
||||
|
||||
(define-key clojure-mode-map (kbd "s-j") 'clj-jump-to-other-file)
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-.") 'clj-hippie-expand-no-case-fold)
|
||||
|
||||
(defun clj-hippie-expand-no-case-fold ()
|
||||
(interactive)
|
||||
(let ((old-syntax (char-to-string (char-syntax ?/))))
|
||||
(modify-syntax-entry ?/ " ")
|
||||
(hippie-expand-no-case-fold)
|
||||
(modify-syntax-entry ?/ old-syntax)))
|
||||
|
||||
(require 'cider)
|
||||
|
||||
(define-key cider-repl-mode-map (kbd "<home>") nil)
|
||||
(define-key cider-repl-mode-map (kbd "C-,") 'complete-symbol)
|
||||
(define-key cider-mode-map (kbd "C-,") 'complete-symbol)
|
||||
(define-key cider-mode-map (kbd "C-c C-q") 'nrepl-close)
|
||||
(define-key cider-mode-map (kbd "C-c C-Q") 'cider-quit)
|
||||
|
||||
(require 'yesql-ghosts)
|
||||
|
||||
;; indent [quiescent.dom :as d] specially
|
||||
|
||||
(define-clojure-indent
|
||||
(d/a 1)
|
||||
(d/button 1)
|
||||
(d/div 1)
|
||||
(d/form 1)
|
||||
(d/h1 1)
|
||||
(d/h2 1)
|
||||
(d/h3 1)
|
||||
(d/h4 1)
|
||||
(d/h5 1)
|
||||
(d/hr 1)
|
||||
(d/img 1)
|
||||
(d/label 1)
|
||||
(d/li 1)
|
||||
(d/option 1)
|
||||
(d/p 1)
|
||||
(d/pre 1)
|
||||
(d/select 1)
|
||||
(d/small 1)
|
||||
(d/span 1)
|
||||
(d/strong 1)
|
||||
(d/ul 1)
|
||||
(d/svg 1)
|
||||
|
||||
;; Hafslund specifics
|
||||
(e/prose 1)
|
||||
(e/value 1)
|
||||
(e/section 1)
|
||||
(e/section-prose 1)
|
||||
(e/page 1)
|
||||
(e/instructions 1)
|
||||
(l/padded 1)
|
||||
(l/bubble-grid 1)
|
||||
(l/slider 1)
|
||||
(l/bottom-fixed 1)
|
||||
(c/box 1)
|
||||
(c/group 1)
|
||||
(c/list 1))
|
||||
|
||||
;; Don't warn me about the dangers of clj-refactor, fire the missiles!
|
||||
(setq cljr-warn-on-eval nil)
|
||||
|
||||
;; Use figwheel for cljs repl
|
||||
(setq cider-cljs-lein-repl "(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")
|
||||
|
||||
;; Indent and highlight more commands
|
||||
(put-clojure-indent 'match 'defun)
|
||||
|
||||
;; Hide nrepl buffers when switching buffers (switch to by prefixing with space)
|
||||
(setq nrepl-hide-special-buffers t)
|
||||
|
||||
;; Enable error buffer popping also in the REPL:
|
||||
(setq cider-repl-popup-stacktraces t)
|
||||
|
||||
;; Specify history file
|
||||
(setq cider-history-file "~/.emacs.d/nrepl-history")
|
||||
|
||||
;; auto-select the error buffer when it's displayed
|
||||
(setq cider-auto-select-error-buffer t)
|
||||
|
||||
;; Prevent the auto-display of the REPL buffer in a separate window after connection is established
|
||||
(setq cider-repl-pop-to-buffer-on-connect nil)
|
||||
|
||||
;; Pretty print results in repl
|
||||
(setq cider-repl-use-pretty-printing t)
|
||||
|
||||
;; Don't prompt for symbols
|
||||
(setq cider-prompt-for-symbol nil)
|
||||
|
||||
;; Enable eldoc in Clojure buffers
|
||||
(add-hook 'cider-mode-hook #'eldoc-mode)
|
||||
|
||||
;; Some expectations features
|
||||
|
||||
(require 'clj-autotest)
|
||||
|
||||
(defun my-toggle-expect-focused ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(search-backward "(expect" (cljr--point-after 'cljr--goto-toplevel))
|
||||
(forward-word)
|
||||
(if (looking-at "-focused")
|
||||
(paredit-forward-kill-word)
|
||||
(insert "-focused"))))
|
||||
|
||||
(defun my-remove-all-focused ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "(expect-focused" nil t)
|
||||
(delete-char -8))))
|
||||
|
||||
(define-key clj-refactor-map
|
||||
(cljr--key-pairs-with-modifier "C-s-" "xf") 'my-toggle-expect-focused)
|
||||
|
||||
(define-key clj-refactor-map
|
||||
(cljr--key-pairs-with-modifier "C-s-" "xr") 'my-remove-all-focused)
|
||||
|
||||
;; Cycle between () {} []
|
||||
|
||||
(defun live-delete-and-extract-sexp ()
|
||||
"Delete the sexp and return it."
|
||||
(interactive)
|
||||
(let* ((begin (point)))
|
||||
(forward-sexp)
|
||||
(let* ((result (buffer-substring-no-properties begin (point))))
|
||||
(delete-region begin (point))
|
||||
result)))
|
||||
|
||||
(defun live-cycle-clj-coll ()
|
||||
"convert the coll at (point) from (x) -> {x} -> [x] -> (x) recur"
|
||||
(interactive)
|
||||
(let* ((original-point (point)))
|
||||
(while (and (> (point) 1)
|
||||
(not (equal "(" (buffer-substring-no-properties (point) (+ 1 (point)))))
|
||||
(not (equal "{" (buffer-substring-no-properties (point) (+ 1 (point)))))
|
||||
(not (equal "[" (buffer-substring-no-properties (point) (+ 1 (point))))))
|
||||
(backward-char))
|
||||
(cond
|
||||
((equal "(" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "{" (substring (live-delete-and-extract-sexp) 1 -1) "}"))
|
||||
((equal "{" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "[" (substring (live-delete-and-extract-sexp) 1 -1) "]"))
|
||||
((equal "[" (buffer-substring-no-properties (point) (+ 1 (point))))
|
||||
(insert "(" (substring (live-delete-and-extract-sexp) 1 -1) ")"))
|
||||
((equal 1 (point))
|
||||
(message "beginning of file reached, this was probably a mistake.")))
|
||||
(goto-char original-point)))
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-`") 'live-cycle-clj-coll)
|
||||
|
||||
;; Warn about missing nREPL instead of doing stupid things
|
||||
|
||||
(defun nrepl-warn-when-not-connected ()
|
||||
(interactive)
|
||||
(message "Oops! You're not connected to an nREPL server. Please run M-x cider or M-x cider-jack-in to connect."))
|
||||
|
||||
(define-key clojure-mode-map (kbd "C-M-x") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-x C-e") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-e") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-l") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-r") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-z") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-k") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-n") 'nrepl-warn-when-not-connected)
|
||||
(define-key clojure-mode-map (kbd "C-c C-q") 'nrepl-warn-when-not-connected)
|
||||
|
||||
(setq cljr-magic-require-namespaces
|
||||
'(("io" . "clojure.java.io")
|
||||
("set" . "clojure.set")
|
||||
("str" . "clojure.string")
|
||||
("walk" . "clojure.walk")
|
||||
("zip" . "clojure.zip")
|
||||
("time" . "clj-time.core")
|
||||
("log" . "clojure.tools.logging")
|
||||
("json" . "cheshire.core")))
|
||||
|
||||
;; refer all from expectations
|
||||
(setq cljr-expectations-test-declaration "[expectations :refer :all]")
|
||||
|
||||
;; Add requires to blank devcards files
|
||||
(defun cljr--find-source-ns-of-devcard-ns (test-ns test-file)
|
||||
(let* ((ns-chunks (split-string test-ns "[.]" t))
|
||||
(test-name (car (last ns-chunks)))
|
||||
(src-dir-name (s-replace "devcards/" "src/" (file-name-directory test-file)))
|
||||
(replace-underscore (-partial 's-replace "_" "-"))
|
||||
(src-ns (car (--filter (or (s-prefix-p it test-name)
|
||||
(s-suffix-p it test-name))
|
||||
(-map (lambda (file-name)
|
||||
(funcall replace-underscore
|
||||
(file-name-sans-extension file-name)))
|
||||
(directory-files src-dir-name))))))
|
||||
(when src-ns
|
||||
(mapconcat 'identity (append (butlast ns-chunks) (list src-ns)) "."))))
|
||||
|
||||
(defun clj--find-devcards-component-name ()
|
||||
(or
|
||||
(ignore-errors
|
||||
(with-current-buffer
|
||||
(find-file-noselect (clj--src-file-name-from-cards (buffer-file-name)))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(search-backward "defcomponent ")
|
||||
(clojure-forward-logical-sexp)
|
||||
(skip-syntax-forward " ")
|
||||
(let ((beg (point))
|
||||
(end (progn (re-search-forward "\\w+")
|
||||
(point))))
|
||||
(buffer-substring-no-properties beg end)))))
|
||||
""))
|
||||
|
||||
(defun cljr--add-card-declarations ()
|
||||
(save-excursion
|
||||
(let* ((ns (clojure-find-ns))
|
||||
(source-ns (cljr--find-source-ns-of-devcard-ns ns (buffer-file-name))))
|
||||
(cljr--insert-in-ns ":require")
|
||||
(when source-ns
|
||||
(insert "[" source-ns " :refer [" (clj--find-devcards-component-name) "]]"))
|
||||
(cljr--insert-in-ns ":require")
|
||||
(insert "[devcards.core :refer-macros [defcard]]"))
|
||||
(indent-region (point-min) (point-max))))
|
||||
|
||||
(defadvice cljr--add-ns-if-blank-clj-file (around add-devcards activate)
|
||||
(ignore-errors
|
||||
(when (and cljr-add-ns-to-blank-clj-files
|
||||
(cljr--clojure-ish-filename-p (buffer-file-name))
|
||||
(= (point-min) (point-max)))
|
||||
ad-do-it
|
||||
(when (clj--is-card? (buffer-file-name))
|
||||
(cljr--add-card-declarations)))))
|
||||
|
||||
;; Set up linting of clojure code with eastwood
|
||||
|
||||
;; Make sure to add [acyclic/squiggly-clojure "0.1.2-SNAPSHOT"]
|
||||
;; to your :user :dependencies in .lein/profiles.clj
|
||||
|
||||
(require 'flycheck-clojure)
|
||||
|
||||
(defun my-cider-mode-enable-flycheck ()
|
||||
;; (when (and (s-ends-with-p ".clj" (buffer-file-name))
|
||||
;; (not (s-ends-with-p "/dev/user.clj" (buffer-file-name))))
|
||||
;; (flycheck-mode 1))
|
||||
)
|
||||
|
||||
(add-hook 'cider-mode-hook 'my-cider-mode-enable-flycheck)
|
||||
|
||||
(eval-after-load 'flycheck '(add-to-list 'flycheck-checkers 'clojure-cider-eastwood))
|
||||
|
||||
;; Make q quit out of find-usages to previous window config
|
||||
|
||||
(defadvice cljr-find-usages (before setup-grep activate)
|
||||
(window-configuration-to-register ?$))
|
||||
|
||||
;; ------------
|
||||
|
||||
;; TODO: Loot more stuff from:
|
||||
;; - https://github.com/overtone/emacs-live/blob/master/packs/dev/clojure-pack/config/paredit-conf.el
|
||||
|
||||
|
||||
(provide 'setup-clojure-mode)
|
|
@ -1,28 +0,0 @@
|
|||
;;; CommonLispExtension --- Enables common lisp development on FG42
|
||||
;;; Commentary:
|
||||
;; In order to user racket extension `racket' itself should
|
||||
;; be available on the path provided by `exec-path'.
|
||||
;;; Code:
|
||||
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/common-lisp/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'paredit)
|
||||
(depends-on 'flycheck)
|
||||
(depends-on 'rainbow-delimiters)
|
||||
(depends-on 'slime)
|
||||
(depends-on 'slime-company)
|
||||
|
||||
(defun common-lisp-doc ()
|
||||
"TBD")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension common-lisp
|
||||
:version "2.32"
|
||||
:on-initialize extensions/common-lisp-initialize
|
||||
:docs "lib/extensions/common-lisp/readme.org")
|
||||
|
||||
(provide 'extensions/common-lisp)
|
||||
;;; common-lisp.el ends here
|
|
@ -1,30 +0,0 @@
|
|||
;;; common-lisp-init --- The entry point for common lisp extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defvar default-lisp-platform "sbcl"
|
||||
"The default Lisp compiler/interpreter to be used with common-lisp extension.")
|
||||
|
||||
(defvar ql-slime-helper-path "~/quicklisp/slime-helper.el"
|
||||
"Default path for the slime-helper installed using quicklisp.")
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/common-lisp-initialize ()
|
||||
"Initialize the common Lisp extension."
|
||||
(require 'slime)
|
||||
|
||||
(setq inferior-lisp-program default-lisp-platform)
|
||||
(setq slime-contribs '(slime-fancy))
|
||||
(slime-setup '(slime-company))
|
||||
|
||||
(add-hook 'slime-load-hook
|
||||
(lambda ()
|
||||
(define-key slime-prefix-map (kbd "M-h")
|
||||
'slime-documentation-lookup)))
|
||||
|
||||
(let ((ql-slime-helper (expand-file-name ql-slime-helper-path)))
|
||||
(when (file-exists-p ql-slime-helper)
|
||||
(load ql-slime-helper))))
|
||||
|
||||
(provide 'extensions/common-lisp/init)
|
||||
;;; init ends here
|
|
@ -1,82 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/development/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'company)
|
||||
(depends-on 'company-statistics)
|
||||
(depends-on 'projectile)
|
||||
(depends-on 'yasnippet)
|
||||
(depends-on 'yasnippet-snippets)
|
||||
(depends-on 'smart-mode-line)
|
||||
|
||||
(depends-on 'quickrun)
|
||||
(depends-on 'dash)
|
||||
(depends-on 'websocket)
|
||||
|
||||
|
||||
(with-ability terraform
|
||||
(depends-on 'terraform-mode))
|
||||
|
||||
(with-ability yaml
|
||||
(depends-on 'yaml-mode))
|
||||
;; (with-ability hl
|
||||
;; (depends-on 'hl-sexp))
|
||||
|
||||
(with-ability dumb-jump
|
||||
(depends-on 'dumb-jump))
|
||||
|
||||
(with-ability bookmarks
|
||||
(depends-on 'bm))
|
||||
|
||||
(with-ability git
|
||||
(depends-on 'diff-hl)
|
||||
(depends-on 'magit)
|
||||
(depends-on 'gh)
|
||||
(when (is-evil?)
|
||||
(depends-on 'evil-magit)))
|
||||
|
||||
(with-ability github
|
||||
(depends-on 'magithub))
|
||||
|
||||
(with-ability focus
|
||||
(depends-on 'focus))
|
||||
|
||||
(with-ability code-browser
|
||||
(depends-on 'neotree))
|
||||
|
||||
(with-ability pt
|
||||
(depends-on 'pt))
|
||||
|
||||
(with-ability spell
|
||||
(depends-on 'flyspell))
|
||||
|
||||
(with-ability file-browser
|
||||
(depends-on 'ranger))
|
||||
|
||||
(with-ability shell
|
||||
(depends-on 'eshell-prompt-extras)
|
||||
(depends-on 'shell-pop))
|
||||
|
||||
(with-ability imenu
|
||||
(depends-on 'imenu)
|
||||
(depends-on 'imenu-list)
|
||||
(depends-on 'imenu-anywhere))
|
||||
|
||||
(with-ability lsp
|
||||
(depends-on 'lsp-mode)
|
||||
(depends-on 'lsp-ui)
|
||||
(depends-on 'company-lsp))
|
||||
|
||||
(with-ability dap
|
||||
(depends-on 'dap-mode))
|
||||
|
||||
;; TODO: Add flycheck-color-modebar
|
||||
;; TODO Add flycheck-tip
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension development
|
||||
:version "2.31"
|
||||
:on-initialize extension/development-initialize)
|
||||
|
||||
(provide 'extensions/development)
|
|
@ -1,368 +0,0 @@
|
|||
;;; development-extension --- A general extension for general development
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;; Functions -------------------------------------------------
|
||||
;;;###autoload
|
||||
(defun disable-projectile ()
|
||||
(interactive)
|
||||
(projectile-global-mode nil))
|
||||
|
||||
;; Quick fix for company-mode and yasnippet clashing
|
||||
(defun company-yasnippet-or-completion ()
|
||||
(interactive)
|
||||
(if (yas/expansion-at-point)
|
||||
(progn (company-abort)
|
||||
(yas/expand))
|
||||
(company-complete-common)))
|
||||
|
||||
(defun yas/expansion-at-point ()
|
||||
"Tested with v0.6.1. Extracted from `yas/expand-1'"
|
||||
(first (yas/current-key)))
|
||||
|
||||
|
||||
(defun eval-and-replace ()
|
||||
"Replace the preceding sexp with its value."
|
||||
(interactive)
|
||||
(backward-kill-sexp)
|
||||
(condition-case nil
|
||||
(prin1 (eval (read (current-kill 0)))
|
||||
(current-buffer))
|
||||
(error (message "Invalid expression")
|
||||
(insert (current-kill 0)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun enable-pt-search ()
|
||||
(interactive)
|
||||
(define-key projectile-mode-map (kbd "C-c p s s") 'projectile-pt)
|
||||
(define-key projectile-mode-map (kbd "C-c p s r") 'pt-regexp))
|
||||
|
||||
|
||||
(defun load-necessary-modes-and-keybindings ()
|
||||
"Load the modes and keybindings which at necessary and are not part ofcourse an ability."
|
||||
(which-function-mode))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extension/development-initialize ()
|
||||
"Development plugin initialization."
|
||||
(load-necessary-modes-and-keybindings)
|
||||
|
||||
(ability project-config ()
|
||||
"Makes projects configurable."
|
||||
(require 'projects/configuration))
|
||||
|
||||
(ability pretty-symbols ()
|
||||
"Replace some symbols with icons"
|
||||
(global-prettify-symbols-mode 1))
|
||||
|
||||
|
||||
(ability lsp ()
|
||||
"LSP integration for FG42"
|
||||
(require 'lsp-mode)
|
||||
(require 'lsp-ui-imenu)
|
||||
|
||||
;; Disabling inline actions. Accessable via lsp-execute-code-action
|
||||
(setq lsp-ui-sideline-show-code-actions nil)
|
||||
(add-hook 'lsp-after-open-hook 'lsp-enable-imenu)
|
||||
(setq lsp-ui-sideline-ignore-duplicate t)
|
||||
(setq lsp-prefer-flymake nil)
|
||||
(add-hook 'lsp-mode-hook 'lsp-ui-mode))
|
||||
|
||||
(ability dap ('lsp)
|
||||
(dap-mode 1)
|
||||
(dap-ui-mode 1))
|
||||
|
||||
(ability bookmarks ()
|
||||
(setq bm-restore-repository-on-load t)
|
||||
|
||||
(require 'bm)
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-p"
|
||||
:description "Toggle bookmarks")
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-]"
|
||||
:description "Jump to next bookmark")
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-["
|
||||
:description "Jump to previous bookmark")
|
||||
|
||||
(global-set-key (kbd "M-p") 'bm-toggle)
|
||||
(global-set-key (kbd "M-]") 'bm-next)
|
||||
(global-set-key (kbd "M-[") 'bm-previous)
|
||||
|
||||
(setq bm-restore-repository-on-load t)
|
||||
(setq bm-in-lifo-order t)
|
||||
(setq bm-cycle-all-buffers t)
|
||||
(setq-default bm-buffer-persistence t)
|
||||
|
||||
(setq bm-repository-file (locate-user-emacs-file "bm-repository"))
|
||||
|
||||
;; (add-hook' after-init-hook 'bm-repository-load)
|
||||
;; (add-hook 'kill-buffer-hook #'bm-buffer-save)
|
||||
;; ;; Restoring bookmarks
|
||||
;; (add-hook 'find-file-hooks #'bm-buffer-restore)
|
||||
;; (add-hook 'after-revert-hook #'bm-buffer-restore)
|
||||
|
||||
;; The `after-revert-hook' is not necessary to use to achieve persistence,
|
||||
;; but it makes the bookmark data in repository more in sync with the file
|
||||
;; state. This hook might cause trouble when using packages
|
||||
;; that automatically reverts the buffer (like vc after a check-in).
|
||||
;; This can easily be avoided if the package provides a hook that is
|
||||
;; called before the buffer is reverted (like `vc-before-checkin-hook').
|
||||
;; Then new bookmarks can be saved before the buffer is reverted.
|
||||
;; Make sure bookmarks is saved before check-in (and revert-buffer)
|
||||
;; (add-hook 'vc-before-checkin-hook #'bm-buffer-save)
|
||||
(add-hook' after-init-hook 'bm-repository-load)
|
||||
|
||||
(add-hook 'kill-emacs-hook '(lambda nil
|
||||
(bm-buffer-save-all)
|
||||
(bm-repository-save))))
|
||||
|
||||
(ability livemd ()
|
||||
"Live markdown preview."
|
||||
(require 'extensions/development/livemd))
|
||||
|
||||
(ability imenu ()
|
||||
"IMenu integration for FG42"
|
||||
(require 'imenu)
|
||||
(require 'imenu-list)
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-'"
|
||||
:description "Toggle IMenu list which shows the symbol definitions based on major mode.")
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-<2>"
|
||||
:description "Search for the definition of the symbol you want anywhere.")
|
||||
|
||||
;; (imenu-list-minor-mode)
|
||||
(setq imenu-list-focus-after-activation t)
|
||||
(setq imenu-list-auto-resize t)
|
||||
(global-set-key (kbd "C-'") #'imenu-list-smart-toggle)
|
||||
(global-set-key (kbd "C-<f2>") #'imenu-anywhere)
|
||||
(global-set-key (kbd "<f13>") #'imenu-anywhere))
|
||||
|
||||
|
||||
(ability dumb-jump ()
|
||||
"Easily jump to defination for most langs using ag"
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-g o"
|
||||
:description "Jump to definition in another window")
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-u y or M-g j"
|
||||
:description "Jump to definition in current buffer")
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-u i or M-g x"
|
||||
:description "Jump to definition using an external tool")
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-g z"
|
||||
:description "Jump to definition in another window using an external tool")
|
||||
|
||||
(require 'dumb-jump)
|
||||
(dumb-jump-mode t)
|
||||
(define-key dumb-jump-mode-map (kbd "M-g o") 'dumb-jump-go-other-window)
|
||||
(define-key dumb-jump-mode-map (kbd "M-g j") 'dumb-jump-go)
|
||||
(define-key dumb-jump-mode-map (kbd "C-u y") 'dumb-jump-go)
|
||||
(define-key dumb-jump-mode-map (kbd "M-g x") 'dumb-jump-go-prefer-external)
|
||||
(define-key dumb-jump-mode-map (kbd "C-u i") 'dumb-jump-go-prefer-external)
|
||||
(define-key dumb-jump-mode-map (kbd "M-g z") 'dumb-jump-go-prefer-external-other-window))
|
||||
|
||||
(ability git ()
|
||||
"A wonderful git interface for FG42"
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-x g"
|
||||
:description "Rise up MAGIT. Git interface for FG42")
|
||||
(global-set-key (kbd "C-x g") 'magit-status)
|
||||
(when (is-evil?)
|
||||
(add-hook 'magit-mode-hook (lambda () (require 'evil-magit)))
|
||||
(defkey global-map 'magit-status :evil (:normal "SPC g s"))))
|
||||
|
||||
|
||||
(ability github ()
|
||||
"Github support"
|
||||
(require 'magithub)
|
||||
(magithub-feature-autoinject t))
|
||||
|
||||
;; (ability hl ()
|
||||
;; "Highligh the current block of code. This ability may slows you down."
|
||||
;; (require 'hl-sexp)
|
||||
;; (add-hook 'prog-mode-hook #'hl-sexp-mode))
|
||||
|
||||
(ability code-completion ()
|
||||
"Use company mode to provides a complete auto completion framwork."
|
||||
(require 'company)
|
||||
(global-company-mode t)
|
||||
|
||||
;; Bigger popup window
|
||||
(setq company-tooltip-limit 20)
|
||||
|
||||
;; Align annotations to the right tooltip border
|
||||
(setq company-tooltip-align-annotations 't)
|
||||
|
||||
;; Decrease delay before autocompletion popup shows
|
||||
(setq company-idle-delay 0.1)
|
||||
(setq company-minimum-prefix-length 2)
|
||||
|
||||
;; Start autpocompletion only after typing
|
||||
(setq company-begin-commands '(self-insert-command))
|
||||
|
||||
;; Force complete file names on "C-c /" key
|
||||
(global-set-key (kbd "C-c /") 'company-files)
|
||||
|
||||
(add-hook 'after-init-hook 'company-statistics-mode)
|
||||
(define-key company-active-map "\t" 'company-yasnippet-or-completion)
|
||||
|
||||
(setq dabbrev-case-fold-search t)
|
||||
|
||||
(add-to-list 'company-backends 'company-dabbrev)
|
||||
(add-to-list 'company-backends 'company-dabbrev-code))
|
||||
|
||||
(ability yas ()
|
||||
"Snippet configuration."
|
||||
(let ((snippet_home (concat (file-name-directory
|
||||
(locate-library "yasnippet-snippets"))
|
||||
"snippets"))
|
||||
(my_snippet (concat fg42-home "/lib/snippets")))
|
||||
(setq yas-snippet-dirs (list my_snippet snippet_home)))
|
||||
|
||||
(yas-global-mode 1))
|
||||
|
||||
(ability project-management ()
|
||||
"Ability to manage projects and project navigation."
|
||||
(projectile-global-mode)
|
||||
(setq projectile-enable-caching t))
|
||||
|
||||
(ability spell ()
|
||||
"Check spell of any word using ispell. This ability may slows you down"
|
||||
(global-set-key (kbd "<f2>") 'ispell-word)
|
||||
(setq flyspell-issue-message-flg nil))
|
||||
|
||||
(ability diff-highlight ()
|
||||
"Highlight the diffs based on VCS."
|
||||
(add-hook 'prog-mode-hook 'turn-on-diff-hl-mode)
|
||||
(add-hook 'vc-dir-mode-hook 'turn-on-diff-hl-mode))
|
||||
|
||||
(ability auto-pair ()
|
||||
"Auto pair stuffs like brackets begin/ends etc."
|
||||
;; TODO: use autopair mode if electric pair was not as good as autopair
|
||||
(electric-pair-mode))
|
||||
|
||||
(ability yaml ()
|
||||
"YAML editor."
|
||||
(require 'yaml-mode)
|
||||
(add-hook 'yaml-mode-hook (lambda () (interactive) (whitespace-mode 1)))
|
||||
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.sls\\'" . yaml-mode)))
|
||||
|
||||
(ability terraform ()
|
||||
"Terraform editor."
|
||||
(require 'terraform-mode)
|
||||
(add-to-list 'auto-mode-alist '("\\.tf\\'" . terraform-mode)))
|
||||
|
||||
(ability code-browser ()
|
||||
"Adds the code browser to FG42."
|
||||
(require 'neotree)
|
||||
(setq neo-theme (if (display-graphic-p) 'icons 'arrow))
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "f8"
|
||||
:description "Toggle project browser sidebar. See ProjectBrowser")
|
||||
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "n"
|
||||
:description "Next line")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "p"
|
||||
:description "Previous line")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "g"
|
||||
:description "Refresh the tree")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "A"
|
||||
:description "Maximize/Minimize the project browser")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "H"
|
||||
:description "Toggle display hidden files")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "C-c C-n"
|
||||
:description "Create a file or create a directory if filename ends with a '/'")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "C-c C-d"
|
||||
:description "Delete a file or a directory.")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "C-c C-r"
|
||||
:description "Rename a file or a directory.")
|
||||
(cheatsheet-add :group '--ProjectBrowser--
|
||||
:key "C-c C-c"
|
||||
:description "Chande root directory.")
|
||||
|
||||
(global-set-key [f8] 'neotree-toggle))
|
||||
|
||||
(ability shell ()
|
||||
"Eshell enhancements."
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-`'"
|
||||
:description "Brings up the eshell")
|
||||
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(shell-pop-default-directory "$HOME")
|
||||
;;'(shell-pop-shell-type (quote ("ansi-term" "*ansi-term*" (lambda nil (ansi-term shell-pop-term-shell)))))
|
||||
'(shell-pop-shell-type (quote ("eshell" "*shell*" (lambda nil (eshell shell-pop-term-shell)))))
|
||||
;;'(shell-pop-term-shell "/bin/zsh")
|
||||
'(shell-pop-term-shell "eshell")
|
||||
|
||||
'(shell-pop-window-size 30)
|
||||
'(shell-pop-full-span t)
|
||||
'(shell-pop-window-position "full")))
|
||||
|
||||
;; (require 'eshell-prompt-extras)
|
||||
;; (with-eval-after-load "esh-opt"
|
||||
;; (autoload 'epe-theme-lambda "eshell-prompt-extras")
|
||||
;; (setq eshell-highlight-prompt nil
|
||||
;; eshell-prompt-function 'epe-theme-lambda))
|
||||
|
||||
|
||||
(ability focus ()
|
||||
"Provides means for focusing on code review."
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "M-x focus-mode"
|
||||
:description "Highlights only the paragraph of code which you are reading for better focus."))
|
||||
(ability pt ()
|
||||
"Provides fast search ability via platinium search"
|
||||
(require 'pt)
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-c p s s"
|
||||
:description "Search within a project using pt. It's fast.")
|
||||
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "C-c p s r"
|
||||
:description "Search for a regexp in a project.")
|
||||
(advice-add 'projectile-ag :around #'projectile-pt)
|
||||
(add-hook 'projectile-mode-hook 'enable-pt-search))
|
||||
|
||||
(ability file-browser ()
|
||||
"A ranger like file browser for FG42"
|
||||
(cheatsheet-add :group '--Development--
|
||||
:key "f7"
|
||||
:description "A ranger like file browser for FG42")
|
||||
(setq ranger-cleanup-eagerly t)
|
||||
(setq ranger-show-dotfiles nil)
|
||||
(global-set-key [f7] 'ranger))
|
||||
|
||||
(ability smart-mode-line ()
|
||||
"Smarter modeline for FG42"
|
||||
(setq sml/no-confirm-load-theme t)
|
||||
(setq sml/theme 'respectful)
|
||||
(sml/setup))
|
||||
(message "'development' extension has been initialized."))
|
||||
|
||||
(provide 'extensions/development/init)
|
|
@ -1,77 +0,0 @@
|
|||
;;; livemd.el --- Realtime Markdown previews for FG42.
|
||||
|
||||
;; Copyright (C) 2014-2016 Hrvoje Simic
|
||||
;; Copyright (C) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
|
||||
;; Author: Hrvoje Simic <hrvoje@twobucks.co>
|
||||
;; Version: 1.0.0
|
||||
;; Keywords: markdown, preview, live
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
|
||||
;; This is a clone of https://github.com/shime/emacs-livedown
|
||||
;; Kudos to Hrvoje Simic for his great work.
|
||||
|
||||
;;; Commentary:
|
||||
;; Realtime Markdown previews for Emacs. install `livedown' package
|
||||
;; using npm like: `npm install -g livedown' and then use `livemd-preview'
|
||||
;; function to start the dev server.
|
||||
|
||||
;;; Code:
|
||||
(defgroup livemd nil
|
||||
"Realtime Markdown previews"
|
||||
:group 'livemd
|
||||
:prefix "livemd-")
|
||||
|
||||
(defcustom livedown-path "livedown"
|
||||
"Path to livedown executable."
|
||||
:type 'string
|
||||
:group 'livemd)
|
||||
|
||||
(defcustom livemd-port 1337
|
||||
"Port on which livemd server will run."
|
||||
:type 'integer
|
||||
:group 'livemd)
|
||||
|
||||
(defcustom livemd-open t
|
||||
"Open browser automatically."
|
||||
:type 'boolean
|
||||
:group 'livemd)
|
||||
|
||||
(defcustom livemd-browser nil
|
||||
"Open alternative browser."
|
||||
:type 'string
|
||||
:group 'livemd)
|
||||
|
||||
(defcustom livemd-autostart nil
|
||||
"Auto-open previews when opening markdown files."
|
||||
:type 'boolean
|
||||
:group 'livemd)
|
||||
|
||||
;;;###autoload
|
||||
(defun livemd-preview ()
|
||||
"Preview the current file in livemd."
|
||||
(interactive)
|
||||
(call-process-shell-command (format "livedown stop --port %s &" livemd-port))
|
||||
(start-process-shell-command
|
||||
"livedown"
|
||||
"*fg42-livemd-buffer*"
|
||||
(format "%s start %s --port %s %s %s "
|
||||
livedown-path
|
||||
buffer-file-name
|
||||
livemd-port
|
||||
(if livemd-browser (concat "--browser " livemd-browser) "")
|
||||
(if livemd-open "--open" "")))
|
||||
|
||||
(add-hook 'kill-emacs-query-functions (lambda () (livemd-kill t)))
|
||||
(print (format "%s rendered @ %s" buffer-file-name livemd-port) (get-buffer "emacs-livemd-buffer")))
|
||||
|
||||
;;;###autoload
|
||||
(defun livemd-kill (&optional async)
|
||||
"Stop the livemd process ASYNC or otherwise."
|
||||
(interactive)
|
||||
(let ((stop-livemd (if async 'async-shell-command 'call-process-shell-command)))
|
||||
(funcall stop-livemd (format "%s stop --port %s &" livedown-path livemd-port))))
|
||||
|
||||
|
||||
(provide 'extensions/development/livemd)
|
||||
;;; livemd.el ends here
|
|
@ -1,11 +0,0 @@
|
|||
;;; lxgithub.el --- Github integration library for FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'gh)
|
||||
;; Functions -------------------------------------------------
|
||||
|
||||
(gh-issues-api "api")
|
||||
|
||||
(provide 'lxgithub)
|
||||
;;; lxgithub.el ends here
|
|
@ -1,19 +0,0 @@
|
|||
;;; DevopsExtension --- Enable Devops support in FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/devops/init)
|
||||
|
||||
;; dependencies
|
||||
(depends-on 'kubel)
|
||||
(depends-on 'ansible)
|
||||
(depends-on 'docker)
|
||||
(depends-on 'dockerfile-mode)
|
||||
|
||||
(extension devops
|
||||
:version 0.0.1
|
||||
:on-initialize extensions/devops-initialize
|
||||
:docs "lib/extensions/devops/readme.org")
|
||||
(provide 'extensions/devops)
|
||||
;; devops ends here
|
|
@ -1,12 +0,0 @@
|
|||
;;; devops-init --- The entry point for devops extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(defun extensions/devops-initialize ()
|
||||
"Initialize devops extension."
|
||||
(exec-path-from-shell-initialize)
|
||||
(add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode))
|
||||
(add-hook 'yaml-mode-hook (lambda () (ansible))))
|
||||
|
||||
(provide 'extensions/devops/init)
|
||||
;;; init ends here.
|
|
@ -1,15 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(defun extensions/editor-theme-initialize ()
|
||||
"Initialize 'editor-theme' extension."
|
||||
(load-default-theme)
|
||||
(message "'editor-theme' extension has been initizlied."))
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension editor-theme
|
||||
:version "2.31"
|
||||
:on-initialize extensions/editor-theme-initialize)
|
||||
|
||||
(provide 'extensions/editor-theme)
|
|
@ -1,98 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/editor/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'multiple-cursors)
|
||||
(depends-on 'expand-region)
|
||||
(depends-on 'seq)
|
||||
(depends-on 'ov)
|
||||
(depends-on 'cheatsheet)
|
||||
(depends-on 'all-the-icons)
|
||||
(depends-on 'markdown-mode)
|
||||
(depends-on 'json-mode)
|
||||
;; Fast move in the buffer
|
||||
(depends-on 'avy)
|
||||
|
||||
;; Moving between windows
|
||||
(depends-on 'ace-window)
|
||||
|
||||
;; Don't worry unless you're evil this mode won't start
|
||||
(depends-on 'evil)
|
||||
|
||||
;; Resize splitted windows
|
||||
(depends-on 'windresize)
|
||||
|
||||
(depends-on 'eyebrowse)
|
||||
|
||||
;; Themes
|
||||
(depends-on 'spacemacs-theme)
|
||||
(depends-on 'doom-themes)
|
||||
;; TODO: Move this to an ability
|
||||
(depends-on 'solaire-mode)
|
||||
|
||||
(with-ability nlinum
|
||||
(depends-on 'nlinum))
|
||||
|
||||
(with-ability spaceline
|
||||
(depends-on 'spaceline))
|
||||
|
||||
(with-ability doom-modeline
|
||||
(depends-on 'doom-modeline))
|
||||
|
||||
(with-ability guru
|
||||
(depends-on 'guru-mode))
|
||||
|
||||
(with-ability tramp
|
||||
(depends-on 'tramp))
|
||||
|
||||
(with-ability ivy
|
||||
(depends-on 'ivy)
|
||||
(depends-on 'counsel))
|
||||
|
||||
(with-ability selectrum
|
||||
(depends-on 'selectrum)
|
||||
(depends-on 'selectrum-prescient)
|
||||
(depends-on 'ctrlf))
|
||||
|
||||
(with-ability ido
|
||||
(depends-on 'ido)
|
||||
(depends-on 'ido-completing-read+)
|
||||
(depends-on 'smex)
|
||||
(depends-on 'ido-vertical-mode)
|
||||
(depends-on 'flx-ido))
|
||||
|
||||
(with-ability helm
|
||||
(depends-on 'helm)
|
||||
(depends-on 'helm-ag)
|
||||
(depends-on 'helm-themes)
|
||||
(depends-on 'helm-flx)
|
||||
(depends-on 'helm-make)
|
||||
(depends-on 'helm-mode-manager)
|
||||
(depends-on 'helm-projectile)
|
||||
(depends-on 'helm-swoop)
|
||||
(depends-on 'helm-themes))
|
||||
|
||||
(with-ability swiper
|
||||
(depends-on 'swiper))
|
||||
|
||||
(with-ability flycheck
|
||||
(depends-on 'flycheck))
|
||||
|
||||
(with-ability emoji
|
||||
(depends-on 'emojify))
|
||||
|
||||
(with-ability tabbar
|
||||
(depends-on 'tabbar))
|
||||
|
||||
(with-ability which-key
|
||||
(depends-on 'which-key))
|
||||
(if (eq system-type 'darwin)
|
||||
(depends-on 'exec-path-from-shell))
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension editor
|
||||
:version "2.31"
|
||||
:on-initialize extensions/editor-initialize)
|
||||
|
||||
(provide 'extensions/editor)
|
|
@ -1,44 +0,0 @@
|
|||
;; Vars -------------------------------
|
||||
(defvar about_fg42_msg "
|
||||
FG42 %%VERSION%% Copyright © 2010-2018 Sameer Rahmani <lxsameer@gnu.org>
|
||||
FG42 release under the term of GPLv2.
|
||||
|
||||
Home page:
|
||||
\thttp://fg42.lxsameer.com
|
||||
|
||||
Credits:
|
||||
\tSameer Rahmani (@lxsameer)
|
||||
\tDanial Parsi (@intuxticated)
|
||||
\tAmir Houghangi
|
||||
\tNima Nazari (niman)
|
||||
\tKeyvan Hedayati (k1-hedayati)
|
||||
\tBehnam Khan Beigi (@yottanami)
|
||||
\tEhsan Mahmoudi
|
||||
|
||||
"
|
||||
"About FG42")
|
||||
|
||||
|
||||
;; Functions ---------------------------
|
||||
(defun about/get_string ()
|
||||
"Get the about message string"
|
||||
(let (msg)
|
||||
(setq msg (replace-regexp-in-string "%%VERSION%%"
|
||||
FG42-VERSION about_fg42_msg))))
|
||||
|
||||
(defun about-fg42 ()
|
||||
"Show an small about note"
|
||||
(interactive)
|
||||
(let (buf msg)
|
||||
(setq buf (get-buffer-create "*About FG42*"))
|
||||
(setq msg (about/get_string))
|
||||
(set-buffer buf)
|
||||
(insert msg)
|
||||
(view-buffer buf)))
|
||||
|
||||
(define-key-after global-map
|
||||
[menu-bar help-menu about-fg42]
|
||||
'("About FG42" . about-fg42-f)
|
||||
'about-emacs)
|
||||
|
||||
(provide 'extensions/editor/about)
|
|
@ -1,51 +0,0 @@
|
|||
;;; Buffers --- All the functions related to buffer management
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(defvar *favorite-buffer* nil)
|
||||
|
||||
(defun switch-to-previous-buffer ()
|
||||
"Switch to previously open buffer.
|
||||
Repeated invocations toggle between the two most recently open buffers."
|
||||
(interactive)
|
||||
(switch-to-buffer (other-buffer (current-buffer) 1)))
|
||||
|
||||
(defun buffer-match-p (buf)
|
||||
"If BUF name match the favorite buffer regexp."
|
||||
(string-match-p *favorite-buffer* (buffer-name buf)))
|
||||
|
||||
(defun switch-and-bury (buf)
|
||||
"Switch to given BUF and bury it as well."
|
||||
(interactive)
|
||||
(bury-buffer buf)
|
||||
(switch-to-buffer buf))
|
||||
|
||||
(defun switch-to-buffer-by-regex ()
|
||||
"Switch to buffer which the name match the *favorite-buffer* regex."
|
||||
(interactive)
|
||||
(if *favorite-buffer*
|
||||
(switch-and-bury
|
||||
(car (remove-if-not #'buffer-match-p (buffer-list))))
|
||||
(eshell)))
|
||||
|
||||
(defun switch-to-favorite-buffer ()
|
||||
"Switch to *favorite-buffer* buffer with is variable assigned to each mode.
|
||||
|
||||
For exampe in clojure mode it would the name of repl buffer. The *favorite-buffer* value should be regex matching to the buffer name"
|
||||
(interactive)
|
||||
(if *favorite-buffer*
|
||||
(if (string-match *favorite-buffer* (buffer-name))
|
||||
(switch-to-previous-buffer)
|
||||
(switch-to-buffer-by-regex))
|
||||
(if (string= (buffer-name) "*eshell*")
|
||||
(switch-to-previous-buffer)
|
||||
(eshell))))
|
||||
(defun reset-favorite-buffer-value ()
|
||||
(message "reseting favorite buffer value...")
|
||||
(message *favorite-buffer*)
|
||||
(setq *favorite-buffer* nil))
|
||||
|
||||
(add-hook 'change-major-mode-hook 'reset-favorite-buffer-value)
|
||||
|
||||
(provide 'extensions/editor/buffers)
|
||||
;;; buffers.el ends here
|
|
@ -1,35 +0,0 @@
|
|||
;; --------------------------------------------------------------------
|
||||
;; Groups
|
||||
;; --------------------------------------------------------------------
|
||||
(defgroup fg42-user-preferences nil
|
||||
"User preferences group. this group contain user specified options for
|
||||
FG42"
|
||||
:group 'fg42
|
||||
:tag '"User Preferences"
|
||||
)
|
||||
|
||||
;; --------------------------------------------------------------------
|
||||
;; Custom Variables
|
||||
;; --------------------------------------------------------------------
|
||||
(defcustom developer-name nil
|
||||
"FG42 use this option as author name in project if the value be non-nil"
|
||||
:group 'fg42-user-preferences
|
||||
:type 'string
|
||||
:tag '"Developer full name"
|
||||
)
|
||||
|
||||
(defcustom developer-email nil
|
||||
"FG42 use this option as author email in project if the value be non-nil"
|
||||
:group 'fg42-user-preferences
|
||||
:type 'string
|
||||
:tag '"Developer Email"
|
||||
)
|
||||
|
||||
(defcustom fg42-workspace "~/src/"
|
||||
"FG42 use this option as default path for new project."
|
||||
:group 'fg42-user-preferences
|
||||
:type 'string
|
||||
:tag '"Workspace"
|
||||
)
|
||||
|
||||
(provide 'extensions/editor/custom)
|
|
@ -1,433 +0,0 @@
|
|||
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Version: 3.0.0
|
||||
;;
|
||||
;; 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:
|
||||
;;; Code:
|
||||
(require 'extensions/editor/buffers)
|
||||
|
||||
;; Customizations --------------------------------------------
|
||||
(defcustom fg42-todo-file "~/.TODO.org"
|
||||
"Path to your todo file. You can use a tramp address here as well."
|
||||
:type 'string
|
||||
:group 'fg42)
|
||||
|
||||
;; Hooks -----------------------------------------------------
|
||||
(defvar fg42-before-open-todo-hook nil)
|
||||
(defvar fg42-after-open-todo-hook nil)
|
||||
|
||||
;; Vars -----------------------------------------------------------------------
|
||||
(defvar fg42-font "Fira Mono"
|
||||
"The default font to be used with FG42.")
|
||||
|
||||
(defvar fg42-font-size 12
|
||||
"The default font to be used with FG42.")
|
||||
|
||||
|
||||
;; Functions -------------------------------------------------
|
||||
(defun fg42-reload ()
|
||||
"Reload the entire FG42."
|
||||
(interactive)
|
||||
(load-file (concat (getenv "FG42_HOME") "/fg42-config.el")))
|
||||
|
||||
;;;###autoload
|
||||
(defun fg42-open-todo ()
|
||||
(interactive)
|
||||
(run-hooks 'fg42-before-open-todo-hook)
|
||||
(find-file fg42-todo-file)
|
||||
(run-hooks 'fg42-after-open-todo-hook))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/editor-initialize ()
|
||||
"Base plugin initialization."
|
||||
|
||||
(if (eq system-type 'darwin)
|
||||
(progn
|
||||
(message "Running on the stupid macOS X.")
|
||||
(exec-path-from-shell-initialize)))
|
||||
|
||||
(require 'all-the-icons)
|
||||
(require 'cheatsheet)
|
||||
(require 'extensions/editor/utils)
|
||||
|
||||
(add-to-list 'custom-theme-load-path
|
||||
(concat fg42-home "/lib/themes/custom_themes"))
|
||||
|
||||
;; Setting user preference based on the race.
|
||||
(if (is-evil?)
|
||||
(progn
|
||||
(require 'evil)
|
||||
(evil-mode 1)))
|
||||
|
||||
(if (is-human?)
|
||||
(progn
|
||||
(cua-mode 'emacs)
|
||||
(cua-selection-mode t)
|
||||
(setq cua-auto-tabify-rectangles nil)
|
||||
(transient-mark-mode 1)))
|
||||
|
||||
;; Automatically removed excess backups of the file
|
||||
(setq delete-old-versions t)
|
||||
|
||||
;; Font Configuration -----------------------------------
|
||||
(ability font ()
|
||||
"Sets the default font to fg42 font"
|
||||
(add-to-list 'default-frame-alist (cons 'font (format "%s-%d" fg42-font fg42-font-size)))
|
||||
(set-face-attribute 'default t :font fg42-font))
|
||||
;; ------------------------------------------------------
|
||||
|
||||
(ability which-key ()
|
||||
(when (is-evil?)
|
||||
(which-key-mode t)))
|
||||
|
||||
;; enhance evil mode with space leader keybindings
|
||||
(ability space-keys (which-key)
|
||||
"evil mode with space leader keybindings"
|
||||
(when (is-evil?)
|
||||
(defkey global-map 'find-file :evil (:normal "SPC f f"))
|
||||
(defkey global-map 'kill-buffer :evil (:normal "SPC b k"))
|
||||
(defkey global-map 'save-buferr :evil (:normal "SPC b s"))
|
||||
(defkey global-map 'next-buffer :evil (:normal "SPC b n"))
|
||||
(defkey global-map 'previous-buffer :evil (:normal "SPC b p"))
|
||||
(defkey global-map 'switch-to-buffer :evil (:normal "SPC b l"))
|
||||
(defkey global-map 'other-window :evil (:normal "SPC w o"))
|
||||
(defkey global-map 'delete-window :evil (:normal "SPC w d"))
|
||||
(defkey global-map 'delete-other-windows :evil (:normal "SPC w m"))
|
||||
(defkey global-map 'split-window-vertically :evil (:normal "SPC w s v"))
|
||||
(defkey global-map 'eval-last-sexp :evil (:normal "SPC e e"))
|
||||
(defkey global-map 'eval-buffer :evil (:normal "SPC e b"))
|
||||
(defkey global-map 'comment-line :evil (:normal "SPC l c"))
|
||||
(defkey global-map 'describe-key :evil (:normal "SPC d k"))
|
||||
(defkey global-map 'describe-function :evil (:normal "SPC d f"))
|
||||
(defkey global-map 'describe-variable :evil (:normal "SPC d v"))))
|
||||
|
||||
(cheatsheet-add :group '--HELP--
|
||||
:key "C-?"
|
||||
:description "Show this cheatsheet")
|
||||
(cheatsheet-add :group '--Navigation--
|
||||
:key "M-f"
|
||||
:description "Move a word to right")
|
||||
(cheatsheet-add :group '--Navigation--
|
||||
:key "M-b"
|
||||
:description "Move a word to left")
|
||||
(cheatsheet-add :group '--Navigation--
|
||||
:key "M-{"
|
||||
:description "Move back a paragraph")
|
||||
(cheatsheet-add :group '--Navigation--
|
||||
:key "M-}"
|
||||
:description "Move forward by a paragraph")
|
||||
|
||||
(global-set-key (kbd "C-?") 'cheatsheet-show)
|
||||
|
||||
;; Fast Move in the buffer
|
||||
(global-set-key (kbd "M-1") 'avy-goto-word-or-subword-1)
|
||||
|
||||
(cheatsheet-add :group '--Navigation--
|
||||
:key "M-1"
|
||||
:description "Jump to the a word or subword in the buffer")
|
||||
|
||||
|
||||
;; Remove splash screen
|
||||
(setq inhibit-splash-screen t)
|
||||
|
||||
;; scratch should be scratch
|
||||
(setq initial-scratch-message nil)
|
||||
|
||||
(ability highligh-current-line ()
|
||||
"Highlights the current line."
|
||||
(global-hl-line-mode t))
|
||||
(ability flycheck ()
|
||||
"Check syntax on the fly using flycheck."
|
||||
(require 'flycheck)
|
||||
|
||||
(add-hook 'prog-mode-hook 'global-flycheck-mode)
|
||||
(add-hook 'after-init-hook 'global-flycheck-mode))
|
||||
|
||||
|
||||
;; ACE Window
|
||||
|
||||
(global-set-key (kbd "C-<tab>") 'ace-window)
|
||||
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
|
||||
|
||||
;; Tramp configuration -------------------------------------
|
||||
(ability tramp ()
|
||||
(setq tramp-default-method "ssh")
|
||||
(cheatsheet-add :group '--EDITOR--
|
||||
:key "f9"
|
||||
:description "Open up your todo file. checkout `fg42-todo-file` var and `fg42-open-todo` function.")
|
||||
(global-set-key [f9] 'fg42-open-todo))
|
||||
|
||||
(global-unset-key (kbd "C-o"))
|
||||
(global-unset-key (kbd "C-v"))
|
||||
|
||||
(cheatsheet-add :group '--EDITOR--
|
||||
:key "C-s-n"
|
||||
:description "Move a paragraph forward")
|
||||
|
||||
(cheatsheet-add :group '--EDITOR--
|
||||
:key "C-s-p"
|
||||
:description "Move a paragraph backward")
|
||||
|
||||
(global-set-key (kbd "C-s-n") 'forward-paragraph)
|
||||
(global-set-key (kbd "C-s-p") 'backward-paragraph)
|
||||
|
||||
;; replace strings
|
||||
(global-set-key (kbd "C-c M-s") 'replace-string)
|
||||
|
||||
;; Basic Key bindings
|
||||
(global-set-key (kbd "\C-c m") 'menu-bar-mode)
|
||||
|
||||
(global-set-key (kbd "<f2>") 'goto-line)
|
||||
|
||||
(global-set-key (kbd "M-TAB") 'switch-to-previous-buffer)
|
||||
(global-set-key (kbd "M-`") 'switch-to-favorite-buffer)
|
||||
|
||||
;; Don't allow tab as indent
|
||||
(setq-default indent-tabs-mode nil)
|
||||
|
||||
(ability nlinum ()
|
||||
"Faster alternative to linum-mode"
|
||||
(require 'nlinum)
|
||||
(setq nlinum-highlight-current-line t)
|
||||
(global-nlinum-mode t))
|
||||
|
||||
;; Default indent width
|
||||
(setq tab-width 2)
|
||||
(add-hook 'before-save-hook 'delete-trailing-whitespace)
|
||||
|
||||
;; Enhancements ---------------------------------------------
|
||||
|
||||
;; Global configurations
|
||||
(tool-bar-mode -1)
|
||||
(scroll-bar-mode -1)
|
||||
(setq x-select-enable-clipboard t)
|
||||
(column-number-mode t)
|
||||
|
||||
;; linum mode
|
||||
(ability linum ()
|
||||
"Line numbering ability"
|
||||
(global-linum-mode)
|
||||
(setq linum-format " %3d "))
|
||||
|
||||
(ability hide-menu ()
|
||||
"Hides the emacs menu completely."
|
||||
(menu-bar-mode -1))
|
||||
|
||||
(show-paren-mode t)
|
||||
(cua-selection-mode t)
|
||||
|
||||
(ability thin-cursor ()
|
||||
(setq-default cursor-type 'bar))
|
||||
|
||||
(ability nonblinker-cursor ()
|
||||
(blink-cursor-mode -1))
|
||||
|
||||
|
||||
;; expand-region -------------------------------------------
|
||||
(global-set-key (kbd "C-=") 'er/expand-region)
|
||||
(global-set-key (kbd "C-+") 'er/contract-region)
|
||||
|
||||
;; Multiple cursor -----------------------------------------
|
||||
;; multiple cursor configurations
|
||||
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
|
||||
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
|
||||
(global-set-key (kbd "C-c C-SPC ") 'mc/mark-all-like-this)
|
||||
|
||||
;; Reload FG42
|
||||
(define-key global-map (kbd "C-<f5>") 'fg42-reload)
|
||||
|
||||
;; Key Chord ------------------------------------------------
|
||||
;; (require 'key-chord)
|
||||
;; (key-chord-mode 1)
|
||||
|
||||
;; (key-chord-define-global "hj" 'undo)
|
||||
;; (key-chord-define-global "kl" 'right-word)
|
||||
;; (key-chord-define-global "sd" 'left-word)
|
||||
;; (key-chord-define-global "m," 'forward-paragraph)
|
||||
;; (key-chord-define-global "p[" 'backward-paragraph)
|
||||
|
||||
;; HideShow -------------------------------------------------------
|
||||
(global-set-key (kbd "C-\-") 'hs-toggle-hiding)
|
||||
(hs-minor-mode)
|
||||
|
||||
;; Guru Configuration
|
||||
(ability guru ()
|
||||
(require 'guru-mode)
|
||||
(guru-global-mode +1))
|
||||
|
||||
;; IDO configurations ---------------------------------------------
|
||||
(ability ido ()
|
||||
(require 'ido)
|
||||
(require 'flx-ido)
|
||||
(require 'ido-vertical-mode)
|
||||
|
||||
(ido-everywhere t)
|
||||
|
||||
(require 'ido-completing-read+)
|
||||
(ido-ubiquitous-mode 1)
|
||||
|
||||
(ido-mode t)
|
||||
|
||||
(ability smex ()
|
||||
(smex-initialize)
|
||||
(global-set-key (kbd "M-x") 'smex))
|
||||
|
||||
(flx-ido-mode 1)
|
||||
(setq ido-use-faces nil)
|
||||
(setq ido-use-filename-at-point nil)
|
||||
(setq ido-enable-flex-matching t)
|
||||
(ido-vertical-mode 1))
|
||||
|
||||
(ability selectrum ()
|
||||
"Selectrum is a better replacement for IDO and Ivy"
|
||||
(require 'selectrum)
|
||||
(require 'selectrum-prescient)
|
||||
|
||||
(selectrum-mode +1)
|
||||
(selectrum-prescient-mode +1)
|
||||
(prescient-persist-mode +1)
|
||||
(when-not-wm
|
||||
(require 'ctrlf)
|
||||
(ctrlf-mode +1))
|
||||
(setq prescient-filter-method '(literal fuzzy regexp initialism)))
|
||||
|
||||
(ability ivy ()
|
||||
"Completion using ivy."
|
||||
(require 'ivy)
|
||||
(require 'counsel)
|
||||
|
||||
(ivy-mode 1)
|
||||
|
||||
(setq ivy-use-virtual-buffers t)
|
||||
(setq enable-recursive-minibuffers t)
|
||||
(global-set-key (kbd "M-x") 'counsel-M-x)
|
||||
|
||||
(global-set-key (kbd "<f1> f") 'counsel-describe-function)
|
||||
(global-set-key (kbd "<f1> v") 'counsel-describe-variable)
|
||||
(global-set-key (kbd "<f1> l") 'counsel-find-library)
|
||||
(global-set-key (kbd "C-c k") 'counsel-ag)
|
||||
(global-set-key (kbd "C-c C-r") 'ivy-resume))
|
||||
|
||||
;; Swiper ---------------------------------------------------
|
||||
(ability swiper (ivy)
|
||||
"Replace default isearch with swiper"
|
||||
(global-set-key "\C-s" 'swiper)
|
||||
(global-set-key "\C-r" 'swiper))
|
||||
;; (with-ability ido
|
||||
;; (global-set-key (kbd "C-x b") 'ido-switch-buffer)))
|
||||
|
||||
(ability tabbar ()
|
||||
(tabbar-mode 1))
|
||||
;; Helm -----------------------------------------------------
|
||||
(ability helm ()
|
||||
"Helm is an emacs incremental completion and selection narrowing framework"
|
||||
(require 'helm)
|
||||
(require 'helm-flx)
|
||||
(global-set-key (kbd "C-c h") 'helm-command-prefix)
|
||||
(global-set-key (kbd "M-x") 'helm-M-x)
|
||||
(global-set-key (kbd "C-x C-f") 'helm-find-files)
|
||||
(global-unset-key (kbd "C-x c"))
|
||||
|
||||
(define-key helm-map (kbd "<tab>")
|
||||
'helm-execute-persistent-action)
|
||||
|
||||
(define-key helm-map (kbd "C-i")
|
||||
'helm-execute-persistent-action)
|
||||
|
||||
(define-key helm-map (kbd "C-z")
|
||||
'helm-select-action)
|
||||
|
||||
|
||||
|
||||
(when (executable-find "curl")
|
||||
(setq helm-google-suggest-use-curl-p t))
|
||||
|
||||
(setq helm-split-window-in-side-p t
|
||||
helm-move-to-line-cycle-in-source t
|
||||
helm-ff-search-library-in-sexp t
|
||||
helm-scroll-amount 8
|
||||
helm-ff-file-name-history-use-recentf t)
|
||||
|
||||
(setq helm-flx-for-helm-find-files t
|
||||
helm-flx-for-helm-locate t)
|
||||
|
||||
(helm-flx-mode +1)
|
||||
(helm-mode 1))
|
||||
|
||||
;; Session Management ---------------------------------------
|
||||
(ability desktop-mode ()
|
||||
"Save your current working buffers and restore later"
|
||||
(desktop-save-mode 1))
|
||||
|
||||
(ability emoji ()
|
||||
"Adds support for emoji support in FG42. (github style)"
|
||||
(require 'emojify)
|
||||
(add-hook 'after-init-hook #'global-emojify-mode))
|
||||
|
||||
(set-fontset-font "fontset-default"
|
||||
(cons (decode-char 'ucs #x0627)
|
||||
(decode-char 'ucs #x0649))
|
||||
"Vazir")
|
||||
|
||||
(set-fontset-font "fontset-default"
|
||||
(cons (decode-char 'ucs #xFE8D)
|
||||
(decode-char 'ucs #xFEF0))
|
||||
"Vazir")
|
||||
|
||||
(set-fontset-font "fontset-default"
|
||||
(cons (decode-char 'ucs #x064e)
|
||||
(decode-char 'ucs #x06a9))
|
||||
"Vazir")
|
||||
|
||||
(set-fontset-font "fontset-default"
|
||||
(cons (decode-char 'ucs #x06F0)
|
||||
(decode-char 'ucs #x00A0))
|
||||
"Vazir")
|
||||
;; Backup files ---------------------------------------------
|
||||
(ability backup-files ()
|
||||
;; Put them in one nice place if possible
|
||||
(if (file-directory-p "~/.backup")
|
||||
(setq backup-directory-alist '(("~/.backup")))
|
||||
(make-directory "~/.backup"))
|
||||
(setq backup-by-copying t))
|
||||
|
||||
(ability versioned-backup ('backup-files)
|
||||
(setq delete-old-versions t)
|
||||
(setq version-control t)
|
||||
(setq kept-new-versions 3)
|
||||
(setq kept-old-versions 2))
|
||||
|
||||
;; get rid of yes-or-no questions - y or n is enough
|
||||
(defalias 'yes-or-no-p 'y-or-n-p)
|
||||
|
||||
(setup-utils)
|
||||
|
||||
(setq my-path (file-name-directory load-file-name))
|
||||
;; Load about submenu
|
||||
(require 'extensions/editor/version)
|
||||
(require 'extensions/editor/about)
|
||||
(require 'extensions/editor/custom)
|
||||
(require 'extensions/editor/session-management)
|
||||
(require 'extensions/editor/lxdrive-mode)
|
||||
(require 'extensions/editor/lxmodeline)
|
||||
(message "'editor' extension has been initialized."))
|
||||
|
||||
(provide 'extensions/editor/init)
|
||||
;;; init.el ends here
|
|
@ -1,94 +0,0 @@
|
|||
;;; lxdrive-mode --- A minor mode for fast cursor movement
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'expand-region)
|
||||
|
||||
(setq original-global-map global-map)
|
||||
(boundp 'lxdrive-minor-mode)
|
||||
|
||||
(defun turn-off-lxdrive ()
|
||||
"Toggle lxdrive mode."
|
||||
(interactive)
|
||||
(lxdrive-minor-mode nil)
|
||||
(setq lxdrive-minor-mode nil)
|
||||
(use-global-map original-global-map))
|
||||
|
||||
(defun turn-on-lxdrive ()
|
||||
"Toggle lxdrive mode."
|
||||
(interactive)
|
||||
(lxdrive-minor-mode t)
|
||||
(use-global-map lxdrive-mode-map))
|
||||
|
||||
(defun turn-off-and-command ()
|
||||
"Turn off the lxdrive mode and run the counsel command."
|
||||
(interactive)
|
||||
(turn-off-lxdrive)
|
||||
(counsel-M-x))
|
||||
|
||||
(defun switch-other ()
|
||||
"Switch to the most recent buffer."
|
||||
(interactive)
|
||||
(switch-to-buffer (other-buffer)))
|
||||
|
||||
|
||||
(defvar lxdrive-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
;; Movement
|
||||
(define-key map (kbd "l") 'forward-char)
|
||||
(define-key map (kbd "j") 'backward-char)
|
||||
(define-key map (kbd "i") 'previous-line)
|
||||
(define-key map (kbd "k") 'next-line)
|
||||
(define-key map (kbd "u") 'backward-word)
|
||||
(define-key map (kbd "o") 'forward-word)
|
||||
(define-key map (kbd "n") 'backward-paragraph)
|
||||
(define-key map (kbd "m") 'forward-paragraph)
|
||||
(define-key map (kbd "TAB") 'indent-for-tab-command)
|
||||
(define-key map (kbd "`") 'cua-set-mark)
|
||||
(define-key map (kbd "=") 'er/expand-region)
|
||||
(define-key map (kbd "]") 'forward-page)
|
||||
(define-key map (kbd "[") 'backward-page)
|
||||
(define-key map (kbd "e") 'move-end-of-line)
|
||||
(define-key map (kbd "a") 'move-beginning-of-line)
|
||||
(define-key map (kbd "<f2>") 'go-to-line)
|
||||
(define-key map (kbd "C-TAB") 'other-window)
|
||||
(define-key map (kbd "M-TAB") 'switch-other)
|
||||
|
||||
;; Actions
|
||||
(define-key map (kbd "RET") 'newline)
|
||||
(define-key map (kbd "d") 'delete-char)
|
||||
(define-key map (kbd "<backspace>") 'delete-backward-char)
|
||||
(define-key map (kbd "y") 'cua-paste)
|
||||
(define-key map (kbd "C-w") 'kill-region)
|
||||
(define-key map (kbd "M-w") 'kill-ring-save)
|
||||
|
||||
(define-key map (kbd "h") 'kill-and-join-forward)
|
||||
|
||||
(define-key map (kbd "g") 'keyboard-quit)
|
||||
(define-key map (kbd "z") 'undo)
|
||||
(define-key map (kbd "/") 'undo)
|
||||
|
||||
(define-key map (kbd "M-x") 'turn-off-and-command)
|
||||
(define-key map (kbd "C-x C-s") 'save-buffer)
|
||||
(define-key map (kbd "SPC") 'self-insert-command)
|
||||
|
||||
;;(define-key map (kbd "ESC ESC") 'turn-off-lxdrive)
|
||||
(define-key map (kbd "q") 'turn-off-lxdrive)
|
||||
(define-key map (kbd "M-SPC") 'turn-off-lxdrive)
|
||||
|
||||
map)
|
||||
"Keymap for lxdrive-minor-mode.")
|
||||
|
||||
(define-minor-mode lxdrive-minor-mode
|
||||
"A minor mode so that my key settings override annoying major modes."
|
||||
:global t
|
||||
:lighter " lx")
|
||||
|
||||
;;(global-set-key (kbd "ESC ESC") 'turn-on-lxdrive)
|
||||
(global-set-key (kbd "M-SPC") 'turn-on-lxdrive)
|
||||
(global-set-key (kbd "M-TAB") 'switch-other)
|
||||
(with-ability spaceline
|
||||
(spaceline-toggle-lxdrive-on))
|
||||
|
||||
(provide 'extensions/editor/lxdrive-mode)
|
||||
;;; lxdrive-mode ends here
|
|
@ -1,33 +0,0 @@
|
|||
;;; lxmode-line --- A small utility library to toggle the modeline.
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
;; (require 'doom-modeline)
|
||||
|
||||
;; (doom-modeline-def-segment lxdrive-info
|
||||
;; "Show the status of lxdrive mode"
|
||||
;; (if (and (boundp 'lxdrive-minor-mode) lxdrive-minor-mode)
|
||||
;; (list " " (all-the-icons-faicon "arrows" :height 0.8 :v-adjust 0.15 :face 'all-the-icons-lgreen))
|
||||
;; (list " " (all-the-icons-faicon "pencil" :height 0.8 :v-adjust 0.15))))
|
||||
|
||||
|
||||
;; (doom-modeline-def-modeline 'fg42-mode-line
|
||||
;; '(bar lxdrive-info matches buffer-info buffer-position parrot selection-info)
|
||||
;; '(process vcs checker))
|
||||
|
||||
|
||||
;; (defun setup-custom-doom-modeline ()
|
||||
;; "Setup fg42 modeline."
|
||||
;; (doom-modeline-set-modeline 'fg42-mode-line 'default))
|
||||
|
||||
;; (with-ability doom-modeline
|
||||
;; (add-hook 'doom-modeline-mode-hook 'setup-custom-doom-modeline)
|
||||
;; (setq doom-modeline-height 15)
|
||||
;; (setq doom-modeline-buffer-encoding nil)
|
||||
;; (setq doom-modeline-lsp nil)
|
||||
;; (setq doom-modeline-mu4e nil)
|
||||
;; (setq doom-modeline-irc nil)
|
||||
;; (setq doom-modeline-buffer-file-name-style 'truncate-with-project)
|
||||
;; (doom-modeline-mode t))
|
||||
|
||||
(provide 'extensions/editor/lxmodeline)
|
||||
;;; lxmodeline ends here
|
|
@ -1,47 +0,0 @@
|
|||
;; ---------------------------------------------------------------------
|
||||
;; Variables
|
||||
;; ---------------------------------------------------------------------
|
||||
(defvar my-desktop-session-dir
|
||||
(concat (getenv "HOME") "/.tmp/")
|
||||
"*Directory to save desktop sessions in")
|
||||
|
||||
(defvar my-desktop-session-name-hist nil
|
||||
"Desktop session name history")
|
||||
|
||||
|
||||
;; ---------------------------------------------------------------------
|
||||
;; Functions
|
||||
;; ---------------------------------------------------------------------
|
||||
|
||||
(defun my-desktop-save (&optional name)
|
||||
"Save desktop with a name."
|
||||
(interactive)
|
||||
(unless name
|
||||
(setq name (my-desktop-get-session-name "Save session as: ")))
|
||||
(make-directory (concat my-desktop-session-dir name) t)
|
||||
(desktop-save (concat my-desktop-session-dir name) t))
|
||||
|
||||
(defun my-desktop-read (&optional name)
|
||||
"Read desktop with a name."
|
||||
(interactive)
|
||||
(unless name
|
||||
(setq name (my-desktop-get-session-name "Load session: ")))
|
||||
(desktop-read (concat my-desktop-session-dir name)))
|
||||
|
||||
(defun my-desktop-get-session-name (prompt)
|
||||
(completing-read prompt (and (file-exists-p my-desktop-session-dir)
|
||||
(directory-files my-desktop-session-dir))
|
||||
nil nil nil my-desktop-session-name-hist))
|
||||
|
||||
(define-key-after global-map
|
||||
[menu-bar file load-session] '("Load Session" . my-desktop-read)
|
||||
'dired)
|
||||
|
||||
(define-key-after
|
||||
global-map [menu-bar file save-session]
|
||||
'("Save Session" . my-desktop-save) 'load-session)
|
||||
|
||||
(define-key global-map (kbd "<f11>") 'my-desktop-read)
|
||||
(define-key global-map (kbd "<f12>") 'my-desktop-save)
|
||||
|
||||
(provide 'extensions/editor/session-management)
|
|
@ -1,45 +0,0 @@
|
|||
;; Functions -----------------------------
|
||||
;;;###autoload
|
||||
(defun comment-dwim-line (&optional arg)
|
||||
"Replacement for the comment-dwim command.
|
||||
If no region is selected and current line is
|
||||
not blank and we are not at the end of the line,
|
||||
then comment current line.
|
||||
Replaces default behaviour of comment-dwim, when
|
||||
it inserts comment at the end of the line."
|
||||
|
||||
;; Original idea from
|
||||
;; http://www.opensubscriber.com/message/emacs-devel@gnu.org/10971693.html
|
||||
|
||||
(interactive "*P")
|
||||
(comment-normalize-vars)
|
||||
(if (and (not (region-active-p))
|
||||
(not (looking-at "[ \t]*$")))
|
||||
(comment-or-uncomment-region (line-beginning-position)
|
||||
(line-end-position))
|
||||
(comment-dwim arg)))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun kill-and-join-forward (&optional arg)
|
||||
"If at end of line, join with following; otherwise kill line.
|
||||
Deletes whitespace at join.
|
||||
http://www.emacswiki.org/emacs/AutoIndentation"
|
||||
(interactive "P")
|
||||
(if (and (eolp) (not (bolp)))
|
||||
(progn (forward-char 1)
|
||||
(just-one-space 0)
|
||||
(backward-char 1)
|
||||
(kill-line arg))
|
||||
(kill-line arg)))
|
||||
|
||||
;;;###autoload
|
||||
(defun setup-utils ()
|
||||
"Setup several utitlies for FG42"
|
||||
(global-set-key (kbd "C-k") 'kill-and-join-forward)
|
||||
(global-set-key (kbd "M-;") 'comment-dwim-line)
|
||||
(global-set-key (kbd "M-j") (lambda ()
|
||||
(interactive) (join-line -1))))
|
||||
|
||||
|
||||
(provide 'extensions/editor/utils)
|
|
@ -1,4 +0,0 @@
|
|||
(defconst FG42-VERSION "2.31.0"
|
||||
"Global version of FG42")
|
||||
|
||||
(provide 'extensions/editor/version)
|
|
@ -1,22 +0,0 @@
|
|||
;;; GoExtention --- Enable Golang support in FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/go/init)
|
||||
|
||||
;; dependencies
|
||||
|
||||
(depends-on 'go-mode)
|
||||
(depends-on 'go-add-tags)
|
||||
(depends-on 'go-stacktracer)
|
||||
(depends-on 'gotest)
|
||||
(depends-on 'exec-path-from-shell)
|
||||
|
||||
|
||||
(extension go
|
||||
:version 0.0.1
|
||||
:on-initialize extensions/go-initialize
|
||||
:docs "lib/extensions/go/readme.org")
|
||||
(provide 'extensions/go)
|
||||
;;; go.el ends here
|
|
@ -1,40 +0,0 @@
|
|||
;;; go-init --- The entry point for golang extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(defun fg42-go-hook ()
|
||||
;; move to action
|
||||
"Set's up emacs hooks and turn necessary modes on."
|
||||
(lsp-register-custom-settings
|
||||
'(("gopls.completeUnimported" t t)
|
||||
("gopls.staticcheck" t t)))
|
||||
(setq lsp-headerline-breadcrumb-enable nil)
|
||||
(lsp)
|
||||
(with-ability yas
|
||||
(yas-minor-mode-on))
|
||||
(setq-local company-backends '(company-capf company-dabbrev company-dabbrev-code))
|
||||
(add-hook 'before-save-hook #'lsp-format-buffer t t)
|
||||
(add-hook 'before-save-hook #'lsp-organize-imports t t)
|
||||
;; (add-hook 'before-save-hook #'eglot-format t t)
|
||||
;; (add-hook 'before-save-hook #' t t)
|
||||
|
||||
(local-set-key (kbd "M-.") #'godef-jump)
|
||||
(local-set-key (kbd "M-*") 'pop-tag-mark))
|
||||
|
||||
|
||||
|
||||
(defun go-path ()
|
||||
"Gets gopath from OS env."
|
||||
(exec-path-from-shell-copy-env "GOPATH"))
|
||||
(defun go-path-binary ()
|
||||
"Gets Go binaries path."
|
||||
(concat (go-path) "/bin"))
|
||||
|
||||
(defun extensions/go-initialize ()
|
||||
"Initialize Golang extension."
|
||||
(exec-path-from-shell-initialize)
|
||||
(add-to-list 'exec-path (go-path-binary))
|
||||
(add-hook 'go-mode-hook 'fg42-go-hook))
|
||||
|
||||
(provide 'extensions/go/init)
|
||||
;;; init ends here.
|
|
@ -1,23 +0,0 @@
|
|||
;;; GodotExtension --- Godot Game engine development in FG42.
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/godot/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'gdscript-mode)
|
||||
|
||||
|
||||
(defun godot-doc ()
|
||||
"TBD"
|
||||
"TBD")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension godot
|
||||
:version "2.32"
|
||||
:on-initialize extensions/godot-initialize
|
||||
:docs "lib/extensions/godot/readme.org")
|
||||
|
||||
(provide 'extensions/godot)
|
||||
;;; godot.el ends here
|
|
@ -1,19 +0,0 @@
|
|||
;;; Godot --- Enables Godot game engine integration with FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;; (defun setup-gdscript()
|
||||
;; (setq-default indent-tabs-mode nil)
|
||||
;; (setq tab-width 2)
|
||||
;; (setq gdscript-tabs-mode t)
|
||||
;; (setq gdscript-tab-width 2))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/godot-initialize ()
|
||||
(add-to-list 'auto-mode-alist '("\\.gd$" . gdscript-mode))
|
||||
(add-hook 'gdscript-mode-hook 'lsp))
|
||||
|
||||
|
||||
(provide 'extensions/godot/init)
|
||||
;;; init.el ends here
|
|
@ -1,22 +0,0 @@
|
|||
;;; HaskellExtension --- Enables haskell development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/haskell/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'haskell-mode)
|
||||
|
||||
|
||||
(defun haskell-doc ()
|
||||
"something fun")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension haskell
|
||||
:version "2.32"
|
||||
:on-initialize extensions/haskell-initialize
|
||||
:docs "lib/extensions/haskell/readme.org")
|
||||
|
||||
(provide 'extensions/haskell)
|
||||
;;; haskell.el ends here
|
|
@ -1,11 +0,0 @@
|
|||
;;; HaskellExtension --- Enables haskell development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/haskell-initialize ())
|
||||
|
||||
|
||||
|
||||
(provide 'extensions/haskell/init)
|
||||
;; init.el ends here
|
|
@ -1,22 +0,0 @@
|
|||
;;; IRCExtension --- Enables irc client on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/irc/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'rcirc-notify)
|
||||
|
||||
(defun irc-doc ()
|
||||
"TBD"
|
||||
"TBD")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension irc
|
||||
:version "2.32"
|
||||
:on-initialize extensions/irc-initialize
|
||||
:docs "lib/extensions/irc/readme.org")
|
||||
|
||||
(provide 'extensions/irc)
|
||||
;;; irc.el ends here
|
|
@ -1,80 +0,0 @@
|
|||
;;; IRCExtension --- Enables irc client on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defvar irc-servers
|
||||
'(("irc.freenode.net"
|
||||
:port 6697
|
||||
:encryption tls
|
||||
:channels ("#5hit")))
|
||||
"A list of servers and channels to connect to.")
|
||||
|
||||
(defvar irc-auth nil
|
||||
"The irc authentication credentials.
|
||||
This would overridethe default behaviour which is based onauth-sources.")
|
||||
|
||||
(defvar irc-nickname "fg42-user"
|
||||
"The default nickname for irc. ")
|
||||
|
||||
(defun irc/extract-secrets-from-auth-source ()
|
||||
"Extract the irc authenticate data from the auth-sources.
|
||||
|
||||
As an example for ~/.authinfo.gpg should contain:
|
||||
|
||||
machine freenode login <nickname> port nickserv password <password>
|
||||
|
||||
Also the auth-sources should be set correctly.
|
||||
It returns nil if no password is available."
|
||||
(let ((auth-list '()))
|
||||
(dolist (p (auth-source-search :port '("nickserv")
|
||||
:require '(:port :user :secret)))
|
||||
(let ((secret (plist-get p :secret))
|
||||
(method (intern (plist-get p :port))))
|
||||
|
||||
(add-to-list 'auth-list
|
||||
(list (plist-get p :host)
|
||||
method
|
||||
(plist-get p :user)
|
||||
(if (functionp secret)
|
||||
(funcall secret)
|
||||
secret)))))
|
||||
auth-list))
|
||||
|
||||
;;;###autoload
|
||||
(defun irc/setup ()
|
||||
"Setup the rcirc library which distributes with Emacs."
|
||||
(set (make-local-variable 'scroll-conservatively) 8192)
|
||||
(setq gnutls-min-prime-bits 2048))
|
||||
|
||||
(defun irc/connect ()
|
||||
"Connects to IRC."
|
||||
(interactive)
|
||||
(require 'rcirc)
|
||||
(require 'rcirc-notify)
|
||||
|
||||
;; Turns off keychain integration
|
||||
(setenv "GPG_AGENT_INFO" nil)
|
||||
|
||||
;; Turn on debugging if the global debuging was enabled
|
||||
(setq rcirc-debug-flag debug-on-error)
|
||||
(setq rcirc-server-alist irc-servers)
|
||||
(setq rcirc-authinfo (or (irc/extract-secrets-from-auth-source)
|
||||
irc-auth))
|
||||
(setq rcirc-default-nick irc-nickname)
|
||||
(rcirc-notify-add-hooks)
|
||||
(rcirc-track-minor-mode 1)
|
||||
(rcirc nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/irc-initialize ()
|
||||
"Initialize the irc extention."
|
||||
|
||||
;; Keep input line at bottom.
|
||||
(add-hook 'rcirc-mode-hook 'irc/setup)
|
||||
|
||||
(ability irc-spell-checking ()
|
||||
(add-hook 'rcirc-mode-hook (lambda ()
|
||||
(flyspell-mode 1)))))
|
||||
;
|
||||
|
||||
(provide 'extensions/irc/init)
|
||||
;;; init.el ends here
|
|
@ -1,31 +0,0 @@
|
|||
;;; JavaExtension --- Enables java development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/java/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
|
||||
(depends-on 'gradle-mode)
|
||||
(depends-on 'flycheck-gradle)
|
||||
|
||||
(depends-on 'groovy-mode)
|
||||
|
||||
(with-ability lsp-java
|
||||
(depends-on 'lsp-java))
|
||||
;;(depends-on 'dap-java))
|
||||
|
||||
|
||||
(defun java-doc ()
|
||||
"TBD")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension java
|
||||
:version "2.32"
|
||||
:on-initialize extensions/java-initialize
|
||||
:docs "lib/extensions/java/readme.org")
|
||||
|
||||
(provide 'extensions/java)
|
||||
;;; java.el ends here
|
|
@ -1,28 +0,0 @@
|
|||
;;; java-init --- The entry point for common lisp extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/java-initialize ()
|
||||
"Initialize the common Lisp extension."
|
||||
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.gradle\\'" . groovy-mode))
|
||||
|
||||
(require 'gradle-mode)
|
||||
(add-hook 'java-mode-hook
|
||||
'(lambda()
|
||||
;; To fix the indentation of function arguments
|
||||
(c-set-offset 'arglist-intro '+)
|
||||
(setq java-basic-offset 2)
|
||||
(setq c-basic-offset 2)
|
||||
(ability lsp-java ('lsp)
|
||||
(setq lsp-java-server-install-dir fg42-tmp)
|
||||
(lsp))
|
||||
(ability dap-java ('dap)
|
||||
(require 'dap-java))
|
||||
(gradle-mode 1))))
|
||||
|
||||
|
||||
(provide 'extensions/java/init)
|
||||
;;; init ends here
|
|
@ -1,30 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/javascript/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'coffee-mode)
|
||||
(depends-on 'js2-mode)
|
||||
(depends-on 'rjsx-mode)
|
||||
(depends-on 'js2-refactor)
|
||||
(depends-on 'smart-forward)
|
||||
(depends-on 'ac-js2)
|
||||
(depends-on 'pug-mode)
|
||||
|
||||
(with-ability prettierjs
|
||||
(depends-on 'prettier-js))
|
||||
|
||||
;;(depends-on 'tern)
|
||||
(with-ability indium
|
||||
(depends-on 'indium))
|
||||
|
||||
|
||||
(depends-on 'company-web)
|
||||
(depends-on 'jquery-doc)
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension javascript
|
||||
:version "2.31"
|
||||
:on-initialize extensions/javascript-initialize)
|
||||
|
||||
(provide 'extensions/javascript)
|
|
@ -1,74 +0,0 @@
|
|||
;; Functions -------------------------------------------------
|
||||
|
||||
;;;###autoload
|
||||
(defun js2-careless-semicolon ()
|
||||
"Don't give a shit about semicolons. According to javascript's bullshit standard."
|
||||
(interactive)
|
||||
(setq js2-strict-missing-semi-warning nil)
|
||||
(js2-mode))
|
||||
|
||||
;;;###autoload
|
||||
(defun javascript-callback ()
|
||||
(require 'jquery-doc)
|
||||
|
||||
(js2-minor-mode t)
|
||||
;; FIXME: don't hard code the indent size
|
||||
(setq js2-basic-offset 2)
|
||||
|
||||
(define-key js2-mode-map (kbd "C-c C-d") 'js2-jump-to-definition)
|
||||
|
||||
(require 'company-web-jade)
|
||||
(define-key js2-mode-map (kbd "C-'") 'company-web-jade)
|
||||
|
||||
(jquery-doc-setup))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/javascript-initialize ()
|
||||
"Javascript development plugin initialization."
|
||||
|
||||
(ability indium ()
|
||||
(defun init-indium ()
|
||||
(interactive)
|
||||
(require 'indium))
|
||||
(add-hook 'js2-mode-hook #'init-indium)
|
||||
;(add-hook 'js2-mode-hook #'jade-interaction-mode)
|
||||
)
|
||||
|
||||
(ability js-complition ()
|
||||
(require 'ac-js2)
|
||||
(add-to-list 'company-backends 'ac-js2-company))
|
||||
|
||||
(with-ability pug-editor ()
|
||||
"Pug template editor."
|
||||
(setq pug-tab-width 2)
|
||||
(add-to-list 'auto-mode-alist '("\\.pug\\'" . (lambda ()
|
||||
(require 'pug-mode)
|
||||
(pug-mode)
|
||||
(setq pug-tab-width 2)))))
|
||||
|
||||
(ability javascript-editor ('flycheck)
|
||||
"Gives FG42 the ability to edit javascript."
|
||||
|
||||
(autoload 'js2-mode "js2-mode" "Javascript mode")
|
||||
;(autoload 'tern-mode "tern.el" nil t)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.js\\'" . rjsx-mode))
|
||||
;(add-to-list 'auto-mode-alist '("\\.jsx\\'" . js2-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.json\\'" . js2-mode))
|
||||
|
||||
(add-hook 'js2-mode-hook 'javascript-callback)
|
||||
|
||||
(setq js2-highlight-level 3)
|
||||
|
||||
(require 'smart-forward)
|
||||
(global-set-key (kbd "M-<up>") 'smart-up)
|
||||
(global-set-key (kbd "M-<down>") 'smart-down)
|
||||
(global-set-key (kbd "M-<left>") 'smart-backward)
|
||||
(global-set-key (kbd "M-<right>") 'smart-forward))
|
||||
|
||||
(ability coffee-editor ()
|
||||
"Gives FG42 ability to edit coffee script files."
|
||||
(custom-set-variables '(coffee-tab-width 2)))
|
||||
(message "'javascript' extension has been initialized."))
|
||||
|
||||
(provide 'extensions/javascript/init)
|
|
@ -1,21 +0,0 @@
|
|||
;;; latex-extension --- Latex extension for FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/latex/init)
|
||||
|
||||
;TODO: add to MELPA and remove lsp-latex.el file beside init.el
|
||||
;(with-ability lsp-latex (depends-on 'lsp-latex))
|
||||
|
||||
(defun latex-doc ()
|
||||
"something fun")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension latex
|
||||
:version "2."
|
||||
:on-initialize extensions/latex-initialize
|
||||
:docs "lib/extensions/latex/readme.org")
|
||||
|
||||
(provide 'extensions/latex)
|
||||
;;; latex.el ends here
|
|
@ -1,19 +0,0 @@
|
|||
;;; latex-init --- The entry point for latex extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defun latex-run-lsp ()
|
||||
(interactive)
|
||||
"Run lsp-mode and set the texlab executable path."
|
||||
(require 'extensions/latex/lsp-latex)
|
||||
(setq lsp-latex-texlab-executable "texlab")
|
||||
(lsp))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/latex-initialize ()
|
||||
"Latex autocompletion support."
|
||||
(ability lsp-latex ('lsp)
|
||||
(add-hook 'tex-mode-hook 'latex-run-lsp)))
|
||||
|
||||
(provide 'extensions/latex/init)
|
||||
;;; init.el ends here
|
|
@ -1,134 +0,0 @@
|
|||
;;; lsp-latex.el --- lsp-mode client for LaTeX. -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2019 ROCKTAKEY
|
||||
|
||||
;; Author: ROCKTAKEY <rocktakey@gmail.com>
|
||||
;; Keywords: languages, extensions, tex
|
||||
|
||||
;; Version: 1.0.0
|
||||
|
||||
;; Package-Requires: ((emacs "25.1") (lsp-mode "6.0"))
|
||||
|
||||
;; 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
(require 'lsp-mode)
|
||||
|
||||
(defgroup lsp-latex nil
|
||||
"Language Server Protocol client for LaTeX."
|
||||
:group 'lsp-mode)
|
||||
|
||||
|
||||
;; Under texlab v1.0
|
||||
|
||||
(defcustom lsp-latex-java-executable "java"
|
||||
"Executable command to run Java.
|
||||
This is used with `lsp-latex-java-argument-list'."
|
||||
:group 'lsp-latex
|
||||
:type 'string)
|
||||
|
||||
(defcustom lsp-latex-java-argument-list '("-jar")
|
||||
"List of arguments passed to `lsp-latex-java-executable'."
|
||||
:group 'lsp-latex
|
||||
:risky t
|
||||
:type '(repeat string))
|
||||
|
||||
(defcustom lsp-latex-texlab-jar-file 'search-from-exec-path
|
||||
"File named \"texlab.jar\".
|
||||
You can install it from https://github.com/latex-lsp/texlab/releases/tag/v0.4.1 .
|
||||
|
||||
The value can be a string (path to \"texlab.jar\") or the symbol search-from-exec-path. See the docstring of `lsp-latex-get-texlab-jar-file'."
|
||||
:group 'lsp-latex
|
||||
:type '(choice string (const search-from-exec-path)))
|
||||
|
||||
(defcustom lsp-latex-texlab-jar-argument-list '()
|
||||
"List of arguments passed to `lsp-latex-texlab-jar-file'. "
|
||||
:group 'lsp-latex
|
||||
:type '(repeat string))
|
||||
|
||||
(defun lsp-latex-get-texlab-jar-file ()
|
||||
"Return the path to \"texlab.jar\".
|
||||
|
||||
If `lsp-latex-texlab-jar-file' is a string, return it.
|
||||
If `lsp-latex-texlab-jar-file' is the symbol search-from-exec-path, then search a file named \"texlab.jar\" from `exec-path'."
|
||||
(cond
|
||||
((stringp lsp-latex-texlab-jar-file)
|
||||
lsp-latex-texlab-jar-file)
|
||||
((eq lsp-latex-texlab-jar-file 'search-from-exec-path)
|
||||
(locate-file "texlab.jar" exec-path))
|
||||
(t (error "invalid value of `lsp-latex-texlab-jar-file'"))))
|
||||
|
||||
|
||||
;; texlab v1.0 or more
|
||||
|
||||
(defcustom lsp-latex-texlab-executable
|
||||
(cond ((eq system-type 'windows-nt)
|
||||
"texlab.exe")
|
||||
(t "texlab"))
|
||||
"Exeucutable command to run texlab.
|
||||
Runned with the arguments `lsp-latex-texlab-executable-argument-list'."
|
||||
:group 'lsp-latex
|
||||
:type 'string)
|
||||
|
||||
(defcustom lsp-latex-texlab-executable-argument-list '()
|
||||
"list of Arguments passed to `lsp-latex-texlab-executable'."
|
||||
:group 'lsp-latex
|
||||
:type '(repeat string))
|
||||
|
||||
|
||||
|
||||
(add-to-list 'lsp-language-id-configuration '(".*\\.tex$" . "latex"))
|
||||
|
||||
(defun lsp-latex-new-connection ()
|
||||
""
|
||||
(let (jar-file)
|
||||
(cond
|
||||
((locate-file lsp-latex-texlab-executable exec-path)
|
||||
(cons lsp-latex-texlab-executable
|
||||
lsp-latex-texlab-executable-argument-list))
|
||||
((setq jar-file (lsp-latex-get-texlab-jar-file))
|
||||
(append
|
||||
(cons
|
||||
lsp-latex-java-executable
|
||||
lsp-latex-java-argument-list)
|
||||
(cons
|
||||
jar-file
|
||||
lsp-latex-texlab-jar-argument-list)))
|
||||
(t
|
||||
(error "No executable \"texlab\" file")))))
|
||||
|
||||
;; Copied from `lsp-clients--rust-window-progress' in `lsp-rust'.
|
||||
(defun lsp-latex-window-progress (_workspace params)
|
||||
"Progress report handling.
|
||||
PARAMS progress report notification data."
|
||||
;; Minimal implementation - we could show the progress as well.
|
||||
(lsp-log (gethash "title" params)))
|
||||
|
||||
(lsp-register-client
|
||||
(make-lsp-client :new-connection
|
||||
(lsp-stdio-connection
|
||||
#'lsp-latex-new-connection)
|
||||
:major-modes '(tex-mode yatex-mode latex-mode)
|
||||
:server-id 'texlab
|
||||
:notification-handlers
|
||||
(lsp-ht
|
||||
("window/progress"
|
||||
'lsp-latex-window-progress))))
|
||||
|
||||
(provide 'extensions/latex/lsp-latex)
|
||||
;;; lsp-latex.el ends here
|
|
@ -1,17 +0,0 @@
|
|||
;;; LuaExtention --- Enable Lua support in FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/lua/init)
|
||||
|
||||
;; dependencies
|
||||
(depends-on 'lua-mode)
|
||||
|
||||
|
||||
(extension lua
|
||||
:version 0.0.1
|
||||
:on-initialize extensions/lua-initialize
|
||||
:docs "lib/extensions/lua/readme.org")
|
||||
(provide 'extensions/lua)
|
||||
;;; lua.el ends here
|
|
@ -1,9 +0,0 @@
|
|||
;;; lua-init --- The entry point for lua extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defun extensions/lua-initialize ()
|
||||
"Initialize lua extension.")
|
||||
|
||||
|
||||
(provide 'extensions/lua/init)
|
||||
;;; init ends here.
|
|
@ -1,22 +0,0 @@
|
|||
;;; OrgExtention --- Enable org-mode support in FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/org/init)
|
||||
|
||||
;; dependencies
|
||||
(depends-on 'org)
|
||||
(depends-on 'org-bullets)
|
||||
(depends-on 'org-ql)
|
||||
(depends-on 'org-roam)
|
||||
(depends-on 'org-make-toc)
|
||||
(depends-on 'org-timeline)
|
||||
|
||||
|
||||
(extension org
|
||||
:version 0.0.1
|
||||
:on-initialize extensions/org-initialize
|
||||
:docs "lib/extensions/org/readme.org")
|
||||
(provide 'extensions/org)
|
||||
;;; rust.el ends here
|
|
@ -1,24 +0,0 @@
|
|||
;;; org-init --- The entry point for Org extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(defun org-setup ()
|
||||
(add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
|
||||
(setq org-agenda-files '("~/orgs/main.org"))
|
||||
;; Need to be set in ~/.fg42.el
|
||||
;; (setq org-directory "~/orgs/")
|
||||
(setq org-default-notes-file (concat org-directory "/notes.org"))
|
||||
|
||||
(require 'org-bullets)
|
||||
(org-bullets-mode 1)
|
||||
|
||||
(define-key org-mode-map (kbd "C-c a") #'org-agenda))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/org-initialize ()
|
||||
"Initialize Rust extension."
|
||||
(add-hook 'org-mode-hook #'org-setup))
|
||||
|
||||
|
||||
(provide 'extensions/org/init)
|
||||
;;; init.el ends here
|
|
@ -1,13 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/php/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'web-mode)
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension php
|
||||
:version "2.31"
|
||||
:on-initialize extensions/php-initialize)
|
||||
|
||||
(provide 'extensions/php)
|
|
@ -1,8 +0,0 @@
|
|||
;; Functions ----------------------------------
|
||||
|
||||
(defun extensions/php-initialize ()
|
||||
"PHP extensions initialization function"
|
||||
(add-to-list 'auto-mode-alist '("\\.php$" . web-mode))
|
||||
)
|
||||
|
||||
(provide 'extensions/php/init)
|
|
@ -1,39 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/python/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'virtualenvwrapper)
|
||||
(depends-on 'flycheck)
|
||||
(depends-on 'pyvenv)
|
||||
(depends-on 'py-autopep8)
|
||||
|
||||
(with-ability anaconda
|
||||
(depends-on 'anaconda-mode)
|
||||
(depends-on 'company-anaconda))
|
||||
|
||||
(with-ability jedi
|
||||
(depends-on 'company-jedi))
|
||||
|
||||
(with-ability elpy
|
||||
(depends-on 'ein)
|
||||
(depends-on 'elpy))
|
||||
|
||||
(with-ability kivy-editor
|
||||
(depends-on 'kivy-mode))
|
||||
|
||||
(with-ability cython-editor
|
||||
(depends-on 'cython-mode))
|
||||
|
||||
(with-ability lsp-python
|
||||
(depends-on 'lsp-python-ms))
|
||||
|
||||
(with-ability python-black
|
||||
(depends-on 'python-black))
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension python
|
||||
:version "2.31"
|
||||
:on-initialize extensions/python-initialize)
|
||||
|
||||
(provide 'extensions/python)
|
|
@ -1,171 +0,0 @@
|
|||
;; Functions -------------------------------------------------
|
||||
(defun setup-keybindings ()
|
||||
"Setup default key bindings for python mode"
|
||||
|
||||
;; FIXME: Replace the global key map with python-mode-map
|
||||
(global-set-key (kbd "C-c C-b") 'python-add-breakpoint)
|
||||
(global-set-key (kbd "C-c C-n") 'python-interactive))
|
||||
|
||||
|
||||
(defun python--encoding-comment-required-p ()
|
||||
(re-search-forward "[^\0-\177]" nil t))
|
||||
|
||||
;;;###autoload
|
||||
(defun python--detect-encoding ()
|
||||
(let ((coding-system
|
||||
(or save-buffer-coding-system
|
||||
buffer-file-coding-system)))
|
||||
(if coding-system
|
||||
(symbol-name
|
||||
(or (coding-system-get coding-system 'mime-charset)
|
||||
(coding-system-change-eol-conversion coding-system nil)))
|
||||
"ascii-8bit")))
|
||||
|
||||
;;;###autoload
|
||||
(defun python--insert-coding-comment (encoding)
|
||||
(let ((newlines (if (looking-at "^\\s *$") "\n" "\n\n")))
|
||||
(insert (format "# coding: %s" encoding) newlines)))
|
||||
|
||||
;;;###autoload
|
||||
(defun python-mode-set-encoding ()
|
||||
"Insert a magic comment header with the proper encoding if necessary."
|
||||
(save-excursion
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(when (prelude-python--encodings-comment-required-p)
|
||||
(goto-char (point-min))
|
||||
(let ((coding-system (python--detect-encoding)))
|
||||
(when coding-system
|
||||
(if (looking-at "^#!") (beginning-of-line 2))
|
||||
(cond ((looking-at "\\s *#\\s *.*\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)")
|
||||
;; update existing encoding comment if necessary
|
||||
(unless (string= (match-string 2) coding-system)
|
||||
(goto-char (match-beginning 2))
|
||||
(delete-region (point) (match-end 2))
|
||||
(insert coding-system)))
|
||||
((looking-at "\\s *#.*coding\\s *[:=]"))
|
||||
(t (python--insert-coding-comment coding-system)))
|
||||
(when (buffer-modified-p)
|
||||
(basic-save-buffer-1)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun python-add-breakpoint ()
|
||||
"Add a break point"
|
||||
(interactive)
|
||||
(newline-and-indent)
|
||||
(insert "import ipdb; ipdb.set_trace()")
|
||||
(highlight-lines-matching-regexp "^[ ]*import ipdb; ipdb.set_trace()"))
|
||||
|
||||
;;;###autoload
|
||||
(defun python-interactive ()
|
||||
"Enter the interactive Python environment"
|
||||
(interactive)
|
||||
(progn
|
||||
(newline-and-indent)
|
||||
(insert "from IPython import embed; embed()")
|
||||
(move-end-of-line 1)))
|
||||
|
||||
(defun jedi-python-mode-hook ()
|
||||
(add-to-list 'company-backends 'company-jedi))
|
||||
|
||||
;;;###autoload
|
||||
(defun python-mode-defaults ()
|
||||
"Defaults for Python programming."
|
||||
|
||||
;(require 'anaconda-mode)
|
||||
;(require 'eldoc-mode)
|
||||
|
||||
(subword-mode +1)
|
||||
;(anaconda-mode 1)
|
||||
(eldoc-mode 1)
|
||||
|
||||
(setup-keybindings)
|
||||
(with-ability auto-pair
|
||||
(setq-local electric-layout-rules
|
||||
'((?: . (lambda ()
|
||||
(and (zerop (first (syntax-ppss)))
|
||||
(python-info-statement-starts-block-p)
|
||||
'after))))))
|
||||
|
||||
;; FIXME: we don't use imenu either remove this or
|
||||
;; setup imenu too
|
||||
(when (fboundp #'python-imenu-create-flat-index)
|
||||
(setq-local imenu-create-index-function
|
||||
#'python-imenu-create-flat-index))
|
||||
(add-hook 'post-self-insert-hook
|
||||
#'electric-layout-post-self-insert-function nil 'local))
|
||||
;(add-hook 'after-save-hook 'python-mode-set-encoding nil 'local))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/python-initialize ()
|
||||
(ability jedi ()
|
||||
"Python autocompletion based on Jedi"
|
||||
(add-hook 'python-mode-hook 'jedi-python-mode-hook))
|
||||
|
||||
(ability elpy ()
|
||||
"Full feature python IDE. (A little bit heavy)"
|
||||
|
||||
(require 'py-autopep8)
|
||||
(advice-add 'python-mode :before 'elpy-enable)
|
||||
|
||||
(setq python-shell-interpreter "ipython"
|
||||
python-shell-interpreter-args "-i --simple-prompt")
|
||||
|
||||
;; enable autopep8 formatting on save
|
||||
(add-hook 'elpy-mode-hook 'py-autopep8-enable-on-save))
|
||||
|
||||
(ability python-black '()
|
||||
"Add support for black syntax linter"
|
||||
(require 'python-black)
|
||||
(add-hook 'python-mode-hook 'python-black-on-save-mode))
|
||||
|
||||
(ability venv ()
|
||||
"Virtualenv support"
|
||||
(require 'virtualenvwrapper)
|
||||
(venv-initialize-interactive-shells)
|
||||
(venv-initialize-eshell))
|
||||
|
||||
(ability python-editor ()
|
||||
"Gives FG42 the ability to edit pytho codes."
|
||||
|
||||
(add-hook 'python-mode-hook 'python-mode-defaults)
|
||||
(add-hook 'after-init-hook #'global-flycheck-mode)
|
||||
(when (fboundp 'exec-path-from-shell-copy-env)
|
||||
(exec-path-from-shell-copy-env "PYTHONPATH"))
|
||||
|
||||
(with-ability kivy-editor
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.kv\\'" . kivy-mode)))
|
||||
|
||||
(with-ability cython-editor
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.pyd\\'" . cython-mode))
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.pyi\\'" . cython-mode))
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.pyx\\'" . cython-mode)))
|
||||
(ability lsp-python ()
|
||||
;; Instruct LSP to use pyls
|
||||
(require 'lsp-python-ms)
|
||||
;; (lsp-register-client
|
||||
;; (make-lsp-client :new-connection (lsp-stdio-connection "pyls")
|
||||
;; :major-modes '(python-mode)
|
||||
;; :server-id 'pyls))
|
||||
;; Setup LSP for python mode
|
||||
(add-hook 'python-mode-hook
|
||||
(lambda ()
|
||||
(push 'company-lsp company-backends)
|
||||
(lsp)
|
||||
(setq lsp-ui-sideline-show-code-actions nil)))))
|
||||
|
||||
|
||||
|
||||
(ability python-code-completion ('code-completion)
|
||||
"Gives FG42 the ability to complete python codes.")
|
||||
|
||||
;(when (boundp 'company-backends)
|
||||
; (add-to-list 'company-backends 'company-anaconda))))
|
||||
|
||||
(message "'python' extension has been initialized."))
|
||||
|
||||
(provide 'extensions/python/init)
|
|
@ -1,28 +0,0 @@
|
|||
;;; RacketExtension --- Enables Racket development on FG42
|
||||
;;; Commentary:
|
||||
;; In order to user racket extension `racket' itself should
|
||||
;; be available on the path provided by `exec-path'.
|
||||
;;; Code:
|
||||
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/racket/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'racket-mode)
|
||||
(depends-on 'paredit)
|
||||
(depends-on 'flycheck)
|
||||
(depends-on 'clojure-mode-extra-font-locking)
|
||||
(depends-on 'rainbow-delimiters)
|
||||
|
||||
(defun racket-doc ()
|
||||
"Something fun.")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension racket
|
||||
:version "2.32"
|
||||
:on-initialize extensions/racket-initialize
|
||||
:docs "lib/extensions/racket/readme.org")
|
||||
|
||||
(provide 'extensions/racket)
|
||||
;;; racket.el ends here
|
|
@ -1,24 +0,0 @@
|
|||
;;; RacketExtension --- Enables Racket development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/racket-initialize ()
|
||||
"Initialize the racket extension."
|
||||
(ability racket-editor ('flycheck)
|
||||
(require 'racket-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.rkts$" . racket-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.rkt$" . racket-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.rktl$" . racket-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.rktd$" . racket-mode))
|
||||
|
||||
(add-hook 'racket-mode-hook #'racket-unicode-input-method-enable)
|
||||
(add-hook 'racket-repl-mode-hook #'racket-unicode-input-method-enable)
|
||||
(add-hook 'racket-mode-hook #'paredit-mode)
|
||||
(add-hook 'racket-mode-hook #'rainbow-delimiters-mode)
|
||||
(setq tmp-directory (concat (getenv "HOME") "/.tmp"))))
|
||||
|
||||
|
||||
(provide 'extensions/racket/init)
|
||||
;;; init.el ends here
|
|
@ -1,29 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/ruby/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'company-inf-ruby)
|
||||
(depends-on 'enh-ruby-mode)
|
||||
(depends-on 'rbenv)
|
||||
(depends-on 'slim-mode)
|
||||
(depends-on 'haml-mode)
|
||||
(depends-on 'inf-ruby)
|
||||
(depends-on 'ruby-tools)
|
||||
(depends-on 'yaml-mode)
|
||||
(depends-on 'ruby-electric)
|
||||
(depends-on 'bundler)
|
||||
(depends-on 'feature-mode)
|
||||
(depends-on 'rspec-mode)
|
||||
(depends-on 'projectile-rails)
|
||||
(depends-on 'robe)
|
||||
(depends-on 'yari)
|
||||
(depends-on 'indent-guide)
|
||||
(depends-on 'rake)
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension ruby
|
||||
:version "2.31"
|
||||
:on-initialize extensions/ruby-initialize)
|
||||
|
||||
(provide 'extensions/ruby)
|
|
@ -1,105 +0,0 @@
|
|||
(require 'extensions/ruby/setup)
|
||||
|
||||
;; Functions -------------------------------------------------
|
||||
|
||||
;;;###autoload
|
||||
(defun enh-ruby-mode-callback ()
|
||||
(setup-general-ruby-editor)
|
||||
(setup-inf-ruby)
|
||||
(setup-bundler)
|
||||
(setup-rake)
|
||||
|
||||
(global-set-key (kbd "M-.") 'my-find-tag)
|
||||
|
||||
(with-ability rbenv
|
||||
(require 'rbenv)
|
||||
(global-rbenv-mode))
|
||||
|
||||
(with-ability auto-pair
|
||||
(ruby-electric-mode t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/ruby-initialize ()
|
||||
"Web development plugin initialization."
|
||||
|
||||
(require 'enh-ruby-mode)
|
||||
(autoload 'enh-ruby-mode "enh-ruby-mode" "Major mode for ruby files" t)
|
||||
|
||||
(with-ability global-rbenv
|
||||
(require 'rbenv)
|
||||
(global-rbenv-mode))
|
||||
|
||||
|
||||
|
||||
(ability indent-guide
|
||||
"Show indent guides."
|
||||
(add-hook 'ruby-mode-hook 'indent-guide-mode)
|
||||
(add-hook 'web-mode-hook 'indent-guide-mode)
|
||||
(ability recursive-indent-guides ()
|
||||
"Show recursive indents guides."
|
||||
(setq indent-guide-recursive t))
|
||||
|
||||
(ability delayed-indent-guides ()
|
||||
"Show indent guides with a delay."
|
||||
(setq indent-guide-delay 0.3)))
|
||||
|
||||
(ability ruby-editor ('flycheck)
|
||||
"Gives FG42 the ability to edit ruby files."
|
||||
|
||||
(dolist (spec '(("\\.rb$" . enh-ruby-mode)
|
||||
("[vV]agrantfile$" . enh-ruby-mode)
|
||||
("[gG]emfile$" . enh-ruby-mode)
|
||||
("[pP]uppetfile$" . enh-ruby-mode)
|
||||
("\\.rake$" . enh-ruby-mode)
|
||||
("\\.rabl$" . enh-ruby-mode)
|
||||
("[cC]apfile$" . enh-ruby-mode)
|
||||
("\\.gemspec$" . enh-ruby-mode)
|
||||
("\\.builder$" . enh-ruby-mode)))
|
||||
(add-to-list 'auto-mode-alist spec))
|
||||
|
||||
(setq enh-ruby-use-encoding-map nil
|
||||
;; don't deep indent arrays and hashes
|
||||
enh-ruby-deep-indent-paren nil)
|
||||
|
||||
;; Autostart yaml-mode
|
||||
(add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
|
||||
(add-hook 'yaml-mode-hook
|
||||
'(lambda ()
|
||||
(define-key yaml-mode-map "\C-m" 'newline-and-indent)))
|
||||
|
||||
;; Add our callback to enh-ruby-mode-hook
|
||||
(add-hook 'enh-ruby-mode-hook 'enh-ruby-mode-callback)
|
||||
|
||||
;; configure hs-minor-mode
|
||||
(add-to-list 'hs-special-modes-alist
|
||||
'(enh-ruby-mode
|
||||
"\\(class\\|def\\|do\\|if\\)" "\\(end\\)" "#"
|
||||
(lambda (arg) (ruby-end-of-block)) nil))
|
||||
|
||||
(add-hook 'enh-ruby-mode-hook 'projectile-mode))
|
||||
|
||||
(ability ruby-code-completion ('code-completion)
|
||||
"Auto complete ruby code on demand."
|
||||
(add-to-list 'enh-ruby-mode-hook 'ruby-code-completion))
|
||||
|
||||
(ability slim-mode ()
|
||||
"Gives FG42 the ability to edit slim templates."
|
||||
(add-to-list 'auto-mode-alist '("\\.slim$" . slim-mode)))
|
||||
|
||||
(ability haml-mode ()
|
||||
"Gives FG42 the ability to edit haml templates."
|
||||
(add-to-list 'auto-mode-alist '("\\.haml$" . haml-mode)))
|
||||
|
||||
(ability cucumber ()
|
||||
"Gives FG42 the ability to works with Cucumber."
|
||||
(autoload 'feature-mode "feature-mode"
|
||||
"Emacs mode for editing Cucumber plain text stories")
|
||||
(add-to-list 'auto-mode-alist '("\.feature$" . feature-mode)))
|
||||
|
||||
(ability rails-projects ()
|
||||
"Gives FG42 the ability to manage rails projects."
|
||||
(add-hook 'projectile-mode-hook 'projectile-rails-on))
|
||||
(message "'ruby' extension has been initialized"))
|
||||
|
||||
|
||||
(provide 'extensions/ruby/init)
|
|
@ -1,16 +0,0 @@
|
|||
(require 'rake)
|
||||
|
||||
;;;###autoload
|
||||
(defun my-rake (task &optional compilation-mode)
|
||||
"Runs rake command."
|
||||
(let* ((root (or (rake--root) (user-error "Rakefile not found")))
|
||||
(arg (or (car arg) 0))
|
||||
(prefix (rake--choose-command-prefix root
|
||||
(list :spring "bundle exec spring rake "
|
||||
:zeus "zeus rake "
|
||||
:bundler "bundle exec rake "
|
||||
:vanilla "rake ")))
|
||||
(mode (or compilation-mode 'rake-compilation-mode)))
|
||||
(rake-compile root task mode)))
|
||||
|
||||
(provide 'my-rake)
|
|
@ -1,129 +0,0 @@
|
|||
;;; Code:
|
||||
;; Functions -------------------------------------------------
|
||||
|
||||
;;;###autoload
|
||||
(defun insert-arrow ()
|
||||
(interactive)
|
||||
(delete-horizontal-space t)
|
||||
(insert " => "))
|
||||
|
||||
;;;###autoload
|
||||
(defun setup-bundler ()
|
||||
"Setup bundler and its keybindings"
|
||||
(require 'bundler)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c b i") 'bundle-install)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c b u") 'bundle-update)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c b e") 'bundle-exec)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c b o") 'bundle-open)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c b c") 'bundle-console))
|
||||
|
||||
;;;###autoload
|
||||
(defun rake-test ()
|
||||
(interactive)
|
||||
(let* ((root (or (rake--root) (user-error "Rakefile not found"))))
|
||||
(rake--with-root root (compile "rake test" 'rake-compilation-mode))))
|
||||
|
||||
;;;###autoload
|
||||
(defun rake-migrate ()
|
||||
(interactive)
|
||||
(let* ((root (or (rake--root) (user-error "Rakefile not found"))))
|
||||
(rake--with-root root (compile "rake db:migrate" 'rake-compilation-mode))))
|
||||
|
||||
(defun rake-seed ()
|
||||
(interactive)
|
||||
(let* ((root (or (rake--root) (user-error "Rakefile not found"))))
|
||||
(rake--with-root root (compile "rake db:seed" 'rake-compilation-mode))))
|
||||
|
||||
;;;###autoload
|
||||
(defun setup-rake ()
|
||||
"Setup bundler and its keybindings"
|
||||
(require 'rake)
|
||||
|
||||
(eval-after-load 'projectile
|
||||
'(setq rake-completion-system projectile-completion-system))
|
||||
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c c r") 'rake)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c c t") 'rake-test)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c c m") 'rake-migrate)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c c s") 'rake-seed))
|
||||
|
||||
;;;###autoload
|
||||
(defun setup-inf-ruby()
|
||||
"Setup inf-ruby and Robe"
|
||||
|
||||
;; Inf Ruby configuration
|
||||
(autoload 'inf-ruby "inf-ruby" "Run an inferior Ruby process" t)
|
||||
(add-hook 'after-init-hook 'inf-ruby-switch-setup)
|
||||
|
||||
(global-set-key (kbd "C-c r r") 'inf-ruby)
|
||||
|
||||
;; TODO: We don't need this if pry setup is present in ~/.irbrc
|
||||
(setq irbparams " --inf-enh-ruby-mode -r irb/completion")
|
||||
(setq irbpath (rbenv--expand-path "shims" "irb"))
|
||||
(setq irb (concat irbpath irbparams))
|
||||
(add-to-list 'inf-ruby-implementations (cons "ruby" irb))
|
||||
(inf-ruby-minor-mode t))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun ruby-code-completion ()
|
||||
"Configure Robe and inf-ruby for code completion."
|
||||
(with-ability ruby-code-completion
|
||||
(robe-mode t)
|
||||
(define-key enh-ruby-mode-map (kbd "\C-c M-j") 'robe-start)
|
||||
(push 'company-robe company-backends)
|
||||
(eval-after-load 'company
|
||||
'(add-to-list 'company-backends 'company-inf-ruby))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun setup-general-ruby-editor ()
|
||||
"Setup basic utilities to write Ruby code"
|
||||
(local-set-key [f1] 'yari)
|
||||
|
||||
;; Install rspec snippets after it loaded
|
||||
(eval-after-load 'rspec-mode
|
||||
'(rspec-install-snippets))
|
||||
|
||||
(ruby-tools-mode t)
|
||||
(define-key enh-ruby-mode-map (kbd "C-.") 'insert-arrow)
|
||||
(hs-minor-mode t)
|
||||
;; Hack autocomplete so it treat :symbole and symbole the same way
|
||||
(modify-syntax-entry ?: "."))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun visit-project-tags ()
|
||||
(interactive)
|
||||
(let ((tags-file (concat (projectile-project-root) "tags")))
|
||||
(visit-tags-table tags-file)
|
||||
(message (concat "Loaded " tags-file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun build-ctag-file ()
|
||||
"Create the ctag of the ruby project"
|
||||
(interactive)
|
||||
(message "building project tags")
|
||||
(let ((root (projectile-project-root)))
|
||||
(shell-command (concat "ctags -e -R . $(bundle list --paths) --extra=+fq --exclude=db --exclude=test --exclude=.git --exclude=public -f " root "tags " root)))
|
||||
(visit-project-tags)
|
||||
(message "tags built successfully"))
|
||||
|
||||
;;;###autoload
|
||||
(defun my-find-tag ()
|
||||
(interactive)
|
||||
(if (file-exists-p (concat (projectile-project-root) "TAGS"))
|
||||
(visit-project-tags)
|
||||
(build-ctag-file))
|
||||
(etags-select-find-tag-at-point))
|
||||
|
||||
(setq erb-regex (concat "\\([^\\\"']+\\.\\)\\(" (rx (or "jpg" "png" "gif" "svg")) "\\)"))
|
||||
|
||||
;;;###autoload
|
||||
(defun erbify-image-paths ()
|
||||
(interactive)
|
||||
(message erb-regex)
|
||||
(replace-regexp erb-regex "<%= image_path '\\1\\2' %>"))
|
||||
|
||||
|
||||
(provide 'extensions/ruby/setup)
|
|
@ -1,17 +0,0 @@
|
|||
;;; RustExtention --- Enable Rust support in FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/rust/init)
|
||||
|
||||
;; dependencies
|
||||
(depends-on 'rustic)
|
||||
|
||||
|
||||
(extension rust
|
||||
:version 0.0.1
|
||||
:on-initialize extensions/rust-initialize
|
||||
:docs "lib/extensions/rust/readme.org")
|
||||
(provide 'extensions/rust)
|
||||
;;; rust.el ends here
|
|
@ -1,13 +0,0 @@
|
|||
;;; rust-init --- The entry point for Rust extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/rust-initialize ()
|
||||
"Initialize Rust extension."
|
||||
(setq rustic-format-trigger 'on-save))
|
||||
|
||||
|
||||
(provide 'extensions/rust/init)
|
||||
;;; init.el ends here
|
|
@ -1,22 +0,0 @@
|
|||
;;; SereneExtension --- Enables Serene development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/serene/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'paredit)
|
||||
(depends-on 'rainbow-delimiters)
|
||||
|
||||
(defun serene-doc ()
|
||||
"something fun")
|
||||
;; Extension -------------------------------------
|
||||
(extension serene
|
||||
:version "2.32"
|
||||
:on-initialize extensions/serene-initialize
|
||||
:docs "lib/extensions/serene/readme.org")
|
||||
|
||||
(provide 'extensions/serene)
|
||||
;;; serene.el ends here
|
|
@ -1,21 +0,0 @@
|
|||
;;; serene-init --- The entry point for serene extension
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/serene-initialize ()
|
||||
"Initialize the Serene extension."
|
||||
|
||||
(require 'extensions/serene/serene-simple-mode)
|
||||
(add-hook 'serene-simple-mode-hook #'paredit-mode)
|
||||
(add-hook 'serene-simple-mode-hook #'rainbow-delimiters-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.srns\\'" . serene-simple-mode))
|
||||
(add-to-list 'auto-mode-alist
|
||||
'("\\.srnl\\'" . serene-simple-mode)))
|
||||
|
||||
|
||||
|
||||
(provide 'extensions/serene/init)
|
||||
;;; init.el ends here
|
|
@ -1,198 +0,0 @@
|
|||
;;; serene-init --- The entry point for serene extension
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; In order to connect to Serene's nRepl process, first you have to make
|
||||
;; that it's running some where (consult Serene's README for learning more
|
||||
;; about it). Then simply use `serene-nrepl-connect' to make a connection.
|
||||
;; at this point you can evaluate Serene's expressions by using `serene-eval-expr-at-point'
|
||||
;; function which evaluates the expression before point end prints out the
|
||||
;; result in minibuffer.
|
||||
;;
|
||||
;;; Code:
|
||||
(defvar serene-simple-mode-map
|
||||
(make-sparse-keymap))
|
||||
|
||||
(defvar serene-nrepl-host "127.0.0.1")
|
||||
(defvar serene-nrepl-port 5544)
|
||||
(defvar serene-nrepl-process nil)
|
||||
|
||||
(defconst serene-simple-mode-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?\" "\"" table)
|
||||
;; / is punctuation, but // is a comment starter
|
||||
(modify-syntax-entry ?\; "<" table)
|
||||
(modify-syntax-entry ?\n ">" table)
|
||||
table))
|
||||
|
||||
|
||||
(defface serene-simple-mode-special-froms-face
|
||||
'((t :inherit font-lock-builtin-face))
|
||||
"Face of special forms."
|
||||
:group 'simple-serene-mode)
|
||||
|
||||
(defface serene-simple-mode-builtin-fns-face
|
||||
'((t :inherit font-lock-keyword-face))
|
||||
"Face of builtin functions."
|
||||
:group 'simple-serene-mode)
|
||||
|
||||
(defface serene-simple-mode-builtin-types-face
|
||||
'((t :inherit font-lock-type-face))
|
||||
"Face of built in types."
|
||||
:group 'simple-serene-mode)
|
||||
|
||||
(defvar serene-simple-mode-special-forms
|
||||
'("do" "let" "def" "fn" "quote" "cond" "if"
|
||||
"defn" "defmacro" "list" "ns"))
|
||||
|
||||
|
||||
(defconst serene-simple-mode-builtin-fns
|
||||
'("=" ">" "<" ">=" "<=" "and" "or" "not" "first" "rest" "println"
|
||||
"quit" "+" "*" "/" "-" "conj" "mod" "new" "pr" "prn" "print"))
|
||||
|
||||
|
||||
(defconst serene-simple-mode-builtin-types
|
||||
'("System" "String" "Boolean"))
|
||||
|
||||
|
||||
(define-derived-mode serene-simple-mode
|
||||
scheme-mode "Serene(Simple)"
|
||||
"Major mode for Serene simple."
|
||||
(define-key serene-simple-mode-map (kbd "C-x C-e") 'serene-eval-expr-at-point))
|
||||
|
||||
|
||||
(defun serene-simple-add-keywords (face-name keyword-rules)
|
||||
"Set the FACE-NAME for keywords in serene-simple using KEYWORD-RULES."
|
||||
(let* ((keyword-list (mapcar #'(lambda (x)
|
||||
(symbol-name (cdr x)))
|
||||
keyword-rules))
|
||||
(keyword-regexp
|
||||
(concat
|
||||
"\\("
|
||||
(regexp-opt keyword-list)
|
||||
"\\)")))
|
||||
(font-lock-add-keywords 'serene-simple-mode
|
||||
`((,keyword-regexp 1 ',face-name))))
|
||||
(mapc #'(lambda (x)
|
||||
(put (cdr x)
|
||||
'serene-simple-indent-function
|
||||
(car x)))
|
||||
keyword-rules))
|
||||
|
||||
|
||||
(serene-simple-add-keywords 'serene-simple-mode-special-froms-face
|
||||
(mapcar (lambda (x) (cons 1 (intern x))) serene-simple-mode-special-forms))
|
||||
|
||||
(serene-simple-add-keywords 'serene-simple-mode-builtin-fns-face
|
||||
(mapcar (lambda (x) (cons 1 (intern x))) serene-simple-mode-builtin-fns))
|
||||
|
||||
(serene-simple-add-keywords 'serene-simple-mode-builtin-types-face
|
||||
(mapcar (lambda (x) (cons 1 (intern x))) serene-simple-mode-builtin-types))
|
||||
|
||||
|
||||
(defun serene-expr-at-point ()
|
||||
"Return sexp before the point."
|
||||
(interactive)
|
||||
(let ((opoint (point))
|
||||
(left-quote ?‘)
|
||||
expr)
|
||||
(save-excursion
|
||||
(with-syntax-table serene-simple-mode-syntax-table
|
||||
;; If this sexp appears to be enclosed in `...' or ‘...’
|
||||
;; then ignore the surrounding quotes.
|
||||
(cond ((eq (preceding-char) ?’)
|
||||
(progn (forward-char -1) (setq opoint (point))))
|
||||
((or (eq (following-char) ?\')
|
||||
(eq (preceding-char) ?\'))
|
||||
(setq left-quote ?\`)))
|
||||
|
||||
;; When after a named character literal, skip over the entire
|
||||
;; literal, not only its last word.
|
||||
(when (= (preceding-char) ?})
|
||||
(let ((begin (save-excursion
|
||||
(backward-char)
|
||||
(skip-syntax-backward "w-")
|
||||
(backward-char 3)
|
||||
(when (looking-at-p "\\\\N{") (point)))))
|
||||
(when begin (goto-char begin))))
|
||||
|
||||
(forward-sexp -1)
|
||||
;; If we were after `?\e' (or similar case),
|
||||
;; use the whole thing, not just the `e'.
|
||||
(when (eq (preceding-char) ?\\)
|
||||
(forward-char -1)
|
||||
(when (eq (preceding-char) ??)
|
||||
(forward-char -1)))
|
||||
|
||||
;; Skip over hash table read syntax.
|
||||
(and (> (point) (1+ (point-min)))
|
||||
(looking-back "#s" (- (point) 2))
|
||||
(forward-char -2))
|
||||
|
||||
(save-restriction
|
||||
(if (eq (following-char) left-quote)
|
||||
(forward-char))
|
||||
(when (looking-at ",@?") (goto-char (match-end 0)))
|
||||
(narrow-to-region (point-min) opoint)
|
||||
(setq expr (read (current-buffer)))
|
||||
expr)))))
|
||||
|
||||
(defun serene-eval-expr-at-point ()
|
||||
"Send the expression at point to the nRepl for evaluation."
|
||||
(interactive)
|
||||
(if (and serene-nrepl-process (process-live-p serene-nrepl-process))
|
||||
(let* ((buf (process-buffer serene-nrepl-process))
|
||||
(expr (format "%s\n" (replace-regexp-in-string
|
||||
(regexp-quote "\n")
|
||||
" "
|
||||
(prin1-to-string (serene-expr-at-point))
|
||||
nil 'literal))))
|
||||
(process-send-string serene-nrepl-process expr))
|
||||
(message "Error: You need to connect to Serene's nRepl first.")))
|
||||
|
||||
|
||||
(defun serene-nrepl-sentinel (process event)
|
||||
"The sentinel fn for the given PROCESS to process the EVENT."
|
||||
(message (format "Process: %s had the event '%s'" process event)))
|
||||
|
||||
(defun serene-process-incoming-result (process value)
|
||||
"Process the incoming VALUE of the given PROCESS."
|
||||
(if (not (= (length value) 0))
|
||||
(let ((status (substring value 0 1)))
|
||||
(if (string= status "0")
|
||||
(message (format "=> %s" (substring value 1 -1)))
|
||||
(message (format "Error: %s" (substring value 1 -1)))))
|
||||
(message "Bad response from nRepl.")))
|
||||
|
||||
(defun serene-nrepl-connect ()
|
||||
"Connect to the running nRepl of Serene and return the process value."
|
||||
(interactive)
|
||||
(if (not serene-nrepl-process)
|
||||
(let ((p (open-network-stream "serene-nrepl"
|
||||
(get-buffer-create "*serene-repl*")
|
||||
serene-nrepl-host
|
||||
serene-nrepl-port)))
|
||||
(setq serene-nrepl-process p)
|
||||
(set-process-sentinel p 'serene-nrepl-sentinel)
|
||||
(set-process-filter p 'serene-process-incoming-result)
|
||||
(message (format "Connected to tcp://%s:%s"
|
||||
serene-nrepl-host
|
||||
serene-nrepl-port)))
|
||||
serene-nrepl-process))
|
||||
|
||||
(defun serene-nrepl-disconnect ()
|
||||
"Disconnect from Serene nRepl."
|
||||
(interactive)
|
||||
(when serene-nrepl-process
|
||||
(delete-process serene-nrepl-process)
|
||||
(setq serene-nrepl-process nil)
|
||||
(message "Disconnected from the nRepl.")))
|
||||
|
||||
(defun serene-nrepl-status ()
|
||||
"Return the status of the connection to Serene's nRepl."
|
||||
(interactive)
|
||||
(if serene-nrepl-process
|
||||
(message (format "%s" (process-status serene-nrepl-process)))
|
||||
(message "Disconnected.")))
|
||||
|
||||
(provide 'extensions/serene/serene-simple-mode)
|
||||
;;; serene-simple-mode.el ends here
|
|
@ -1,25 +0,0 @@
|
|||
;;; TypescriptExtension --- Enables Typescript development on FG42
|
||||
;;; Commentary:
|
||||
;; In order to user typescript extension `typescript' itself should
|
||||
;; be available on the path provided by `exec-path'.
|
||||
;;; Code:
|
||||
|
||||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/typescript/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'typescript-mode)
|
||||
|
||||
|
||||
(defun typescript-doc ()
|
||||
"Something fun.")
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension typescript
|
||||
:version "2.32"
|
||||
:on-initialize extensions/typescript-initialize
|
||||
:docs "lib/extensions/typescript/readme.org")
|
||||
|
||||
(provide 'extensions/typescript)
|
||||
;;; typescript.el ends here
|
|
@ -1,41 +0,0 @@
|
|||
;;; TypescriptExtension --- Enables Typescript development on FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(defun setup-tide-mode ()
|
||||
(interactive)
|
||||
(require 'typescript-mode)
|
||||
(require 'web-mode)
|
||||
(setq tmp-directory (concat (getenv "HOME") "/.tmp"))
|
||||
;; aligns annotation to the right hand side
|
||||
(setq company-tooltip-align-annotations t)
|
||||
(flycheck-mode 1)
|
||||
(setq flycheck-check-syntax-automatically '(save mode-enabled))
|
||||
|
||||
(eldoc-mode 1)
|
||||
(company-mode 1))
|
||||
|
||||
|
||||
(defun lsp-typescript-config ()
|
||||
(interactive)
|
||||
(require 'lsp)
|
||||
(require 'lsp-clients))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/typescript-initialize ()
|
||||
"Initialize the typescript extension."
|
||||
(ability typescript-editor ('flycheck)
|
||||
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
|
||||
|
||||
(add-hook 'web-mode-hook
|
||||
(lambda ()
|
||||
(when (string-equal "tsx" (file-name-extension buffer-file-name))
|
||||
(setup-tide-mode))))
|
||||
|
||||
(add-hook 'typescript-mode-hook #'lsp-typescript-config)
|
||||
;; enable typescript-tslint checker
|
||||
(flycheck-add-mode 'typescript-tslint 'web-mode)))
|
||||
|
||||
|
||||
(provide 'extensions/typescript/init)
|
||||
;;; init.el ends here
|
|
@ -1,21 +0,0 @@
|
|||
(require 'fpkg)
|
||||
(require 'fg42/extension)
|
||||
(require 'extensions/web/init)
|
||||
|
||||
;; Dependencies ----------------------------------
|
||||
(depends-on 'emmet-mode)
|
||||
(depends-on 'company-web)
|
||||
(depends-on 'web-mode)
|
||||
(depends-on 'sass-mode)
|
||||
(depends-on 'scss-mode)
|
||||
(depends-on 'less-css-mode)
|
||||
(depends-on 'handlebars-mode)
|
||||
(depends-on 'rainbow-mode)
|
||||
(depends-on 'mustache-mode)
|
||||
|
||||
;; Extension -------------------------------------
|
||||
(extension web
|
||||
:version "2.31"
|
||||
:on-initialize extensions/web-initialize)
|
||||
|
||||
(provide 'extensions/web)
|
|
@ -1,122 +0,0 @@
|
|||
;; Functions -------------------------------------------------
|
||||
;;;###autoload
|
||||
(defun web-mode-hook-func ()
|
||||
"Hooks for Web mode."
|
||||
(with-ability code-completion
|
||||
(require 'company-web-html)
|
||||
(set (make-local-variable
|
||||
'company-backends) '(company-web-html))
|
||||
|
||||
(define-key web-mode-map (kbd "C-'") 'company-web-html))
|
||||
(setq web-mode-css-indent-offset 2)
|
||||
(setq web-mode-code-indent-offset 2)
|
||||
|
||||
(setq web-mode-markup-indent-offset 2))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/web-activate-modes ()
|
||||
"Activate necessary modes"
|
||||
(setq css-indent-offset 2)
|
||||
|
||||
(with-ability rainbow
|
||||
(rainbow-mode t))
|
||||
|
||||
(with-ability spell
|
||||
(flyspell-prog-mode))
|
||||
|
||||
(with-ability flycheck
|
||||
(flycheck-mode t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun jsx ()
|
||||
"Activate web-mode for editing jsx."
|
||||
(interactive)
|
||||
|
||||
(flycheck-define-checker jsxhint-checker
|
||||
"A JSX syntax and style checker based on JSXHint."
|
||||
|
||||
:command ("jsxhint" source)
|
||||
:error-patterns
|
||||
((error line-start (1+ nonl) ": line " line ", col " column ", " (message) line-end))
|
||||
:modes (web-mode))
|
||||
|
||||
(add-hook 'web-mode-hook
|
||||
(lambda ()
|
||||
(when (equal web-mode-content-type "jsx")
|
||||
;; enable flycheck
|
||||
(flycheck-select-checker 'jsxhint-checker)
|
||||
(flycheck-mode))))
|
||||
|
||||
(defadvice web-mode-highlight-part (around tweak-jsx activate)
|
||||
(if (equal web-mode-content-type "jsx")
|
||||
(let ((web-mode-enable-part-face nil))
|
||||
ad-do-it)
|
||||
ad-do-it))
|
||||
|
||||
(setq web-mode-markup-indent-offset 2)
|
||||
(setq web-mode-code-indent-offset 2)
|
||||
|
||||
|
||||
(web-mode))
|
||||
|
||||
;;;###autoload
|
||||
(defun extensions/web-initialize ()
|
||||
"Web development plugin initialization."
|
||||
|
||||
(ability web-editor ('flycheck)
|
||||
"Gives FG42 the ability to edit web contents."
|
||||
(require 'web-mode)
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.jsp\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.handlebars\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.html$" . web-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.jsx$" . js2-jsx-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.esx$" . js2-jsx-mode))
|
||||
|
||||
(add-hook 'web-mode-hook 'web-mode-hook-func)
|
||||
(add-hook 'web-mode-hook 'emmet-mode)
|
||||
(add-hook 'web-mode-hook 'extensions/web-activate-modes))
|
||||
|
||||
(ability css-editor
|
||||
"Gives FG42 the ability to edit CSS."
|
||||
(add-hook 'css-mode-hook 'extensions/web-activate-modes))
|
||||
|
||||
(ability sass-editor
|
||||
"Gives FG42 the ability to edit SASS/SCSS."
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.scss$" . scss-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.sass$" . sass-mode))
|
||||
|
||||
(setq scss-compile-at-save nil)
|
||||
(setq sass-compile-at-save nil)
|
||||
|
||||
(add-hook 'scss-mode-hook 'extensions/web-activate-modes)
|
||||
(add-hook 'sass-mode-hook 'extensions/web-activate-modes))
|
||||
|
||||
(ability less-editor
|
||||
"Gives FG42 the ability to edit lesscss."
|
||||
(add-to-list 'auto-mode-alist '("\\.less$" . less-css-mode))
|
||||
(add-hook 'less-css-mode-hook 'extensions/web-activate-modes))
|
||||
|
||||
(ability js-editor
|
||||
"Gives FG42 the ability to edit Javascript."
|
||||
(add-hook 'js2-mode-hook 'extensions/web-activate-modes)
|
||||
(add-to-list 'auto-mode-alist '("\\.js.erb$" . js2-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.es$" . js2-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.es6$" . js2-mode))
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)))
|
||||
(ability jsx-editor
|
||||
"Gives FG42 the ability to edit JSX."
|
||||
(add-to-list 'auto-mode-alist '("\\.jsx$" . js2-jsx-mode))))
|
||||
(message "'web' extension has been initialized.")
|
||||
|
||||
|
||||
|
||||
(provide 'extensions/web/init)
|
113
lib/fg42.el
113
lib/fg42.el
|
@ -1,113 +0,0 @@
|
|||
;;; FG42 --- a simple package manager for FG42 -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2010-2018 lxsameer
|
||||
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; Keywords: lisp fg42 IDE package manager
|
||||
;; Version: 2.31
|
||||
|
||||
;; 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:
|
||||
|
||||
;; An Editor/IDE bundle base on Lovely Gnu/Emacs to make your life easier
|
||||
|
||||
;;; Code:
|
||||
(defvar fg42-home (getenv "FG42_HOME")
|
||||
"The pass to fg42-home.")
|
||||
|
||||
(defvar fg42-tmp (concat fg42-home "/tmp"))
|
||||
|
||||
(require 'fpkg)
|
||||
(fpkg-initialize-once)
|
||||
|
||||
(require 'fg42/base)
|
||||
(require 'fg42/splash)
|
||||
(require 'fg42/race)
|
||||
(require 'fg42/utils)
|
||||
(require 'fg42/key-bindings)
|
||||
|
||||
|
||||
(defvar fg42-before-initialize-hook nil
|
||||
"This hook will be called before FG42 initilization process.")
|
||||
|
||||
(defvar fg42-after-initialize-hook nil
|
||||
"This hook will be called after FG42 initilization process.")
|
||||
|
||||
(defvar fg42-gc-cons-threshold 16777216
|
||||
"Value of GC threshold of FG42.")
|
||||
|
||||
(defun defer-garbage-collection ()
|
||||
"Disable garbage collection."
|
||||
(setq gc-cons-threshold fg42-gc-cons-threshold))
|
||||
|
||||
(defun restore-garbage-collection ()
|
||||
"Restore garbage collection to it's default value."
|
||||
(run-at-time
|
||||
1 nil (lambda () (setq gc-cons-threshold most-positive-fixnum))))
|
||||
|
||||
(defun fg42--startup-optimization ()
|
||||
"Optimize FG42 startup."
|
||||
;; by setting gc threshold to the largest number
|
||||
;; Emacs can understand we are basically disabling it :).
|
||||
(setq gc-cons-threshold most-positive-fixnum
|
||||
gc-cons-percentage 0.6)
|
||||
;; after initilization phase restore cons threshold to normal
|
||||
(add-hook 'emacs-startup-hook
|
||||
(lambda ()
|
||||
(setq gc-cons-threshold fg42-gc-cons-threshold ; 16mb
|
||||
gc-cons-percentage 0.1)))
|
||||
|
||||
;; disable auto initilization of package.el
|
||||
(setq package-enable-at-startup nil)
|
||||
;; disable gc when we are in minibuffer using the same method we
|
||||
;; use for initilization time
|
||||
(add-hook 'minibuffer-setup-hook #'defer-garbage-collection)
|
||||
;; just enable gc when exiting minibuffer
|
||||
(add-hook 'minibuffer-exit-hook #'restore-garbage-collection)
|
||||
;; we dont need Emacs to check every file type and look for file
|
||||
;; handlers when we are initializing so we backup the original
|
||||
;; value and set it to nil
|
||||
(setq --file-name-handler-alist file-name-handler-alist)
|
||||
|
||||
(setq file-name-handler-alist nil)
|
||||
;; after initialization we can restore that file-name-handler-alist
|
||||
;; to original value.
|
||||
(add-hook 'emacs-startup-hook
|
||||
(lambda ()
|
||||
(setq file-name-handler-alist
|
||||
--file-name-handler-alist)))
|
||||
;; initial mode for emacs can be fundamental mode we have nothing to lose
|
||||
(setq initial-major-mode 'fundamental-mode))
|
||||
|
||||
|
||||
(defun fg42-initialize ()
|
||||
"Initialize FG42 editor."
|
||||
(setq fg42-start-timestamp (float-time))
|
||||
(fg42--startup-optimization)
|
||||
(run-hooks 'fg42-before-initialize-hook)
|
||||
(mkdir fg42-tmp t)
|
||||
(setq package-user-dir (concat fg42-home "/packages"))
|
||||
(fpkg-initialize)
|
||||
(initialize-extensions)
|
||||
(run-hooks 'fg42-after-initialize-hook)
|
||||
|
||||
(setq read-process-output-max (* 1024 1024))
|
||||
|
||||
(message "startup time: %s" (- (float-time) fg42-start-timestamp)))
|
||||
|
||||
|
||||
|
||||
(provide 'fg42)
|
||||
;; fg42.el ends here
|
|
@ -1,27 +0,0 @@
|
|||
;;; ability --- ability library of FG42
|
||||
;;; Commentary:
|
||||
;;;
|
||||
;;; Code:
|
||||
(require 'cl-lib)
|
||||
|
||||
(defvar fg42--abilities '()
|
||||
"Internal data structure to store abilities.")
|
||||
|
||||
(cl-defstruct fg42-ability
|
||||
"Each FG42 ability should implement a copy of this structure."
|
||||
name
|
||||
docs
|
||||
depends-on
|
||||
(start! nil)
|
||||
(stop! nil))
|
||||
|
||||
(defun register-ability (ability-name)
|
||||
"Register the given ABILITY-NAME as an activity."
|
||||
(add-to-list
|
||||
fg42--abilities
|
||||
'(ability-name . (make-fg42-ability :name ability-name))))
|
||||
|
||||
(defun start-ability (ability-name))
|
||||
|
||||
(provide 'fg42/ability)
|
||||
;;; ability ends here
|
|
@ -1,54 +0,0 @@
|
|||
;;; actions --- Extension action library of FG42
|
||||
;;
|
||||
;; Copyright (c) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Version: 0.1.0
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
|
||||
|
||||
(cl-defstruct fg42-actions
|
||||
"This data structure contains all the actions that are common
|
||||
among different extensions."
|
||||
;; A function that starts the development server for the given extension if
|
||||
;; there's any.
|
||||
(start-lang-sever nil)
|
||||
|
||||
;; A function that stops the development server for the given extension if
|
||||
;; there's any.
|
||||
(stop-lang-sever nil)
|
||||
|
||||
;; Action for inserting a print expr in the code
|
||||
(print-expr nil))
|
||||
|
||||
|
||||
(defmacro actions (&rest body)
|
||||
"A simple DSL to define a list of actions for an extension and BODY."
|
||||
;(declare (doc-string 1) (indent 1))
|
||||
`(setq ,name (apply 'make-fg42-extension :name ,(symbol-name name) (quote ,args))))
|
||||
|
||||
|
||||
(provide 'fg42/actions)
|
||||
;;; actions.el ends here
|
|
@ -1,69 +0,0 @@
|
|||
;;; Base --- Base library of FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'fg42/extension)
|
||||
|
||||
(require 'fg42/vars)
|
||||
|
||||
|
||||
;; Macros ---------------------------------
|
||||
(defmacro theme (name &optional local)
|
||||
"Mark the given theme NAME as default them.
|
||||
LOCAL should be 't' if theme is on FG42 it self"
|
||||
`(progn
|
||||
(setq default-theme ',(intern (symbol-name name)))
|
||||
(when (not (null ,local))
|
||||
(depends-on default-theme))))
|
||||
|
||||
|
||||
;; Functions ------------------------------
|
||||
(defun load-default-theme ()
|
||||
"Load the given theme name."
|
||||
(message "Load theme %s" default-theme)
|
||||
(require default-theme)
|
||||
|
||||
;; Setup the face look up function for spaceline
|
||||
(with-ability spaceline
|
||||
(let ((other-face (intern (concat (symbol-name default-theme)
|
||||
"-spaceline-faces"))))
|
||||
(if (functionp other-face)
|
||||
(setq spaceline-face-func other-face))))
|
||||
|
||||
;; Call the function name with same name as the them which should
|
||||
;; be responsible for loading the actual "custom-theme"
|
||||
(funcall (symbol-function default-theme)))
|
||||
|
||||
|
||||
(defun load--extension (extension)
|
||||
"Load a single EXTENSION and call its :on-initialize function."
|
||||
(let ((lib (concat "extensions/" (symbol-name extension))))
|
||||
(require (intern lib))))
|
||||
|
||||
|
||||
(defun initialize--extension (extension)
|
||||
"Initialize given EXTENSION by calling its :on-initialize function."
|
||||
(let ((init-func (fg42-extension-on-initialize (symbol-value extension))))
|
||||
(funcall (symbol-function init-func))))
|
||||
|
||||
|
||||
(defun initialize-extensions ()
|
||||
"Call the :on-initialize function on all extensions."
|
||||
(mapcar 'initialize--extension activated-extensions))
|
||||
|
||||
|
||||
(defun activate-extensions (&rest extensions)
|
||||
"Mark given EXTENSIONS to load on FG42."
|
||||
(setq activated-extensions extensions)
|
||||
(mapcar 'load--extension extensions))
|
||||
|
||||
|
||||
(defun load-user-config (file)
|
||||
"Load the given FILE as user config file."
|
||||
(if (file-exists-p file)
|
||||
(load-file file)))
|
||||
|
||||
|
||||
(provide 'fg42/base)
|
||||
;;; base ends here
|
|
@ -1,194 +0,0 @@
|
|||
;;; brain-switch --- Brain switch library to keep the state of mind
|
||||
;;
|
||||
;; Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ()
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;; Personally I switch between many many tasks constantly during a week.
|
||||
;; It's really hard to deal with the context switch and some times I forget
|
||||
;; about what I was doing on a project or why the other task was blocked.
|
||||
;; This library helps me which keeping my state of mind when I'm leaving a
|
||||
;; Task for another one.
|
||||
;;
|
||||
;; This library simply creates a database of the WORK you do and keeps track
|
||||
;; of some NOTES related to each WORK. You can review the notes on each WORK
|
||||
;; when ever you like via `fg42/brain-notes-for' function. You can switch to
|
||||
;; other state of mind with `fg42/brain-switch' which takes a note for your
|
||||
;; current WORK and switches to a new state by showing you what ever note
|
||||
;; you took on the same WORK previously.
|
||||
;;; Code:
|
||||
(require 'seq)
|
||||
(require 'fg42/utils)
|
||||
|
||||
(defvar fg42/brain-state-file "~/.brain.state"
|
||||
"The path to the brain state db.")
|
||||
|
||||
(defvar fg42/brain-state-date-format "%Y-%m-%d %T")
|
||||
|
||||
|
||||
(defun fg42/brain-state-create (current-work entries logs)
|
||||
"Create a new state out of the given ENTRIES and LOGS.
|
||||
CURRENT-WORK is the key that is considered to be the current work."
|
||||
(list 'entry-map entries 'logs logs 'current current-work))
|
||||
|
||||
|
||||
(defun fg42/-brain-entry-map (state)
|
||||
"Return the map of entries of the given STATE."
|
||||
(plist-get state 'entry-map))
|
||||
|
||||
|
||||
(defun fg42/-brain-logs (state)
|
||||
"Return the list of entries of the given STATE."
|
||||
(plist-get state 'logs))
|
||||
|
||||
|
||||
(defun fg42/-brain-current (state)
|
||||
"Return the current work of the given STATE."
|
||||
(plist-get state 'current))
|
||||
|
||||
|
||||
(defun fg42/load-brain-state ()
|
||||
"Load the brain state from the state file."
|
||||
(if (file-exists-p fg42/brain-state-file)
|
||||
(file->lisp fg42/brain-state-file)
|
||||
(list)))
|
||||
|
||||
|
||||
(defun fg42/save-brain-state (state)
|
||||
"Override the state on the brain state file by the given STATE."
|
||||
(lisp->file fg42/brain-state-file state))
|
||||
|
||||
|
||||
(defun fg42/add-brain-entry (state work entry)
|
||||
"Add the given ENTRY under the key WORK in the given STATE."
|
||||
(let ((entries (assoc work (fg42/-brain-entry-map state)))
|
||||
(log (list :add (format-time-string fg42/brain-state-date-format) work)))
|
||||
(fg42/brain-state-create
|
||||
(fg42/-brain-current state)
|
||||
(cons (list work (cons entry (cadr entries)))
|
||||
(fg42/-brain-entry-map state))
|
||||
(cons log (fg42/-brain-logs state)))))
|
||||
|
||||
|
||||
(defun fg42/brain-keys (state)
|
||||
"Return all the entry-map keys of the given STATE."
|
||||
(seq-reduce (lambda (acc x)
|
||||
(let ((v (car x)))
|
||||
|
||||
(if (member v acc)
|
||||
acc
|
||||
(cons v acc))))
|
||||
(fg42/-brain-entry-map state)
|
||||
'()))
|
||||
|
||||
|
||||
(defun fg42/brain-delete-work (state work)
|
||||
"Remove the give WORK from the given STATE."
|
||||
(interactive
|
||||
(let ((state (fg42/load-brain-state)))
|
||||
(list state
|
||||
(completing-read "Work: " (fg42/brain-keys state)))))
|
||||
(fg42/save-brain-state
|
||||
(fg42/brain-state-create
|
||||
nil
|
||||
(seq-filter (lambda (x) (equal (car x) work))
|
||||
(fg42/-brain-entry-map state))
|
||||
(cons (list :delete
|
||||
(format-time-string fg42/brain-state-date-format)
|
||||
work)
|
||||
(fg42/-brain-logs state)))))
|
||||
|
||||
|
||||
|
||||
(defun fg42/brain-notes-for (state work)
|
||||
"Create a buffer with all the nosts of the given WORK in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state
|
||||
(completing-read "Work: " (fg42/brain-keys state)))))
|
||||
(let ((buf (get-buffer-create (format "*%s-notes*" work)))
|
||||
(entries (cadr (assoc work (fg42/-brain-entry-map state)))))
|
||||
(set-buffer buf)
|
||||
(erase-buffer)
|
||||
(mapcar (lambda (entry)
|
||||
(insert (format "[%s]: %s\n"
|
||||
(propertize (car entry) 'face 'font-lock-builtin-face)
|
||||
(propertize (cadr entry) 'face 'bold))))
|
||||
entries)
|
||||
(switch-to-buffer buf)))
|
||||
|
||||
|
||||
(defun fg42/brain-notes-for-current-work (state)
|
||||
"Create a buffer with all the nosts of the current work in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state)))
|
||||
(fg42/brain-notes-for state (fg42/-brain-current state)))
|
||||
|
||||
|
||||
(defun fg42/brain-add-notes-for (state work note)
|
||||
"Add a note for the given WORK in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state
|
||||
(completing-read "Work: " (fg42/brain-keys state))
|
||||
(read-string "Note: "))))
|
||||
(fg42/save-brain-state
|
||||
(fg42/add-brain-entry state
|
||||
work
|
||||
(list (format-time-string fg42/brain-state-date-format)
|
||||
note))))
|
||||
|
||||
|
||||
(defun fg42/brain-switch (state src-work note dst-work)
|
||||
"Switch the brain focus from SRC-WORK to DST-WORK on the given STATE.
|
||||
NOTE is the message that has to be saved for the SRC-WORK."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state))
|
||||
(keys (fg42/brain-keys state))
|
||||
(current (fg42/-brain-current state)))
|
||||
(list
|
||||
state
|
||||
(completing-read "What were you working on: " keys nil 'confirm)
|
||||
(read-string
|
||||
"Note for the current work: ")
|
||||
|
||||
(completing-read "Switch brain to: "
|
||||
keys))))
|
||||
|
||||
(fg42/save-brain-state
|
||||
(plist-put
|
||||
(fg42/add-brain-entry state
|
||||
src-work
|
||||
(list (format-time-string fg42/brain-state-date-format)
|
||||
note))
|
||||
'current
|
||||
(intern dst-work)))
|
||||
;; We don't use the latest state for the target work
|
||||
(fg42/brain-notes-for state dst-work))
|
||||
|
||||
|
||||
(provide 'fg42/brain-switch)
|
||||
;;; brain-switch.el ends here
|
|
@ -1,331 +0,0 @@
|
|||
;;; fg42-devtools --- Webkit devtool driver for FG42
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ((dash "2.11.0") (websocket "1.5"))
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
|
||||
(require 'url)
|
||||
(require 'json)
|
||||
(require 'dash)
|
||||
(require 'websocket)
|
||||
|
||||
(require 'fg42/utils)
|
||||
|
||||
;;; Customs & Vars ------------------------------------------------------------
|
||||
(defcustom fg42/devtools-remote-host "127.0.0.1"
|
||||
"Default host for connection to WebKit remote debugging API."
|
||||
:group 'fg42/devtools)
|
||||
|
||||
|
||||
(defcustom fg42/devtools-remote-port 9222
|
||||
"Default port for connection to WebKit remote debugging API."
|
||||
:group 'fg42/devtools)
|
||||
|
||||
|
||||
(defvar fg42/devtools-socket nil
|
||||
"Websocket connection to WebKit remote debugging API.")
|
||||
|
||||
|
||||
(defvar fg42/devtools-rpc-id 0)
|
||||
(defvar fg42/devtools-rpc-callbacks nil)
|
||||
(defvar fg42/devtools-rpc-scripts nil
|
||||
"List of JavaScript files available for live editing.")
|
||||
|
||||
;;; Functions -----------------------------------------------------------------
|
||||
(defun fg42/devtools-encode (data)
|
||||
"Convert the given DATA to json."
|
||||
(let ((json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(json-encode data)))
|
||||
|
||||
|
||||
(defun fg42/devtools-decode (data)
|
||||
"Convert the given json DATA to elisp data structure."
|
||||
(let ((json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(json-read-from-string data)))
|
||||
|
||||
|
||||
(defun fg42/devtools-next-rpc-id ()
|
||||
"Retun the next RPC call id to be used."
|
||||
(setq fg42/devtools-rpc-id (+ 1 fg42/devtools-rpc-id)))
|
||||
|
||||
|
||||
(defun fg42/devtools-register-callback (id fn)
|
||||
"Register the given FN function with the given ID as rpc Callback."
|
||||
(let ((hook (intern (number-to-string id) fg42/devtools-rpc-callbacks)))
|
||||
(add-hook hook fn t)))
|
||||
|
||||
|
||||
(defun fg42/devtools-dispatch-callback (id data)
|
||||
"Execute the callback registered by the given ID with the given DATA."
|
||||
(let ((hook (intern (number-to-string id) fg42/devtools-rpc-callbacks)))
|
||||
(when hook
|
||||
(run-hook-with-args hook data)
|
||||
(unintern hook fg42/devtools-rpc-callbacks))))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-open (socket)
|
||||
"Connect to the given SOCKET."
|
||||
(message "FG42: connected to devtools."))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-close (socket)
|
||||
"Disconnect from the given SOCKET."
|
||||
(message "FG42: disconnected from devtools."))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-script-parsed (data)
|
||||
(let ((extension? (plist-get data :isContentScript))
|
||||
(url (plist-get data :url))
|
||||
(id (plist-get data :scriptId)))
|
||||
(when (and (eq extension? :json-false) (not (string-equal "" url)))
|
||||
(add-to-list 'fg42/devtools-rpc-scripts (list :id id :url url)))))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-script-failed-to-parse (data)
|
||||
(fg42/devtools-console-append (format "%s" data)))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-message-added (data)
|
||||
(let* ((message (plist-get data :message))
|
||||
(url (plist-get message :url))
|
||||
(column (plist-get message :column))
|
||||
(line (plist-get message :line))
|
||||
(type (plist-get message :type))
|
||||
(level (plist-get message :level))
|
||||
(text (plist-get message :text)))
|
||||
;; TODO: add colors based on level
|
||||
(fg42/devtools-console-append
|
||||
(propertize
|
||||
(format "%s: %s\t%s (line: %s column: %s)"
|
||||
level text url line column)
|
||||
'font-lock-face (intern (format "fg42/devtools-log-%s" level))))))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-message (socket data)
|
||||
"The on message callback that gets the incoming DATA from the SOCKET."
|
||||
(let* ((data (fg42/devtools-decode (websocket-frame-payload data)))
|
||||
(method (plist-get data :method))
|
||||
(params (plist-get data :params)))
|
||||
(inspect-data-append data)
|
||||
(pcase method
|
||||
("Debugger.scriptParsed" (fg42/devtools-on-script-parsed params))
|
||||
;; we are getting an error in Console.messageAdded
|
||||
;; ("Debugger.scriptFailedToParse" (fg42/devtools-on-script-failed-to-parse params))
|
||||
("Console.messageAdded" (fg42/devtools-on-message-added params))
|
||||
;; ;; TODO: do something usefull here, possibly great for REPL
|
||||
("Console.messageRepeatCountUpdated")
|
||||
;; nil -> These are return messages from RPC calls, not notification
|
||||
(_ (if method
|
||||
(inspect-data-append data)
|
||||
(fg42/devtools-dispatch-callback (plist-get data :id)
|
||||
(plist-get data :result)))))))
|
||||
|
||||
|
||||
(defun fg42/devtools-call-rpc (method &optional params callback)
|
||||
"Call the given METHOD with PARAMS and call CALLBACK with the result."
|
||||
(let ((id (fg42/devtools-next-rpc-id)))
|
||||
(when callback
|
||||
(fg42/devtools-register-callback id callback))
|
||||
(websocket-send-text
|
||||
fg42/devtools-socket
|
||||
(fg42/devtools-encode (list :id id
|
||||
:method method
|
||||
:params params)))))
|
||||
|
||||
|
||||
(defun fg42/devtools-open-socket (url)
|
||||
"Connect to the given URL and return a socket."
|
||||
(websocket-open url
|
||||
:on-open #'fg42/devtools-on-open
|
||||
:on-message #'fg42/devtools-on-message
|
||||
:on-close #'fg42/devtools-on-close))
|
||||
|
||||
|
||||
(defun fg42/devtools-get-json (url)
|
||||
"Fetch the json data of the given URL using a GET request."
|
||||
(let* ((url-request-method "GET")
|
||||
(url-http-attempt-keepalives nil)
|
||||
(json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(with-current-buffer (url-retrieve-synchronously url)
|
||||
(if (not (eq 200 (url-http-parse-response)))
|
||||
(error "FG42: Unable to connect to devtools host")
|
||||
(goto-char (+ 1 url-http-end-of-headers))
|
||||
(json-read)))))
|
||||
|
||||
|
||||
(defun fg42/devtools-get-tabs (host port)
|
||||
"Read the list of open tabs from the webkit instance at HOST:PORT."
|
||||
(let* ((url (url-parse-make-urlobj
|
||||
"http" nil nil host port "/json"))
|
||||
(tabs (fg42/devtools-get-json url)))
|
||||
(-filter (lambda (tab)
|
||||
(and (plist-get tab :webSocketDebuggerUrl)
|
||||
(string-equal (plist-get tab :type) "page")))
|
||||
tabs)))
|
||||
|
||||
|
||||
(defun fg42/devtools-tab-completion (tab)
|
||||
"A simple completion backend for the given TAB."
|
||||
(let ((title (plist-get tab :title))
|
||||
(url (plist-get tab :url)))
|
||||
(cons (format "%s" title) tab)))
|
||||
|
||||
|
||||
(defun fg42/devtools-select-tab (host port)
|
||||
"Print out the list of tabs from HOST:PORT for the user to choose from."
|
||||
(let* ((tabs (mapcar #'fg42/devtools-tab-completion
|
||||
(fg42/devtools-get-tabs host port)))
|
||||
(selection (completing-read
|
||||
"Tab: " tabs nil t "" nil (caar tabs)))
|
||||
(tab (cdr (assoc selection tabs))))
|
||||
(plist-get tab :webSocketDebuggerUrl)))
|
||||
|
||||
|
||||
(defun fg42/devtools-connect ()
|
||||
"Conntect to the Webkit devtools."
|
||||
(interactive)
|
||||
(message "FG42: Disconnect from any previous connection.")
|
||||
(fg42/devtools-disconnect)
|
||||
(let* ((socket-url (fg42/devtools-select-tab fg42/devtools-remote-host
|
||||
fg42/devtools-remote-port)))
|
||||
(message (format "FG42: Connecting to %s" socket-url))
|
||||
(setq fg42/devtools-socket (fg42/devtools-open-socket socket-url))
|
||||
(message "Sending initial RPC calls...")
|
||||
(fg42/devtools-call-rpc "Console.enable")
|
||||
(fg42/devtools-call-rpc "Debugger.enable")
|
||||
(fg42/devtools-call-rpc "Network.setCacheDisabled" '(:cacheDisabled t))))
|
||||
|
||||
|
||||
(defun fg42/devtools-disconnect ()
|
||||
"Disconnect from the Webkit devtools."
|
||||
(interactive)
|
||||
(when (websocket-openp fg42/devtools-socket)
|
||||
(websocket-close fg42/devtools-socket)
|
||||
(setq fg42/devtools-socket nil
|
||||
fg42/devtools-rpc-scripts nil)))
|
||||
|
||||
|
||||
(defun fg42/devtools-send-eval (code &optional callback)
|
||||
"Send the given CODE to the devtools for evaluation and call the CALLBACK."
|
||||
(fg42/devtools-call-rpc
|
||||
"Runtime.evaluate"
|
||||
(list :expression code
|
||||
:returnByValue t)
|
||||
callback))
|
||||
|
||||
|
||||
(defun fg42/devtools-remove-script (script)
|
||||
(setq fg42/devtools-rpc-scripts
|
||||
(delete script fg42/devtools-rpc-scripts)))
|
||||
|
||||
|
||||
(defun fg42/devtools-script-id (file)
|
||||
(let* ((name (file-name-nondirectory file))
|
||||
(script (--find (string-suffix-p name (plist-get it :url))
|
||||
fg42/devtools-rpc-scripts)))
|
||||
(when script (plist-get script :id))))
|
||||
|
||||
|
||||
(defun fg42/devtools-update ()
|
||||
(interactive)
|
||||
(let ((id (fg42/devtools-script-id (buffer-file-name)))
|
||||
(source (buffer-substring-no-properties
|
||||
(point-min) (point-max))))
|
||||
(if id
|
||||
(fg42/devtools-call-rpc
|
||||
"Debugger.setScriptSource"
|
||||
(list :scriptId id :scriptSource source))
|
||||
(message "No matching script for current buffer."))))
|
||||
|
||||
|
||||
(defun fg42/devtools-reload ()
|
||||
"Reload the tab."
|
||||
(interactive)
|
||||
(fg42/devtools-call-rpc
|
||||
"Page.reload"
|
||||
(list :ignoreCache t)))
|
||||
|
||||
|
||||
(defun fg42/devtools-evaluate-region-or-line (&optional args)
|
||||
(interactive "*P")
|
||||
(let ((start (if (region-active-p)
|
||||
(region-beginning)
|
||||
(line-beginning-position)))
|
||||
(end (if (region-active-p)
|
||||
(region-end)
|
||||
(line-end-position))))
|
||||
(fg42/devtools-send-eval (buffer-substring-no-properties start end))))
|
||||
|
||||
|
||||
(defvar fg42/devtools-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(prog1 map
|
||||
(define-key map (kbd "C-c C-c") #'fg42/devtools-evaluate-region-or-line)
|
||||
(define-key map (kbd "C-c C-k") #'fg42/devtools-update)
|
||||
(define-key map (kbd "C-c C-r") #'fg42/devtools-reload)))
|
||||
"Keymap for FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(defun turn-on-fg42/devtools-mode ()
|
||||
"Turn on FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(defun turn-off-fg42/devtools-mode ()
|
||||
"Turn off FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode fg42/devtools-mode
|
||||
"Minor mode for interact with WebKit remote debugging API."
|
||||
:global nil
|
||||
:group 'fg42/devtools
|
||||
:init-value nil
|
||||
:lighter ""
|
||||
:keymap fg42/devtools-mode-map
|
||||
(if fg42/devtools-mode
|
||||
(turn-on-fg42/devtools-mode)
|
||||
(turn-off-fg42/devtools-mode)))
|
||||
|
||||
(defun fg42/devtools-debug-on ()
|
||||
(interactive)
|
||||
(setq websocket-callback-debug-on-error t))
|
||||
|
||||
(defun fg42/devtools-debug-restart ()
|
||||
(interactive)
|
||||
(fg42/devtools-debug-on)
|
||||
(message "D: disconnect")
|
||||
(fg42/devtools-disconnect)
|
||||
(fg42/devtools-connect))
|
||||
|
||||
;; (fg42/devtools-debug-restart)
|
||||
|
||||
|
||||
(provide 'fg42/devtools)
|
||||
;;; devtools.el ends here
|
|
@ -1,313 +0,0 @@
|
|||
;;; fg42-devtools --- Webkit devtool driver for FG42
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ((dash "2.11.0") (websocket "1.5"))
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'cl)
|
||||
(require 'comint)
|
||||
(require 'fg42/devtools)
|
||||
;; For syntax highlighting
|
||||
(require 'js)
|
||||
|
||||
;;; Faces for console message -------------------------------------------------
|
||||
(defface fg42/devtools-log-warning
|
||||
'((t :inherit warning))
|
||||
"Basic face used to highlight warnings."
|
||||
:version "24.1"
|
||||
:group 'fg42/devtools-faces)
|
||||
|
||||
|
||||
(defface fg42/devtools-log-error
|
||||
'((t :inherit error))
|
||||
"Basic face used to highlight errors."
|
||||
:version "24.1"
|
||||
:group 'fg42/devtools-faces)
|
||||
|
||||
|
||||
(defface fg42/devtools-log-debug
|
||||
'((t :inherit font-lock-comment))
|
||||
"Basic face used to highlight debug-level messages."
|
||||
:version "24.1"
|
||||
:group 'fg42/devtools-faces)
|
||||
|
||||
|
||||
(defface fg42/devtools-log-log
|
||||
'((t :inherit default))
|
||||
"Basic face used to highlight regular messages."
|
||||
:version "24.1"
|
||||
:group 'fg42/devtools-faces)
|
||||
|
||||
|
||||
;; Customs & Variables --------------------------------------------------------
|
||||
(defcustom fg42/devtools-console-prompt "JS> "
|
||||
"Prompt used in fg42/devtools-console."
|
||||
:group 'fg42/devtools)
|
||||
|
||||
|
||||
(defvar fg42/devtools-console-mode-map
|
||||
(let ((map (copy-keymap widget-keymap))
|
||||
(menu-map (make-sparse-keymap)))
|
||||
;;(suppress-keymap map t)
|
||||
(define-key map "\t" 'fg42/devtools-async-completion-at-point)
|
||||
(define-key map "\C-cX" 'kite-clear-console)
|
||||
(define-key map "\C-cg" 'kite-console-visit-source)
|
||||
(define-key map "\C-ci" 'kite-show-log-entry)
|
||||
(define-key map "\C-j" 'fg42/devtools-console-send-input)
|
||||
(define-key map (kbd "RET") 'fg42/devtools-console-send-input)
|
||||
map)
|
||||
"Local keymap for `kite-console-mode' buffers.")
|
||||
|
||||
|
||||
(defvar fg42/devtools-console-input)
|
||||
|
||||
|
||||
(defun fg42/devtools-append-to-console-buffer)
|
||||
(define-derived-mode fg42/devtools-console-mode comint-mode "fg42/devtools-console"
|
||||
"Provide a REPL into the visiting browser."
|
||||
:group 'fg42/devtools
|
||||
:syntax-table emacs-lisp-mode-syntax-table
|
||||
(setq comint-prompt-regexp (concat "^" (regexp-quote fg42/devtools-console-prompt))
|
||||
comint-get-old-input 'fg42/devtools-console-get-old-input ;; TODO: why?
|
||||
comint-input-sender 'fg42/devtools-console-input-sender
|
||||
comint-process-echoes nil)
|
||||
;; (set (make-local-variable 'comint-prompt-read-only) t)
|
||||
(unless (comint-check-proc (current-buffer))
|
||||
(start-process "fg42/devtools-console" (current-buffer) nil)
|
||||
(set-process-query-on-exit-flag (fg42/devtools-console-process) nil)
|
||||
|
||||
(set (make-local-variable 'font-lock-defaults)
|
||||
(list js--font-lock-keywords))
|
||||
|
||||
(goto-char (point-max))
|
||||
(set (make-local-variable 'comint-inhibit-carriage-motion) t)
|
||||
(comint-output-filter (fg42/devtools-console-process) fg42/devtools-console-prompt)
|
||||
(set-process-filter (fg42/devtools-console-process) 'comint-output-filter)))
|
||||
|
||||
(defun fg42/devtools-append-to-console-buffer (log-entry)
|
||||
(let* ((message (plist-get data :message))
|
||||
(url (plist-get message :url))
|
||||
(column (plist-get message :column))
|
||||
(line (plist-get message :line))
|
||||
(type (plist-get message :type))
|
||||
(level (plist-get message :level))
|
||||
(text (plist-get message :text)))
|
||||
(->buffer
|
||||
fg42/devtools-console-buffer-name
|
||||
(format "[%s:%s:%s]<%s>: %s"
|
||||
(apply-face 'error url)
|
||||
line
|
||||
column
|
||||
level
|
||||
message))))
|
||||
|
||||
|
||||
;; (defun fg42/devtools-console-append (data)
|
||||
;; (let ((buffer (get-buffer-create fg42/devtools-console-buffer-name)))
|
||||
;; (when buffer
|
||||
;; (with-current-buffer buffer
|
||||
;; (comint-output-filter (fg42/devtools-console-process) (concat data "\n"))))))
|
||||
|
||||
|
||||
(defun fg42/devtools-console-process ()
|
||||
;; Return the current buffer's process.
|
||||
(get-buffer-process (current-buffer)))
|
||||
|
||||
|
||||
(defun fg42/devtools-console-get-old-input nil
|
||||
;; Return the previous input surrounding point
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(unless (looking-at-p comint-prompt-regexp)
|
||||
(re-search-backward comint-prompt-regexp))
|
||||
(comint-skip-prompt)
|
||||
(buffer-substring (point) (progn (forward-sexp 1) (point)))))
|
||||
|
||||
|
||||
(defun fg42/devtools-console-input-sender (_proc input)
|
||||
;; Just sets the variable fg42/devtools-console-input, which is in the scope
|
||||
;; of `fg42/devtools-console-send-input's call.
|
||||
(setq fg42/devtools-console-input input))
|
||||
|
||||
|
||||
(defun fg42/devtools-console-send-input ()
|
||||
"Evaluate the current console prompt input."
|
||||
(interactive)
|
||||
(let (fg42/devtools-console-input) ; set by
|
||||
; kite-console-input-sender
|
||||
(comint-send-input) ; update history, markers etc.
|
||||
(fg42/devtools-console-eval-input fg42/devtools-console-input)))
|
||||
|
||||
|
||||
(defun fg42/devtools-console-eval-input (input)
|
||||
(fg42/devtools-send-eval
|
||||
input
|
||||
(lambda (result)
|
||||
(if (eq :json-false (plist-get result :wasThrown))
|
||||
(comint-output-filter
|
||||
(fg42/devtools-console-process)
|
||||
(format "%s\n%s"
|
||||
(plist-get (plist-get result :result) :value)
|
||||
fg42/devtools-console-prompt))
|
||||
;; TODO: fix and release object?
|
||||
(format "Error: %s\n%s"
|
||||
result
|
||||
fg42/devtools-console-prompt)))))
|
||||
;; (let ((object-id
|
||||
;; (kite--get result :result :objectId)))
|
||||
;; (when object-id
|
||||
;; (kite--release-object object-id)))
|
||||
|
||||
;; (defun fg42/devtools--eval-in-current-context (input success-function)
|
||||
;; "Evaluate INPUT in the remote remote debugger in the current
|
||||
;; execution context and asynchronously invoke SUCCESS-FUNCTION with
|
||||
;; the results in case of success."
|
||||
;; (let ((eval-params (list :expression input))
|
||||
;; (context-id (plist-get (kite-session-current-context
|
||||
;; kite-session)
|
||||
;; :id)))
|
||||
;; (when context-id
|
||||
;; (setq eval-params (plist-put eval-params :contextId context-id)))
|
||||
;; (kite-send
|
||||
;; "Runtime.evaluate"
|
||||
;; :params
|
||||
;; eval-params
|
||||
;; :success-function
|
||||
;; success-function)))
|
||||
|
||||
|
||||
(defconst fg42/devtools--identifier-part-regexp
|
||||
(rx
|
||||
word-boundary
|
||||
(1+ (or alnum
|
||||
?.
|
||||
(: "\\x" (repeat 2 xdigit))
|
||||
(: "\\u" (repeat 4 xdigit))))
|
||||
point)
|
||||
"Used by `kite-async-completion-at-point' to find a part of a
|
||||
JavaScript identifier.")
|
||||
|
||||
|
||||
(defun fg42/devtools-async-completion-at-point ()
|
||||
"Asynchronously fetch completions for the JavaScript expression
|
||||
at point and, once results have arrived, perform completion using
|
||||
`completion-in-region'.
|
||||
|
||||
Note: we can't use the usual mechanism of hooking into the
|
||||
completions API (`completion-at-point-functions') because it
|
||||
doesn't support asynchronicity."
|
||||
(interactive)
|
||||
(let (completion-begin)
|
||||
|
||||
;; Find the dotted JavaScript expression (consisting of
|
||||
;; identifiers only) before point. Note that we can't use just a
|
||||
;; single regex because greedy regexes don't work when searching
|
||||
;; backwards.
|
||||
(save-excursion
|
||||
(save-match-data
|
||||
(while (re-search-backward fg42/devtools--identifier-part-regexp nil t))
|
||||
(setq completion-begin (point))))
|
||||
|
||||
;; FIXME: the previous step is too broad, it will find identifiers
|
||||
;; starting with a digit. Could do a second pass here to make
|
||||
;; sure that we're looking at a valid expression, or improve error
|
||||
;; handling in `kite--get-properties-fast' to ensure that we do
|
||||
;; the right thing when the JavaScript side gets back to us with a
|
||||
;; complaint.
|
||||
|
||||
(when (< completion-begin (point))
|
||||
(let* ((components (split-string (buffer-substring-no-properties
|
||||
completion-begin
|
||||
(point))
|
||||
"\\."))
|
||||
(last-component (car (last components))))
|
||||
|
||||
(lexical-let ((lex-completion-begin (- (point)
|
||||
(length last-component)))
|
||||
(lex-completion-end (point)))
|
||||
(fg42/devtools--get-properties-fast
|
||||
(if (> (length components) 1)
|
||||
(mapconcat 'identity
|
||||
(subseq components
|
||||
0
|
||||
(- (length components) 1))
|
||||
".")
|
||||
"window")
|
||||
(concat "^" (regexp-quote last-component))
|
||||
(lambda (completions)
|
||||
(let* (completion-extra-properties
|
||||
completion-in-region-mode-predicate)
|
||||
(completion-in-region
|
||||
lex-completion-begin
|
||||
lex-completion-end
|
||||
completions)))))))))
|
||||
|
||||
|
||||
(defun fg42/devtools--get-properties-fast (object-expr js-regex callback)
|
||||
"Efficiently and asynchronously fetch matching property names
|
||||
for the object resulting from evaluating OBJECT-EXPR, a
|
||||
JavaScript expression. Only properties matching JS-REGEX, a
|
||||
regular expression using JavaScript syntax, are fetched. The
|
||||
resulting property names are passed as an unsorted list of
|
||||
strings to CALLBACK, which should accept a single parameter.
|
||||
|
||||
FIXME: no error handling."
|
||||
(lexical-let ((lex-callback callback))
|
||||
(fg42/devtools-send-eval
|
||||
(format "(function(val) {
|
||||
var regex = new RegExp('%s')
|
||||
var test = regex.test.bind(regex)
|
||||
var keys = new Set
|
||||
for (var key in val) regex.test(key) && keys.add(key)
|
||||
Object.getOwnPropertyNames(val).forEach(key => regex.test(key) && keys.add(key))
|
||||
return Array.from(keys)
|
||||
})(%s)"
|
||||
js-regex
|
||||
object-expr)
|
||||
(lambda (result)
|
||||
(funcall lex-callback (plist-get (plist-get result :result) :value))))))
|
||||
|
||||
|
||||
(defun fg42/devtools--release-object (object-id)
|
||||
"Release the object with the given OBJECT-ID on the browser
|
||||
side."
|
||||
(when (null object-id)
|
||||
(error "kite--release-object called with null OBJECT-ID"))
|
||||
(fg42/devtools-call-rpc "Runtime.releaseObject"
|
||||
`((objectId . ,object-id))))
|
||||
|
||||
|
||||
(defun fg42/devtools-console ()
|
||||
"Start a FG42 devtools console."
|
||||
(interactive)
|
||||
(when (not (get-buffer "*fg42/devtools-console*"))
|
||||
(with-current-buffer (get-buffer-create "*fg42/devtools-console*")
|
||||
(fg42/devtools-console-mode)))
|
||||
(pop-to-buffer (get-buffer "*fg42/devtools-console*")))
|
||||
|
||||
|
||||
(provide 'fg42/devtools/console)
|
||||
;; console.el ends here
|
|
@ -1,313 +0,0 @@
|
|||
;;; fg42-devtools --- Webkit devtool driver for FG42
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ((dash "2.11.0") (websocket "1.5"))
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
|
||||
(require 'url)
|
||||
(require 'dash)
|
||||
(require 'websocket)
|
||||
|
||||
(require 'fg42/utils/json)
|
||||
(require 'fg42/utils)
|
||||
(require 'fg42/devtools/vars)
|
||||
|
||||
;;; Functions -----------------------------------------------------------------
|
||||
(defun fg42/devtools-next-rpc-id ()
|
||||
"Retun the next RPC call id to be used."
|
||||
(setq fg42/devtools-rpc-id (+ 1 fg42/devtools-rpc-id)))
|
||||
|
||||
|
||||
(defun fg42/devtools-register-callback (id fn)
|
||||
"Register the given FN function with the given ID as rpc Callback."
|
||||
(let ((hook (intern (number-to-string id) fg42/devtools-rpc-callbacks)))
|
||||
(add-hook hook fn t)))
|
||||
|
||||
|
||||
(defun fg42/devtools-dispatch-callback (id data)
|
||||
"Execute the callback registered by the given ID with the given DATA."
|
||||
(let ((hook (intern (number-to-string id) fg42/devtools-rpc-callbacks)))
|
||||
(when hook
|
||||
(run-hook-with-args hook data)
|
||||
(unintern hook fg42/devtools-rpc-callbacks))))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-open (socket)
|
||||
"Connect to the given SOCKET."
|
||||
(message "FG42: connected to devtools."))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-close (socket)
|
||||
"Disconnect from the given SOCKET."
|
||||
(message "FG42: disconnected from devtools."))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-script-parsed (data)
|
||||
(let ((extension? (plist-get data :isContentScript))
|
||||
(url (plist-get data :url))
|
||||
(id (plist-get data :scriptId)))
|
||||
(when (and (eq extension? :json-false) (not (string-equal "" url)))
|
||||
(add-to-list 'fg42/devtools-rpc-scripts (list :id id :url url)))))
|
||||
|
||||
(defun fg42/devtools->inspect-buffer (data)
|
||||
(inspect-data-append (list "ERRRR" data)))
|
||||
|
||||
(defun fg42/devtools-on-script-failed-to-parse (data)
|
||||
;; (fg42/devtools-console-append (format "%s" data))
|
||||
(fg42/devtools->inspect-buffer data))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-message-added (data)
|
||||
(let* ((message (plist-get data :message))
|
||||
(url (plist-get message :url))
|
||||
(column (plist-get message :column))
|
||||
(line (plist-get message :line))
|
||||
(type (plist-get message :type))
|
||||
(level (plist-get message :level))
|
||||
(text (plist-get message :text)))
|
||||
;; TODO: add colors based on level
|
||||
;;(fg42/devtools-console-append
|
||||
(fg42/devtools->inspect-buffer data)))
|
||||
;; (fg42/devtools->inspect-buffer
|
||||
;; (propertize
|
||||
;; (format "%s: %s\t%s (line: %s column: %s)"
|
||||
;; level text url line column)
|
||||
;; 'font-lock-face (intern (format "fg42/devtools-log-%s" level))))))
|
||||
|
||||
(defun fg42/devtools-log-added (data)
|
||||
(fg42/devtools-append-to-console-buffer data))
|
||||
|
||||
|
||||
(defun fg42/devtools-on-message (socket data)
|
||||
"The on message callback that gets the incoming DATA from the SOCKET."
|
||||
(let* ((data (<-json (websocket-frame-payload data)))
|
||||
(method (plist-get data :method))
|
||||
(params (plist-get data :params)))
|
||||
(inspect-data-append data)
|
||||
(pcase method
|
||||
("Debugger.scriptParsed" (fg42/devtools-on-script-parsed params))
|
||||
;; we are getting an error in Console.messageAdded
|
||||
;; ("Debugger.scriptFailedToParse" (fg42/devtools-on-script-failed-to-parse params))
|
||||
("Log.entryAdded" (fg42/devtools-log-added params))
|
||||
;; ("Console.messageAdded" (fg42/devtools-on-message-added params))
|
||||
;; ;; TODO: do something usefull here, possibly great for REPL
|
||||
("Console.messageRepeatCountUpdated")
|
||||
;; nil -> These are return messages from RPC calls, not notification
|
||||
(_ (if method
|
||||
(message "FG42: Got a method - %s" method)
|
||||
(fg42/devtools-dispatch-callback (plist-get data :id)
|
||||
(plist-get data :result)))))))
|
||||
|
||||
|
||||
(defun fg42/devtools-call-rpc (method &optional params callback)
|
||||
"Call the given METHOD with PARAMS and call CALLBACK with the result."
|
||||
(let ((id (fg42/devtools-next-rpc-id)))
|
||||
(when callback
|
||||
(fg42/devtools-register-callback id callback))
|
||||
(websocket-send-text
|
||||
fg42/devtools-socket
|
||||
(->json (list :id id
|
||||
:method method
|
||||
:params params)))))
|
||||
|
||||
(defun fg42/devtools-on-error (socket where error)
|
||||
(message "FG42: Got and error in %s" where)
|
||||
(message error))
|
||||
|
||||
(defun fg42/devtools-open-socket (url)
|
||||
"Connect to the given URL and return a socket."
|
||||
(websocket-open url
|
||||
:on-open #'fg42/devtools-on-open
|
||||
:on-message #'fg42/devtools-on-message
|
||||
:on-error #'fg42/devtools-on-error
|
||||
:on-close #'fg42/devtools-on-close))
|
||||
|
||||
|
||||
(defun fg42/devtools-get-json (url)
|
||||
"Fetch the json data of the given URL using a GET request."
|
||||
(let* ((url-request-method "GET")
|
||||
(url-http-attempt-keepalives nil)
|
||||
(json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(with-current-buffer (url-retrieve-synchronously url)
|
||||
(if (not (eq 200 (url-http-parse-response)))
|
||||
(error "FG42: Unable to connect to devtools host")
|
||||
(goto-char (+ 1 url-http-end-of-headers))
|
||||
(json-read)))))
|
||||
|
||||
|
||||
(defun fg42/devtools-get-tabs (host port)
|
||||
"Read the list of open tabs from the webkit instance at HOST:PORT."
|
||||
(let* ((url (url-parse-make-urlobj
|
||||
"http" nil nil host port "/json"))
|
||||
(tabs (fg42/devtools-get-json url)))
|
||||
(-filter (lambda (tab)
|
||||
(and (plist-get tab :webSocketDebuggerUrl)
|
||||
(string-equal (plist-get tab :type) "page")))
|
||||
tabs)))
|
||||
|
||||
|
||||
(defun fg42/devtools-tab-completion (tab)
|
||||
"A simple completion backend for the given TAB."
|
||||
(let ((title (plist-get tab :title))
|
||||
(url (plist-get tab :url)))
|
||||
(cons (format "%s" title) tab)))
|
||||
|
||||
|
||||
(defun fg42/devtools-select-tab (host port)
|
||||
"Print out the list of tabs from HOST:PORT for the user to choose from."
|
||||
(let* ((tabs (mapcar #'fg42/devtools-tab-completion
|
||||
(fg42/devtools-get-tabs host port)))
|
||||
(selection (completing-read
|
||||
"Tab: " tabs nil t "" nil (caar tabs)))
|
||||
(tab (cdr (assoc selection tabs))))
|
||||
(plist-get tab :webSocketDebuggerUrl)))
|
||||
|
||||
|
||||
(defun fg42/devtools-connect ()
|
||||
"Conntect to the Webkit devtools."
|
||||
(interactive)
|
||||
(message "FG42: Disconnect from any previous connection.")
|
||||
(fg42/devtools-disconnect)
|
||||
(let* ((socket-url (fg42/devtools-select-tab fg42/devtools-remote-host
|
||||
fg42/devtools-remote-port)))
|
||||
(message (format "FG42: Connecting to %s" socket-url))
|
||||
(setq fg42/devtools-socket (fg42/devtools-open-socket socket-url))
|
||||
(message "Sending initial RPC calls...")
|
||||
;; (fg42/devtools-call-rpc "Console.enable")
|
||||
(fg42/devtools-call-rpc "Log.enable")
|
||||
(fg42/devtools-call-rpc "Debugger.enable")
|
||||
(fg42/devtools-call-rpc "Runtime.enable")
|
||||
(fg42/devtools-call-rpc "Network.setCacheDisabled" '(:cacheDisabled t))))
|
||||
|
||||
|
||||
(defun fg42/devtools-disconnect ()
|
||||
"Disconnect from the Webkit devtools."
|
||||
(interactive)
|
||||
(when (websocket-openp fg42/devtools-socket)
|
||||
(websocket-close fg42/devtools-socket)
|
||||
(setq fg42/devtools-socket nil
|
||||
fg42/devtools-rpc-scripts nil)))
|
||||
|
||||
|
||||
(defun fg42/devtools-send-eval (code &optional callback)
|
||||
"Send the given CODE to the devtools for evaluation and call the CALLBACK."
|
||||
(fg42/devtools-call-rpc
|
||||
"Runtime.evaluate"
|
||||
(list :expression code
|
||||
:returnByValue t)
|
||||
callback))
|
||||
|
||||
|
||||
(defun fg42/devtools-remove-script (script)
|
||||
(setq fg42/devtools-rpc-scripts
|
||||
(delete script fg42/devtools-rpc-scripts)))
|
||||
|
||||
|
||||
(defun fg42/devtools-script-id (file)
|
||||
(let* ((name (file-name-nondirectory file))
|
||||
(script (--find (string-suffix-p name (plist-get it :url))
|
||||
fg42/devtools-rpc-scripts)))
|
||||
(when script (plist-get script :id))))
|
||||
|
||||
|
||||
(defun fg42/devtools-update ()
|
||||
(interactive)
|
||||
(let ((id (fg42/devtools-script-id (buffer-file-name)))
|
||||
(source (buffer-substring-no-properties
|
||||
(point-min) (point-max))))
|
||||
(if id
|
||||
(fg42/devtools-call-rpc
|
||||
"Debugger.setScriptSource"
|
||||
(list :scriptId id :scriptSource source))
|
||||
(message "No matching script for current buffer."))))
|
||||
|
||||
|
||||
(defun fg42/devtools-reload ()
|
||||
"Reload the tab."
|
||||
(interactive)
|
||||
(fg42/devtools-call-rpc
|
||||
"Page.reload"
|
||||
(list :ignoreCache t)))
|
||||
|
||||
|
||||
(defun fg42/devtools-evaluate-region-or-line (&optional args)
|
||||
(interactive "*P")
|
||||
(let ((start (if (region-active-p)
|
||||
(region-beginning)
|
||||
(line-beginning-position)))
|
||||
(end (if (region-active-p)
|
||||
(region-end)
|
||||
(line-end-position))))
|
||||
(fg42/devtools-send-eval (buffer-substring-no-properties start end))))
|
||||
|
||||
|
||||
(defvar fg42/devtools-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(prog1 map
|
||||
(define-key map (kbd "C-c C-c") #'fg42/devtools-evaluate-region-or-line)
|
||||
(define-key map (kbd "C-c C-k") #'fg42/devtools-update)
|
||||
(define-key map (kbd "C-c C-r") #'fg42/devtools-reload)))
|
||||
"Keymap for FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(defun turn-on-fg42/devtools-mode ()
|
||||
"Turn on FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(defun turn-off-fg42/devtools-mode ()
|
||||
"Turn off FG42 devtools mode.")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode fg42/devtools-mode
|
||||
"Minor mode for interact with WebKit remote debugging API."
|
||||
:global nil
|
||||
:group 'fg42/devtools
|
||||
:init-value nil
|
||||
:lighter ""
|
||||
:keymap fg42/devtools-mode-map
|
||||
(if fg42/devtools-mode
|
||||
(turn-on-fg42/devtools-mode)
|
||||
(turn-off-fg42/devtools-mode)))
|
||||
|
||||
(defun fg42/devtools-debug-on ()
|
||||
(interactive)
|
||||
(setq websocket-callback-debug-on-error t))
|
||||
|
||||
(defun fg42/devtools-debug-restart ()
|
||||
(interactive)
|
||||
(fg42/devtools-debug-on)
|
||||
(message "D: disconnect")
|
||||
(fg42/devtools-disconnect)
|
||||
(fg42/devtools-connect))
|
||||
|
||||
;; (fg42/devtools-debug-restart)
|
||||
;; (fg42/devtools-disconnect)
|
||||
|
||||
(provide 'fg42/devtools/core)
|
||||
;;; core.el ends here
|
|
@ -1,58 +0,0 @@
|
|||
;;; fg42-devtools --- Webkit devtool driver for FG42
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;;; Customs & Vars ------------------------------------------------------------
|
||||
(defcustom fg42/devtools-remote-host "127.0.0.1"
|
||||
"Default host for connection to WebKit remote debugging API."
|
||||
:group 'fg42/devtools)
|
||||
|
||||
|
||||
(defcustom fg42/devtools-remote-port 9222
|
||||
"Default port for connection to WebKit remote debugging API."
|
||||
:group 'fg42/devtools)
|
||||
|
||||
|
||||
(defvar fg42/devtools-socket nil
|
||||
"Websocket connection to WebKit remote debugging API.")
|
||||
|
||||
|
||||
(defvar fg42/devtools-rpc-id 0)
|
||||
|
||||
|
||||
(defvar fg42/devtools-rpc-callbacks nil)
|
||||
|
||||
|
||||
(defvar fg42/devtools-rpc-scripts nil
|
||||
"List of JavaScript files available for live editing.")
|
||||
|
||||
(defvar fg42/devtools-console-buffer-name "*1-console*")
|
||||
(defvar fg42/devtools-network-buffer-name "*2-network*")
|
||||
|
||||
(provide 'fg42/devtools/vars)
|
||||
;;; vars.el ends here
|
|
@ -1,169 +0,0 @@
|
|||
;;; extension --- Extension library of FG42
|
||||
;;
|
||||
;; Copyright (c) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Version: 0.1.0
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
;; This library provides some basic means to create a new FG42 extensions
|
||||
(require 'cl-lib)
|
||||
(require 'fg42/utils)
|
||||
|
||||
;; Variables -----------------------------
|
||||
(defvar fg42/extensions '()
|
||||
"A list of official FG42 extensions.")
|
||||
|
||||
(defvar activated-extensions ()
|
||||
"A list of all activated extensions.")
|
||||
|
||||
(defvar disabled-abilities (make-hash-table)
|
||||
"A hash of all the disabled abilities.")
|
||||
|
||||
;; Structures -----------------------------
|
||||
(cl-defstruct fg42-extension
|
||||
"Each FG42 extension should implement a copy of this structure."
|
||||
name
|
||||
|
||||
;; Let's keep this field for backward compatiblity for a while
|
||||
docs
|
||||
|
||||
;; Each extension should expose a info page.
|
||||
doc-index
|
||||
;; Projectile provides a project type that we can use to
|
||||
;; activate/load the extensions based on their registered
|
||||
;; type.
|
||||
project-types
|
||||
|
||||
(version nil)
|
||||
|
||||
;; An instance of fg42-actions structure that describe the
|
||||
;; different actions of the given extension
|
||||
(actions nil)
|
||||
(path nil)
|
||||
;; Callbacks
|
||||
(on-initialize nil)
|
||||
(on-load)
|
||||
(on-unload))
|
||||
|
||||
;; Functions ------------------------------
|
||||
(defun active-ability? (name)
|
||||
"Return t if ability with the given NAME was not in disabled-abilities."
|
||||
(if (gethash name disabled-abilities) nil t))
|
||||
|
||||
|
||||
(defun disable (&rest abilities)
|
||||
"Add the given ABILITIES to disabled-abilities hash."
|
||||
(dolist (abl abilities)
|
||||
(puthash abl t disabled-abilities)))
|
||||
|
||||
|
||||
(defun extension-path (extension)
|
||||
"Return the path to the given EXTENSION."
|
||||
(or (fg42-extension-path extension)
|
||||
;; TODO: should we extract variables such as `fg42-home' to their
|
||||
;; dedicated ns in order to avoid the warning ?
|
||||
(concat fg42-home "/lib/extensions/" (fg42-extension-name extension) ".el")))
|
||||
|
||||
|
||||
(defun load-extension (ext)
|
||||
"Load the given EXT which is a `fg42-extension' instance."
|
||||
(load-file (extension-path ext))
|
||||
(when-let ((init-fn (eval (fg42-extension-on-initialize ext))))
|
||||
(apply (symbol-function init-fn) '(ext))))
|
||||
|
||||
|
||||
;; Macros ---------------------------------
|
||||
(defmacro ability (name deps &rest body)
|
||||
"Define an ability with the given NAME, DEPS, and BODY.
|
||||
|
||||
*deps* should be a list of abilities with the defined ability dependens
|
||||
to them.
|
||||
|
||||
*body* is a block of code which will run as the ability initializer code."
|
||||
(declare (doc-string 2) (indent 0))
|
||||
`(if (active-ability? (intern ,(symbol-name name)))
|
||||
(when (null (delq t (mapcar 'active-ability? (quote ,deps))))
|
||||
,@body)))
|
||||
|
||||
|
||||
(defmacro defability (name deps &optional docs &rest body)
|
||||
"Define an ability with the given NAME, DEPS, DOCS and BODY.
|
||||
|
||||
*deps* should be a list of abilities with the defined ability dependens
|
||||
to them.
|
||||
|
||||
*body* is a block of code which will run as the ability initializer code."
|
||||
(declare (doc-string 3) (indent 2))
|
||||
;; TODO: there's no point of using `if' in the quoted code. evaluate
|
||||
;; the `if' in compile time and return nil or evalute the body.
|
||||
`(if (active-ability? (intern ,(symbol-name name)))
|
||||
(when (null (delq t (mapcar 'active-ability? (quote ,deps))))
|
||||
,@body)))
|
||||
|
||||
|
||||
(defmacro extension (name &rest args)
|
||||
"A simple DSL to define new fg42 extension by given NAME and ARGS."
|
||||
;(declare (doc-string 1) (indent 1))
|
||||
`(setq ,name (apply 'make-fg42-extension :name ,(symbol-name name) (quote ,args))))
|
||||
|
||||
|
||||
(defmacro defextension (name &optional docstring &rest args)
|
||||
"A simple DSL to define new fg42 extension by given NAME, DOCSTRING and ARGS."
|
||||
(declare (doc-string 2) (indent 1))
|
||||
;; TODO: Inject the docstring to the current `system' in order
|
||||
;; to collect it later for `describe-extension' function.
|
||||
`(setq ,name (apply 'make-fg42-extension
|
||||
:name ,(symbol-name name)
|
||||
(quote ,args))))
|
||||
|
||||
|
||||
(defmacro with-ability (name &rest body)
|
||||
"If the ability with the given NAME is not disabled, Run the BODY."
|
||||
`(when (active-ability? (intern ,(symbol-name name)))
|
||||
,@body))
|
||||
|
||||
|
||||
(defun describe-extension (extension)
|
||||
"Show the doc-string of the EXTENSION."
|
||||
(interactive)
|
||||
(let ((doc-file (fg42-extension-docs (symbol-value extension)))
|
||||
(b (get-buffer-create (concat "*" (symbol-name extension) " docs*"))))
|
||||
(set-buffer b)
|
||||
(insert-file-contents (concat fg42-home "/" doc-file))
|
||||
(read-only-mode t)
|
||||
(switch-to-buffer b)
|
||||
(org-mode)))
|
||||
|
||||
|
||||
(comment
|
||||
(defextension example-extension
|
||||
"Very simple extention as a test"
|
||||
:path "~/example-extension.el"
|
||||
:on-initialize 'example-extention-init)
|
||||
|
||||
(load-extension example-extension))
|
||||
|
||||
|
||||
(provide 'fg42/extension)
|
||||
;;; extension ends here
|
|
@ -1,25 +0,0 @@
|
|||
;;; Helpers --- Helper functions of FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'cl-lib)
|
||||
|
||||
;;;###autoload
|
||||
(defun what-face (pos)
|
||||
"Return the face of the thing at the current POS."
|
||||
(interactive "d")
|
||||
(let ((face (or (get-char-property (point) 'read-face-name)
|
||||
(get-char-property (point) 'face))))
|
||||
(if face (message "Face: %s" face) (message "No face at %d" pos))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun env (&rest args)
|
||||
"Setup environment variables given as ARGS."
|
||||
(require 'seq)
|
||||
(let ((pairs (seq-partition args 2)))
|
||||
(dolist (pair pairs)
|
||||
(progn (setenv (substring (symbol-name (car pair)) 1) (car (cdr pair)))))))
|
||||
|
||||
|
||||
(provide 'fg42/helpers)
|
||||
;;; helpers ends here
|
|
@ -1,70 +0,0 @@
|
|||
;;; fg42-keybindings --- Keybinding helper macros for FG42
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: keybinding
|
||||
;; Version: 0.1.0
|
||||
;;
|
||||
;; 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:
|
||||
;;; Code:
|
||||
|
||||
|
||||
(defun -defkey-god (map key fn)
|
||||
"Set the given KEY on key map MAP to FN."
|
||||
(define-key map (kbd key) fn))
|
||||
|
||||
|
||||
(defun -defkey-human (map key fn)
|
||||
"Set the given KEY on key map MAP to FN."
|
||||
(define-key map (kbd key) fn))
|
||||
|
||||
|
||||
(defun -defkey-evil (map state-keys fn)
|
||||
"Set the given STATE-KEYS on key map MAP to FN."
|
||||
(let ((normal-key (plist-get state-keys :normal))
|
||||
(visual-key (plist-get state-keys :visual))
|
||||
(insert-key (plist-get state-keys :insert))
|
||||
(emacs-key (plist-get state-keys :emacs)))
|
||||
(cond
|
||||
((not (null normal-key)) (evil-define-key 'normal map (kbd normal-key) fn))
|
||||
((not (null visual-key)) (evil-define-key 'visual map (kbd visual-key) fn))
|
||||
((not (null insert-key)) (evil-define-key 'insert map (kbd insert-key) fn))
|
||||
((not (null emacs-key)) (evil-define-key 'emacs map (kbd emacs-key) fn)))))
|
||||
|
||||
|
||||
(defmacro defkey (map fn &rest keys)
|
||||
"Defines a key binding for FG42 for different types.
|
||||
Defines a keybinding in the given MAP for the given KEYS that maps
|
||||
to the given FN with the given DOCSTRING.
|
||||
Example usage :
|
||||
\\(defkey `'global-map`' 'goto-line
|
||||
:evil \\(:normal \"SPC s u\"\\)
|
||||
:god \"<f2>\"\\)"
|
||||
(let ((god-key (plist-get keys :god))
|
||||
(human-key (plist-get keys :human))
|
||||
(evil-state-key (plist-get keys :evil)))
|
||||
(when (and (is-evil?) (null evil-state-key)) (error "You should pass :evil keys when you are evil user"))
|
||||
(when (and (is-god?) (null god-key)) (error "You should pass :god keys when you are a god user"))
|
||||
(when (and (is-human?) (null human-key)) (error "You should pass :evil keys when you are a human user"))
|
||||
(cond
|
||||
((is-god?) `(-defkey-god ,map ,god-key ,fn))
|
||||
((is-human?) `(-defkey-human ,map ,human-key ,fn))
|
||||
((is-evil?) `(-defkey-evil ,map (quote ,evil-state-key) ,fn)))))
|
||||
|
||||
(provide 'fg42/key-bindings)
|
||||
;;; key-bindings.el ends here
|
|
@ -1,8 +0,0 @@
|
|||
;;; logger --- logger library of FG42
|
||||
;;; Commentary:
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
|
||||
(provide 'fg42/logger)
|
||||
;;; logger ends here
|
|
@ -1,8 +0,0 @@
|
|||
;; Vars ------------------------
|
||||
(defvar fg42-default-project-file ".fg42.json"
|
||||
"The name of default project file in projects.")
|
||||
|
||||
;; Functions -------------------
|
||||
(defun fg42-read-project-data ())
|
||||
|
||||
(defun fg42-write-project-data ())
|
|
@ -1,44 +0,0 @@
|
|||
;;; Race --- A utitlity to tweak shortkeys based on user preference
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defvar fg42-user-race :god
|
||||
"The race of the user.")
|
||||
|
||||
(defun i-am (race)
|
||||
"Set the user race to the given RACE."
|
||||
(if (member race '(:god :human :evil))
|
||||
(setq fg42-user-race race)
|
||||
(error "Invalid race '%s'. Choices are ':god', ':human', ':evil'" race)))
|
||||
|
||||
(defun i-am-evil ()
|
||||
"Set the user race to :evil."
|
||||
(interactive)
|
||||
(setq fg42-user-race :evil))
|
||||
|
||||
(defun i-am-god ()
|
||||
"Set the user race to :god."
|
||||
(interactive)
|
||||
(setq fg42-user-race :god))
|
||||
|
||||
(defun i-am-human ()
|
||||
"Set the user race to :human."
|
||||
(interactive)
|
||||
(setq fg42-user-race :human))
|
||||
|
||||
(defun is-evil? ()
|
||||
"Is user a evil?"
|
||||
(interactive)
|
||||
(eq fg42-user-race :evil))
|
||||
|
||||
(defun is-god? ()
|
||||
"Is user a god?"
|
||||
(interactive)
|
||||
(eq fg42-user-race :god))
|
||||
|
||||
(defun is-human? ()
|
||||
"Is user a human?"
|
||||
(interactive)
|
||||
(eq fg42-user-race :human))
|
||||
|
||||
(provide 'fg42/race)
|
||||
;;; race.el ends here
|
|
@ -1,65 +0,0 @@
|
|||
(defconst fg42-about-text
|
||||
`("FG42")
|
||||
"A list of texts to show in the middle part of the About screen.
|
||||
Each element in the list should be a list of strings or pairs
|
||||
`:face FACE', like `fancy-splash-insert' accepts them.")
|
||||
|
||||
;; Vars ------------------------------
|
||||
(defvar fg42-logo-image (concat (getenv "FG42_HOME") "/assets/images/logo.png")
|
||||
"Default fg42 logo")
|
||||
|
||||
;; Functions -------------------------
|
||||
(defun fg42-about-screen ()
|
||||
"Display fancy About screen."
|
||||
(interactive)
|
||||
(let ((frame (fancy-splash-frame)))
|
||||
(save-selected-window
|
||||
(select-frame frame)
|
||||
(switch-to-buffer "*FG42 About*")
|
||||
(setq buffer-undo-list t)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(if pure-space-overflow
|
||||
(insert pure-space-overflow-message))
|
||||
;(fg42-splash-head)
|
||||
(dolist (text fg42-about-text)
|
||||
;(apply #'fancy-splash-insert text)
|
||||
(insert (propertize text 'display `(space :align-to (+ center 5))))
|
||||
(insert "\n"))
|
||||
(set-buffer-modified-p nil)
|
||||
(goto-char (point-min))
|
||||
(force-mode-line-update))
|
||||
(use-local-map splash-screen-keymap)
|
||||
(setq-local browse-url-browser-function 'eww-browse-url)
|
||||
(setq tab-width 22)
|
||||
(setq buffer-read-only t)
|
||||
(goto-char (point-min))
|
||||
(forward-line 3))))
|
||||
|
||||
|
||||
(defun fg42-splash-head ()
|
||||
"Insert the head part of the splash screen into the current buffer."
|
||||
(let* ((img (create-image fg42-logo-image))
|
||||
(image-width (and img (car (image-size img))))
|
||||
(window-width (window-width)))
|
||||
(when img
|
||||
(when (> window-width image-width)
|
||||
;; Center the image in the window.
|
||||
(insert (propertize " " 'display
|
||||
`(space :align-to (+ center (-0.5 . ,img)))))
|
||||
|
||||
;; Change the color of the XPM version of the splash image
|
||||
;; so that it is visible with a dark frame background.
|
||||
(when (and (memq 'xpm img)
|
||||
(eq (frame-parameter nil 'background-mode) 'dark))
|
||||
(setq img (append img '(:color-symbols (("#000000" . "gray30"))))))
|
||||
|
||||
;; Insert the image with a help-echo and a link.
|
||||
(make-button (prog1 (point) (insert-image img)) (point)
|
||||
'face 'default
|
||||
'help-echo "mouse-2, RET: Browse http://www.gnu.org/"
|
||||
'action (lambda (_button) (browse-url "http://www.gnu.org/"))
|
||||
'follow-link t)
|
||||
(insert "\n\n")))))
|
||||
|
||||
(provide 'fg42/splash)
|
|
@ -1,67 +0,0 @@
|
|||
;;; system --- System library of FG42
|
||||
;;
|
||||
;; Copyright (c) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Version: 0.1.0
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'fg42/utils)
|
||||
|
||||
|
||||
(defun start-system (system)
|
||||
"Start the given SYSTEM.
|
||||
|
||||
This is the default function to boot a system. Each system might
|
||||
provide a different function to boo rather than this one."
|
||||
(require 'fg42))
|
||||
|
||||
|
||||
(cl-defstruct fg42-system
|
||||
"A `system' describes a FG42 instance. Everything that is needed
|
||||
to load FG42."
|
||||
name
|
||||
(packages '())
|
||||
(abilities '())
|
||||
;; A function which takes the `system' and starts it.
|
||||
(start 'start-system)
|
||||
(stop nil))
|
||||
|
||||
|
||||
(defmacro defsystem (name &optional docstring &rest body)
|
||||
"Define a system with the given NAME, DOCSTRING and BODY."
|
||||
(declare (doc-string 2) (indent 1))
|
||||
`(setq ,name (apply 'make-fg42-system
|
||||
:name ,(symbol-name name)
|
||||
(quote ,body))))
|
||||
|
||||
|
||||
(comment
|
||||
(defsystem FG42
|
||||
"docstring"
|
||||
:packages '(('elisp-extension :version "1.3.3"))
|
||||
:abilities '()))
|
||||
|
||||
(provide 'fg42/system)
|
||||
;;; system.el ends here
|
|
@ -1,109 +0,0 @@
|
|||
;;; Utils --- A collection of utility functions for FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'cl)
|
||||
|
||||
(require 'fg42/vars)
|
||||
(require 'fg42/utils/json)
|
||||
|
||||
;;; Buffer helpers ------------------------------------------------------------
|
||||
(defun buffer-mode (buffer-or-string)
|
||||
"Return the major mode associated with a the given BUFFER-OR-STRING."
|
||||
(with-current-buffer buffer-or-string
|
||||
major-mode))
|
||||
|
||||
|
||||
(defun ->buffer (buffer-name data &optional fn)
|
||||
"Insert the given DATA into the given buffer provided by BUFFER-NAME.
|
||||
|
||||
It will create a the buffer if it doesn't exist. It will call the given FN
|
||||
at the end in context of the buffer. This function accepts only one argument
|
||||
with is the buffer."
|
||||
(let ((buf (get-buffer-create buffer-name)))
|
||||
(with-current-buffer buf
|
||||
(insert data)
|
||||
(when fn
|
||||
(funcall fn buf)))))
|
||||
|
||||
|
||||
(defun inspect-as-json-and-switch (data)
|
||||
"Convert the given DATA to json and put it in the debug buffer."
|
||||
(->buffer fg42/inspect-buffer
|
||||
(->json data)
|
||||
#'(lambda (buf)
|
||||
(require 'json-mode)
|
||||
(json-mode)
|
||||
(json-pretty-print-buffer)
|
||||
(switch-to-buffer buf))))
|
||||
|
||||
|
||||
(defun inspect-as-json (data)
|
||||
"Convert the given DATA to json and put it in the debug buffer."
|
||||
(->buffer fg42/inspect-buffer
|
||||
(->json data)
|
||||
#'(lambda (buf)
|
||||
(require 'json-mode)
|
||||
(json-mode)
|
||||
(json-pretty-print-buffer))))
|
||||
|
||||
(defmacro inspect-expression (&rest body)
|
||||
"Pretty prints the result of the given BODY."
|
||||
`(pp-display-expression ,@body (get-buffer-create fg42/inspect-buffer)))
|
||||
|
||||
(defun inspect-data-append (data)
|
||||
"Append the given DATA to the inspection buffer with padding."
|
||||
(->buffer
|
||||
fg42/inspect-buffer
|
||||
(format
|
||||
"\n;; START ======================================================\n%s%s"
|
||||
(pp-to-string data)
|
||||
";; END.\n")))
|
||||
|
||||
|
||||
(defun apply-face (face-symbol text)
|
||||
"Apply the given FACE-SYMBOL to the given TEXT."
|
||||
(put-text-property 0 (length text) 'face face-symbol text))
|
||||
|
||||
|
||||
(defmacro comment (&rest body)
|
||||
"A macro similar to Clojure's comment macro that ignore the BODY."
|
||||
(declare (indent 0))
|
||||
`nil)
|
||||
|
||||
|
||||
(defmacro -> (x &optional form &rest more)
|
||||
"Thread the expr through the forms FORM and rest of form in MORE.
|
||||
Insert X as the second item in the first form, making a list of
|
||||
it if it is not a list already. If there are more forms, insert
|
||||
the first form as the second item in second form, etc."
|
||||
(declare (debug (form &rest [&or symbolp (sexp &rest form)])))
|
||||
(cond
|
||||
((null form) x)
|
||||
((null more) (if (listp form)
|
||||
`(,(car form) ,x ,@(cdr form))
|
||||
(list form x)))
|
||||
(:else `(-> (-> ,x ,form) ,@more))))
|
||||
|
||||
|
||||
(defun read-file (path)
|
||||
"Return the content of the file at the given PATH as string."
|
||||
(when (file-exists-p path)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents path)
|
||||
(buffer-string))))
|
||||
|
||||
|
||||
(defun file->lisp (path)
|
||||
"Read the content of the file at PATH and return the Lisp in it."
|
||||
(read (or (read-file path) "()")))
|
||||
|
||||
|
||||
(defun lisp->file (path expr)
|
||||
"Write the given EXPR to the given file at PATH."
|
||||
(with-temp-file path
|
||||
(print expr (current-buffer))))
|
||||
|
||||
|
||||
(provide 'fg42/utils)
|
||||
;;; utils.el ends here
|
|
@ -1,49 +0,0 @@
|
|||
;;; json --- FG42 json helpers
|
||||
;;
|
||||
;; Copyright (c) 2019 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ((dash "2.11.0") (websocket "1.5"))
|
||||
;;
|
||||
;; 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/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
|
||||
(require 'json)
|
||||
|
||||
|
||||
(defun ->json (data)
|
||||
"Convert the given DATA to json."
|
||||
(let ((json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(json-encode data)))
|
||||
|
||||
|
||||
(defun <-json (data)
|
||||
"Convert the given json DATA to elisp data structure."
|
||||
(let ((json-array-type 'list)
|
||||
(json-object-type 'plist))
|
||||
(json-read-from-string data)))
|
||||
|
||||
|
||||
(provide 'fg42/utils/json)
|
||||
;;; json.el ends here
|
|
@ -1,10 +0,0 @@
|
|||
;;; vars --- vars library of FG42
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defvar default-theme nil "Default FG42 theme.")
|
||||
|
||||
(defvar fg42/inspect-buffer "*inspect-buffer*"
|
||||
"The name of the buffer that is going to be used for data inspection.")
|
||||
|
||||
(provide 'fg42/vars)
|
||||
;;; vars.el ends here
|
156
lib/fg42/wm.el
156
lib/fg42/wm.el
|
@ -1,156 +0,0 @@
|
|||
;;; WM --- Enables FG42 as a window manager using EXWM
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'fpkg)
|
||||
|
||||
|
||||
(defmacro when-wm (&rest body)
|
||||
"Run the BODY only if in wm mode."
|
||||
(if (string= (getenv "FG42_WM") "true")
|
||||
`(progn ,@body)
|
||||
nil))
|
||||
|
||||
|
||||
(defmacro when-not-wm (&rest body)
|
||||
"Run the BODY only if in wm mode."
|
||||
(if (string= (getenv "FG42_WM") "true")
|
||||
nil
|
||||
`(progn ,@body)))
|
||||
|
||||
|
||||
(defun disable-nlinum ()
|
||||
"Disable nlinum and fringe-mode."
|
||||
(fringe-mode -1)
|
||||
(nlinum-mode -1))
|
||||
|
||||
|
||||
(defun run-program (path)
|
||||
"Execute the program at the given PATH."
|
||||
(start-process-shell-command path nil path))
|
||||
|
||||
|
||||
(defun run-program-in-xterm (path &optional name)
|
||||
"Execute the program at the given PATH via xterm with the given NAME."
|
||||
(run-program (concat "xterm -e " path)))
|
||||
|
||||
|
||||
(defun rename-x-window (&optional name)
|
||||
"Rename the current buffer to NAME."
|
||||
(interactive)
|
||||
(let ((new-name (or name (read-string "New name: "))))
|
||||
(exwm-workspace-rename-buffer new-name)))
|
||||
|
||||
|
||||
(defability wm ()
|
||||
"Window manager ability for FG42."
|
||||
(depends-on 'exwm)
|
||||
|
||||
(defun initialize-wm ()
|
||||
(when-wm
|
||||
(require 'exwm)
|
||||
(require 'exwm-config)
|
||||
(require 'exwm-systemtray)
|
||||
(exwm-config-ido)
|
||||
;; Set the initial number of workspaces (they can also be created later).
|
||||
(setq exwm-workspace-number 10)
|
||||
|
||||
;; All buffers created in EXWM mode are named "*EXWM*". You may want to
|
||||
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
|
||||
;; are run when a new X window class name or title is available. Here's
|
||||
;; some advice on this topic:
|
||||
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
|
||||
;; + For applications with multiple windows (e.g. GIMP), the class names of
|
||||
; all windows are probably the same. Using window titles for them makes
|
||||
;; more sense.
|
||||
;; In the following example, we use class names for all windows except for
|
||||
;; Java applications and GIMP.
|
||||
(add-hook 'exwm-update-class-hook
|
||||
(lambda ()
|
||||
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
|
||||
(string= "gimp" exwm-instance-name))
|
||||
(exwm-workspace-rename-buffer exwm-class-name))))
|
||||
(add-hook 'exwm-update-title-hook
|
||||
(lambda ()
|
||||
(when (or (not exwm-instance-name)
|
||||
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
|
||||
(string= "gimp" exwm-instance-name))
|
||||
(exwm-workspace-rename-buffer exwm-title))))
|
||||
|
||||
|
||||
;; Global keybindings can be defined with `exwm-input-global-keys'.
|
||||
;; Here are a few examples:
|
||||
(setq exwm-input-global-keys
|
||||
`(
|
||||
;; Bind "s-r" to exit char-mode and fullscreen mode.
|
||||
([?\s-r] . exwm-reset)
|
||||
([?\s-g] . keyboard-quit)
|
||||
([8388640] . other-window)
|
||||
;; Bind "s-w" to switch workspace interactively.
|
||||
([?\s-w] . exwm-workspace-switch)
|
||||
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))
|
||||
;; Bind "s-&" to launch applications ('M-&' also works if the output
|
||||
;; buffer does not bother you).
|
||||
([?\s-d] . (lambda (command)
|
||||
(interactive (list (read-shell-command "$ ")))
|
||||
(start-process-shell-command command nil command)))
|
||||
;; Bind "s-<f2>" to "slock", a simple X display locker.
|
||||
([s-f2] . (lambda ()
|
||||
(interactive)
|
||||
(start-process "" nil "/usr/bin/slock")))))
|
||||
;; To add a key binding only available in line-mode, simply define it in
|
||||
;; `exwm-mode-map'. The following example shortens 'C-c q' to 'C-q'.
|
||||
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
|
||||
|
||||
(push ?\C-c exwm-input-prefix-keys)
|
||||
|
||||
;; The following example demonstrates how to use simulation keys to mimic
|
||||
;; the behavior of Emacs. The value of `exwm-input-simulation-keys` is a
|
||||
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
|
||||
;; and DEST is what EXWM actually sends to application. Note that both SRC
|
||||
;; and DEST should be key sequences (vector or string).
|
||||
(setq exwm-input-simulation-keys
|
||||
`(
|
||||
;; movement
|
||||
(,(kbd "C-b") . left)
|
||||
(,(kbd "M-b") . ,(kbd "C-<left>"))
|
||||
(,(kbd "C-f") . right)
|
||||
(,(kbd "M-f") . ,(kbd "C-<right>"))
|
||||
(,(kbd "C-p") . up)
|
||||
(,(kbd "C-n") . down)
|
||||
(,(kbd "C-a") . home)
|
||||
(,(kbd "C-e") . end)
|
||||
(,(kbd "M-v") . prior)
|
||||
(,(kbd "C-v") . next)
|
||||
(,(kbd "C-d") . delete)
|
||||
;;(,(kbs "C-k") . [S-end delete])
|
||||
;; navigation
|
||||
(,(kbd "C-c b") . ,(kbd "M-<left>"))
|
||||
(,(kbd "C-c f") . ,(kbd "M-<right>"))
|
||||
(,(kbd "C-c w") . ,(kbd "C-w"))
|
||||
(,(kbd "C-w") . ,(kbd "C-x"))
|
||||
(,(kbd "M-w") . ,(kbd "C-c"))
|
||||
(,(kbd "C-y") . ,(kbd "C-v"))
|
||||
;; search
|
||||
(,(kbd "C-s") . ,(kbd "C-f"))))
|
||||
|
||||
;; You can hide the minibuffer and echo area when they're not used, by
|
||||
;; uncommenting the following line.
|
||||
;(setq exwm-workspace-minibuffer-position 'bottom)
|
||||
|
||||
;; Do not forget to enable EXWM. It will start by itself when things are
|
||||
;; ready. You can put it _anywhere_ in your configuration.
|
||||
(exwm-enable)
|
||||
(exwm-systemtray-enable)
|
||||
|
||||
(with-ability nlinum
|
||||
(add-hook 'exwm-mode-hook 'disable-nlinum)))))
|
||||
|
||||
|
||||
(provide 'fg42/wm)
|
||||
;;; wm.el ends here
|
135
lib/fpkg.el
135
lib/fpkg.el
|
@ -1,135 +0,0 @@
|
|||
;;; fpkg --- a simple package manager for FG42 -*- lexical-binding: t; -*-
|
||||
;;
|
||||
;; Copyright (C) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; Keywords: lisp fg42 IDE package manager
|
||||
;; Version: 1.0.0
|
||||
;;
|
||||
;; 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:
|
||||
;;
|
||||
;; Simple package manager for FG42
|
||||
;;
|
||||
;;; Code:
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
(require 'fg42/extension)
|
||||
(require 'fg42/utils)
|
||||
(require 'fpkg/installers)
|
||||
|
||||
;; Variables ---------------------------------
|
||||
(cl-defstruct fpkg-dependency
|
||||
"Package structure for FG42."
|
||||
name
|
||||
(version "0")
|
||||
(path nil)
|
||||
(source 'elpa))
|
||||
|
||||
|
||||
(defvar fpkg-initilized-p nil
|
||||
"A boolean flag that indicates whether FPKG is initialized or not.")
|
||||
|
||||
|
||||
(defvar required-packages (make-hash-table)
|
||||
"A hash of `fg42-package structure representing required packages.")
|
||||
|
||||
|
||||
;; Functions ----------------------------------
|
||||
(defun all-dependencies-installed? ()
|
||||
"Return t if all the dependencies installed."
|
||||
(let ((result t))
|
||||
(dolist (pkg (hash-table-keys required-packages))
|
||||
(when (not (package-installed-p pkg))
|
||||
(message "'%s' package is not installed" pkg)
|
||||
(setq result nil)))
|
||||
result))
|
||||
|
||||
|
||||
(defun install--package (pkg)
|
||||
"Intall the package PKG via its propreate source."
|
||||
(let* ((source (fpkg-dependency-source pkg))
|
||||
(func-name (concat "install-package-via-" (symbol-name source)))
|
||||
(install-func (symbol-function (intern func-name))))
|
||||
(funcall install-func pkg)))
|
||||
|
||||
|
||||
(defun fpkg-initialize ()
|
||||
"Initilize the `package.el' and related stuff to be used in FG42."
|
||||
(let ((packages (hash-table-values required-packages)))
|
||||
|
||||
(require 'package)
|
||||
|
||||
(add-to-list 'package-archives
|
||||
'("melpa" . "http://melpa.org/packages/") t)
|
||||
(when (< emacs-major-version 24)
|
||||
;; For important compatibility libraries like cl-lib
|
||||
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
|
||||
|
||||
;; Initialize package.el
|
||||
(package-initialize)
|
||||
|
||||
(setq url-http-attempt-keepalives nil)
|
||||
|
||||
(unless (all-dependencies-installed?)
|
||||
;; check for new packages (package versions)
|
||||
(message "%s" "Refreshing package database...")
|
||||
(package-refresh-contents)
|
||||
|
||||
;; install the missing packages
|
||||
(dolist (pkg packages)
|
||||
(when (not (package-installed-p (fpkg-dependency-name pkg)))
|
||||
(install--package pkg))))))
|
||||
|
||||
|
||||
(defun fpkg-initialize-once ()
|
||||
"Initilize FPKG only once."
|
||||
(when (not fpkg-initilized-p)
|
||||
(fpkg-initialize)))
|
||||
|
||||
|
||||
|
||||
(defun official-extension-p (args)
|
||||
"Predicate to say if ARGS is an official FG42 extension."
|
||||
(member args fg42/extensions))
|
||||
|
||||
|
||||
(defun get-receipe (name)
|
||||
"Get the receipe for given NAME if that is an official extension."
|
||||
(list name :host 'gitlab :repo (format "FG42/%s" name)))
|
||||
|
||||
|
||||
(defmacro fg42-install-extension (args)
|
||||
"Install if given ARGS is an official extension."
|
||||
;; TODO: Straight supports reciepe registery it might worth
|
||||
;; using it.
|
||||
(let ((reciepe (get-receipe args)))
|
||||
`(use-package ,args :straight ,reciepe)))
|
||||
|
||||
|
||||
(defmacro depends-on (pkgname &rest details)
|
||||
"Install the given PKGNAME with the optional DETAILS."
|
||||
(if (official-extension-p pkgname)
|
||||
`(fg42-install-extension ,(eval pkgname))
|
||||
`(use-package ,(eval pkgname) ,@details)))
|
||||
|
||||
(defun depends-on (pkgname &rest args)
|
||||
"Install the package PKGNAME with respect to the ARGS."
|
||||
(let ((pkg (apply 'make-fpkg-dependency :name pkgname args)))
|
||||
(puthash pkgname pkg required-packages)))
|
||||
|
||||
|
||||
(provide 'fpkg)
|
||||
;;; fpkg.el ends here
|
|
@ -1,6 +0,0 @@
|
|||
;;; Code:
|
||||
(defun install-package-via-elpa (pkg)
|
||||
"Install a package via package.el."
|
||||
(package-install (fpkg-dependency-name pkg)))
|
||||
|
||||
(provide 'fpkg/installers)
|
17
lib/lab.el
17
lib/lab.el
|
@ -1,17 +0,0 @@
|
|||
(defun add-debug-js ()
|
||||
(interactive)
|
||||
(insert (concat "console.log('" (which-function) ": ', );"))
|
||||
(goto-char (- (point) 2)))
|
||||
|
||||
(defun add-debug-py ()
|
||||
(interactive)
|
||||
(insert (concat "print('" (which-function) ": ', )"))
|
||||
(goto-char (- (point) 1)))
|
||||
|
||||
(defun insert-printer ()
|
||||
(interactive)
|
||||
(cond
|
||||
((member (buffer-mode (current-buffer)) '(rjsx-mode js2-mode)) (add-debug-js))
|
||||
((member (buffer-mode (current-buffer)) '(python-mode)) (add-debug-py))))
|
||||
|
||||
(global-set-key (kbd "M-2") 'insert-printer)
|
|
@ -1,54 +0,0 @@
|
|||
;;; configurations --- A small library to load project specific configurations.
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(require 'seq)
|
||||
|
||||
(defvar project-config-dir "~/.fg42/project-config"
|
||||
"This variable contains the path to the projects global configurations.")
|
||||
|
||||
(defvar __project-name__ nil
|
||||
"It's an internal variable to holds the current project name.")
|
||||
|
||||
(defun project-name (project)
|
||||
"Return the project name of the given PROJECT."
|
||||
(car (last (seq-filter
|
||||
(lambda (x) (not (equal "" x)))
|
||||
(split-string project "/")))))
|
||||
|
||||
(defun global-project-config-path (project)
|
||||
"Return path of the global project config for the given PROJECT or nil."
|
||||
(let ((config-path (format "%s/%s.el"
|
||||
project-config-dir
|
||||
(project-name project))))
|
||||
(if (file-exists-p config-path)
|
||||
config-path
|
||||
nil)))
|
||||
|
||||
(defun config-path (project)
|
||||
"Return the path of the given PROJECT configuration."
|
||||
(let ((in-proj-config (format "%s.fg42.el" project))
|
||||
(global-proj-config (global-project-config-path project)))
|
||||
(if (file-exists-p in-proj-config)
|
||||
in-proj-config
|
||||
global-proj-config)))
|
||||
|
||||
|
||||
(defun load-config-file (project-name config)
|
||||
"Load the given CONFIG file with the given PROJECT-NAME."
|
||||
(require 'projects/dsl)
|
||||
(setq __project-name__ project-name)
|
||||
(load config))
|
||||
|
||||
|
||||
(defun load-configuration ()
|
||||
"Load the configuration for the current project."
|
||||
(interactive)
|
||||
(let* ((project (cdr (project-current)))
|
||||
(config (config-path project)))
|
||||
(if (not (equal nil config))
|
||||
(load-config-file project config)
|
||||
(message "No configuration has been found for current project."))))
|
||||
|
||||
|
||||
(provide 'projects/configuration)
|
||||
;;; configuration.el ends here
|
|
@ -1,46 +0,0 @@
|
|||
;;; dsl --- A dsl to be used with project configurations.
|
||||
;;; Commentary:
|
||||
;;; Code:
|
||||
(defvar open-project-configurations (make-hash-table :test 'equal)
|
||||
"This hashmap is responsible for storing project configurations.")
|
||||
|
||||
;; DSL -----------------------------------------------------
|
||||
(defmacro deftask (name &rest body)
|
||||
"Create a new task for the project with the given NAME and BODY."
|
||||
`(let ((pmap (gethash __project-name__
|
||||
open-project-configurations
|
||||
(make-hash-table :test 'equal))))
|
||||
|
||||
(puthash ,(symbol-name name) (lambda (project-path buffer) ,@body) pmap)
|
||||
(puthash __project-name__ pmap open-project-configurations)))
|
||||
|
||||
(defmacro run-shell-command (command)
|
||||
"Run the given shell COMMAND on the run buffer."
|
||||
`(async-shell-command ,command buffer))
|
||||
|
||||
;; TASK RUNNERS --------------------------------------------
|
||||
(defun with-buffer (name action)
|
||||
"Create a buffer with the given NAME for the given ACTION."
|
||||
(get-buffer-create (format "*%s %s*" name action)))
|
||||
|
||||
(defun run-task-buffer (project-name)
|
||||
"Create or get the buffer which hold the output of run task.
|
||||
|
||||
The buffer name will contains PROJECT-NAME."
|
||||
(with-buffer project-name "run"))
|
||||
|
||||
(defun execute-task (project task-name)
|
||||
"Run the task for PROJECT with the given TASK-NAME."
|
||||
(let* ((project-hash (gethash project open-project-configurations))
|
||||
(task (gethash task-name project-hash))
|
||||
(buf (with-buffer project task-name)))
|
||||
(funcall task project buf)))
|
||||
|
||||
(defun execute-run-task ()
|
||||
"Execute the :run task for the current project."
|
||||
(interactive)
|
||||
(let ((project (cdr (project-current))))
|
||||
(execute-task project "run")))
|
||||
|
||||
(provide 'projects/dsl)
|
||||
;;; dsl ends here
|
|
@ -1,8 +0,0 @@
|
|||
;;; Compiled snippets and support files for `go-mode'
|
||||
;;; Snippet definitions:
|
||||
;;;
|
||||
(yas-define-snippets 'go-mode
|
||||
'(("err" "if err != nil {\n\n}\n" "err_check" nil nil nil "/home/amirreza/.fg42/lib/snippets/go-mode/err_check" nil nil)))
|
||||
|
||||
|
||||
;;; Do not edit! File generated at Sun Feb 23 22:37:27 2020
|
|
@ -1,8 +0,0 @@
|
|||
# name: err_check
|
||||
# key: err
|
||||
# contributor: amirrezaask <raskarpour@gmail.com>
|
||||
# --
|
||||
|
||||
if err != nil {
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
;;; Compiled snippets and support files for `js-mode'
|
||||
;;; Snippet definitions:
|
||||
;;;
|
||||
(yas-define-snippets 'js-mode
|
||||
'(("resource" "{\n \"name\": \"$1\",\n \"fields\": [\n $0\n ],\n \"no_filter\": ${2:$$(yas-choose-value '(\"true\" \"false\"))},\n \"title-field\": \"$3\"\n}\n" "resource"
|
||||
(featurep 'flymake-json)
|
||||
nil nil "/home/amirreza/.fg42/lib/snippets/js-mode/resource" nil nil)
|
||||
("in" "{\n \"name\": \"$1\",\n \"type\": \"in\",\n \"bulk\": ${2:$$(yas-choose-value '(\"true\" \"false\"))},\n \"to\": [\n $0\n ]\n},\n" "in"
|
||||
(featurep 'flymake-json)
|
||||
nil nil "/home/amirreza/.fg42/lib/snippets/js-mode/in" nil nil)
|
||||
("hm" "{\n \"name\": \"$1\",\n \"type\": \"has_many\",\n \"bulk\": ${2:$$(yas-choose-value '(\"true\" \"false\"))},\n \"to\": \"${1:$(pluralize-string yas-text)}\"\n},\n $0" "has_many"
|
||||
(featurep 'flymake-json)
|
||||
nil nil "/home/amirreza/.fg42/lib/snippets/js-mode/has_many" nil nil)
|
||||
("ff" "{\n \"name\": \"$1\",\n \"type\": \"${2:$$(yas-choose-value '(\"string\" \"integer\" \"datetime\" \"float\" \"image\" \"in\" \"belongs_to\" \"has_many\"))}\",\n \"bulk\": ${3:$$(yas-choose-value '(\"true\" \"false\"))}\n},\n $0" "field"
|
||||
(featurep 'flymake-json)
|
||||
nil nil "/home/amirreza/.fg42/lib/snippets/js-mode/field" nil nil)
|
||||
("bt" "{\n \"name\": \"$1\",\n \"type\": \"belongs_to\",\n \"bulk\": ${2:$$(yas-choose-value '(\"true\" \"false\"))},\n \"to\": \"${1:$(pluralize-string yas-text)}\"\n},\n $0" "belongs_to"
|
||||
(featurep 'flymake-json)
|
||||
nil nil "/home/amirreza/.fg42/lib/snippets/js-mode/belongs_to" nil nil)))
|
||||
|
||||
|
||||
;;; Do not edit! File generated at Sun Feb 23 22:37:27 2020
|
|
@ -1,13 +0,0 @@
|
|||
# name: belongs_to
|
||||
# key: bt
|
||||
# expand-env: ((yas-indent-line 'fixed) (yas-wrap-around-region 'nil)
|
||||
# condition: (featurep 'flymake-json)
|
||||
# contributor: Sameer Rahmani <lxsameer@gnu.org>
|
||||
# --
|
||||
{
|
||||
"name": "$1",
|
||||
"type": "belongs_to",
|
||||
"bulk": ${2:$$(yas-choose-value '("true" "false"))},
|
||||
"to": "${1:$(pluralize-string yas-text)}"
|
||||
},
|
||||
$0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue