Quantcast
Channel: Sacha Chua - category - emacs
Viewing all 816 articles
Browse latest View live

2019-05-20 Emacs news

$
0
0

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


2019-05-27 Emacs news

$
0
0

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

2019-06-03 Emacs news

$
0
0

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

Making a numpad-based hydra for categorizing Org list items

$
0
0

I like to categorize links for Emacs News so that it’s not an overwhelmingly long wall of text. After I’ve deleted duplicate links, there are around a hundred links left to categorize. I used to use Helm and some custom code to simplify moving Org list items into different categories in the same list. Then I can type “org” to move something to the Org Mode category and “dev” to move something to the Emacs development category.

When I don’t have a lot of computer time, I usually do this categorization by SSHing into my server from my phone. It’s hard to type on my phone, though. I thought a numpad-based Hydra might be better for quick entry, like a phone system. I wanted to be able to use the numeric keypad to sort items into the most common categories, with a few shortcuts for making it easier to organize. Here’s a list of shortcuts:

0-9 Select options from the list, with 0 for other.
\/ Opens the URL in a web browser
, Selects a category by name, creating as needed
\* Shows the URL in the messages buffer, and toggles it
Deletes the item
. Quits

Here’s what the Helm version looked like on the left, and here’s the new numpad-powered one on the right. I liked how fewer buttons made it easier to hit the right one when I’m sorting on my phone. I can add new categories with completion. Because I assigned numbers to specific categories instead of having them automatically calculated based on the headings in the list, it was easy to get into the rhythm of tapping 6 for Org, 7 for coding, and so on.

Comparison of Helm and Hydra approaches

Here’s the code that makes it happen. I experimented with dynamically defining a hydra using eval and defmacro so that I could more easily define the menu in a variable. It seems to work fine so far.

(defvar my/org-categorize-emacs-news-menu 
  '(("0" . "Other")
    ("1" . "Emacs Lisp")
    ("2" . "Emacs development")
    ("3" . "Emacs configuration")
    ("4" . "Appearance")
    ("5" . "Navigation")
    ("6" . "Org Mode")
    ("7" . "Coding")
    ("8" . "Community")
    ("9" . "Spacemacs")))

(defun my/org-move-current-item-to-category (category)
  "Move current list item under CATEGORY earlier in the list.
CATEGORY can be a string or a list of the form (text indent regexp).
Point should be on the next line to process, even if a new category
has been inserted."
  (interactive "MCategory: ")
  (when category
    (let* ((beg (line-beginning-position))
           (end (line-end-position))
           (string (org-trim (buffer-substring-no-properties beg end)))
           (category-text (if (stringp category) category (elt category 0)))
           (category-indent (if (stringp category) 2 (+ 2 (elt category 1))))
           (category-regexp (if (stringp category) category (elt category 2)))
           (pos (point))
           s)
      (delete-region beg (min (1+ end) (point-max)))
      (unless (string= category-text "x")
        (if (re-search-backward category-regexp nil t)
            (forward-line 1)
          (setq s (concat "- " category-text "\n"))
          (insert s)
          (setq pos (+ (length s) pos)))
        (insert (make-string category-indent ?\ )
                string "\n")
        (goto-char (+ pos (length string) category-indent 1))
        (recenter)))))

(eval 
 `(defhydra my/org-categorize-emacs-news (global-map "C-c e")
    ,@(mapcar
       (lambda (x)
         `(,(car x)
           (lambda () (interactive) (my/org-move-current-item-to-category ,(concat (cdr x) ":")))
           ,(cdr x)))
       my/org-categorize-emacs-news-menu)
    (","
     (lambda () (interactive)
       (my/org-move-current-item-to-category 
        (completing-read (match-string 2) (my/org-get-list-categories))))
     "By string")
    ("/" (lambda () (interactive)
           (save-excursion
             (re-search-forward org-link-bracket-re)
             (backward-char)
             (org-open-at-point)))
     "Open")
    ("*"
     (lambda () (interactive)
       (if (string= (buffer-name) "*Messages*")
           (bury-buffer)
         (save-excursion
           (re-search-forward org-link-bracket-re)
           (message (match-string 1)))
         (switch-to-buffer "*Messages*")))
     "Show URL")
    ("-" kill-whole-line "Kill")
    ("." nil "Done")))

Let’s see how it holds up next week!

Turning an Org Mode outline into an HTML table with a column for more notes

$
0
0

The last time A- had a babysitter, I quickly scribbled down some ideas for activities that A- might enjoy. The babysitter found the list very helpful, so I figured I’d make a list that I could easily update as A-‘s interests change. I wanted a two-column table with space for notes, but I didn’t want to fiddle with LibreOffice or manually writing HTML. Org Mode to the rescue! To turn something like this:

* Activity ideas  :noexport:
** Gross motor
*** Balance on one leg
*** Coast on the balance bike
** Fine motor
*** Cut along a curve or shape
...

into a table like this:

Two-column table

I wrote this bit of code inside a #+begin_src emacs-lisp :exports results :results value html#+end_src block:

(let* ((elements (org-element-parse-buffer))
       (activity-ideas
        (org-element-contents
         (org-export-resolve-link
          "Activity ideas"
          `(:parse-tree ,elements)))))
  (format
   "<table><tr><th width=\"50%%\">Activity ideas</th><th width=\"50%%\">Notes</th></tr>%s</table>"
   (mapconcat
    (lambda (section)
      (format "<tr><td><h2>%s</h2><ul>%s</ul></td><td></td></tr>"
              (org-element-property :raw-value section)
              (mapconcat (lambda (idea)
                           (format "<li>%s</li>"
                                   (org-element-property :raw-value idea)))
                         (org-element-contents section)
                         "")))
    (org-element-contents activity-ideas)
    "")))

I can then export the buffer to HTML and get my nice neat table by itself, since the data comes from a subtree with the :noexport: tag. The code parses the elements in the buffer, looks at the children under the “Activity ideas” header, turns each child into a table row, and turns the children of those nodes into list items.

The code coincidentally takes advantage of the org-export-resolve-link I wrote to help someone with an Org feature request. Yay for multipurpose code!

For the next step, I’ll probably put TODO state filtering in so that I can keep a long list of activities and then select a few for each category. It’s nice to have an outline I can easily update!

2019-06-10 Emacs news

$
0
0

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

2019-06-17 Emacs news

$
0
0

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

2019-06-24 Emacs news

$
0
0

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


2019-07-01 Emacs news

$
0
0

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

2019-07-08 Emacs news

$
0
0

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

Tweaking Emacs on Android via Termux: xclip, xdg-open, syncthing conflicts

$
0
0

Update: Fixed reference to termux.properties

I’m planning to leave my laptop at home during our 3-week trip, so I’ve been shifting more things to my phone in preparation. Orgzly is handy for reviewing my agenda and adding items on the go, but nothing beats Emacs for full flexibility. Runnng Emacs via Termux works pretty well. I can resize by pinch-zooming, scroll by swiping, and even enter in more text by swiping right on the row of virtual keyboard buttons.

Here’s what I’ve configured in ~/.termux/termux.properties:

extra-keys = [['ESC','/','-','HOME','UP','END','PGUP','F5'],['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN','F6']]

and here’s what that looks like:

Screenshot of Emacs

I patched my Termux to allow the use of function keys in the extra keys shortcut bar. It’s been merged upstream, but the new version hasn’t been released yet, so I’m still running the one I compiled from source. It would be nice to fix accidental keypresses when swiping extra keys to get to the input field, but that can wait a bit.

I set up Syncthing to synchronize files with my server and laptop, Termux:API to make storage accessible, and symlinks in my home directory to replicate the main parts of my setup. I set up Orgzly to auto-sync with a local repository (synchronized with my server and laptop via Syncthing) and the same Org files set up in my agenda in Emacs on Termux. That way, I can hop between Orgzly and Emacs as quickly as I want. Here are a few tweaks that made Emacs even better.

First, a little bit of code for phone-specific config, taking advantage of the weird automatic username I have there.

(defun my/phone-p ()
  (and (equal (system-name) "localhost") 
       (not (equal user-login-name "sacha"))))

For Emacs News, I wanted to be able to easily open Org Mode links to webpages by tapping on them. This code makes that work (and in general, anything that involves opening webpages):

(setq browse-url-browser-function 'browse-url-xdg-open)

This piece of code cleans up my Inbox.org file so that it’s easier to skim in Orgzly. It archives all the done tasks and sorts them.

     (defun my/org-clean-up-inbox ()
       "Archive all DONE tasks and sort the remainder by TODO order."
       (interactive)
       (with-current-buffer (find-file my/org-inbox-file)
         (my/org-archive-done-tasks 'file)
         (goto-char (point-min))
         (if (org-at-heading-p) (save-excursion (insert "\n")))
         (org-sort-entries nil ?p)
         (goto-char (point-min))
         (org-sort-entries nil ?o)
         (save-buffer)))

     (defun my/org-archive-done-tasks (&optional scope)
       "Archive finished or cancelled tasks.
SCOPE can be 'file or 'tree."
       (interactive)
       (org-map-entries
        (lambda ()
          (org-archive-subtree)
          (setq org-map-continue-from (outline-previous-heading)))
        "TODO=\"DONE\"|TODO=\"CANCELLED\"" (or scope (if (org-before-first-heading-p) 'file 'tree))))

I also sometimes wanted to copy and paste between Termux and Emacs by using the keyboard, so I submitted a patch for xclip.el so that it would detect and work with termux-clipboard-get/set. That code is now in xclip 1.9 in ELPA, so if you M-x package-install xclip, you should be able to turn on xclip-mode and have it copy and paste between applications. In my config, that looks like:

(when (my/phone-p)
  (use-package xclip :config (xclip-mode 1)))

Because I use Orgzly and Termux to edit my Org files and I also edit the files on my laptop, I occasionally get synchronization errors. I came across this handy bit of code to find Syncthing conflicts and resolve them. I just had to change some of the code (in bold below) in order to make it work, and I needed to pkg install diffutils to solve the diff errors. Here’s the fixed code below, along with a convenience function that checks my Orgzly directory:

(defun my/resolve-orgzly-syncthing ()
  (interactive)
  (ibizaman/syncthing-resolve-conflicts "~/cloud/orgzly"))

(defun ibizaman/syncthing-resolve-conflicts (directory)
  "Resolve all conflicts under given DIRECTORY."
  (interactive "D")
  (let* ((all (ibizaman/syncthing--get-sync-conflicts directory))
        (chosen (ibizaman/syncthing--pick-a-conflict all)))
    (ibizaman/syncthing-resolve-conflict chosen)))

(defun ibizaman/syncthing-show-conflicts-dired (directory)
  "Open dired buffer at DIRECTORY showing all syncthing conflicts."
  (interactive "D")
  (find-name-dired directory "*.sync-conflict-*"))

(defun ibizaman/syncthing-resolve-conflict-dired (&optional arg)
  "Resolve conflict of first marked file in dired or close to point with ARG."
  (interactive "P")
  (let ((chosen (car (dired-get-marked-files nil arg))))
    (ibizaman/syncthing-resolve-conflict chosen)))

(defun ibizaman/syncthing-resolve-conflict (conflict)
  "Resolve CONFLICT file using ediff."
  (let* ((normal (ibizaman/syncthing--get-normal-filename conflict)))
    (ibizaman/ediff-files
     (list conflict normal)
     `(lambda ()
       (when (y-or-n-p "Delete conflict file? ")
         (kill-buffer (get-file-buffer ,conflict))
         (delete-file ,conflict))))))

(defun ibizaman/syncthing--get-sync-conflicts (directory)
  "Return a list of all sync conflict files in a DIRECTORY."
  (directory-files-recursively directory "\\.sync-conflict-"))

(defvar ibizaman/syncthing--conflict-history nil 
  "Completion conflict history")

(defun ibizaman/syncthing--pick-a-conflict (conflicts)
  "Let user choose the next conflict from CONFLICTS to investigate."
  (completing-read "Choose the conflict to investigate: " conflicts
                   nil t nil ibizaman/syncthing--conflict-history))


(defun ibizaman/syncthing--get-normal-filename (conflict)
  "Get non-conflict filename matching the given CONFLICT."
  (replace-regexp-in-string "\\.sync-conflict-.*\\(\\..*\\)$" "\\1" conflict))


(defun ibizaman/ediff-files (&optional files quit-hook)
  (interactive)
  (lexical-let ((files (or files (dired-get-marked-files)))
                (quit-hook quit-hook)
                (wnd (current-window-configuration)))
    (if (<= (length files) 2)
        (let ((file1 (car files))
              (file2 (if (cdr files)
                         (cadr files)
                       (read-file-name
                        "file: "
                        (dired-dwim-target-directory)))))
          (if (file-newer-than-file-p file1 file2)
              (ediff-files file2 file1)
            (ediff-files file1 file2))
          (add-hook 'ediff-after-quit-hook-internal
                    (lambda ()
                      (setq ediff-after-quit-hook-internal nil)
                      (when quit-hook (funcall quit-hook))
                      (set-window-configuration wnd))))
      (error "no more than 2 files should be marked"))))

If you use Emacs on Android via Termux, I hope some of these tweaks help you too!

2019-07-15 Emacs news

$
0
0

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-07-22 Emacs news

$
0
0

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

2019-07-29 Emacs news

$
0
0

EmacsConf 2019 (Nov 2, online): Propose a session: https://emacsconf.org/2019/cfp (before Aug 31) Share ideas: https://emacsconf.org/2019/ideas

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-08-05 Emacs news

$
0
0

EmacsConf 2019 (Nov 2, online): Propose a session: https://emacsconf.org/2019/cfp (before Aug 31) Share ideas: https://emacsconf.org/2019/ideas

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.


2019-08-12 Emacs news

$
0
0

EmacsConf 2019 (Nov 2, online): Propose a session: https://emacsconf.org/2019/cfp (before Aug 31) Share ideas: https://emacsconf.org/2019/ideas

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-08-19 Emacs news

$
0
0

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-08-26 Emacs news

$
0
0

EmacsConf 2019 (Nov 2, online): Propose a session: https://emacsconf.org/2019/cfp (before Aug 31) Share ideas: https://emacsconf.org/2019/ideas

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-09-02 Emacs news

$
0
0

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

2019-09-09 Emacs news

$
0
0

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Hacker News, planet.emacslife.com, YouTube, the Emacs NEWS file and emacs-devel.

Viewing all 816 articles
Browse latest View live