Added app launcher
This commit is contained in:
parent
a167696b4c
commit
78caf1d337
1 changed files with 206 additions and 2 deletions
208
config.org
208
config.org
|
|
@ -8,6 +8,9 @@
|
|||
- [[#evil-mode][Evil Mode]]
|
||||
- [[#recent-files][Recent Files]]
|
||||
- [[#general-keybindings][General Keybindings]]
|
||||
- [[#startup-time][Startup Time]]
|
||||
- [[#app-launcher][App Launcher]]
|
||||
- [[#standalone-run][Standalone run]]
|
||||
- [[#fonts][Fonts]]
|
||||
- [[#zooming-inout][Zooming In/Out]]
|
||||
- [[#graphical-user-interface-tweaks][GRAPHICAL USER INTERFACE TWEAKS]]
|
||||
|
|
@ -119,14 +122,18 @@
|
|||
"t l" '(display-line-numbers-mode :wk "Toggle line numbers")
|
||||
"t t" '(visual-line-mode :wk "Toggle truncated lines")
|
||||
"t v" '(vterm-toggle :wk "Toggle vterm"))
|
||||
(kylekrein/leader-keys
|
||||
"o" '(:ignore t :wk "Open")
|
||||
"o a" '(org-agenda :wk "Agenda")
|
||||
)
|
||||
(kylekrein/leader-keys
|
||||
"n" '(:ignore t :wk "Notes")
|
||||
"n r" '(:ignore t :wk "Roam")
|
||||
"n r f" '(org-roam-node-find :wk "Find and open")
|
||||
"n r i" '(org-roam-node-insert :wk "Insert link")
|
||||
"n r l" '(org-roam-buffer-toggle :wk "Show backlinks")
|
||||
"n r d" '(:ignore t :wk "Dailies")
|
||||
"n r d m" '(org-roam-dailies-map :wk "Show dailies map")
|
||||
"n r m" '(org-roam-dailies-map :wk "Dailies")
|
||||
"n r s" '(org-roam-db-sync :wk "Sync Notes DB (After changes on another device)")
|
||||
)
|
||||
|
||||
(kylekrein/leader-keys
|
||||
|
|
@ -150,6 +157,203 @@
|
|||
|
||||
#+end_src
|
||||
|
||||
* Startup Time
|
||||
#+begin_src emacs-lisp
|
||||
;; Startup time
|
||||
(defun efs/display-startup-time ()
|
||||
(message
|
||||
"Emacs loaded in %s with %d garbage collections."
|
||||
(format
|
||||
"%.2f seconds"
|
||||
(float-time
|
||||
(time-subtract after-init-time before-init-time)))
|
||||
gcs-done))
|
||||
|
||||
(add-hook 'emacs-startup-hook #'efs/display-startup-time)
|
||||
#+end_src
|
||||
* App Launcher
|
||||
This code creates a menu to launch linux apps, that have Desktop entry.
|
||||
Code was taken from [[https://github.com/SebastienWae/app-launcher/blob/main/app-launcher.el][this awesome repo]]
|
||||
#+begin_src emacs-lisp
|
||||
(require 'xdg)
|
||||
(require 'cl-seq)
|
||||
|
||||
(defcustom app-launcher-apps-directories
|
||||
(mapcar (lambda (dir) (expand-file-name "applications" dir))
|
||||
(cons (xdg-data-home)
|
||||
(xdg-data-dirs)))
|
||||
"Directories in which to search for applications (.desktop files)."
|
||||
:type '(repeat directory))
|
||||
|
||||
(defcustom app-launcher--annotation-function #'app-launcher--annotation-function-default
|
||||
"Define the function that genereate the annotation for each completion choices."
|
||||
:type 'function)
|
||||
|
||||
(defcustom app-launcher--action-function #'app-launcher--action-function-default
|
||||
"Define the function that is used to run the selected application."
|
||||
:type 'function)
|
||||
|
||||
(defvar app-launcher--cache nil
|
||||
"Cache of desktop files data.")
|
||||
|
||||
(defvar app-launcher--cache-timestamp nil
|
||||
"Time when we last updated the cached application list.")
|
||||
|
||||
(defvar app-launcher--cached-files nil
|
||||
"List of cached desktop files.")
|
||||
|
||||
(defun app-launcher-list-desktop-files ()
|
||||
"Return an alist of all Linux applications.
|
||||
Each list entry is a pair of (desktop-name . desktop-file).
|
||||
This function always returns its elements in a stable order."
|
||||
(let ((hash (make-hash-table :test #'equal))
|
||||
result)
|
||||
(dolist (dir app-launcher-apps-directories)
|
||||
(when (file-exists-p dir)
|
||||
(let ((dir (file-name-as-directory dir)))
|
||||
(dolist (file (directory-files-recursively dir ".*\\.desktop$"))
|
||||
(let ((id (subst-char-in-string ?/ ?- (file-relative-name file dir))))
|
||||
(when (and (not (gethash id hash)) (file-readable-p file))
|
||||
(push (cons id file) result)
|
||||
(puthash id file hash)))))))
|
||||
result))
|
||||
|
||||
(defun app-launcher-parse-files (files)
|
||||
"Parse the .desktop files to return usable informations."
|
||||
(let ((hash (make-hash-table :test #'equal)))
|
||||
(dolist (entry files hash)
|
||||
(let ((file (cdr entry)))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(goto-char (point-min))
|
||||
(let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t))
|
||||
(end (re-search-forward "^\\[" nil t))
|
||||
(visible t)
|
||||
name comment exec)
|
||||
(catch 'break
|
||||
(unless start
|
||||
(message "Warning: File %s has no [Desktop Entry] group" file)
|
||||
(throw 'break nil))
|
||||
|
||||
(goto-char start)
|
||||
(when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t)
|
||||
(setq visible nil))
|
||||
(setq name (match-string 1))
|
||||
|
||||
(goto-char start)
|
||||
(unless (re-search-forward "^Type *= *Application *$" end t)
|
||||
(throw 'break nil))
|
||||
(setq name (match-string 1))
|
||||
|
||||
(goto-char start)
|
||||
(unless (re-search-forward "^Name *= *\\(.+\\)$" end t)
|
||||
(push file counsel-linux-apps-faulty)
|
||||
(message "Warning: File %s has no Name" file)
|
||||
(throw 'break nil))
|
||||
(setq name (match-string 1))
|
||||
|
||||
(goto-char start)
|
||||
(when (re-search-forward "^Comment *= *\\(.+\\)$" end t)
|
||||
(setq comment (match-string 1)))
|
||||
|
||||
(goto-char start)
|
||||
(unless (re-search-forward "^Exec *= *\\(.+\\)$" end t)
|
||||
;; Don't warn because this can technically be a valid desktop file.
|
||||
(throw 'break nil))
|
||||
(setq exec (match-string 1))
|
||||
|
||||
(goto-char start)
|
||||
(when (re-search-forward "^TryExec *= *\\(.+\\)$" end t)
|
||||
(let ((try-exec (match-string 1)))
|
||||
(unless (locate-file try-exec exec-path nil #'file-executable-p)
|
||||
(throw 'break nil))))
|
||||
|
||||
(puthash name
|
||||
(list (cons 'file file)
|
||||
(cons 'exec exec)
|
||||
(cons 'comment comment)
|
||||
(cons 'visible visible))
|
||||
hash))))))))
|
||||
|
||||
(defun app-launcher-list-apps ()
|
||||
"Return list of all Linux .desktop applications."
|
||||
(let* ((new-desktop-alist (app-launcher-list-desktop-files))
|
||||
(new-files (mapcar 'cdr new-desktop-alist)))
|
||||
(unless (and (equal new-files app-launcher--cached-files)
|
||||
(null (cl-find-if
|
||||
(lambda (file)
|
||||
(time-less-p
|
||||
app-launcher--cache-timestamp
|
||||
(nth 5 (file-attributes file))))
|
||||
new-files)))
|
||||
(setq app-launcher--cache (app-launcher-parse-files new-desktop-alist))
|
||||
(setq app-launcher--cache-timestamp (current-time))
|
||||
(setq app-launcher--cached-files new-files)))
|
||||
app-launcher--cache)
|
||||
|
||||
(defun app-launcher--annotation-function-default (choice)
|
||||
"Default function to annotate the completion choices."
|
||||
(let ((str (cdr (assq 'comment (gethash choice app-launcher--cache)))))
|
||||
(when str (concat " - " (propertize str 'face 'completions-annotations)))))
|
||||
|
||||
(defun app-launcher--action-function-default (selected)
|
||||
"Default function used to run the selected application."
|
||||
(let* ((exec (cdr (assq 'exec (gethash selected app-launcher--cache))))
|
||||
(command (let (result)
|
||||
(dolist (chunk (split-string exec " ") result)
|
||||
(unless (or (equal chunk "%U")
|
||||
(equal chunk "%F")
|
||||
(equal chunk "%u")
|
||||
(equal chunk "%f"))
|
||||
(setq result (concat result chunk " ")))))))
|
||||
(call-process-shell-command command nil 0 nil)))
|
||||
|
||||
;;;###autoload
|
||||
(defun app-launcher-run-app (&optional arg)
|
||||
"Launch an application installed on your machine.
|
||||
When ARG is non-nil, ignore NoDisplay property in *.desktop files."
|
||||
(interactive)
|
||||
(let* ((candidates (app-launcher-list-apps))
|
||||
(result (completing-read
|
||||
"Run app: "
|
||||
(lambda (str pred flag)
|
||||
(if (eq flag 'metadata)
|
||||
'(metadata
|
||||
(annotation-function . (lambda (choice)
|
||||
(funcall
|
||||
app-launcher--annotation-function
|
||||
choice))))
|
||||
(complete-with-action flag candidates str pred)))
|
||||
(lambda (x y)
|
||||
(if arg
|
||||
t
|
||||
(cdr (assq 'visible y))))
|
||||
t nil 'app-launcher nil nil)))
|
||||
(funcall app-launcher--action-function result)))
|
||||
#+end_src
|
||||
** Standalone run
|
||||
This code snippet runs app launcher without emacs frame
|
||||
To use it, create a global keyboard shortcut with the following code
|
||||
~emacsclient -cF "((visibility . nil))" -e "(emacs-run-launcher)~
|
||||
#+begin_src emacs-lisp
|
||||
(defun emacs-run-launcher ()
|
||||
"Create and select a frame called emacs-run-launcher which consists only of a minibuffer and has specific dimensions. Runs app-launcher-run-app on that frame, which is an emacs command that prompts you to select an app and open it in a dmenu like behaviour. Delete the frame after that command has exited"
|
||||
(interactive)
|
||||
(with-selected-frame
|
||||
(make-frame '((name . "emacs-run-launcher")
|
||||
(minibuffer . only)
|
||||
(fullscreen . 0) ; no fullscreen
|
||||
(undecorated . t) ; remove title bar
|
||||
;;(auto-raise . t) ; focus on this frame
|
||||
;;(tool-bar-lines . 0)
|
||||
;;(menu-bar-lines . 0)
|
||||
(internal-border-width . 10)
|
||||
(width . 80)
|
||||
(height . 11)))
|
||||
(unwind-protect
|
||||
(app-launcher-run-app)
|
||||
(delete-frame))))
|
||||
#+end_src
|
||||
* Fonts
|
||||
Defining the various fonts that Emacs will use.
|
||||
#+begin_src emacs-lisp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue