org-mode – ¿Cómo calcular automáticamente las líneas de inicio y final al incluir archivos de origen en modo org?

Pregunta:

Tengo lo siguiente en mi documentación:

#+INCLUDE: "code/basic.sv" :src systemverilog :lines "14-117"

Aquí la línea 14 es donde tengo la class basic extends .. y la línea 116 es donde tengo la endclass .

¿Hay alguna manera de insertar automáticamente los números 14 y 117 (= 116 + 1) para que no tenga que actualizarlos manualmente cada vez que modifique el code/basic.sv ?

Respuesta:

Aquí tienes otra opción. Este le permite personalizar las expresiones regulares por inclusión. Debería encajar mejor con algunos flujos de trabajo, ya que no está limitado a definiciones basadas en extensiones.

Usar

Haga algo como lo siguiente en su archivo de organización. (La palabra clave :lines es opcional)

#+INCLUDE: "code/my-class.sv" :src systemverilog :range-begin "^class" :range-end "^endclass" :lines "14-80"

La función visitará "my-class.sv" y buscará esas dos expresiones regulares, y luego actualizará la palabra clave :lines acuerdo con el resultado de la coincidencia.

Si falta :range-begin , el rango será "-80".
Si falta :range-end , el rango será "14-".

El código

(add-hook 'before-save-hook #'endless/update-includes)

(defun endless/update-includes (&rest ignore)
  "Update the line numbers of #+INCLUDE:s in current buffer.
Only looks at INCLUDEs that have either :range-begin or :range-end.
This function does nothing if not in org-mode, so you can safely
add it to `before-save-hook'."
  (interactive)
  (when (derived-mode-p 'org-mode)
    (save-excursion
      (goto-char (point-min))
      (while (search-forward-regexp
              "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)"
              nil 'noerror)
        (let* ((file (expand-file-name (match-string-no-properties 1)))
               lines begin end)
          (forward-line 0)
          (when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"")
            (setq begin (match-string-no-properties 1)))
          (when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"")
            (setq end (match-string-no-properties 1)))
          (setq lines (endless/decide-line-range file begin end))
          (when lines
            (if (looking-at ".*:lines *\"\\([-0-9]+\\)\"")
                (replace-match lines :fixedcase :literal nil 1)
              (goto-char (line-end-position))
              (insert " :lines \"" lines "\""))))))))

(defun endless/decide-line-range (file begin end)
  "Visit FILE and decide which lines to include.
BEGIN and END are regexps which define the line range to use."
  (let (l r)
    (save-match-data
      (with-temp-buffer
        (insert-file file)
        (goto-char (point-min))
        (if (null begin)
            (setq l "")
          (search-forward-regexp begin)
          (setq l (line-number-at-pos (match-beginning 0))))
        (if (null end)
            (setq r "")
          (search-forward-regexp end)
          (setq r (1+ (line-number-at-pos (match-end 0)))))
        (format "%s-%s" l r)))))

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım