Remove the very old lib dir

This commit is contained in:
Sameer Rahmani 2022-12-19 21:08:13 +00:00
parent 2fa1243482
commit ba177678cc
116 changed files with 0 additions and 6952 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -1,6 +0,0 @@
* Clojure Extension
This extension provides an integrated environment for developing clojure applications
using FG42 on top of cider.
** Usage

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -1,4 +0,0 @@
(defconst FG42-VERSION "2.31.0"
"Global version of FG42")
(provide 'extensions/editor/version)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,8 +0,0 @@
;;; logger --- logger library of FG42
;;; Commentary:
;;;
;;; Code:
(provide 'fg42/logger)
;;; logger ends here

View File

@ -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 ())

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,8 +0,0 @@
# name: err_check
# key: err
# contributor: amirrezaask <raskarpour@gmail.com>
# --
if err != nil {
}

View File

@ -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

View File

@ -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