Irreal: Emacs in the Humanities

I stumbled across a link to this post in the Emacs reddit and ignored it but curiosity go the better of me so I went back to it. Like most Irreal readers (I assume) the label nerd or geek can appropriately be applied to me so the question, “Is anybody using emacs in the humanities or divinity?” wouldn’t normally interest me. Except for the Emacs part.

In any event, I did follow the link and found a pretty interesting discussion from folks in the humanities on how they are using Emacs—and often AUCTeX and Org mode—for their work and writing. It’s a tribute to the power and usefulness of Emacs that people so far removed from the technical world that most of us live in nevertheless find it useful and worth the pain of learning it.

These folks deserve our admiration not only for taking the trouble to learn Emacs but also for enduring the friction it adds to their everyday work. Remember that Word stands supreme in the humanities and if you’re using Emacs you have to worry about converting your work to a form that your colleagues can read and work with. As for writing \LaTeX with Word: shudder.

-1:-- Emacs in the Humanities (Post jcs)--L0--C0--November 03, 2017 04:02 PM

Irreal: Association List Library

Back in August, I wrote about a series of libraries for handling hash tables and key/value pairs, and a general library for handling hash tables, alists, and arrays. A little later I came across another library for handling alists by Troy Pracy but forgot to write about it until now.

You might think that there’s not much required for alists other than assoc and assq but Pracy provides a large number of functions that make some of the routine coding associated (heh) with alists a bit easier. The list includes creating, filtering, and mapping functions. Take a look at the README for the complete list and documentation on each.

If you prefer to use libraries for handling data structures and none of the other libraries we’ve discussed meets your needs, perhaps you’ll find Pracy’s useful.

-1:-- Association List Library (Post jcs)--L0--C0--November 02, 2017 07:45 PM

emacshorrors: bytecomp.el

It’s halloween, so here’s a real treat for you, the commentary in bytecomp.el! The author of that piece of code is Jamie Zawinski who did invaluable work for both GNU Emacs and XEmacs, these days he runs a night club and blogs. Here are my favorite parts of the file:

  • ";; We successfully didn't compile this file."
    
  • (insert "\n") ; aaah, unix.
    
  •             (when old-style-backquotes
                  (byte-compile-warn "!! The file uses old-style backquotes !!
    This functionality has been obsolete for more than 10 years already
    and will be removed soon.  See (elisp)Backquote in the manual."))
    
  • ;; Insert semicolons as ballast, so that byte-compile-fix-header
    ;; can delete them so as to keep the buffer positions
    ;; constant for the actual compiled code.
    ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
    ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n"
    
  • ;; To avoid consing up monstrously large forms at load time, we split
    ;; the output regularly.
    
  • ;; If things not being bound at all is ok, so must them being
    ;; obsolete.  Note that we add to the existing lists since Tramp
    ;; (ab)uses this feature.
    
  • ;; If foo.el declares `toto' as obsolete, it is likely that foo.el will
    ;; actually use `toto' in order for this obsolete variable to still work
    ;; correctly, so paradoxically, while byte-compiling foo.el, the presence
    ;; of a make-obsolete-variable call for `toto' is an indication that `toto'
    ;; should not trigger obsolete-warnings in foo.el.
    
  • ;; FIXME: we also use this hunk-handler to implement the function's dynamic
    ;; docstring feature.  We could actually implement it more elegantly in
    ;; byte-compile-lambda so it applies to all lambdas, but the problem is that
    ;; the resulting .elc format will not be recognized by make-docfile, so
    ;; either we stop using DOC for the docstrings of preloaded elc files (at the
    ;; cost of around 24KB on 32bit hosts, double on 64bit hosts) or we need to
    ;; build DOC in a more clever way (e.g. handle anonymous elements).
    
  • ;; Don't reload the source version of the files below
    ;; because that causes subsequent byte-compilation to
    ;; be a lot slower and need a higher max-lisp-eval-depth,
    ;; so it can cause recompilation to fail.
    
  • ;; To avoid "lisp nesting exceeds max-lisp-eval-depth" when bytecomp compiles
    ;; itself, compile some of its most used recursive functions (at load time).
    

Don’t get me wrong, I’m aware that these are all necessary and don’t indicate deeper faults in the source code. I merely find it interesting what hacks one has to come up with for byte-code compilation and found studying the file enlightening to say the least.

-1:-- bytecomp.el (Post Vasilij Schneidermann)--L0--C0--October 31, 2017 07:44 AM

Marcin Borkowski: Pdf-tools and follow mode

Today I discovered an extremely cool feature of pdf-tools. Assume that you have a pdf file with annotations (that is, those funny yellow sticky-note-like thingies which show some text when hovered or clicked). Assume that they are done by the editor of a journal you work for, and you have to modify the source LaTeX file accordingly. (This is a rather specialized use, but I think the feature may have more applications.) My previous workflow involved using a mouse (actually, a touchpad, but I hate both with a passion). But there’s a much better way.
-1:-- Pdf-tools and follow mode (Post)--L0--C0--October 30, 2017 06:59 PM

Chen Bin (redguardtoo): Auto complete everything in Emacs

complete everything in Emacs :en:emacs:

As a web developer using modern front end framework like React/Angular, I spend a lot of time on web components.

A component instance is like:

<GenericTable
  onSelectRow={ row => console.log(row) }
  numberOfPinnedColumns={2}
  withToolBar
  onClickCell={ cell => console.log(cell) }
>
  <PaginationButtons />
  <TotalSum />
  <ReportButtons />
</GenericTable>

Basically a component instance is a big chunk of html tags.

I created a new package EACL (Emacs auto complete lines) which could help me input components in unbelievable speed.

The idea is simple. If I've already used one component elsewhere in the project. It's unnecessary to re-type the similar code again.

All I need to do is to input the first characters of the component and run M-x eacl-complete-tag which will grep the project and input the remaining part of component.

Here is a demo to input component ButtonToolbar:

eacl-demo.gif

Please note EACL is generic and can be use in any programming language.

M-x eacl-complete-statement to complete below Javascript code:

import {
  Button,
  Row,
  Column
} from 'react-bootstrap';

M-x eacl-complete-snippet to complete below C code:

static int v9fs_drop_inode(struct inode *inode)
{
    struct v9fs_session_info *v9ses;
    v9ses = v9fs_inode2v9ses(inode);
    if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
        return generic_drop_inode(inode);
    /*
     * in case of non cached mode always drop the
     * the inode because we want the inode attribute
     * to always match that on the server.
     */
    return 1;
}

You can also create your own commands based on API eacl-complete-multi-lines-internal.

For example, it is a piece of cake to support Lisp by creating comand my-complete-lisp:

(require 'eacl)
(defun my-complete-lisp ()
  (interactive)
  (eacl-complete-multi-lines-internal "[^)]*)"))
-1:-- Auto complete everything in Emacs (Post Chen Bin)--L0--C0--October 30, 2017 11:13 AM

sachachua: 2017-10-30 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, Hacker News, planet.emacsen.org, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

-1:-- 2017-10-30 Emacs news (Post Sacha Chua)--L0--C0--October 30, 2017 07:58 AM

Modern Emacs: Deep diving into a major mode - Part 2 (IDE Features)

In Part 1 I addressed: syntax tables, indentation, font locking, and context-sensitive syntax.

We now build out a "Hyde" with: shell/async process integration, Eldoc support, and Autocompletion. Also "shift-K" documentation lookup for the symbol-at-point.

/img/eldoc-auto.png

Building Inferior Hy

The basics

The easiest way to add a REPL to your major-mode is through setting the variable inferior-lisp-program, possibly adding setup code through inferior-lisp-load-command, then running the inferior-lisp command.


;; within the define-derived-mode hy-mode setup...
(setq-local inferior-lisp-program "hy")
(setq-local inferior-lisp-load-command "(print \"Hy there!\")")

This isn't sufficient for advanced shells. The custom is to create a function named run-hy (eg. there is run-python, run-haskell...) which starts up the shell, sets inferior-hy-mode , and switches to the shell.

Comint-mode

It is a "Major mode for interacting with an inferior interpreter". Most-all inferior modes will derive from comint-mode. It provides many utilities for interacting with shell-like processes.

Hy mode's prompt is a right arrow.


(define-derived-mode inferior-hy-mode comint-mode "Inferior Hy"
  "Major mode for Hy inferior process."
  (setq-local indent-tabs-mode nil)

  ;; How to dispaly the process status in the mode-line
  (setq mode-line-process '(":%s"))
  ;; This disables editing and traversing the "=>" prompts
  (setq-local comint-prompt-read-only t)
  ;; Lets comint mode recognize the prompt
  (setq-local comint-prompt-regexp (rx bol "=>" space))

  ;; ... other specialized config introduced later ...
  )

There are several comint components we will make use of:

  1. comint-last-prompt - a cons cell of begin/end markers of last prompt.
  2. comint-send-string - perform process-send-string with comint
  3. bookkeeping.
  4. comint-redirect-send-command-to-process and comint-redirect-completed - for sending strings asynchronously.
  5. comint-(pre)output-filter-functions - entry points into capturing and
  6. cleaning process output.
  7. make-comint-in-buffer - entry point into comint mode.

Managing buffers and processes

We must manage: the standard hy shell process, the internal hy process used for autocompletion and eldoc, and temporal buffers for more advanced buffer transformations of the standard hy shell process.

The configuration required of inferior-hy-mode :


;;; Configuration

(defconst hy-shell-interpreter "hy"
  "Default Hy interpreter name.")

(defvar hy-shell-interpreter-args "--spy"
  "Default arguments for Hy interpreter.")

;;; Internal

(defconst hy-shell-buffer-name "Hy"
  "Default buffer name for Hy interpreter.")

(defconst hy-shell-internal-buffer-name "Hy Internal"
  "Default buffer name for the internal Hy process.")

(defvar hy-shell-buffer nil
  "The current shell buffer for Hy.")

(defvar hy--shell-output-filter-in-progress nil
  "Whether we are waiting for output in `hy-shell-send-string-no-output'.")

(defvar hy--shell-font-lock-enable t
  "Whether the shell should font-lock the current line.")

Now the building blocks of the shell can be defined.

The implementations are rather straightforward. To keep space down, only name and docstring are provided:


(defun hy--shell-format-process-name (proc-name)
  "Format a PROC-NAME with closing astericks.")

(defun hy-shell-get-process (&optional internal)
  "Get process corr. to `hy-shell-buffer-name'/`hy-shell-internal-buffer-name'.")

(defun hy--shell-current-buffer-process ()
  "Get process associated with current buffer.")

(defun hy--shell-current-buffer-a-process? ()
  "Is `current-buffer' a live process?")

(defun hy--shell-get-or-create-buffer ()
  "Get or create `hy-shell-buffer' buffer for current hy shell process.")

(defun hy--shell-buffer? ()
  "Is `hy-shell-buffer' set and does it exist?")

(defun hy--shell-kill-buffer ()
  "Kill `hy-shell-buffer'.")

(defun hy--shell-calculate-command (&optional internal)
  "Calculate the string used to execute the inferior Hy process.")
  ;; Straightforward string formatting - see: `shell-quote-argument'

Starting up the shell

The commands above are enough to build out some basic shell support. Lets look at run-hy :


(defun run-hy (&optional cmd)
  "Run an inferior Hy process.

CMD defaults to the result of `hy--shell-calculate-command'."
  (interactive)
  (unless (executable-find "hy")
    (message "Hy not found, activate a virtual environment with Hy."))

  (-> (or cmd (hy--shell-calculate-command))
     (hy--shell-make-comint hy-shell-buffer-name 'show)
     get-buffer-process))

Most of the work is delegated to hy--shell-make-comint as we also must have the internal variant:


(defun run-hy-internal ()
  "Start an inferior hy process in the background for autocompletion."
  (interactive)
  (unless (executable-find "hy")
    (message "Hy not found, activate a virtual environment containing Hy to use
Eldoc, Anaconda, and other hy-mode features."))

  (when (and (not (hy-shell-get-process 'internal))
             (executable-find "hy"))
    (-let [hy--shell-font-lock-enable
           nil]
      (prog1
          (-> (hy--shell-calculate-command 'internal)
             (hy--shell-make-comint hy-shell-internal-buffer-name nil 'internal)
             get-buffer-process)
        (hy--shell-send-internal-setup-code)
        (message "Hy internal process successfully started")))))

This is a simple variation of run-hy that passes the internal argument through the hy shell building blocks and also sends setup code for eldoc-mode and company-mode.

Now we are ready to startup our inferior-hy-mode :


(defun hy--shell-make-comint (cmd proc-name &optional show internal)
  "Create and return comint process PROC-NAME with CMD, opt. INTERNAL and SHOW."
  (-when-let* ((proc-buffer-name
                (hy--shell-format-process-name proc-name))
               (_
                (not (comint-check-proc proc-buffer-name)))
               (cmdlist
                (split-string-and-unquote cmd))
               (buffer
                (apply 'make-comint-in-buffer proc-name proc-buffer-name
                       (car cmdlist) nil (cdr cmdlist)))
               (process
                (get-buffer-process buffer)))
    (with-current-buffer buffer
      (inferior-hy-mode))
    (when show
      (display-buffer buffer))
    (if internal
        (set-process-query-on-exit-flag process nil)
      (setq hy-shell-buffer buffer))
    proc-buffer-name))

All the work is once again delegated to our shell building blocks. There are several things to notice:

  1. If the process is meant to be autostarted/quited, make sure to use set-process-query-on-exit-flag to nil.
  2. The cmdlist car is "hy" and cdr is the hy interpreter arguments.
  3. Further accessing of the shell is done with the hy-shell-buffer variable.

Working with the shell

The shell is now functional, but we still don't have methods to send strings to the shell (for instance, sending the current-form or the buffer for evaluation). Nor do we have any support for asynchronously sending and extracting information from our internal process.

Like always, lets define some utilities:


(defun hy--shell-end-of-output? (string)
  "Return non-nil if STRING ends with the prompt."
  (s-matches? comint-prompt-regexp string))

(defun hy--shell-output-filter (string)
  "If STRING ends with input prompt then set filter in progress done."
  (when (hy--shell-end-of-output? string)
    (setq hy--shell-output-filter-in-progress nil))
  "\n=> ")

hy--shell-output-filter-in-progress is the critical component. Lets see how it is used:


(defun hy--shell-send-string (string &optional process internal)
  "Internal implementation of shell send string functionality."
  (let ((process (or process (hy-shell-get-process internal)))
        (hy--shell-output-filter-in-progress t))
    (comint-send-string process string)
    (while hy--shell-output-filter-in-progress
      (accept-process-output process))))

The shell process is obtained, we set it to be in progress, and send it off to comint. But how and when is the filter reset?

We come back to the comint-(pre)output-filter-functions. When we send the string via comint-send-string, part of its bookkeeping is to apply these filter functions to the output. However, the output can come in chunks, so simply accepting the process output is not sufficient. We must recognize when the last of the expected process output is retrieved and signal to stop accepting output.

The difference between the pre and standard filters is when they are applied. The pre variation is executed before the process output is inserted into the buffer.

Looking back to hy--shell-output-filter, what are the outcomes of using it as a pre or standard filter? Lets look at the exposed send strings:


(defun hy-shell-send-string-no-output (string &optional process internal)
  "Send STRING to hy PROCESS and inhibit printing output."
  (-let [comint-preoutput-filter-functions
         '(hy--shell-output-filter)]
    (hy--shell-send-string string process internal)))

(defun hy-shell-send-string (string &optional process)
  "Send STRING to hy PROCESS."
  (-let [comint-output-filter-functions
         '(hy--shell-output-filter)]
    (hy--shell-send-string string process)))

Lastly, these functions won't work for asynchronous ops like Eldoc and Autocompletion. You will see a Blocking call inhibiting process output error messaged in the minibuffer.

The asynchronous version is different. We redirect the process output to a temporary buffer and capture its output.

The key is the 100ms timeout argument passed to accept-process-output.


(defun hy--shell-send-async (string)
  "Send STRING to internal hy process asynchronously."
  (let ((output-buffer " *Comint Hy Redirect Work Buffer*")
        (proc (hy-shell-get-process 'internal)))
    (with-current-buffer (get-buffer-create output-buffer)
      (erase-buffer)
      (comint-redirect-send-command-to-process string output-buffer proc nil t)

      (set-buffer (process-buffer proc))
      (while (and (null comint-redirect-completed)
                  (accept-process-output proc nil 100 t)))
      (set-buffer output-buffer)
      (buffer-string))))

Our shell is now ready for autocompletion, eldoc, and other awesome IDE features.

I originally planned to go into font-locking the prompt input (highly non-trivial), but given the length of this post I will provide and link to it as a separate future post.

Autocompletion

All the work for autocompletion was in setting up the asynchronous process support. Lets see how easy autocompletion becomes:


(defconst hy-company-setup-code
  "(import [hy.completer [Completer]])
(setv --HYCOMPANY (Completer))"
  "Autocompletion setup code to send to the internal process.")

(defconst hy--company-regexp
  (rx "'"
      (group (1+ (not (any ",]"))))
      "'"
      (any "," "]"))
  "Regex to extra candidates from --HYCOMPANY.")

(defun hy--company-format-str (string)
  "Format STRING to send to hy for completion candidates."
  (when string
    (format "(.%s --HYCOMPANY \"%s\")"
            (cond ((s-starts-with? "#" string)  ; Tag matches broken in Hy atm
                   "tag-matches")
                  ((s-contains? "." string)
                   "attr-matches")
                  (t
                   "global-matches"))
            string)))

(defun hy--company-candidates (string)
  "Get candidates for completion of STRING."
  (-when-let* ((command (hy--company-format-str string))
               (candidates (hy--shell-send-async command))
               (matches (s-match-strings-all hy--company-regexp candidates)))
    (-select-column 1 matches)))  ; Get match-data-1 for each match

(defun company-hy (command &optional arg &rest ignored)
  (interactive (list 'interactive))
  (cl-case command
    (prefix (company-grab-symbol))
    (candidates (hy--company-candidates arg))
    (meta (-> arg hy--eldoc-get-docs hy--str-or-empty))))

Completer is a hy builtin that completes a given string and does all the work here. We simply call it's appropriate method, extract the items in the retrieved list, and hand it off to company.

company-grab-symbol gets the current symbol which is handed off as arg in the subsequent call.

The meta argument shows the eldoc output for the current selected company candidate in the minibuffer, as seen in this post's initial image.

company-hy can then be enabled either through adding to company-backends or for Spacemacs users adding:


;; Technically this should be within a hy layer, but this still works uncaptured
(spacemacs|add-company-backends
  :backends company-hy
  :modes hy-mode inferior-hy-mode)

Developing a major-mode that accommodates Spacemacs users will be touched on in future posts.

Eldoc

For those unfamiliar, in the initial image eldoc-mode provides the formatted docstring and arguments in the minibuffer for the symbol-at-point (or completion candidate).

Perhaps surprisingly, Eldoc is a lot more challenging than autocompletion.

For starters, your language won't provide Eldoc like strings (formatted argument list + first line of docstring) by default. How difficult inspecting language constructs is entirely dependent on the language. Hy in particular is difficult due to how macros are implemented and namespaced. I won't provide the hy-eldoc-setup-code here, it can be found within the source.

Next, your implementation must mirror any relevant DSLs. For lisps, Eldoc inspects the form opener. It is hydiomatic to:


(setv x "hi")
(.format "{} there" x)
(setv a-list [])
(.append a-list "friend")

We need to send str.format and a-list.append - the form opener alone is insufficient.

Implementation

Eldoc is setup via the eldoc-documentation-function :


(defun hy-eldoc-documentation-function ()
  "Drives `eldoc-mode', retrieves eldoc msg string for inner-most symbol."
  (-> (hy--eldoc-get-inner-symbol)
     hy--eldoc-get-docs))

(defun hy--mode-setup-eldoc ()
  (make-local-variable 'eldoc-documentation-function)
  (setq-local eldoc-documentation-function 'hy-eldoc-documentation-function)
  (eldoc-mode +1))

There are three core components:

  1. hy--eldoc-send for sending a formatted string and cleaning its output.
  2. hy--eldoc-get-inner-symbol getting opening form and completing the dot DSL.
  3. hy--eldoc-fontify-text for highlighting the final text string like in the image.

Lets look at fontifying first. We can't blindly apply Hy's font-locks as the docstring isn't captured in quotes. Since the text is static, we just add the faces to the string ourselves.


(defun hy--fontify-text (text regexp &rest faces)
  "Fontify portions of TEXT matching REGEXP with FACES."
  (when text
    (-each
        (s-matched-positions-all regexp text)
      (-lambda ((beg . end))
        (--each faces
          (add-face-text-property beg end it nil text))))))

(defun hy--eldoc-fontify-text (text)
  "Fontify eldoc TEXT."
  (let ((kwd-rx
         (rx string-start (1+ (not (any space ":"))) ":"))
        (kwargs-rx
         (rx symbol-start "&" (1+ word)))
        (quoted-args-rx
         (rx "`" (1+ (not space)) "`")))
    (hy--fontify-text
     text kwd-rx 'font-lock-keyword-face)
    (hy--fontify-text
     text kwargs-rx 'font-lock-type-face)
    (hy--fontify-text
     text quoted-args-rx 'font-lock-constant-face 'bold-italic))
  text)

Next lets see the sending and formatting of the shell's raw eldoc output.


(defun hy--eldoc-send (string)
  "Send STRING for eldoc to internal process returning output."
  (-> string
     hy--shell-send-async
     hy--eldoc-chomp-output
     hy--eldoc-remove-syntax-errors
     hy--str-or-nil))

The string/output formatting are implementation details specific to Hy and so won't be detailed. If we are dealing with an empty string, we return nil rather than the empty string to pass-by parent when clauses.

The meat of Eldoc is in extracting the innermost symbol of the current point


(defun hy--eldoc-get-inner-symbol ()
  "Traverse and inspect innermost sexp and return formatted string for eldoc."
  (save-excursion
    (-when-let* ((_ (hy-shell-get-process 'internal))
                 (state (syntax-ppss))
                 (start-pos (hy--sexp-inermost-char state))
                 (_ (progn (goto-char start-pos)
                           (not (hy--not-function-form-p))))
                 (function (progn (forward-char)
                                  (thing-at-point 'symbol))))

      ;; Attribute method call (eg. ".format str") needs following sexp
      (if (s-starts-with? "." function)
          (when (ignore-errors (forward-sexp) (forward-char) t)
            (pcase (char-after)
              ;; Can't send just .method to eldoc
              (?\) (setq function nil))
              (?\s (setq function nil))
              (?\C-j (setq function nil))  ; newline

              ;; Dot dsl doesn't work on literals
              (?\[ (concat "list" function))
              (?\{ (concat "dict" function))
              (?\  (concat "str" function))  ; the " is deleted in blog as breaks rainbow.js

              ;; Otherwise complete the dot dsl
              (_ (progn
                   (forward-char)
                   (concat (thing-at-point 'symbol) function)))))
        function))))

So Eldoc's path is to call hy--eldoc-get-inner-symbol if an internal process is active, syntax-ppss indicates we are within a form, and that the innermost form is a symbol. The completed string is sent off to the internal process we've built up, the output is chomped of quote characters and the prompt and syntax errors (eg. completing "str." while we are still typing) are ignored. The result is fontified and returned by the documentation function.

Spacemacs shift-k documentation lookup

A feature of Spacemacs is typing "K" to perform spacemacs/evil-smart-doc-lookup to get the full documentation of the symbol-at-point in a separate buffer.

Using Eldoc's documentation functions, with slightly different formatting, we already have most of shift-K implemented.

We moved most of hy-eldoc-documentation-function into hy--eldoc-get-docs which distinctly accepts an optional argument for buffer-style rather than eldoc-style formatting.

We then create a mirror of the documentation function as hy--docs-for-thing-at-point. We format the text to account for newlines (newlines from process output are escaped so we must trim one backslash from each newline).


(defun hy--docs-for-thing-at-point ()
  "Mirrors `hy-eldoc-documentation-function' formatted for a buffer, not a msg."
  (-> (thing-at-point 'symbol)
     (hy--eldoc-get-docs t)
     hy--format-docs-for-buffer))

(defun hy--format-docs-for-buffer (text)
  "Format raw hydoc TEXT for inserting into hyconda buffer."
  (when text
    (-let [kwarg-newline-regexp
           (rx ","
               (1+ (not (any "," ")")))
               (group-n 1 "\\\n")
               (1+ (not (any "," ")"))))]
      (--> text
         (s-replace "\\n" "\n" it)
         (replace-regexp-in-string kwarg-newline-regexp "newline" it nil t 1)))))

It is interesting how "K" is actually called, I'm not sure if any other function operates quite the same. "K" calls the function bound to "SPC m h h".


(spacemacs/set-leader-keys-for-major-mode 'hy-mode
  "hh" 'hy-describe-thing-at-point)

Lastly we need to create, switch-to, and insert the retrieved docs as hy-describe-thing-at-point.


(defun hy-describe-thing-at-point ()
  "Implement shift-k docs lookup for `spacemacs/evil-smart-doc-lookup'."
  (interactive)
  (-when-let* ((text (hy--docs-for-thing-at-point))
               (doc-buffer "*Hyconda*"))
    (with-current-buffer (get-buffer-create doc-buffer)
      (erase-buffer)
      (switch-to-buffer-other-window doc-buffer)

      (insert text)
      (goto-char (point-min))
      (forward-line)

      (insert "------\n")
      (fill-region (point) (point-max))

      ;; Eventually make hyconda-view-minor-mode, atm this is sufficient
      (local-set-key "q" 'quit-window)
      (when (fboundp 'evil-local-set-key)
        (evil-local-set-key 'normal "q" 'quit-window)))))

Closing

There are several other features worth discussion like font-locking the shell prompt input and the send-(form/region/buffer)-to-shell that are sizable enough to warrant their own posts later. With this post, the series is caught up to the current featureset. Linting would be the next big problem to attack. I'd also like to integrate ert.

Going without Company and Eldoc has helped me appreciate the value in IDEs. Hy is quickly becoming a pleasant development experience.

My only guidance was source code. I hope this series make the problem more tractable for prospective major mode authors.

-1:-- Deep diving into a major mode - Part 2 (IDE Features) (Post)--L0--C0--October 29, 2017 12:00 AM

Pragmatic Emacs: View and annotate PDFs in Emacs with PDF-tools

The pdf-tools packages allows you to read and annotate PDF documents in Emacs. The installation process is described on the github page, but on my Mac, I needed to install poppler (I used macports) and add

export PKG_CONFIG_PATH=/opt/local/lib/pkgconfig

to my zshrc. Then after installing the package in Emacs with the following code

(use-package pdf-tools
 :pin manual ;; manually update
 :config
 ;; open pdfs scaled to fit page
 (setq-default pdf-view-display-size 'fit-page)
 ;; automatically annotate highlights
 (setq pdf-annot-activate-created-annotations t)
 ;; use normal isearch
 (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward))

I ran M-x pdf-tools-install, ignored an error message about epdfinfo and then restarted emacs, and all was well.

I use the :pin manual option in use-package to stop pdf-tools being automatically updated when I update the rest of my packages, since it would need the installation command and restart each time it updated.

There are lots of nice features in pdf-tools but I’ll just mention the ones I use most often. You can search pdf files like normal buffers, but the enhanced search tool swiper doesn’t work with pdf-tools so I set C-s to call the normal isearch when in this mode.

You can also make annotations in pdf-tools and I set my configuration above so that when an annotation (like highlighting some text) is created, a buffer opens prompting for a text note to go with the annotation. So for example, to highlight a comment on some text I

  1. Select the text in the pdf (mouse required for this unfortunately)
  2. Use C-c C-a h to highlight it yellow
  3. Type some notes in the annotation buffer that pops up and use C-c C-c to complete the annotation.

Other useful annotations are C-c C-a t and then mouse click to add a text note somewhere to the pdf page, C-c C-a o to strike-through text, and C-c C-a D and then click to delete an annotation.

Saving the pdf buffer as normal saves all the annotations, and they will be readable in any PDF viewer so this works well when collaborating with the unenlightened!

-1:-- View and annotate PDFs in Emacs with PDF-tools (Post Ben Maughan)--L0--C0--October 28, 2017 03:22 PM

(or emacs: Orca - new package to improve org-capture from browser

Intro

Orca is a new Emacs package, an attempt to refactor my old org-fu into something that's much more re-usable and easier to get started with.

Orca functionality

Problem:

When capturing from Firefox using org-protocol (together with this addon):

  • either I refile each time I capture, which is slow
  • or my captures pile up in one place, which is messy

Solution:

  1. Define rules for where links from certain websites should be captured.
  2. Allow to capture directly into the current org-mode buffer, since it's likely related to what I'm working with on.

Part 1: Rules example

Here is my example list of configurations:

Corresponding code:

(setq orca-handler-list
      '((orca-handler-match-url
         "https://www.reddit.com/"
         "~/Dropbox/org/wiki/emacs.org" "Reddit")
        (orca-handler-match-url
         "https://emacs.stackexchange.com/"
         "~/Dropbox/org/wiki/emacs.org" "\\* Questions")
        (orca-handler-file
         "~/Dropbox/org/ent.org" "\\* Articles")))

Part 2: Current buffer example

For example, I'm researching how to implement something with docker. This means that I have docker.org open, along with dozens of tabs in the browser.

I can configure to capture into the current org-mode buffer with a * Tasks heading like this:

(push '(orca-handler-current-buffer "\\* Tasks") orca-handler-list)

Since docker.org has * Tasks, I just click the capture button in Firefox and follow up with an immediate C-c C-c in Emacs. The link is already in the right position, no need for an extra refile step.

Using customize with orca

You can set up the capture rules using M-x customize-group RET orca RET.

Here's a screenshot: orca-customize

As you see, the customization is a list of an arbitrary length, with each element falling into one of three categories, each backed by an Elisp function (orca-handler-current-buffer, orca-handler-file, and orca-handler-match-url). Each function takes a different number of arguments (one, two, and three, respectively) - they are all annotated by the interface.

Here's the code that describes the expected :type to customize:

(defcustom orca-handler-list
  ;; ...
  :type '(repeat
          (choice
           (list
            :tag "Current buffer"
            (const orca-handler-current-buffer)
            (string :tag "Heading"))
           (list
            :tag "URL matching regex"
            (const orca-handler-match-url)
            (string :tag "URL")
            (string :tag "File")
            (string :tag "Heading"))
           (list
            :tag "Default"
            (const orca-handler-file)
            (string :tag "File")
            (string :tag "Heading")))))

You can read more about the customization types in this manual section.

Outro

I hope you enjoy orca. I've submitted it to MELPA. Hopefully, it will be available for an easy install very soon.

Org-mode is a beautiful thing, but my previous attempts to configure it were huge config files of loosely related (i.e. the only thing in common was Org-mode) stuff spanning hundreds of lines. Orca is an improvement in this respect, since it focuses on a very narrow domain. It still tries to be flexible (just like org-capture) - you can plug in your own functions into orca-handler-list. But initially, the flexibility can be constrained into the customize-group interface, to allow for a self-documenting solution that's easy to get started with. Happy hacking!

PS. Thanks to all my patrons for advancing my Patreon campaign! As of this writing, we're almost at the 25% mark with 61 contributors.

-1:-- Orca - new package to improve org-capture from browser (Post)--L0--C0--October 27, 2017 10:00 PM

Chris Wellons: Make Flet Great Again

Do you long for the days before Emacs 24.3 when flet was dynamically scoped? Well, you probably shouldn’t since there are some very good reasons lexical scope. But, still, a dynamically scoped flet is situationally really useful, particularly in unit testing. The good news is that it’s trivial to get this original behavior back without relying on deprecated functions nor third-party packages.

But first, what is flet and what does it mean for it to be dynamically scoped? The name stands for “function let” (or something to that effect). It’s a macro to bind named functions within a local scope, just as let binds variables within some local scope. It’s provided by the now-deprecated cl package.

(require 'cl)  ; deprecated!

(defun norm (x y)
  (flet ((square (v) (* v v)))
    (sqrt (+ (square x) (square y)))))

However, a gotcha here is that square is visible not just to the body of norm but also to any function called directly or indirectly from the flet body. That’s dynamic scope.

(flet ((sqrt (v) (/ v 2)))  ; close enough
  (norm 2 2))
;; -> 4

Note: This works because sqrt hasn’t (yet?) been assigned a bytecode opcode. One weakness with flet is that, due to being dynamically scoped, it is unable to define or override functions whose calls evaporate under byte compilation. For example, addition:

(defun add-with-flet ()
  (flet ((+ (&rest _) :override))
    (+ 1 2 3)))

(add-with-flet)
;; -> :override

(funcall (byte-compile #'add-with-flet))
;; -> 6

Since + has its own opcode, the function call is eliminated under byte-compilation and flet can’t do its job. This is similar these same functions being unadvisable.

cl-lib and cl-flet

The cl-lib package introduced in Emacs 24.3, replacing cl, adds a namespace prefix, cl-, to all of these Common Lisp style functions. In most cases this was the only change. One exception is cl-flet, which has different semantics: It’s lexically scoped, just like in Common Lisp. Its bindings aren’t visible outside of the cl-flet body.

(require 'cl-lib)

(cl-flet ((sqrt (v) (/ v 2)))
  (norm 2 2))
;; -> 2.8284271247461903

In most cases this is what you actually want. The old flet subtly changes the environment for all functions called directly or indirectly from its body.

Besides being cleaner and less error prone, cl-flet also doesn’t have special exceptions for functions with assigned opcodes. At macro-expansion time it walks the body, taking its action before the byte-compiler can interfere.

(defun add-with-cl-flet ()
  (cl-flet ((+ (&rest _) :override))
    (+ 1 2 3)))

(add-with-cl-flet)
;; -> :override

(funcall (byte-compile #'add-with-cl-flet))
;; -> :override

In order for it to work properly, it’s essential that functions are quoted with sharp-quotes (#') so that the macro can tell the difference between functions and symbols. Just make a general habit of sharp-quoting functions.

In unit testing, temporarily overriding functions for all of Emacs is useful, so flet still has some uses. But it’s deprecated!

Unit testing with flet

Since Emacs can do anything, suppose there is an Emacs package that makes sandwiches. In this package there’s an interactive function to set the default sandwich cheese.

(defvar default-cheese 'cheddar)

(defun set-default-cheese (type)
  (interactive
   (let* ((options '("cheddar" "swiss" "american"))
          (input (completing-read "Cheese: " options nil t)))
     (when input
       (list (intern input)))))
  (setf default-cheese type))

Since it’s interactive, it uses completing-read to prompt the user for input. A unit test could call this function non-interactively, but perhaps we’d also like to test the interactive path. The code inside interactive occasionally gets messy and may warrant testing. It would obviously be inconvenient to prompt the user for input during testing, and it wouldn’t work at all in batch mode (-batch).

With flet we can stub out completing-read just for the unit test:

;;; -*- lexical-binding: t; -*-

(ert-deftest test-set-default-cheese ()
  ;; protect original with dynamic binding
  (let (default-cheese)
    ;; simulate user entering "american"
    (flet ((completing-read (&rest _) "american"))
      (call-interactively #'set-default-cheese)
      (should (eq 'american default-cheese)))))

Since default-cheese was defined with defvar, it will be dynamically scoped despite let normally using lexical scope in this example. Both of the side effects of the tested function — setting a global variable and prompting the user — are captured using a combination of let and flet.

Since cl-flet is lexically scoped, it cannot serve this purpose. If flet is deprecated and cl-flet can’t do the job, what’s the right way to fix it? The answer lies in generalized variables.

cl-letf

What’s really happening inside flet is it’s globally binding a function name to a different function, evaluating the body, and rebinding it back to the original definition when the body completes. It macro-expands to something like this:

(let ((original (symbol-function 'completing-read)))
  (setf (symbol-function 'completing-read)
        (lambda (&rest _) "american"))
  (unwind-protect
      (call-interactively #'set-default-cheese)
    (setf (symbol-function 'completing-read) original)))

The unwind-protect ensures the original function is rebound even if the body of the call were to fail. This is very much a let-like pattern, and I’m using symbol-function as a generalized variable via setf. Is there a generalized variable version of let?

Yes! It’s called cl-letf! In this case the f suffix is analogous to the f suffix in setf. That form above can be reduced to a more general form:

(cl-letf (((symbol-function 'completing-read)
           (lambda (&rest _) "american")))
  (call-interactively #'set-default-cheese))

And that’s the way to reproduce the dynamically scoped behavior of flet since Emacs 24.3. There’s nothing complicated about it.

(ert-deftest test-set-default-cheese ()
  (let (default-cheese)
    (cl-letf (((symbol-function 'completing-read)
               (lambda (&rest _) "american")))
      (call-interactively #'set-default-cheese)
      (should (eq 'american default-cheese)))))

Keep in mind that this suffers the exact same problem with bytecode-assigned functions as flet, and for exactly the same reasons. If completing-read were to ever be assigned its own opcode then cl-letf would no longer work for this particular example.

-1:-- Make Flet Great Again (Post)--L0--C0--October 27, 2017 09:02 PM

Flickr tag 'emacs': alpha-omega

andy50312 posted a photo:

alpha-omega

-1:-- alpha-omega (Post andy50312 (nobody@flickr.com))--L0--C0--October 27, 2017 12:33 PM

Flickr tag 'emacs': IMG_20171016_174834

andy50312 posted a photo:

IMG_20171016_174834

-1:-- IMG_20171016_174834 (Post andy50312 (nobody@flickr.com))--L0--C0--October 27, 2017 03:51 AM

Phil Hagelberg: in which a path is charted through the coming apocalypse

I've long counted myself among the grumpy old-timers who grudgingly accept the shift towards web-based-everything and just try to make the most of it, wistfully remembering the days when I could just do everything from within Emacs. One of my core survival strategies in this web-first world has been to trick my browser into at least having the decency to pretend to be Emacs. I accomplished this in Firefox1 with the Keysnail extension. Keysnail has remarkable flexibility in how it overrides Firefox's default key bindings to match those of Emacs, and everything has been more or less great.

Unfortunately, a soon-to-be-released update to Firefox will remove the extension mechanism used by Keysnail.

laptop at Green Lake

I have felt very conflicted about this, because the old state of affairs is admittedly untenable. Firefox currently uses Gecko, a decades-old rendering engine written in C++, and like much software written in C++ it has a pretty distressing security track record. Version 57 of Firefox replaces parts of Gecko with functionality from Servo, a browser engine implemented in the Rust programming language. Most of the bugs in Gecko which have led to embarrassing security flaws are simply impossible in Servo. The fact that so much safety-critical code is still being written in C++ and similar languages is a sad state of affairs, and we should celebrate changes that mean end users will no longer bear the penalty for programmers' reluctance to move beyond the technology of the 1980s.

But on the other hand, losing the ability to shape your computing environment to your whims is awful. I lost track of how many times (when using Chromium or other keysnail-less browsers) I've wanted to throw my laptop out the window when I held down ctrl-n to scroll down and it opened seventeen new windows instead. I can't remember ever wanting to open a new browser window in the past decade; why should I be stuck with a key bound to that command and no way to disable it?

Of course, the new Firefox will still have an extension mechanism, but it's a pale shadow of the old one. Citing the flimsy2 excuse of security, key bindings like C-n are hard-coded into the browser and forbidden from being overridden.

Tumwater Falls

Things were looking bleak for me, and I contemplated whether I would switch to curl or just give up software development altogether for a career in goat-herding. I ended up finding a solution from a most unlikely place.


I had heard of EXWM a while ago, and it struck me as a quixotic curiosity. The X Window System uses a network socket for its control protocol, allowing a lot of flexibility including native forwarding of interfaces for remote programs. The developer of EXWM had taken an XML description of the specification for the network protocol and written a compiler to turn it into a library of Emacs Lisp functions which he then used to implement a window manager in pure Emacs Lisp. While I admired the chutzpah this must have taken, I assumed it was a novelty that could never be practical.

Eventually the Firefox conundrum prompted me to give it a second look due to a feature called Simulation Keys. The exwm-input-set-simulation-keys function allows you to define a translation mapping so that a certain key combination will be intercepted by EXWM when a non-Emacs program has focus, and a different set of key input events will be sent instead. It seemed too good to be true; I could let go of Keysnail and instead get the same features applied to every program I use3.

I'm happy to report that EXWM does actually function startlingly well as a window manager. The simulation keys feature is amazing and puts my Firefox-related fears at ease, and having all configuration written in a single language simplifies my setup dramatically. Every X window you launch is given an Emacs buffer, and all your normal splits and window resizing commands work great with it. With the tiling window managers I used in the past, it was so unusual for me to use something other than the "one fullscreen window per display" setup that I would often forget the key bindings for splitting and rearranging windows. EXWM even integrates "system tray" programs into the Emacs echo area, so your wifi connect tool shows up unobtrusively in the bottom right corner.

There are a handful of gotchas. Emacs Lisp lacks general-purpose concurrency features, but it does allow for concurrency when dealing with subprocesses and network communication. Most well-written Emacs Lisp will never block the main event loop, which is good because when using EXWM that means the entire window manager is stuck until the blocking operation completes. I only came across two exceptions to this rule. One of them is smtpmail-send-it, which can be replaced by the smtpmail-async library. The other is the racket-run command, which I was able to patch in about an hour to remove the blocking call4.

Other folks might run into more problems if they use other third-party libraries which don't take care to use the network functions properly. But for my use5, it's been very smooth, and I'm thrilled to have it.


[1] I used Conkeror for several years, but eventually things got to the point where browsing without Noscript became untenable, and I could never get the two to work well together.

[2] The rationale of "it's for security" would stand up to a little more scrutiny if it weren't for the fact that extensions can rebind C-t, a key which is used hundreds if not thousands of times more often than C-n.

[3] Granted gnumeric is the only program I use outside the browser and Emacs, but it's still greatly appreciated. I also use the Saka Key extension, which implements Keysnail's ability to trigger links from the keyboard even if they don't have text attached to them.

[4] I feel that the increasing "Emacs needs concurrency!" calls tend to overstate the problem. Yes, of course it would be nicer for the programmer to code using coroutines (coming in Emacs 26!) instead of callbacks, but in the end this is a convenience for the author, not for the end user.

[5] My customizations largely revolve around replacing my xbindkeys config with elisp, mapping workspace numbers to physical displays, and some eshell commands to give one eshell buffer per workspace. EXWM has XMonad-style workspaces where you can change the workspace for each display independently rather than forcing you to change them all at once like many more conventional WMs, and I'm very glad it does.

-1:-- in which a path is charted through the coming apocalypse (Post Phil Hagelberg)--L0--C0--October 23, 2017 07:04 PM

sachachua: 2017-10-23 Emacs news

Links from reddit.com/r/emacs, /r/orgmode, /r/spacemacs, Hacker News, planet.emacsen.org, YouTube, the changes to the Emacs NEWS file, and emacs-devel.

Thanks for your patience!

-1:-- 2017-10-23 Emacs news (Post Sacha Chua)--L0--C0--October 23, 2017 06:14 AM

emacsninja: Design Is Hard

This isn’t about the pixel pushing kind of design, but the engineering one. Given a problematic matter, what choices do you make to create a tool that enables its user to effectively interact another object? More importantly, how do you deal with choices that are hard to rectify afterwards? While this is going to be a rant, the subject is one of my more popular Emacs packages, Shackle. I thought the 1.0.0 release of it with a new debugging facility to make troubleshooting easier is just the right moment to ponder a bit about those choices I made and why I regret some of them.

You may wonder “Wait, what is wrong with Shackle? It has over a hundred stars of GitHub, a few thousand downloads on MELPA, dozens of people using it in their init files and a handful of people recommending it to others.”. While all of this is true, it’s not all roses. I occasionally get issues from users that don’t understand it at all and I can’t really blame them. There is a fundamental mismatch going on here because all this package does is hijacking the display-buffer-alist variable to invent a similar, but not quite as powerful mechanism on top of it. It’s an inherently leaky abstraction which makes for less than ideal debugging: If it ever breaks down, you’ll have to understand both the abstraction and the underlying code it’s built upon.

This project started off with me not understanding how to use this variable at all. In hindsight, this should have been the first warning signal: If you can’t fully understand the problem, don’t expect to solve it in a satisfactory manner. There are a few glaring problems with display-buffer-alist:

  • The docstring for it is hard to parse. If a newbie asks how to customize the display of a certain buffer and is directed to that variable, I couldn’t blame them for just giving up on this altogether.
  • It isn’t clear how to display a buffer in a certain way. I’ve found only one example in the elisp manual so far and it’s more about display-buffer than display-buffer-alist.
  • Conditions may be buffer names and functions, but not major modes. This is rather annoying as it means you’ll have to write a function to check the major mode yourself. While this is far from fool-proof (the code setting up the buffer may enable the desired major mode only after displaying it), it works in many cases.
  • If your customization of display-buffer-alist contains a call to a function that errors out, the display of that buffer will fail. This is particularly annoying if you have a catch-all rule there that prevents the source debugger window from appearing, something I mostly ran into while developing Shackle. While you can use M-: (setq display-buffer-alist nil), it’s relatively annoying to do so.
  • The default behavior is rather inscrutable and mostly, but not only determined by display-buffer-fallback-action. Worse, some packages rely on the default behavior just to fail with customizations to display-buffer-alist.

Now, does Shackle do better? Well, it does in some ways while being worse in others:

  • Conditions are interpreted as buffer names (if a string) or modes (if a symbol) or a list of either. While this is convenient, the original design had the issue of making it impossible to match by regex or use a custom function, so I added a :regex modifier to the action (which is just wrong because it changes all of them to match by regex) and interpret a list starting with :custom as a function which isn’t nice either. Judging by GitHub’s search there’s about three users of this functionality, with the most prolific one being doom.
  • Shackle tries being easier to understand with regards to actions by abolishing the alist approach and instead going for a flat plist. There is no hierarchy whatsoever which turned out to be a mistake, people didn’t understand that there were keywords with mutually-exclusive behavior, keywords that modified other keywords and keywords that work universally. I’ve had feature requests where I was asked to allow to combine keywords more flexibly, to explain how the whole thing works and most surprisingly, to provide a grammar of the implemented language. The latter found its way into the README and is more confusing than helpful IMO. If you want to understand the behavior, you’re best off with heading to the source. I consider this to be the ultimate proof of failing at its design.
  • It’s way harder to shoot yourself in the foot, in case you do you can always bail out with M-x shackle-mode and revert to vanilla Emacs behavior.
  • The mere act of enabling Shackle will subtly change the default behavior of displaying buffers. The reason for this is shackle--display-buffer-popup-window which tries to do something sensible, but will never behave like the original.
  • I’ve added a feature that doesn’t display a window differently, but rather modifies the window parameter. Admittedly it makes things more convenient because you’d otherwise need a second package to achieve the same effect, but it’s the main reason for display of buffers intended to not be selected to have weird side effects.
  • Debugging Shackle not working as expected is rather tricky. In the best case you’ll need to look at the source code of a package to check whether it’s using display-buffer or a function using it internally (like pop-to-buffer, pop-to-buffer-same-window, switch-to-buffer-other-window, etc.). In the worst case you’ll need to debug the part of the package displaying such windows or Shackle itself while it tries matching conditions and applying actions. I’ve added a tracing mode to make the former easier, but the inherent leaky abstraction remains.
  • While Shackle stayed mostly the same, Emacs gained new capabilities for display-buffer-alist. There isn’t nearly as much reason for using Shackle now, other than laziness. Other people reached the same conclusion that it’s worth investing some of your time in customizing display-buffer-alist.

The bottom line is that I’m not happy with Shackle’s design, but am wise enough to keep it as is and not do any more invasive changes. My happiness (or the lack of) isn’t worth risking the happiness of its users.

-1:-- Design Is Hard (Post Vasilij Schneidermann)--L0--C0--October 20, 2017 09:34 AM

emacshorrors: Unjustified Indirection

I finally made that EPUB mode. This adventure mostly taught me that eww, or rather, shr.el isn’t quite reusable. That itself is not really a problem, but I handed in a patch to improve the situation. An old saying among programmers is that every problem can be solved by applying an extra level of indirection, so that’s what I did after discussing it out on the bug tracker, however after my patch got merged it was deemed too much:

;; We don't use shr-indirect-call here, since shr-descend is
;; the central bit of shr.el, and should be as fast as
;; possible.  Having one more level of indirection with its
;; negative effect on performance is deemed unjustified in
;; this case.

Hadn’t I spoken up about inclusion of this comment, an unsuspecting future hacker wouldn’t even know why there’s duplicated code not using the helper. I can only wonder how production-ready browser engines solve this kind of problem…

-1:-- Unjustified Indirection (Post Vasilij Schneidermann)--L0--C0--October 19, 2017 09:44 PM

Manuel Uberti: Simplify my Docker workflow with Emacs

Up until a few weeks ago, I had never messed with Docker. Not that I had anything against it per se, but never before had I felt the need to isolate my work in containers that can be readily built up and torn down.

Docker and its helpful companion Docker Compose come with a rich command-line interface. Nonetheless, I don’t want to leave Emacs for simple tasks such as building a Docker image or preparing the containers with Docker Compose.

Fortunately, the Emacs ecosystem is ready to help. Four packages have improved my workflow with Docker:

The first two packages add syntax highlighting, completion and a bunch of useful key bindings to work with Dockerfile and docker-compose.yml.

The real magic, though, happens with docker-tramp. The beauty of interacting directly with the contents of a container is impressive. Combine docker-tramp with the handy completion of counsel and the power of Dired and you might feel like Henry Dorsett Case in his ecstatic hunt for the Neuromancer.

Through docker-tramp I can also run EShell on any available container and that is where eshell-bookmark shines. I just have to bookmark a remote EShell buffer and use counsel-bookmark to jump back to it. Managing containers hardly gets any faster than this.

A little advice if you use both counsel and eshell-bookmark: do not set counsel-bookmark-avoid-dired to t, otherwise selecting a bookmark with counsel-bookmark will take you to counsel-find-file instead of opening the desired EShell buffer.

-1:-- Simplify my Docker workflow with Emacs (Post)--L0--C0--October 19, 2017 12:00 AM

Sanel Zukan: Closing all parentheses at once

While watching interesting presentation called Inspiring a future Clojure editor with forgotten Lisp UX, I've noticed author mentioned one really cool feature I was looking for some time - Interlisp's super-paren.

In short, Interlisp had this unique super-paren option, bound to ] key, that would close all opened parentheses at once.

To my knowledge, Emacs doesn't have something like this out of the box, unless you use Allegro CL mode or SLIME, but let's see how would it be hard to implement it.

First Google hit is this, which brings really nice implementation from Gilles. Copied code is down below:

(defun close-all-parentheses ()
  (interactive "*")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (apply #'insert (nreverse closing))))

The function is using backward-up-list to find open parentheses for current block and get matching closing parentheses using syntax-table. Unique feature of this implementation is that target language doesn't have to have parentheses only. It works with Clojure, Java, C/C++, Javascript...

Assuming this function is bound to C-c ] in Emacs, let's see how it works out of the box with nested block in Clojure:

(defn my-func []
  {:key
    [(fun1) (fun2) (fun3 {:key2 
                           {:a1 "str"
                            :a2 (call [1 2 3 
                                            ^
                                            cursor is here

When you place the cursor where caret sign is (^) and press C-c ], everything will be nicely balanced and closed:

(defn my-func []
  {:key
    [(fun1) (fun2) (fun3 {:key2 
                           {:a1 "str"
                            :a2 (call [1 2 3])}})]})

Even better, it works correctly when open parentheses is found in comments:

;; testing ([{[[[
(defn my-func []
  {:key
    [(fun1) (fun2) (fun3 {:key2 
                           {:a1 "str"
                            :a2 (call [1 2 3])}})]})

Where it doesn't work is inside blocks where broader knowledge of surrounding structure is required. For example:

(defn my-fun []
  (let [a (call [1 2
                    ^
    (println a)))

and when you try to close the parentheses where caret is, it will yield:

(defn my-fun []
  (let [a (call [1 2])]))
    (println a)))

In short, it will close the whole block! However, to keep things fairly simple without adding complex modes like paren-mode, smartparens and etc. I'm pretty much fine with this.

Use it with other languages

Let's be adventurous and try this this facility for other modes, specifically editing C code (this should be applicable for C++, Java, Javascript...).

Nested C code example:

if (myfunc()) {
  if (v1) {
    if (v2) {
      call(); 
             ^

again, cursor is when caret is placed. Pressing C-c ] will yield a surprise:

if (myfunc()) {
  if (v1) {
    if (v2) {
      call();}}}

which is kind of too lispy for ordinary C developer. Let's fix that by adding formatting function and optional argument for calling it:

(defun close-all-parentheses (arg)
  (interactive "P")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))

    ;; changed part - call (newline-and-indent) when C-u prefix is given
    (dolist (token (nreverse closing))
      (when arg
        (newline-and-indent))
      (insert token))))

Now, when you go to above C code example and press C-u C-c ] (argument is set to true), it will insert remaining braces with correct formatting.

if (myfunc()) {
  if (v1) {
    if (v2) {
      call();
      }
    }
  }

Close, but not perfect. c-mode is using c-electric-brace to insert braces with proper formatting and something like this will make it near perfect. Here is a modified chunk of above code:

;; ...
    (dolist (token (nreverse closing))
      (if arg
          (progn
            (let ((last-command-event ?}))
              (newline)
              (c-electric-brace nil)))
        (insert token))

which will yield this:

if (myfunc()) {
  if (v1) {
    if (v2) {
        call();
    }
  }
}

Notice that calling (insert token) is not necessary: setting last-command-event to } in combination with c-electric-brace will actually insert } in buffer and place it with correct indentation.

This starts to show all complexities of c-mode that one should tackle with and I even didn't touch c++-mode with templates (implementing proper completion for <> should not be that hard).

Now, let's make close-all-parentheses implementation a bit more generic, so caller can provide own formatting function if necessary.

;; internal function which does most of the job

(defun close-all-parentheses* (indent-fn)
  (let* ((closing nil)
         ;; by default rely on (newline-and-indent)
         (local-indent-fn (lambda (token)
                            (newline-and-indent)
                            (insert token)))
         (indent-fn (if indent-fn
                      indent-fn
                      local-indent-fn)))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (dolist (token (nreverse closing))
      (if arg
        (funcall indent-fn token)
        (insert token)))))

Formatting function is expected to be in form:

(defun my-formatter (token)
  ;; do some formatting if necessary
  ;; and finally insert a token
  (insert token))

where (insert token) will do actual matched character insertion. Emacs supports number of ways to insert a character, so this is optional approach.

Here is the final implementation of close-all-parentheses:

(defun close-all-parentheses (arg)
  (interactive "P")
  (let ((my-format-fn (lambda (token)
                        ;; 125 is codepoint for '}'
                        (if (and (= token 125)
                                 ;; C, C++ and Java
                                 (member major-mode '(c-mode c++-mode java-mode)))
                            (let ((last-command-event ?}))
                              (newline)
                              (c-electric-brace nil))
                          (insert token)))))
    (close-all-parentheses* my-format-fn)))

Default formatting is using newline-and-indent, which will be enough for most cases. For specialized modes, close-all-parentheses can be a starting point. Note however that my implementation of c-mode formatting isn't perfect: mixing braces and brackets will easily confuse it so there is a bit room for improvements.

Again, if you prefer simplicity like I do, use original implementation ;)

-1:-- Closing all parentheses at once (Post)--L0--C0--October 18, 2017 10:00 PM

Raimon Grau: rust + emacs = remacs

I've lately being collaborating a bit with the Remacs project, which attempts to bring Rust to emacs by porting the C parts of emacs. Here's the latest remacs report, by Wilfred, the creator of remacs.

If you love emacs and want to learn Rust, there's enough low hanging fruit in the project that makes a good place to start learning both the emacs internals and also rust (Which is not a simple language IMHO).

Remacs comunity is small, but quite helpful, and many things are still being figured out as migration of different parts take place.

I've personally have contributed with ports of a handful of functions (point and buffer related). Not a lot, but few steps to bring me closer to Rust and emacs at the same time.

From time to time, there's the issue raised about "what benefit do I get by using remacs instead of gnu emacs" or, "Should you try remacs?" I honestly don't know. If you don't have any interest in emacs internals and you don't usually compile your own emacs you won't gain much with remacs.  Projectwise, I don't know how gnu emacs will benefit from remacs.

Another question that raises is "if (how) gnu emacs benfits from the contributions on remacs?".  Not being a hostile fork but just a fork to experiment with different technologies at a different pace than gnu emacs, remacs is allowed to try different approaches to solving some problems. Support for very old platforms has been dropped, and the idea is to use crates (Rust libraries) for some things that emacs writes ad-hoc (json, md5, regex...).

For now, there's just a tiny fraction of users that use remacs, so it's way too early to think about any impact it may have to mainline gnu emacs.

And on the question: Aren't we moving to guilemacs? Why are you not investing your time on that? ..... For my personal case, I'll say that the low hanging fruit in guilemacs are over my skills. Not so for remacs, where I can chip in and merge my small PR's. Also, github (it's sad, but that's how it is) makes it easier for me to collaborate.

But I get you: The idea of guilemacs is very cool. You know what's also super cool? El compilador. But I don't know, I feel I'm unable to move any of those any forward, and they are still experimental.

[OFFTOPIC: I'm looking for projects where to collaborate. If you have any proposal drop me a line @ raimonster@gmail.com, and we can talk about it. Learning, experience, impact, fun and remote are my metrics nowadays ]
-1:-- rust + emacs = remacs (Post Raimon Grau (noreply@blogger.com))--L0--C0--October 18, 2017 07:22 PM

(or emacs: Please consider supporting me on Patreon

In light of the recent success of the Magit Kickstarter (congratulations to @tarsius, by the way), I got a lot more optimistic about Free Software crowdfunding.

So I opened a Patreon account where you can support my work: https://www.patreon.com/abo_abo. The goal I set there is both optimistic and (hopefully) realistic: I'd like to hack on Free Software 1 day per week indefinitely, reducing my real world job days to 4 per week.

Ideally, I'd like to work on Free Software full time (one can dream), but it doesn't look like that level of donations is attainable right now. But I think I could accomplish a lot working a full day per week:

  • improve the level of maintenance of my current projects
  • polish and release a few projects I have in a semi-complete unreleased state
  • produce more content on my YouTube channel
  • maybe start working on an Emacs book

Here's a list of popular repositories I've made over the last 5 years in my free time (all Free Software under GPL):

If you are a user of my work, don't feel any pressure to donate. We are all here voluntarily: I publish because I enjoy it, you use the software because you find it useful. But out there is the real world, and, although I like my real world job enough, I can't say that would I do it voluntarily if I had enough money to meet my needs.

If you do what you love, you'll never work a day in your life

I'd like to do what I love, and I wish you all the same. Happy hacking!

-1:-- Please consider supporting me on Patreon (Post)--L0--C0--October 17, 2017 10:00 PM

Marcin Borkowski: emacs-reveal

Some time ago, I learned from the Org-mode mailing list about a very interesting extension to the well-known org-reveal package. The emacs-reveal allows to embed audio files in reveal.js presentations. I find this quite fascinating, especially that I actually did prepare quite a few educational presentations.
-1:-- emacs-reveal (Post)--L0--C0--October 16, 2017 04:19 PM

Wilfred Hughes: These Weeks in Remacs III

Time for another Remacs update: lots of contributions, a wide range of features, and even a logo!

Contributing

Since the last update, we’ve seen contributions from lots of new people. We’ve added @brotzeit and @shanavas786, bringing us to seven wonderful people who can approve your PRs.

Speaking of PRs, we’ve merged an amazing 64 pull requests since the last update!

If you’re looking for a good feature for your first contribution, @brotzeit has been regularly adding new suggestions under the ‘good first issue’ label.

Features

Many Emacs features have now been ported to Rust, with new Rust APIs for accessing elisp datastructures.

Here’s an overview of the features that have landed.

Arithmetic: arithmetic, floating point, random number generation (using a Rust RNG!), and comparisons.

Symbols: symbol properties, interning, obarrays unbinding, keywords and indirect symbols.

Checksums: MD5sum (using a Rust MD5 crate!).

Windows: liveness check, type check, overlays and minibuffer, minibuffer check positions and margins.

Processes: accessing, type check, data structures and names.

Buffers: for the current thread, accessing, file names, size and modification.

Point: bobp, bolp, eolp, markers, point-min, point-max forward-point and goto-char.

Hash tables: copying and accessing.

Characters: multibyte conversions, character tables, category tables

Fonts: type checks.

Miscellaneous: prefix arguments and identity.

We’re also periodically pulling GNU Emacs features into Remacs, so all the features available GNU Emacs trunk are included in Remacs.

Idiomatic Rust in Remacs

Remacs has gradually developed a set of conventions for elisp data types. For each type Foo, we define a LispObject::as_foo, LispObject::as_foo_or_error and a FooRef when you know your elisp datatype is actually a Foo.

For example, here’s how overlay-start was implemented in C:

DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
       doc: /* Return the position at which OVERLAY starts.  */)
  (Lisp_Object overlay)
{
  CHECK_OVERLAY (overlay);

  return (Fmarker_position (OVERLAY_START (overlay)));
}

The C codebase makes heavy use of macros for checking types (CHECK_OVERLAY) and for accessing struct attributes (OVERLAY_START).

Here’s the Rust equivalent:

/// Return the position at which OVERLAY starts.
#[lisp_fn]
fn overlay_start(overlay: LispObject) -> LispObject {
    let marker = overlay.as_overlay_or_error().start();
    marker_position(marker)
}

We use procedural macros to simplify defining an elisp primitive function, and type checking is much more explicit.

(This example is from PR #298.)

Other exciting Rusty features include variadic macros to replace call1, call2 in C with just call! in Rust, and the ability to mock extern C functions so we can write unit tests.

Hash Maps

We’re not always able to leverage the Rust libraries available. @DavidDeSimone showed some amazing Rust-fu exploring using Rust’s FnvHashMap inside Remacs.

Sadly, we weren’t able to use the Rust hash map implementation. The C layer assumes that it can mutate hash table keys in place, and unexec does not play nicely with mmap. See the PR for the full details.

Finally, we’re discussing a logo for Remacs. We’ve had some great submissions:

You can join the logo discussion at PR #360.

As always, if you fancy writing some Rust in support of the world’s lispiest text editor, you can join us on GitHub!

-1:-- These Weeks in Remacs III (Post Wilfred Hughes (me@wilfred.me.uk))--L0--C0--October 16, 2017 12:00 AM

Pragmatic Emacs: Using a visible bell in Emacs

Here’s a tiny and basic tip. If you want you Emacs to flash at you instead of beeping for an error, add the following to your emacs config file

;; turn on visible bell
(setq visible-bell t)
-1:-- Using a visible bell in Emacs (Post Ben Maughan)--L0--C0--October 15, 2017 11:35 PM

Modern Emacs: Emacs-lisp exercises and solutions

I present exercises ordered by aspect and difficulty with the intent of making more tangible the Emacs slogan "the infinitely customizable editor".

Be familiar with:

  1. Lisp syntax.
  2. Emacs help facilities like describe-function.

To learn:

  1. How to work with Emacs rx macro for regexes.
  2. Traverse buffers and org-mode.

The basics

Regexes and the rx macro

The rx macro makes maintaining and writing regexes enjoyable and easy.

match-beginning and match-end are Emacs facilities for extracting regex matches for particular groups.

Solve the following exercises with the rx syntax.

Q1 (E) - Match the string in an org-mode header of any level.


(rx (1+ "*")
    space
    (group (0+ not-newline)))

There is the group-n construct for specifying the group of a particular particular part of the regex.

Q2 (E) - Match both the string and the level of an org-mode header.


(rx (group-n 1 (1+ "*"))
    space
    (group-n 2 (0+ not-newline)))

Org-mode

Q1 (E) - Get the heading name string above the current point.


(defun ex-current-heading ()
  (org-previous-visible-heading 1)
  (re-search-forward (rx (1+ "*") space))
  (buffer-substring (point) (line-end-position)))
-1:-- Emacs-lisp exercises and solutions (Post)--L0--C0--October 13, 2017 12:00 AM

Endless Parentheses: Mold Slack entirely to your liking with Emacs

Although fine-tuning your slack notifications is already reason enough to run slack in Emacs, that’s only the beginning. Once everything is up and running you get to decide what you want out of your slack. Some of the snippets below simply make up for missing functionality, other customize the package beyond what you can do on the Slack Webapp.

Priorities first. The most important improvement you can implement is install emojify-mode and turn it on for slack chats.

(add-hook 'slack-mode-hook #'emojify-mode)

Secondly, make sure you costumize the chat faces to your liking. Just open a chat buffer, place your cursor on a piece of text whose face you want to customize, and call customize-face.

In order to keep track of new messages in the mode-line, slack.el uses a package called tracking, which is the same one circe uses for IRC chats. The command tracking-next-buffer is a fantastic way to cycle through your pending messages, bind it to something short.

(with-eval-after-load 'tracking
  (define-key tracking-mode-map [f11]
    #'tracking-next-buffer))
;; Ensure the buffer exists when a message arrives on a
;; channel that wasn't open.
(setq slack-buffer-create-on-notify t)

I’ll never know who thought user statuses were a good idea for Slack. But, thanks to a tip by _asummers on HackerNews, I can live in a world where they don’t exist.

(defun slack-user-status (_id _team) "")

I like notifications with minimal titles, and the package is kind enough to make these configurable.

;;; Channels
(setq slack-message-notification-title-format-function
      (lambda (_team room threadp)
        (concat (if threadp "Thread in #%s") room)))

(defun endless/-cleanup-room-name (room-name)
  "Make group-chat names a bit more human-readable."
  (replace-regexp-in-string
   "--" " "
   (replace-regexp-in-string "#mpdm-" "" room-name)))

;;; Private messages and group chats
(setq
 slack-message-im-notification-title-format-function
 (lambda (_team room threadp)
   (concat (if threadp "Thread in %s") 
           (endless/-cleanup-room-name room))))

Slack.el uses lui for the chat buffers. If you, like me, are a heavy user of abbrevs in Emacs, you’ll find it annoying that the final word of each message won’t get expanded unless you explicitly hit SPC before RET. That’s easy to remedy with an advice.

(advice-add #'lui-send-input :before
            (lambda (&rest _)
              (ignore-errors (expand-abbrev))))

Finally, the biggest missing feature from this package is that it displays the author on every message output, even when the same user sends several messages in a row. The snippet below adds a hook to omit the author name for a message whenever it’s the same author as the previous message.

(defun endless/-author-at (pos)
  (replace-regexp-in-string
   (rx "\n" (* anything)) ""
   (or (get-text-property pos 'lui-raw-text) "")))

(defun endless/-remove-slack-author ()
  "Remove author here if it's the same as above."
  (let ((author-here (endless/-author-at (point)))
        (author-above (endless/-author-at (1- (point)))))
    (when (and (looking-at-p (regexp-quote author-here))
               (equal author-here author-above))
      (delete-region (1- (point))
                     (1+ (line-end-position))))))

(defun endless/remove-slack-author-hook ()
  "For usage in `lui-pre-output-hook'."
  (when (derived-mode-p 'slack-mode)
    (save-excursion
      (goto-char (point-min))
      (save-restriction
        (widen)
        (endless/-remove-slack-author)))))

(add-hook 'lui-pre-output-hook
          #'endless/remove-slack-author-hook)

You don’t have to stop here, of course. Want to fine-tune which buffers get tracked on the mode-line? Hack into tracking.el. Want to change the face used for your own messages, or even align them to the right? Redefine slack-buffer-insert. Your workflow is yours to build.

Comment on this.

-1:-- Mold Slack entirely to your liking with Emacs (Post)--L0--C0--October 09, 2017 11:43 PM

Manuel Uberti: To shell or not to shell

As much as most of my daily workflow revolves around Emacs, I always have GNOME terminal ready to fly with Fish shell and tmux. I keep EShell next to me for quick tasks, but I have never relied on shell-mode or ansi-term for other CLI-intensive work.

I don’t know what happened to the lovely “Emacs Chat” series from Sacha Chua, but more than three years ago she interviewed Mickey Petersen. Mickey talked with great enthusiasm about shell-mode and at the time I admittedly made a mental note about giving it a try. Regretfully, I have only recently come back to that note.

My first M-x shell didn’t look that great. I haven’t debugged the compatibility issues with Fish, probably something related to my heavily customised config.fish. Anyway, falling back to Bash is enough.

(validate-setq explicit-shell-file-name "/bin/bash")

Note that I am using validate-setq as explained here.

Another thing I have noticed is the lack of colours for the output of ls. Fortunately, Emacs StackExchange has an answer for that, so I have added this line to my .bash_aliases file:

alias ls="TERM=ansi ls --color=always"

The input echoing is easily turned off following the instructions on the manual. Also, the history is much cleaner and easier to navigate with counsel-shell-history.

(unbind-key "C-c C-l" shell-mode-map)
(bind-key "C-c C-l" #'counsel-shell-history shell-mode-map)

Note that unbind-key and bind-key are macros from bind-key.el, which is part of the fantastic use-package.

Last but not least, I like to have my shell buffer filling the whole window in the current frame. Thus, display-buffer-alist to the rescue.

(validate-setq
 display-buffer-alist
 `(
   ;; … other stuff …
   (,(rx bos "*shell")
    (display-buffer-same-window)
    (reusable-frames . nil))
   ;; … other stuff …
  ))
-1:-- To shell or not to shell (Post)--L0--C0--October 07, 2017 12:00 AM

Endless Parentheses: Turbo up your Ruby console in Emacs

Keeping a REPL (or a console) always by your side is never a bad habit, and if you use an IDE-package (like Robe for Ruby, or Cider for Clojure) it’s nigh unavoidable. Being an essential part of your environment, it would be ridiculous not to invest some time optimizing it.

One obvious optimization is to bind a key to your “start console” command, but that’s just the start. You pretty much never need two running consoles for the same project, so why not have the same key switch to it if it’s already running?

But we can go a bit farther with very little work. I have a file where I define a lot of small helper methods for my Ruby console, so let’s require it automatically whenever a new console is started.

(defcustom endless/ruby-extensions-file
  "../console_extensions.rb"
  "File loaded when a ruby console is started.
Name is relative to the project root.")

;; Skip ENV prompt that shows up in some cases.
(setq inf-ruby-console-environment "development")

(defun endless/run-ruby ()
  (interactive)
  (require 'inf-ruby)
  (let ((default-directory (projectile-project-root))
        (was-running (get-buffer-process inf-ruby-buffer)))
    ;; This function automatically decides between starting
    ;; a new console or visiting an existing one.
    (inf-ruby-console-auto)
    (when (and (not was-running)
               (get-buffer-process (current-buffer))
               (file-readable-p endless/ruby-extensions-file))
      ;; If this brand new buffer has lots of lines then
      ;; some exception probably happened.
      (send-string
       (get-buffer-process (current-buffer))
       (concat "require '" endless/ruby-extensions-file
               "'\n")))))

;; CIDER users might recognize this key.
(define-key ruby-mode-map (kbd "C-c M-j")
  #'endless/run-ruby)

If you use Projectile and want to go even faster, check out the j key on my post about Projectile.

Comment on this.

-1:-- Turbo up your Ruby console in Emacs (Post)--L0--C0--October 02, 2017 08:57 PM

Jonas Bernoulli: Borg 2.0 and Epkg 3.0 released

I am excited to announce the release of Borg v2.0, Epkg v3.0, Closql v0.4 and Emir v2.0.
-1:-- Borg 2.0 and Epkg 3.0 released (Post)--L0--C0--September 20, 2017 03:00 PM

Bryan Murdock: Not Leaky, Just Wrong

Intel recently announced new tools for FPGA design. I should probably try to understand OpenCL better before bagging on it, but when I read, "[OpenCL] allows users to abstract away hardware-specific development and use a higher-level software development flow." I cringe. I don't think that's how we get to a productive, higher-level of abstraction in FPGA design. When you look at the progress of software from low-level detailed design to high-level abstract design you see assembly to C to Java to Python (to pick one line of progression among many). The thing that happened every time a new higher-level language gained traction is people recognized patterns that developers were using over and over in one language and made language features in a new language that made those patterns one-liners to implement.

Examples of design patterns turning into language features are, in assembly people developed the patterns of function calls: push arguments onto the stack, save the program counter, jump to the code the implements the function, the function code pops arguments off the stack, does it's thing, then jumps back to the the code that called it. In C the tedium of all that was abstracted away by the language providing you with syntax to define a function, pass it arguments, and just call return at the end. In C people then started developing patterns of structs containing data and function pointers for operating on that data which turned into classes and objects in Java. Java also abstracted away memory management with a garbage collector. Patterns in Java (Visitor, State, etc.) are no longer needed in Python because of features in that language (related discussion here).

This is the path that makes most sense to me for logic design as well. Right now in RTL Verilog people use patterns like registers (always block that activates on posedge clk, has reset, inputs, outputs, etc.), state machines (case statement and state registers, next_state logic...), interfaces (SV actually attempted to add syntax for this), and so on. It seems like the next step in raising the abstraction level is to have a language with those sorts of constructs built-in. Then let people use that for a while and see what new patterns develop and encapsulate those patterns in new language features. Maybe OpenCL does this? I kind of doubt it if it's a "software development flow." It's probably still abstracting away CPU instructions.

-1:-- Not Leaky, Just Wrong (Post Bryan (noreply@blogger.com))--L0--C0--September 15, 2017 03:04 PM

Timo Geusch: Emacs 25.3 released

Emacs 25.3 has been released on Monday. Given that it’s a security fix I’m downloading the source as I write this. If you’re using the latest Emacs I’d recommend you update your Emacs. The vulnerability as been around since Emacs Read More

The post Emacs 25.3 released appeared first on The Lone C++ Coder's Blog.

-1:-- Emacs 25.3 released (Post Timo Geusch)--L0--C0--September 15, 2017 04:20 AM