Attaching Metals LSP debugger to existing process in Emacs

Metals supports the DAP Protocol which allows to debug Scala code in Emacs. By default all the setup is done to use code lenses to start an instance of the program to debug it, set breakpoints inspect variables, all the good stuff to expect from a debugger. It is not as obvious how to debug a remote Scala process however as this requires a bit of setup.

Setting up the Scala process

Scala, as running on the JVM, allows to be run with the well know flags to be debugged namely

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

When using sbt this can be simplified to running as

sbt -jvm-debug 5005

which launches an sbt shell exposing a debug port 5005 on localhost. It is good practice to always use localhost and if truly remote to use SSH port forwarding, as the debugger has no authentication or any security in place.

Attaching the debugger

In dap-mode in Emacs uses debug-templates to determine what to run, in the case of scala and metals we need to provide the connection information as well as the lsp-project to use as the source for the code to set breakpoints and in general browse the code. The project name to use can normally be found in the build.sbt file this means for a project like the one associated with the FP Tower Foundations Course the setup looks like

  "Scala Attach Foundations (localhost:5005)"
  '(:type "scala"
    :request "attach"
    :name "Scala Attach Foundations (localhost:5005)"
    :hostName "localhost"
    :port 5005
    :targets [(:uri "file:///Users/pfehre/source/foundations?id=foundation")]))

important is the targets uri in this case as the default template for scala attach sets the project name to root resulting in the invalid target file:///Users/pfehre/source/foundations?id=root. With this setup and evaluated the commad dap-debug will now contain a Scala Attach Foundations (localhost:5005) target to use to attach to the process.

As this is project specific setup it makes sense to add it to the .dir-locals.el file so it automatically gets registered when visiting the project folder.

((nil . ((eval . (dap-register-debug-template
                  "Scala Attach Foundations (localhost:5005)"
                  '(:type "scala"
                    :request "attach"
                    :name "Scala Attach Foundations (localhost:5005)"
                    :hostName "localhost"
                    :port 5005
                    :targets [(:uri "file:///Users/pfehre/source/foundations?id=foundation")]))))))

would make this work.

Opening Sourcegraph from Emacs

Sourcegraph is super useful when browsing through code and dependencies, there is currently no plugin for emacs, but it is pretty easy to configure git-link to do the trick as @sqs pointed out to me on Twitter.

This is all the configuration to make git-link work as expected, and it should be pretty generic.

Bloop integration in Emacs

Some quick and hacky integration of Scala bloop with Emacs, using ammonite as the console and projectile for compilation and testing.

;;; bloop --- bloop minor mode
;; Author: Philipp Fehre <>
;; Keywords: scala, bloop, tools, convenience
;;; Commentary:
;; Helpers to integrate better with bloop, inspired by emacs-bloop
;; C-c M-j jack-in a bloop project running a new Ammonite REPL buffer
;; C-c M-z switch to an active Ammonite REPL
;; C-c b c Compile a bloop project backed by projectile-compile-project
;; C-c b t Test a bloop project backed by projectile-test-project
;; C-c b r Run a bloop project
;; Changelog:
;; - 25/8/2020 - Added run command mapping bloop-run (C-c b r)
;; - 1/5/2020 - initial working version
;;; Code:
(require 'projectile)
(require 'scala-mode)
(require 'ammonite-term-repl)
(require 's)
(defgroup bloop nil
"Bloop integration for emacs"
:group 'tools
:group 'convenience
:link '(url-link :tag "Gist" ""))
(defcustom bloop-program-name "bloop"
"Program used to run bloop commands, default to whatever is in the path."
:type 'string
:group 'bloop)
(defcustom bloop-reporter "scalac"
"Either bloop or scalac.
The main difference is that bloop shows errors in reverse order.
Emacs generally assumes the first error in the output is the most
relevant so the scalac reporter will most likely be preferred.
This is used for test and compile."
:type 'string
:group 'bloop)
(defun bloop--command (&rest args)
"Build a bloop command for ARGS."
(s-join " " (cons bloop-program-name args)))
(defun bloop--available-projects ()
"Get a list of currently available projects from bloop."
(projectile-with-default-dir (projectile-project-root)
(let ((projects-string (shell-command-to-string (bloop--command "projects"))))
(split-string projects-string))))
(defun bloop-switch-to-ammonite ()
"Switch to the running Ammonite REPL."
(if-let ((ammonite-buffer (get-buffer ammonite-term-repl-buffer-name)))
(switch-to-buffer ammonite-buffer)
(message "Ammonite is not running try C-c M-j to start an Ammonite REPL for bloop.")))
(defun bloop-run-ammonite (project)
"Run Ammonite for a bloop PROJECT."
(interactive (list (completing-read "Run Ammonite REPL for project: " (bloop--available-projects))))
(projectile-with-default-dir (projectile-project-root)
(let ((ammonite-term-repl-program bloop-program-name)
(ammonite-term-repl-program-args (list "console" project)))
(defun bloop-compile (project)
"Compile a bloop PROJECT."
(interactive (list (completing-read "Compile bloop project: " (bloop--available-projects))))
(let ((command (bloop--command "compile" project)))
(projectile--run-project-cmd command projectile-compilation-cmd-map
:show-prompt 't
:prompt-prefix "Compile command: "
:save-buffers t)))
(defun bloop-test (project)
"Test a bloop PROJECT."
(interactive (list (completing-read "Test bloop project: " (bloop--available-projects))))
(let ((test-command (bloop--command "test" "--reporter" bloop-reporter project)))
(projectile--run-project-cmd test-command projectile-test-cmd-map
:show-prompt 't
:prompt-prefix "Test command: "
:save-buffers t)))
(defun bloop-run (project)
"Run a bloop PROJECT."
(interactive (list (completing-read "Run bloop project: " (bloop--available-projects))))
(let ((run-command (bloop--command "run" project)))
(projectile--run-project-cmd run-command projectile-run-cmd-map
:show-prompt 't
:prompt-prefix "Run command: "
:save-buffers t)))
(define-minor-mode bloop-mode
"Bloop integration for emacs."
:lighter " bloop"
:keymap (let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c M-j") #'bloop-run-ammonite)
(define-key map (kbd "C-c M-z") #'bloop-switch-to-ammonite)
(define-key map (kbd "C-c b c") #'bloop-compile)
(define-key map (kbd "C-c b t") #'bloop-test)
(define-key map (kbd "C-c b r") #'bloop-run)
(add-hook 'scala-mode-hook 'bloop-mode)
(provide 'bloop)
;;; bloop.el ends here
view raw bloop.el hosted with ❤ by GitHub

Emacs Markdown list DWIM

Markdown has multiple types of lists, and in my mind checking items from those list means different things depending on the type.

- [ ] this item is open
- [x] this item is close
- this item is also open
- ~~this item is also close~~

For checklists I want the box to be checked when I toggle the item for, others I want the item to be crossed out via strike-through. All of those actions already exist in Emacs Markdown-Mode, but they are different depending on the list, I want Emacs to do what I mean no matter the list so I added this

(defun coder--markdown-toogle-list-item-dwim ()
    "Toogle the current list item depending on the type do the right thing.

1. When it is not a markdown list, ignore
2. When the list is a checklist indicated by [ ] check the checkbox
3. When the list is a normal list, strike-through the current item
4. When the item already has strike-through applied, un-strike it"
        (when-let ((bounds (markdown-cur-list-item-bounds)))
          ;; move to the beginning of the item after the list marker
          (goto-char (cl-first bounds))
          (forward-char (cl-fourth bounds))

          (cond ((looking-at "\\[[\s-xX]\\]") (markdown-toggle-gfm-checkbox))
                ((thing-at-point-looking-at markdown-regex-strike-through) (markdown-insert-strike-through))
                (t (progn
                     (set-mark (point))
                     ;; remove trailing whitespace from line first, this
                     ;; otherwise breaks strikethrough rendering

Happy markdown editing!

Lauching Emacsclient via Spotlight

When installing Emacs via

$ brew cask install emacs

it automatically installs emacsclient, but this needs to be launched via the terminal. When running the from Applications it will launch a new instance of emacs every time. Most of the time when I want to quickly edit something I tend to prefer to launch emacsclient to create a new window or frame in the existing running instance. Since I launch almost all my applications via Spotlight the simple way to achieve this is to create a script with the .command and use this instead.

$ cat ec.command 

$EMACSCLIENT -n -c -a '' $*

With this in place configure the script to be run via the terminal of your choice, in my case iTerm, by right clicking on the file and Get Info.

ec.command GetInfo

Thats it now Spotlight will execute the script when typing ec and hitting Enter on the top hit, assuming it is indexed.

My experience in getting my AWS Solutions Architect Professional certification

Disclaimer: While studying for the exam I was working Amazon as a Software Engineer, not part of AWS but Prime Video. Given that I largely didn’t have any special AWS resources or knowledge. I did however work work with AWS technologies for quite some time especially CloudFormation, Dynamo and EC2.

Here we go, a couple of weeks ago I finally got around to taking my AWS Certified Solutions Architect – Professional exam and therefor I am now certified.


I decided to take the exam mostly because I was looking for a reason to invest the time to really get to know what services are available and get a good overview of AWS in general (at least at this given point in time since AWS changes very quickly after all). Given this background I have to say the certification is well worth it, it is a great motivation to get studying and is a good way to guide the learning towards the more relevant (less buzzwords more value) parts of AWS.

My most reliable resource has been A Cloud Guru, which provide a quite comprehensive course with exercises, which make studying less dry but also are actually valuable in getting to know AWS better. I don’t think they are required to pass the exam, but given my motivation of getting to know AWS better they most certainly were helpful! Besides A Cloud Guru, I mostly ended up reading white-papers, and watching reinvent videos. Personally I found the white-papers mostly useful to pickup on the terms used, I don’t think the contain much new knowledge outside of that. I think as with most AWS exams the main enemy is time, with each question allowing for on average 2 minutes. It comes down to knowing what you know well and plow through those question quickly to have time for the ones which are less clear and require more analysis. While taking the exam I flagged multiple questions I was unsure about, but didn’t have time to go back, it was a close one for me.

Overall would I take it again: Yes, Is it worth it? Depending on the motivation for me it was. Thanks to A Cloud Guru for putting together a worth while course.

Grep in sections of a file

Processing files which are obviously organized in sections, chunks whatever you want to call it, happens and trying to find elements in it in an AND relationship is my most common use case. Sadly grep does not seem to have a nice way of processing based on a separator, but purely goes by line, so the easy way around this is to join all the lines in a chunk and grep in the result. Think input like this


Some AWK magic does the joining trick,

awk '/SECTION/ {printf "\n%s\n",$0;next} {printf "%s ",$0} END {print "\n"}' INPUT_FILE

And now

awk '/SECTION/ {printf "\n%s\n",$0;next} {printf "%s ",$0} END {print "\n"}' INPUT_FILE | \
grep 'foo=bar' | \
grep 'baz=blob'

Gives the matching section.

Solving Sudoku with Clojure core.logic

Recently I had some fun solving Sudoku using Clojure.core.logic. Afterwards figuring out that it would actually be the example on the Wiki, but hey fun non the less and my solution actually is very close to the Wiki one, especially after cleaning it up.

I find core.logic fascinating as it allows to express logic problems in a very straight forward fashion, and given I will not learn Prolog anytime soon, it get me to some understanding of the ideas.

Solving a puzzle like Sudoku basically breaks down towards the following steps:

  1. Break down the puzzle according to the rules, in case of Sudoku this means defining rows, columns and squares
  2. Defining the variables for the pieces to be computed, in my case this means replacing input zeros with core.logic lvars.
  3. Define the rules, in case of Sudoku there are only, constraint on the numbers to 1-9, constraint on rows, columns and squares to have each number show up only once.
(defn solve
  "Takes a sudoku as a vector, with all empty cells set to 0 and returns
  a solved sudoku as a vector.

    [0 0 0 2 6 0 7 0 1
     6 8 0 0 7 0 0 9 0
     1 9 0 0 0 4 5 0 0
     8 2 0 1 0 0 0 4 0
     0 0 4 6 0 2 9 0 0
     0 5 0 0 0 3 0 2 8
     0 0 9 3 0 0 0 7 4
     0 4 0 0 5 0 0 3 6
     7 0 3 0 1 8 0 0 0])
  (let [board (vec (map #(if (zero? %) (lvar) %) sudoku))
        rows (indexed-sub-board board row-indexes)
        cols (indexed-sub-board board column-indexes)
        squares (indexed-sub-board board square-indexes)]

     (run 1 [q]
       (== q board)
       ;; only 1 - 9 are allowed
       (everyg #(fd/in % (fd/interval 1 9)) board)

       ;; every number can appear only once per row
       (everyg fd/distinct rows)
       ;; every number can appear only once per column
       (everyg fd/distinct cols)
       ;; every number can appear only once per square
       (everyg fd/distinct squares)))))

Overall the whole solution ended up very straight forward, the only problem I faced was the very macro heavy definition of core.logic, making debugging not as straight forward and I ended up reading a log of library code to figure out how things were supposed to work. But I guess this also comes from my general lack of knowledge in this specific kind of programming, and therefore having to read up on very basic concepts along the way.

The full code is available on github.