org-babel – búfer de conmutación para programación alfabetizada

Pregunta:

Cuando hago programación alfabetizada, desarrollo web en un solo archivo de organización y organizo enredo para generar los archivos html y css relevantes. Esto funciona, por unas pocas horas / días. Cuando el número de archivos en el archivo de la organización es superior a 20, por ejemplo, es una verdadera molestia buscar / navegar entre los bloques #+BEGIN_SRC .

Preferiría mucho si pudiera usar algo similar a la forma habitual de emacs de cambiar búferes Cx Cb switch-buffer. Entonces, en una posible solución, tome este archivo org, por ejemplo

#+BEGIN_SRC css :tangle public/styles.css
 some css
#+END_SRC

literate discussion here.

** org subheading
  + list item1
  + list item 2

#+BEGIN_SRC html :tangle public/index.html
<!doctype html>
...
#+END_SRC

Cuando Cu Cx Cb , se me presentan estas opciones de menú de búfer alfabetizado:

public/index.html
public/styles.css

Si cambiaría / enfocaría a uno de estos bloques begin_src usando un flujo similar al menú de búfer.

La programación alfabetizada ha existido durante unos 20 años, emacs más del doble, así que me pregunto si otras personas se han enfrentado a mi problema y lo han superado.

Respuesta:

Puede probar el comando list-org-src del siguiente código elisp.

Está probado con emacs 25.3.1 y org-mode 9.1.6.

Instale la fuente en su archivo init (después de (package-initialize) ).

Abra su archivo de organización y escriba Mx list-org-src RET .

Eso crea un búfer org-src con una lista tabulada de las entradas del bloque de código fuente. Cada entrada tiene los siguientes componentes:

  • Name : el #+NAME: -componente del bloque de código fuente
  • Language : el lenguaje de programación
  • Headline : comienzo del título principal
  • Tangle : el archivo de enredos

Si hace clic en el nombre de un bloque de origen en la lista de bloques de origen, ese bloque de origen se busca en el archivo de organización. Si hace clic en la entrada de enredo, se encuentra el archivo de enredo.

Vincula list-org-src a la secuencia de teclas que desees. Tenga en cuenta que no debe hacer un mal uso de Cx Cb ya que este enlace es global e importante. Es mejor vincular una secuencia de teclas específica del usuario, como Cc b .

Tenga en cuenta que list-org-src no guarda posiciones de búfer. Identifica los bloques de origen por su código sha1 o por el nombre, el idioma y el componente Tangle. Si hace clic en un enlace de Name punto del archivo de organización se mueve al primer bloque de origen en el archivo donde coinciden el código sha1 o los tres indicadores. Si ha editado el código fuente después de la última llamada a list-org-src y hay varios bloques fuente que coinciden con los indicadores, solo se encuentra el primer bloque fuente en el archivo org.

Esta estrategia le permite editar el búfer de la organización y utilizar el búfer org-src sin actualizar este último.

(require 'org)
(require 'org-element)
(require 'ob-core)
(require 'pulse)

(defgroup org-list-src nil
  "Customization group for listing source blocks."
  :group 'org-babel)

(defcustom org-list-src-search '(sha1 name-language-tangle)
  "Search method for org source blocks.
Possible choices are:
sha1: Use sha1 key for comparing source blocks.
      Source blocks match if they and their properties are not edited.
      This method may cause lower performance for large org files.
name-language-tangle: Use the source block name, the programming language,
                      and the tangle file.
                      Source blocks match if those three indicators match."
  :type '(set (const sha1) (const name-language-tangle))
  :group 'org-list-src)

(defvar-local org-list-src-org-buf nil
  "Original org mode buffer corresponding to the org source block list")

(defun org-list-src-assert ()
  "Make sure we have an original org buffer."
  (cl-assert (buffer-live-p org-list-src-org-buf) nil "Missing org-mode buffer %s" org-list-src-org-buf))

(defun org-list-src-tangle (element)
  "Get tangle header argument from org element ELEMENT."
  (cdr (assoc :tangle (org-babel-parse-header-arguments (org-element-property :parameters element)))))

(defun org-list-src-sha1 (sblock)
  "Get the sha1 key of the source block SBLOCK.
SBLOCK can be the result of `org-element-context'
or one of the elements in the result of `org-element-parse-buffer'."
  (org-babel-sha1-hash (org-babel-get-src-block-info nil sblock)))

(defun org-list-src-show (sblock)
  "Show source block SBLOCK in currently selected org buffer window."
  (display-buffer (current-buffer))
  (let ((beg (org-element-property :begin sblock))
        (end (org-element-property :end sblock)))
    (with-selected-window (get-buffer-window)
      (goto-char beg)
      (org-reveal)
      (pulse-momentary-highlight-region beg end)
      (recenter))))

(defun org-list-src-button-find (button)
  "Find org source block with matching BUTTON.
BUTTON is a button with the properties retrived by `button-get':
:src-name   The name of the source block.
:src-language   The type of the source block.
:src-tangle The target file name."
  (org-list-src-assert)
  (let ((name (button-get button :src-name))
        (language (button-get button :src-language))
        (tangle (button-get button :src-tangle))
        (sha1 (button-get button :src-sha1)))
    (with-current-buffer org-list-src-org-buf
      (let ((data (org-element-parse-buffer)))
        (cond
         ;; 1st try comparing sha1 keys (may fail if the block is edited)
         ((memq 'sha1 org-list-src-search)
              (org-element-map data 'src-block
                (lambda (sblock)
                  (when
                      (string=
                       (org-list-src-sha1 sblock)
                       sha1)
                    (org-list-src-show sblock)
                    t))
                nil t))
         ;; 2nd try comparing name, language, and tangle file
         ((memq 'name-language-tangle org-list-src-search)
          (org-element-map data 'src-block
            (lambda (sblock)
              (when
                  (and
                   (equal name (org-element-property :name sblock))
                   (string= language (org-element-property :language sblock))
                   (equal tangle (org-list-src-tangle sblock)))
                (org-list-src-show sblock)
                t))
            nil t))
         (t
          (message "Source block not found.")))))))

(defun org-list-src-button-find-file (button)
  "Find file with name retrieved as property :src-tangle from BUTTON."
  (let ((fname (button-get button :src-tangle)))
    (when (stringp fname)
      (find-file fname))))

(defun org-list-src-button-headline (button)
  "Find headline from button in org buffer."
  (org-list-src-assert)
  (let ((headline (button-get button :src-headline)))
    (when (stringp headline)
      (with-current-buffer org-list-src-org-buf
    (goto-char (org-find-exact-headline-in-buffer headline))
    (org-list-src-show (org-element-context))))))

(defun org-list-src-headline (sblock)
  "Determine parent headline of source block SBLOCK."
  (catch :found
    (while
        (progn
          (setq sblock (org-element-property :parent sblock))
          (and sblock
               (null
                (and (eq (org-element-type sblock) 'headline)
                     (throw :found (org-element-property :raw-value sblock)))))))))

(defun org-list-src-entries ()
  "Create list of org source code blocks suitable for `tabulated-list-entries'.
The command works in `org-list-src-mode' buffers and the list is generated for org buffer `org-list-src-org-buf'."
  (org-list-src-assert)
  (with-current-buffer org-list-src-org-buf
    (let ((data (org-element-parse-buffer)))
      (org-element-map
          data 'src-block
        (lambda (sblock)
          (let* ((name (org-element-property :name sblock))
                 (language (or (org-element-property :language sblock)
                               (error "Not accepting source block without language")))
                 (headline (or (org-list-src-headline sblock) ""))
                 (tangle (org-list-src-tangle sblock))
                 (sha1 (org-list-src-sha1 sblock)))
            (list name
                  (vector
                   (list (or name "*no name*")
                         'action #'org-list-src-button-find
                         :src-name name
                         :src-language language
                         :src-headline headline
                         :src-tangle tangle
                         :src-sha1 sha1)
                   language
                   (if (stringp headline)
               (list headline 'action #'org-list-src-button-headline :src-headline headline)
             "")
                   (if tangle
                       (list tangle 'action #'org-list-src-button-find-file :src-tangle tangle)
                       "")
                   ))))))))

(define-derived-mode org-list-src-mode tabulated-list-mode "OrgSrc"
  "Mode for listing org src blocks."
  (setq tabulated-list-format [("Name" 20 t) ("Language" 20 t) ("Headline" 40 t) ("Tangle" 0 t)]
        tabulated-list-entries #'org-list-src-entries))

(defun list-org-src ()
  "List source blocks of current org buffer."
  (interactive)
  (let* ((orig-buffer (current-buffer)))
    (with-current-buffer (get-buffer-create (format "*org-src:%S*" (buffer-name)))
      (setq buffer-read-only nil) ;; tabulated-list-mode sets this to t
      (delete-region (point-min) (point-max))
      (org-list-src-mode)
      (setq org-list-src-org-buf orig-buffer)
      (tabulated-list-init-header)
      (tabulated-list-print)
      (display-buffer (current-buffer)))))

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım