Compare commits
5 commits
281e45431a
...
a1118e0c2e
Author | SHA1 | Date | |
---|---|---|---|
|
a1118e0c2e | ||
|
9bb159c087 | ||
|
de618dfde7 | ||
|
e7e61b4134 | ||
|
65ff19ba32 |
9 changed files with 255 additions and 167 deletions
|
@ -26,9 +26,9 @@ If I want to build from source (and not build from Homebrew), install all the de
|
||||||
libtiff jansson libpng librsvg gnutls cmake
|
libtiff jansson libpng librsvg gnutls cmake
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
To get the native compilation for Emacs working, install:
|
To get the native compilation for Emacs working, I [[https://github.com/d12frosted/homebrew-emacs-plus/issues/680#issuecomment-2481633820][need to *un*-install]], as the new brew recipe will take care of this:
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
brew install libgccjit
|
brew uninstall libgccjit gcc
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Oh, and if we are still building with [[https://imagemagick.org/][ImageMagick]], install that first:
|
Oh, and if we are still building with [[https://imagemagick.org/][ImageMagick]], install that first:
|
||||||
|
|
|
@ -98,7 +98,8 @@
|
||||||
|
|
||||||
(defun org-confluence-checkbox (checkbox info)
|
(defun org-confluence-checkbox (checkbox info)
|
||||||
"Format CHECKBOX into Confluence (even though Confluence won't take it. We take the CHECKBOX to be either 'on' or 'off' and we ignore INFO."
|
"Format CHECKBOX into Confluence (even though Confluence won't take it. We take the CHECKBOX to be either 'on' or 'off' and we ignore INFO."
|
||||||
(case checkbox (on "(/)")
|
(cl-case checkbox
|
||||||
|
(on "(/)")
|
||||||
(off "(x)")
|
(off "(x)")
|
||||||
(trans "(-)")
|
(trans "(-)")
|
||||||
(t "")))
|
(t "")))
|
||||||
|
@ -107,7 +108,7 @@
|
||||||
"Wrap a list with the html-ish stuff, but only if descriptive."
|
"Wrap a list with the html-ish stuff, but only if descriptive."
|
||||||
(let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item
|
(let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item
|
||||||
(type (org-element-property :type plain-list)))
|
(type (org-element-property :type plain-list)))
|
||||||
(case type
|
(cl-case type
|
||||||
(descriptive (format "{html}<dl>\n%s\n</dl>{html}" contents))
|
(descriptive (format "{html}<dl>\n%s\n</dl>{html}" contents))
|
||||||
(otherwise contents))))
|
(otherwise contents))))
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@
|
||||||
(br "\n\n"))
|
(br "\n\n"))
|
||||||
(message "Got %s with %s" type contents)
|
(message "Got %s with %s" type contents)
|
||||||
(concat
|
(concat
|
||||||
(case type
|
(cl-case type
|
||||||
(ordered
|
(ordered
|
||||||
(let* ((counter term-counter-id)
|
(let* ((counter term-counter-id)
|
||||||
(extra (if counter (format " value=\"%s\"" counter) "")))
|
(extra (if counter (format " value=\"%s\"" counter) "")))
|
||||||
|
|
|
@ -79,7 +79,20 @@ I get issues with Magic and Dimmer, so let’s turn off this feature in certain
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
As an interesting alternative, check out the [[https://www.emacs.dyerdwelling.family/emacs/20240208164549-emacs-selected-window-accent-mode-now-on-melpa/][selected-window-accent]] project.
|
As an interesting alternative, check out the [[https://www.emacs.dyerdwelling.family/emacs/20240208164549-emacs-selected-window-accent-mode-now-on-melpa/][selected-window-accent]] project.
|
||||||
* Find the Bloody Cursor
|
** Ultra Scroll
|
||||||
|
|
||||||
|
The [[https://github.com/jdtsmith/ultra-scroll][ultra-scroll]] project allows smoother scrolling of text and images. While this splits text at the top/bottom of buffer windows, we no longer work within a 80x24 text matrix. Large images would
|
||||||
|
either be "there or not" which resulted large jumps and large distractions.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(use-package ultra-scroll
|
||||||
|
:straight (:type git :host github :repo "jdtsmith/ultra-scroll")
|
||||||
|
:config
|
||||||
|
(setq scroll-conservatively 101 ; important!
|
||||||
|
scroll-margin 0)
|
||||||
|
(ultra-scroll-mode 1))
|
||||||
|
#+END_SRC
|
||||||
|
** Find the Bloody Cursor
|
||||||
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F8~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
|
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F8~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
|
|
@ -43,6 +43,9 @@ I like =debug-on-error=, but not in Eshell, so I set this up when entering Eshel
|
||||||
(setq mode-line-format nil))
|
(setq mode-line-format nil))
|
||||||
#+end_src
|
#+end_src
|
||||||
** Directory Notification
|
** Directory Notification
|
||||||
|
:PROPERTIES:
|
||||||
|
:ID: AD963BB5-6346-46C0-A364-4C8AEBA29882
|
||||||
|
:END:
|
||||||
While most people put the “current directory” in their shell prompt, I’ve always found that pretty distracting, difficult when copy/pasting commands, and cuts out on the length of my commands (which might be a good thing, tbh).
|
While most people put the “current directory” in their shell prompt, I’ve always found that pretty distracting, difficult when copy/pasting commands, and cuts out on the length of my commands (which might be a good thing, tbh).
|
||||||
|
|
||||||
I use the =header-line= for this.
|
I use the =header-line= for this.
|
||||||
|
@ -155,7 +158,7 @@ Keep in mind that the predicates are somewhat finicky. For instance, the followi
|
||||||
mv $f $f(:r).txt
|
mv $f $f(:r).txt
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
But you could call this:
|
Instead, call this:
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
mv $f $f(:s/org$/txt/)
|
mv $f $f(:s/org$/txt/)
|
||||||
|
@ -1247,23 +1250,6 @@ I use =ex= to refer to both =en= / =ec=. Use cases:
|
||||||
|
|
||||||
The =-c= option can be combined with the /command/, but I don’t want it to grab the last output, as I think I would just like to send text to the notebook as after thoughts. If the option to =-c= is blank, perhaps it just calls the capture template to allow me to enter voluminous content.
|
The =-c= option can be combined with the /command/, but I don’t want it to grab the last output, as I think I would just like to send text to the notebook as after thoughts. If the option to =-c= is blank, perhaps it just calls the capture template to allow me to enter voluminous content.
|
||||||
|
|
||||||
This requires capture templates that don’t do any formatting. I will reused =c c= from [[file:ha-capturing-notes.org::*General Notes][capturing-notes]] code, and create other templates under =e= prefix:
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
;; (setq org-capture-templates nil)
|
|
||||||
(add-to-list 'org-capture-templates
|
|
||||||
'("e" "Engineering Notebook"))
|
|
||||||
|
|
||||||
(add-to-list 'org-capture-templates
|
|
||||||
'("ee" "Notes and Commentary" plain
|
|
||||||
(file+olp+datetree org-default-notes-file "General Notes")
|
|
||||||
"%i" :empty-lines 1 :tree-type month :unnarrowed t))
|
|
||||||
|
|
||||||
(add-to-list 'org-capture-templates
|
|
||||||
'("ef" "Piped-in Contents" plain
|
|
||||||
(file+olp+datetree org-default-notes-file "General Notes")
|
|
||||||
"%i" :immediate-finish t :empty-lines 1 :tree-type month))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-eshell-engineering-notebook (capture-template args)
|
(defun ha-eshell-engineering-notebook (capture-template args)
|
||||||
"Capture commands and output from Eshell into an Engineering Notebook.
|
"Capture commands and output from Eshell into an Engineering Notebook.
|
||||||
|
@ -1328,7 +1314,33 @@ This requires capture templates that don’t do any formatting. I will reused =c
|
||||||
;; Return output from the command, or nothing if there wasn't anything:
|
;; Return output from the command, or nothing if there wasn't anything:
|
||||||
(or output "")))
|
(or output "")))
|
||||||
#+end_src
|
#+end_src
|
||||||
And now we have a =en= and a =ec= version:
|
|
||||||
|
This requires capture templates that don’t do any formatting. I will reused =c c= from [[file:ha-capturing-notes.org::*General Notes][capturing-notes]] code, and create other templates under =e= prefix:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(add-to-list 'org-capture-templates '("e" "Engineering Notebook"))
|
||||||
|
|
||||||
|
(add-to-list 'org-capture-templates
|
||||||
|
'("ee" "Notes and Commentary" plain
|
||||||
|
(file+olp+datetree org-default-notes-file "General Notes")
|
||||||
|
"%i" :empty-lines 1 :tree-type month :unnarrowed t))
|
||||||
|
|
||||||
|
(add-to-list 'org-capture-templates
|
||||||
|
'("ef" "Piped-in Contents" plain
|
||||||
|
(file+olp+datetree org-default-notes-file "General Notes")
|
||||||
|
"%i" :immediate-finish t :empty-lines 1 :tree-type month))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
The =cap= function simply calls [[help-org-capture][org-capture]] with [[info:org#Template elements][a template]]:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defun eshell/cap (&rest args)
|
||||||
|
"Call `org-capture' with the `ee' template to enter text into the engineering notebook."
|
||||||
|
(org-capture nil "ee"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
The =en= and =ec= functions, since they do /pre-processing/ before calling =org-capture= calls some helper functions:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun eshell/en (&rest args)
|
(defun eshell/en (&rest args)
|
||||||
"Call `ha-eshell-engineering-notebook' to \"General Notes\"."
|
"Call `ha-eshell-engineering-notebook' to \"General Notes\"."
|
||||||
|
@ -1341,12 +1353,7 @@ And now we have a =en= and a =ec= version:
|
||||||
(ha-eshell-engineering-notebook "cc" args))
|
(ha-eshell-engineering-notebook "cc" args))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
This function simply calls [[help-org-capture][org-capture]] with [[info:org#Template elements][a template]]:
|
In order to have /devices/, for instance =some-command > e=, we define some functions:
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(defun eshell/cap (&rest args)
|
|
||||||
"Call `org-capture' with the `ee' template to enter text into the engineering notebook."
|
|
||||||
(org-capture nil "ee"))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-eshell-target-engineering-notebook (output)
|
(defun ha-eshell-target-engineering-notebook (output)
|
||||||
|
@ -1357,7 +1364,9 @@ This function simply calls [[help-org-capture][org-capture]] with [[info:org#Tem
|
||||||
"Write OUTPUT into the current clocked in task via `org-capture'."
|
"Write OUTPUT into the current clocked in task via `org-capture'."
|
||||||
(ha-eshell-engineering-capture "cc" nil nil output))
|
(ha-eshell-engineering-capture "cc" nil nil output))
|
||||||
#+end_src
|
#+end_src
|
||||||
And finally, add our new functions to [[elisp(describe-variable 'eshell-virtual-targets)][eshell-virtual-targets]]:
|
|
||||||
|
And add these functions to [[elisp(describe-variable 'eshell-virtual-targets)][eshell-virtual-targets]], after =eshell= has been loaded:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(with-eval-after-load "eshell"
|
(with-eval-after-load "eshell"
|
||||||
(add-to-list 'eshell-virtual-targets '("/dev/e" ha-eshell-target-engineering-notebook nil))
|
(add-to-list 'eshell-virtual-targets '("/dev/e" ha-eshell-target-engineering-notebook nil))
|
||||||
|
@ -1505,8 +1514,11 @@ Now tie it all together with a prompt function can color each of the prompts com
|
||||||
|
|
||||||
(setq-default eshell-prompt-function #'eshell/eshell-local-prompt-function)
|
(setq-default eshell-prompt-function #'eshell/eshell-local-prompt-function)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Here is the result:
|
Here is the result:
|
||||||
[[http://imgur.com/nkpwII0.png]]
|
[[file:screenshots/eshell-special-prompt.png]]
|
||||||
|
|
||||||
|
To be honest, this sort of prompt is garish and distracting. A better approach is to have that information in either the mode line, or a [[Directory Notification][header-line]].
|
||||||
** Simple Prompt with Mode Line
|
** Simple Prompt with Mode Line
|
||||||
To achieve more /screen estate/, leave your prompt simple:
|
To achieve more /screen estate/, leave your prompt simple:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
@ -1615,6 +1627,17 @@ And let’s bind it:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(bind-key "C-!" 'eshell-here)
|
(bind-key "C-!" 'eshell-here)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
Obviously, I usually want to open a shell in the root of the current project.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun eshell-project ()
|
||||||
|
"Call `eshell-there' with the current project root."
|
||||||
|
(interactive)
|
||||||
|
(eshell-there (or (project-root (project-current))
|
||||||
|
default-directory)))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
** Shell Over There
|
** Shell Over There
|
||||||
Would be nice to be able to run an eshell session and use Tramp to connect to the remote host in one fell swoop:
|
Would be nice to be able to run an eshell session and use Tramp to connect to the remote host in one fell swoop:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
|
|
@ -892,7 +892,7 @@ Since the /definitions/ do not work, so let's use the [[https://github.com/abo-a
|
||||||
:bind ("s-d" . define-word-at-point)
|
:bind ("s-d" . define-word-at-point)
|
||||||
:config
|
:config
|
||||||
(ha-leader :keymaps 'text-mode-map
|
(ha-leader :keymaps 'text-mode-map
|
||||||
"s d" '(:ignore t :which-key "thesaurus")
|
"s d" '(:ignore t :which-key "dictionary")
|
||||||
"s d d" '("define this word" . define-word-at-point)
|
"s d d" '("define this word" . define-word-at-point)
|
||||||
"s d a" '("define any word" . define-word)))
|
"s d a" '("define any word" . define-word)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
|
@ -337,7 +337,7 @@ All the above loveliness can be easily accessible with a [[https://github.com/je
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package major-mode-hydra
|
(use-package major-mode-hydra
|
||||||
:config
|
:config
|
||||||
(major-mode-hydra-define emacs-lisp-mode (:quit-key "q" :color pink)
|
(major-mode-hydra-define emacs-lisp-mode (:quit-key "q" :color blue)
|
||||||
("Evaluating"
|
("Evaluating"
|
||||||
(("e" ha-eval-current-expression "Current")
|
(("e" ha-eval-current-expression "Current")
|
||||||
("d" lispy-debug/body "Debugging")
|
("d" lispy-debug/body "Debugging")
|
||||||
|
|
|
@ -49,6 +49,53 @@ Note: Install the following checks:
|
||||||
pip install flake8 pylint pyright mypy pycompile
|
pip install flake8 pylint pyright mypy pycompile
|
||||||
#+end_src
|
#+end_src
|
||||||
Or better yet, add those to the =requirements-dev.txt= file.
|
Or better yet, add those to the =requirements-dev.txt= file.
|
||||||
|
|
||||||
|
All the above loveliness can be easily accessible with a [[https://github.com/jerrypnz/major-mode-hydra.el][major-mode-hydra]] defined for =emacs-lisp-mode=:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package major-mode-hydra
|
||||||
|
:config
|
||||||
|
(defvar ha-python-eval-title (font-icons 'mdicon "run" :title "Python Evaluation"))
|
||||||
|
(defvar ha-python-goto-title (font-icons 'faicon "python" :title "Python Symbol References"))
|
||||||
|
|
||||||
|
(pretty-hydra-define python-evaluate (:color blue :quit-key "q"
|
||||||
|
:title ha-python-eval-title)
|
||||||
|
("Section"
|
||||||
|
(("f" python-shell-send-defun "Function/Class")
|
||||||
|
("e" python-shell-send-statement "Line")
|
||||||
|
(";" python-shell-send-string "Expression"))
|
||||||
|
"Entirety"
|
||||||
|
(("F" python-shell-send-file "File")
|
||||||
|
("B" python-shell-send-buffer "Buffer")
|
||||||
|
("r" python-shell-send-region "Region"))))
|
||||||
|
|
||||||
|
(pretty-hydra-define python-goto (:color blue :quit-key "q"
|
||||||
|
:title ha-python-goto-title)
|
||||||
|
("Symbols"
|
||||||
|
(("s" xref-find-apropos "Find Symbol")
|
||||||
|
("e" python-shell-send-statement "Line")
|
||||||
|
(";" python-shell-send-string "Expression"))
|
||||||
|
"Entirety"
|
||||||
|
(("F" python-shell-send-file "File")
|
||||||
|
("B" python-shell-send-buffer "Buffer")
|
||||||
|
("r" python-shell-send-region "Region"))))
|
||||||
|
|
||||||
|
(major-mode-hydra-define python-mode (:quit-key "q" :color blue)
|
||||||
|
("Server"
|
||||||
|
(("S" run-python "Start Server")
|
||||||
|
("s" python-shell-switch-to-shell "Go to Server"))
|
||||||
|
"Edit"
|
||||||
|
(("r" iedit-mode "Rename")
|
||||||
|
(">" python-indent-shift-left "Shift Left")
|
||||||
|
("<" python-indent-shift-right "Shift Right"))
|
||||||
|
"Navigate/Eval"
|
||||||
|
(("e" python-evaluate/body "Evaluate...")
|
||||||
|
("g" python-goto/body "Go to..."))
|
||||||
|
"Docs"
|
||||||
|
(("d" python-eldoc-at-point "Docs on Symbol")
|
||||||
|
("D" python-describe-at-point "Describe Symbol")))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Virtual Environment
|
** Virtual Environment
|
||||||
For a local virtual machine, put the following in your =.envrc= file:
|
For a local virtual machine, put the following in your =.envrc= file:
|
||||||
#+begin_src conf
|
#+begin_src conf
|
||||||
|
@ -108,15 +155,25 @@ container_layout
|
||||||
:after python
|
:after python
|
||||||
:commands python-pytest-dispatch
|
:commands python-pytest-dispatch
|
||||||
:init
|
:init
|
||||||
(ha-local-leader :keymaps 'python-mode-map
|
(use-package major-mode-hydra
|
||||||
"t" '(:ignore t :which-key "tests")
|
:config
|
||||||
"t a" '("all" . python-pytest)
|
(defvar ha-python-tests-title (font-icons 'devicon "pytest" :title "Python Test Framework"))
|
||||||
"t f" '("file dwim" . python-pytest-file-dwim)
|
(pretty-hydra-define python-tests (:color blue :quit-key "q"
|
||||||
"t F" '("file" . python-pytest-file)
|
:title ha-python-tests-title)
|
||||||
"t t" '("function-dwim" . python-pytest-function-dwim)
|
("Suite"
|
||||||
"t T" '("function" . python-pytest-function)
|
(("a" python-pytest "All")
|
||||||
"t r" '("repeat" . python-pytest-repeat)
|
("f" python-pytest-file-dwim "File DWIM")
|
||||||
"t p" '("dispatch" . python-pytest-dispatch)))
|
("F" python-pytest-file "File"))
|
||||||
|
"Specific"
|
||||||
|
(("d" python-pytest-function-dwim "Function DWIM")
|
||||||
|
("D" python-pytest-function "Function"))
|
||||||
|
"Again"
|
||||||
|
(("r" python-pytest-repeat "Repeat tests")
|
||||||
|
("p" python-pytest-dispatch "Dispatch"))))
|
||||||
|
|
||||||
|
(major-mode-hydra-define+ python-mode (:quit-key "q" :color blue)
|
||||||
|
("Misc"
|
||||||
|
(("t" python-tests/body "Tests..."))))))
|
||||||
#+end_src
|
#+end_src
|
||||||
** Python Dependencies
|
** Python Dependencies
|
||||||
Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=):
|
Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=):
|
||||||
|
@ -156,102 +213,87 @@ The [[https://github.com/emacs-lsp/lsp-pyright][pyright package]] works with LSP
|
||||||
(setq lsp-pyright-python-executable-cmd "python3")))
|
(setq lsp-pyright-python-executable-cmd "python3")))
|
||||||
#+end_src
|
#+end_src
|
||||||
* LSP Integration of Python
|
* LSP Integration of Python
|
||||||
Now that the [[file:ha-programming.org::*Language Server Protocol (LSP) Integration][LSP Integration]] is complete, we can stitch the two projects together, by calling =lsp=. I oscillate between automatically turning on LSP mode with every Python file, but I sometimes run into issues when starting, so I turn it on with ~, w s~.
|
Now that the [[file:ha-programming.org::*Language Server Protocol (LSP) Integration][LSP Integration]] is complete, we can stitch the two projects together, by calling =lsp=. I oscillate between automatically turning on LSP mode with every Python file, but I sometimes run into issues when starting, so I conditionally turn it on.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defvar ha-python-lsp-title (font-icons 'faicon "python" :title "Python LSP"))
|
||||||
|
|
||||||
|
(defun ha-setup-python-lsp ()
|
||||||
|
"Configure the keybindings for LSP in Python."
|
||||||
|
(interactive)
|
||||||
|
|
||||||
|
(pretty-hydra-define python-lsp (:color blue :quit-key "q"
|
||||||
|
:title ha-python-lsp-title)
|
||||||
|
("Server"
|
||||||
|
(("D" lsp-disconnect "Disconnect")
|
||||||
|
("R" lsp-workspace-restart "Restart")
|
||||||
|
("S" lsp-workspace-shutdown "Shutdown")
|
||||||
|
("?" lsp-describe-session "Describe"))
|
||||||
|
"Refactoring"
|
||||||
|
(("a" lsp-execute-code-action "Code Actions")
|
||||||
|
("o" lsp-organize-imports "Organize Imports")
|
||||||
|
("l" lsp-avy-lens "Avy Lens"))
|
||||||
|
"Toggles"
|
||||||
|
(("b" lsp-headerline-breadcrumb-mode "Breadcrumbs")
|
||||||
|
("d" lsp-ui-doc-mode "Documentation Popups")
|
||||||
|
("m" lsp-modeline-diagnostics-mode "Modeline Diagnostics")
|
||||||
|
("s" lsp-ui-sideline-mode "Sideline Mode"))
|
||||||
|
""
|
||||||
|
(("t" lsp-toggle-on-type-formatting "Type Formatting")
|
||||||
|
("h" lsp-toggle-symbol-highlight "Symbol Highlighting")
|
||||||
|
("L" lsp-toggle-trace-io "Log I/O"))))
|
||||||
|
|
||||||
|
(pretty-hydra-define+ python-goto (:quit-key "q")
|
||||||
|
("LSP"
|
||||||
|
(("g" lsp-find-definition "Definition")
|
||||||
|
("d" lsp-find-declaration "Declaration")
|
||||||
|
("r" lsp-find-references "References")
|
||||||
|
("t" lsp-find-type-definition "Type Definition"))
|
||||||
|
"Peek"
|
||||||
|
(("D" lsp-ui-peek-find-definitions "Definitions")
|
||||||
|
("I" lsp-ui-peek-find-implementation "Implementations")
|
||||||
|
("R" lsp-ui-peek-find-references "References")
|
||||||
|
("S" lsp-ui-peek-find-workspace-symbol "Symbols"))
|
||||||
|
"LSP+"
|
||||||
|
(("u" lsp-ui-imenu "UI Menu")
|
||||||
|
("i" lsp-find-implementation "Implementations")
|
||||||
|
("h" lsp-treemacs-call-hierarchy "Hierarchy")
|
||||||
|
("E" lsp-treemacs-errors-list "Error List"))))
|
||||||
|
|
||||||
|
(major-mode-hydra-define+ python-mode nil
|
||||||
|
("Server"
|
||||||
|
(("l" python-lsp/body "LSP..."))
|
||||||
|
"Edit"
|
||||||
|
(("r" lsp-rename "Rename")
|
||||||
|
("=" lsp-format-region "Format"))
|
||||||
|
"Navigate"
|
||||||
|
(("A" lsp-workspace-folders-add "Add Folder")
|
||||||
|
("R" lsp-workspace-folders-remove "Remove Folder"))
|
||||||
|
"Docs"
|
||||||
|
(("D" lsp-describe-thing-at-point "Describe LSP Symbol")
|
||||||
|
("h" lsp-ui-doc-glance "Glance Help")
|
||||||
|
("H" lsp-document-highlight "Highlight"))))
|
||||||
|
|
||||||
|
(call-interactively 'lsp))
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no
|
|
||||||
(use-package lsp-mode
|
(use-package lsp-mode
|
||||||
;; :hook ((python-mode . lsp)))
|
|
||||||
:config
|
:config
|
||||||
(ha-local-leader :keymaps 'lsp-mode-map
|
(major-mode-hydra-define+ python-mode (:quit-key "q")
|
||||||
"0" '("treemacs" . lsp-treemacs-symbols)
|
("Server"
|
||||||
|
(("L" ha-setup-python-lsp "Start LSP Server")))))
|
||||||
|
|
||||||
"/" '("complete" . completion-at-point)
|
;; ----------------------------------------------------------------------
|
||||||
"k" '("check code" . python-check)
|
;; Missing Symbols to be integrated?
|
||||||
"]" '("shift left" . python-indent-shift-left)
|
;; "0" '("treemacs" . lsp-treemacs-symbols)
|
||||||
"[" '("shift right" . python-indent-shift-right)
|
;; "/" '("complete" . completion-at-point)
|
||||||
|
;; "k" '("check code" . python-check)
|
||||||
;; actions
|
;; "Fb" '("un-blacklist folder" . lsp-workspace-blacklist-remove)
|
||||||
"a" '(:ignore t :which-key "code actions")
|
;; "hs" '("signature help" . lsp-signature-activate)
|
||||||
"aa" '("code actions" . lsp-execute-code-action)
|
;; "tT" '("toggle treemacs integration" . lsp-treemacs-sync-mode)
|
||||||
"ah" '("highlight symbol" . lsp-document-highlight)
|
;; "ta" '("toggle modeline code actions" . lsp-modeline-code-actions-mode)
|
||||||
"al" '("lens" . lsp-avy-lens)
|
;; "th" '("toggle highlighting" . lsp-toggle-symbol-highlight)
|
||||||
|
;; "tl" '("toggle lenses" . lsp-lens-mode)
|
||||||
;; formatting
|
;; "ts" '("toggle signature" . lsp-toggle-signature-auto-activate)
|
||||||
"=" '(:ignore t :which-key "formatting")
|
|
||||||
"==" '("format buffer" . lsp-format-buffer)
|
|
||||||
"=r" '("format region" . lsp-format-region)
|
|
||||||
|
|
||||||
"e" '(:ignore t :which-key "eval")
|
|
||||||
"e P" '("run python" . run-python)
|
|
||||||
"e e" '("send statement" . python-shell-send-statement)
|
|
||||||
"e b" '("send buffer" . python-shell-send-buffer)
|
|
||||||
"e f" '("send defun" . python-shell-send-defun)
|
|
||||||
"e F" '("send file" . python-shell-send-file)
|
|
||||||
"e r" '("send region" . python-shell-send-region)
|
|
||||||
"e ;" '("expression" . python-shell-send-string)
|
|
||||||
"e p" '("switch-to-shell" . python-shell-switch-to-shell)
|
|
||||||
|
|
||||||
;; folders
|
|
||||||
"F" '(:ignore t :which-key "folders")
|
|
||||||
"Fa" '("add folder" . lsp-workspace-folders-add)
|
|
||||||
"Fb" '("un-blacklist folder" . lsp-workspace-blacklist-remove)
|
|
||||||
"Fr" '("remove folder" . lsp-workspace-folders-remove)
|
|
||||||
|
|
||||||
;; goto
|
|
||||||
"g" '(:ignore t :which-key "goto")
|
|
||||||
"ga" '("find symbol in workspace" . xref-find-apropos)
|
|
||||||
"gd" '("find declarations" . lsp-find-declaration)
|
|
||||||
"ge" '("show errors" . lsp-treemacs-errors-list)
|
|
||||||
"gg" '("find definitions" . lsp-find-definition)
|
|
||||||
"gh" '("call hierarchy" . lsp-treemacs-call-hierarchy)
|
|
||||||
"gi" '("find implementations" . lsp-find-implementation)
|
|
||||||
"gm" '("imenu" . lsp-ui-imenu)
|
|
||||||
"gr" '("find references" . lsp-find-references)
|
|
||||||
"gt" '("find type definition" . lsp-find-type-definition)
|
|
||||||
|
|
||||||
;; peeks
|
|
||||||
"G" '(:ignore t :which-key "peek")
|
|
||||||
"Gg" '("peek definitions" . lsp-ui-peek-find-definitions)
|
|
||||||
"Gi" '("peek implementations" . lsp-ui-peek-find-implementation)
|
|
||||||
"Gr" '("peek references" . lsp-ui-peek-find-references)
|
|
||||||
"Gs" '("peek workspace symbol" . lsp-ui-peek-find-workspace-symbol)
|
|
||||||
|
|
||||||
;; help
|
|
||||||
"h" '(:ignore t :which-key "help")
|
|
||||||
"he" '("eldoc" . python-eldoc-at-point)
|
|
||||||
"hg" '("glance symbol" . lsp-ui-doc-glance)
|
|
||||||
"hh" '("describe symbol at point" . lsp-describe-thing-at-point)
|
|
||||||
"gH" '("describe python symbol" . python-describe-at-point)
|
|
||||||
"hs" '("signature help" . lsp-signature-activate)
|
|
||||||
|
|
||||||
"i" 'imenu
|
|
||||||
|
|
||||||
;; refactoring
|
|
||||||
"r" '(:ignore t :which-key "refactor")
|
|
||||||
"ro" '("organize imports" . lsp-organize-imports)
|
|
||||||
"rr" '("rename" . lsp-rename)
|
|
||||||
|
|
||||||
;; toggles
|
|
||||||
"t" '(:ignore t :which-key "toggle")
|
|
||||||
"tD" '("toggle modeline diagnostics" . lsp-modeline-diagnostics-mode)
|
|
||||||
"tL" '("toggle log io" . lsp-toggle-trace-io)
|
|
||||||
"tS" '("toggle sideline" . lsp-ui-sideline-mode)
|
|
||||||
"tT" '("toggle treemacs integration" . lsp-treemacs-sync-mode)
|
|
||||||
"ta" '("toggle modeline code actions" . lsp-modeline-code-actions-mode)
|
|
||||||
"tb" '("toggle breadcrumb" . lsp-headerline-breadcrumb-mode)
|
|
||||||
"td" '("toggle documentation popup" . lsp-ui-doc-mode)
|
|
||||||
"tf" '("toggle on type formatting" . lsp-toggle-on-type-formatting)
|
|
||||||
"th" '("toggle highlighting" . lsp-toggle-symbol-highlight)
|
|
||||||
"tl" '("toggle lenses" . lsp-lens-mode)
|
|
||||||
"ts" '("toggle signature" . lsp-toggle-signature-auto-activate)
|
|
||||||
|
|
||||||
;; workspaces
|
|
||||||
"w" '(:ignore t :which-key "workspaces")
|
|
||||||
"wD" '("disconnect" . lsp-disconnect)
|
|
||||||
"wd" '("describe session" . lsp-describe-session)
|
|
||||||
"wq" '("shutdown server" . lsp-workspace-shutdown)
|
|
||||||
"wr" '("restart server" . lsp-workspace-restart)
|
|
||||||
"ws" '("start server" . lsp)))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
* Project Configuration
|
* Project Configuration
|
||||||
I work with a lot of projects with my team where I need to /configure/ the project such that LSP and my Emacs setup works. Let's suppose I could point a function at a project directory, and have it /set it up/:
|
I work with a lot of projects with my team where I need to /configure/ the project such that LSP and my Emacs setup works. Let's suppose I could point a function at a project directory, and have it /set it up/:
|
||||||
|
@ -290,6 +332,7 @@ I work with a lot of projects with my team where I need to /configure/ the proje
|
||||||
(insert "pylsp-rope\n"))
|
(insert "pylsp-rope\n"))
|
||||||
(shell-command "pip install -r requirements-dev.txt")))
|
(shell-command "pip install -r requirements-dev.txt")))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
* Major Mode Hydra
|
||||||
* Technical Artifacts :noexport:
|
* Technical Artifacts :noexport:
|
||||||
Let's =provide= a name so we can =require= this file:
|
Let's =provide= a name so we can =require= this file:
|
||||||
|
|
||||||
|
|
|
@ -1157,7 +1157,8 @@ And then we can use it. For some reason, the =pymarkdown= (which I need to use f
|
||||||
(use-package markdown-mode
|
(use-package markdown-mode
|
||||||
:after flycheck
|
:after flycheck
|
||||||
:config
|
:config
|
||||||
(setq flycheck-markdown-pymarkdown-config ".pymarkdown.yml")
|
(setq flycheck-markdown-pymarkdown-config
|
||||||
|
(expand-file-name ".pymarkdown.yml" (getenv "HOME")))
|
||||||
(flycheck-may-enable-checker 'markdown-pymarkdown))
|
(flycheck-may-enable-checker 'markdown-pymarkdown))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,7 @@ While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[
|
||||||
("terminfo/65" "terminfo/65/*")
|
("terminfo/65" "terminfo/65/*")
|
||||||
("integration" "integration/*")
|
("integration" "integration/*")
|
||||||
(:exclude ".dir-locals.el" "*-tests.el")))
|
(:exclude ".dir-locals.el" "*-tests.el")))
|
||||||
|
:commands (eat eat-make eat-project)
|
||||||
:bind (:map eat-semi-char-mode-map
|
:bind (:map eat-semi-char-mode-map
|
||||||
("C-c C-t" . ha-eat-narrow-to-shell-prompt-dwim))
|
("C-c C-t" . ha-eat-narrow-to-shell-prompt-dwim))
|
||||||
:config
|
:config
|
||||||
|
@ -475,7 +476,7 @@ We'll give =openstack= CLI a =--format json= option to make it easier for parsin
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-ssh-overcloud-query-for-hosts ()
|
(defun ha-ssh-overcloud-query-for-hosts ()
|
||||||
"If the overcloud cache hasn't be populated, ask the user if we want to run the command."
|
"If the overcloud cache hasn't be populated, ask the user if we want to run the command."
|
||||||
(when (not ha-ssh-favorite-hostnames)
|
(unless ha-ssh-favorite-hostnames
|
||||||
(when (y-or-n-p "Cache of Overcloud hosts aren't populated. Retrieve hosts?")
|
(when (y-or-n-p "Cache of Overcloud hosts aren't populated. Retrieve hosts?")
|
||||||
(call-interactively 'ha-ssh-overcloud-cache-populate))))
|
(call-interactively 'ha-ssh-overcloud-cache-populate))))
|
||||||
|
|
||||||
|
@ -488,7 +489,7 @@ We'll do the work of getting the /server list/ with this function:
|
||||||
(defun ha-ssh-overcloud-cache-populate (cluster)
|
(defun ha-ssh-overcloud-cache-populate (cluster)
|
||||||
"Given an `os-cloud' entry, stores all available hostnames.
|
"Given an `os-cloud' entry, stores all available hostnames.
|
||||||
Calls `ha-ssh-add-favorite-host' for each host found."
|
Calls `ha-ssh-add-favorite-host' for each host found."
|
||||||
(interactive (list (completing-read "Cluster: " '(devprod501 devprod502))))
|
(interactive (list (completing-read "Cluster: " '(devprod501 devprod502 devprod502-yawxway))))
|
||||||
(message "Calling the `openstack' command...this will take a while. Grab a coffee, eh?")
|
(message "Calling the `openstack' command...this will take a while. Grab a coffee, eh?")
|
||||||
(let* ((command (format "openstack --os-cloud %s server list --no-name-lookup -f json" cluster))
|
(let* ((command (format "openstack --os-cloud %s server list --no-name-lookup -f json" cluster))
|
||||||
(json-data (thread-last command
|
(json-data (thread-last command
|
||||||
|
@ -496,10 +497,12 @@ We'll do the work of getting the /server list/ with this function:
|
||||||
(json-read-from-string))))
|
(json-read-from-string))))
|
||||||
(dolist (entry (seq--into-list json-data))
|
(dolist (entry (seq--into-list json-data))
|
||||||
(ha-ssh-add-favorite-host (alist-get 'Name entry)
|
(ha-ssh-add-favorite-host (alist-get 'Name entry)
|
||||||
|
(or
|
||||||
(thread-last entry
|
(thread-last entry
|
||||||
(alist-get 'Networks)
|
(alist-get 'Networks)
|
||||||
(alist-get 'cedev13)
|
(alist-get 'cedev13)
|
||||||
(seq-first))))
|
(seq-first))
|
||||||
|
(alist-get 'Name entry))))
|
||||||
(message "Call to `openstack' complete. Found %d hosts." (length json-data))))
|
(message "Call to `openstack' complete. Found %d hosts." (length json-data))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -554,3 +557,7 @@ Before you can build this on a new system, make sure that you put the cursor ove
|
||||||
#+options: num:nil toc:t todo:nil tasks:nil tags:nil date:nil
|
#+options: num:nil toc:t todo:nil tasks:nil tags:nil date:nil
|
||||||
#+options: skip:nil author:nil email:nil creator:nil timestamp:nil
|
#+options: skip:nil author:nil email:nil creator:nil timestamp:nil
|
||||||
#+infojs_opt: view:nil toc:t ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
#+infojs_opt: view:nil toc:t ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# eval: (org-next-visible-heading 1)
|
||||||
|
# End:
|
||||||
|
|
Loading…
Reference in a new issue