diff options
author | Yuchen Pei <id@ypei.org> | 2023-06-19 11:19:19 +1000 |
---|---|---|
committer | Yuchen Pei <id@ypei.org> | 2023-06-19 22:41:03 +1000 |
commit | 06914aff2b0011d41bc50447965a8d7c6ef52c9b (patch) | |
tree | 278047a8c1c02347d5cf7a0119ac4cc373e3e191 /emacs/.emacs.d/lisp/my | |
parent | f06c1c12456a598b7007a6ef08306051d0d49064 (diff) |
precision fixes
- Adding org-jira
- Also fixed getting builders in buildbot
- Adding gdb-mi and gud
- Adding gdb and shell configs
- Also mariadb dev related stuff
- A few more modes
- some more updates
Diffstat (limited to 'emacs/.emacs.d/lisp/my')
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-magit.el | 11 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-mariadb.el | 126 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-org-jira.el | 184 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-ox-jira.el | 45 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-prog.el | 279 |
5 files changed, 645 insertions, 0 deletions
diff --git a/emacs/.emacs.d/lisp/my/my-magit.el b/emacs/.emacs.d/lisp/my/my-magit.el index 779c7c7..cf6749b 100644 --- a/emacs/.emacs.d/lisp/my/my-magit.el +++ b/emacs/.emacs.d/lisp/my/my-magit.el @@ -55,5 +55,16 @@ (interactive) (magit-status (my-project-read-project-root))) +;; override `magit-status' to allow build dir and src dir distinction +;; FIXME: there ought to be a better solution to do project things +;; from the builddir +(defun my-magit-status () + (interactive) + (if (magit-toplevel) + (magit-status) + (magit-status + (replace-regexp-in-string "/build\\>.*" "/src" + default-directory)))) + (provide 'my-magit) ;;; my-magit.el ends here diff --git a/emacs/.emacs.d/lisp/my/my-mariadb.el b/emacs/.emacs.d/lisp/my/my-mariadb.el new file mode 100644 index 0000000..5ffd6a0 --- /dev/null +++ b/emacs/.emacs.d/lisp/my/my-mariadb.el @@ -0,0 +1,126 @@ +;;; my-mariadb.el -- Customization for mariadb development-branch -*- lexical-binding: t -*- + +;; Copyright (C) 2023 Free Software Foundation. + +;; Author: Yuchen Pei <id@ypei.org> +;; Package-Requires: ((emacs "28.2")) + +;; This file is part of dotted. + +;; dotted is free software: you can redistribute it and/or modify it under +;; the terms of the GNU Affero General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; dotted is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General +;; Public License for more details. + +;; You should have received a copy of the GNU Affero General Public +;; License along with dotted. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Customization for mariadb development-branch. + +;;; Code: + +(require 'my-prog) + +(defun my-sql-maybe-mtrr () + (interactive) + (if (equal (file-name-extension (buffer-file-name)) + "test") + (call-interactively 'project-compile) + (sql-send-buffer))) + +(defun my-gdb-maria () + (require 'ycp-gdb) + (interactive) + (when (and (buffer-live-p gud-comint-buffer) + (get-buffer-process gud-comint-buffer)) + (my-gdb-quit)) + (sleep-for 1) + (my-gdb + (format "rr replay %s -d ~/bin/gdb-mi.sh" + (expand-file-name + (replace-regexp-in-string + "/src" + "/build/mysql-test/var/log/mysqld.1.rr/latest-trace" + (project-root (project-current t))))))) + +(defun my-gdb-maria-spider () + (require 'ycp-gdb) + (interactive) + (when (and (buffer-live-p gud-comint-buffer) + (get-buffer-process gud-comint-buffer)) + (my-gdb-quit)) + (sleep-for 1) + (my-gdb + (format "rr replay %s -d /home/ycp/source/mariadb-tools/gdb-mi.sh" + (expand-file-name + (replace-regexp-in-string + "/src" + "/build/mysql-test/var/log/mysqld.1.1.rr/latest-trace" + (project-root (project-current t))))))) + +(defun my-maria-style () + (setq comment-start "/* " + comment-end " */" + comment-continue " " + comment-style 'extra-line)) + +(setq my-c-style-maria-spider + '("maria-spider" + (c-basic-offset . 2) + (c-offsets-alist + . (;; no indentation when opening an brace + (substatement-open . 0) + ;; no extra space when aligning continued lines of block comments + (c . 0) + (arglist-intro . +) + (arglist-close . 0) + (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist) + (arglist-cont . 0) + (statement-block-intro . +) + )) + ;; empty comment start on block comment continuation refill + (c-block-comment-prefix . "") +)) + +(add-to-list 'c-style-alist my-c-style-maria-spider) + +(defun my-mdev-22979 (beg end) + (interactive "r") + (save-excursion + (goto-char end) + (insert " )}, +") + (goto-char beg) + (insert " {C_STRING_WITH_LEN( +"))) + +(defun my-gdb-mysql-parse-frame () + (interactive) + (let ((old-frame) (level)) + (with-current-buffer (gdb-stack-buffer-name) + (save-excursion + (beginning-of-buffer) + (setq old-frame (point)) + (text-property-search-forward + 'gdb-frame + "mysql_parse" + (lambda (val prop) (equal (alist-get 'func prop) val))) + (beginning-of-line) + (setq level (alist-get 'level (get-text-property (point) 'gdb-frame))))) + (with-current-buffer gud-comint-buffer + (insert "f " level) + (comint-send-input)) + (with-current-buffer (gdb-stack-buffer-name) + (save-excursion + (goto-char old-frame) + (gdb-select-frame))))) + +(provide 'my-mariadb) +;;; my-mariadb.el ends here diff --git a/emacs/.emacs.d/lisp/my/my-org-jira.el b/emacs/.emacs.d/lisp/my/my-org-jira.el new file mode 100644 index 0000000..7ff7738 --- /dev/null +++ b/emacs/.emacs.d/lisp/my/my-org-jira.el @@ -0,0 +1,184 @@ +;;; my-org-jira.el -- Extensions for org-jira -*- lexical-binding: t -*- + +;; Copyright (C) 2023 Free Software Foundation. + +;; Author: Yuchen Pei <id@ypei.org> +;; Package-Requires: ((emacs "28.2")) + +;; This file is part of dotted. + +;; dotted is free software: you can redistribute it and/or modify it under +;; the terms of the GNU Affero General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; dotted is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General +;; Public License for more details. + +;; You should have received a copy of the GNU Affero General Public +;; License along with dotted. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Extensions for org-jira. + +;;; Code: + +(require 'org-jira) + +;; Override `org-jira--render-issue' +;; include issue-id in the headline +(defun my-org-jira--render-issue (Issue) + "Render single ISSUE." + ;; (org-jira-log "Rendering issue from issue list") + ;; (org-jira-log (org-jira-sdk-dump Issue)) + (with-slots (filename proj-key issue-id summary status priority headline id) Issue + (let (p) + (with-current-buffer (org-jira--get-project-buffer Issue) + (org-jira-freeze-ui + (org-jira-maybe-activate-mode) + (org-jira--maybe-render-top-heading proj-key) + (setq p (org-find-entry-with-id issue-id)) + (save-restriction + (if (and p (>= p (point-min)) + (<= p (point-max))) + (progn + (goto-char p) + (forward-thing 'whitespace) + (org-jira-kill-line)) + (goto-char (point-max)) + (unless (looking-at "^") + (insert "\n")) + (insert "** ")) + (org-jira-insert + (concat (org-jira-get-org-keyword-from-status status) + " " + (org-jira-get-org-priority-cookie-from-issue priority) + issue-id " " headline)) + (save-excursion + (unless (search-forward "\n" (point-max) 1) + (insert "\n"))) + (org-narrow-to-subtree) + (save-excursion + (org-back-to-heading t) + (org-set-tags-to (replace-regexp-in-string "-" "_" issue-id))) + (mapc (lambda (entry) + (let ((val (slot-value Issue entry))) + (when (or (and val (not (string= val ""))) + (eq entry 'assignee)) ;; Always show assignee + (org-jira-entry-put (point) (symbol-name entry) val)))) + '(assignee filename reporter type type-id priority labels resolution status components created updated sprint)) + + (org-jira-entry-put (point) "ID" issue-id) + (org-jira-entry-put (point) "CUSTOM_ID" issue-id) + + ;; Insert the duedate as a deadline if it exists + (when org-jira-deadline-duedate-sync-p + (let ((duedate (oref Issue duedate))) + (when (> (length duedate) 0) + (org-deadline nil duedate)))) + + (mapc + (lambda (heading-entry) + (ensure-on-issue-id-with-filename issue-id filename + (let* ((entry-heading + (concat (symbol-name heading-entry) + (format ": [[%s][%s]]" + (concat jiralib-url "/browse/" issue-id) issue-id)))) + (setq p (org-find-exact-headline-in-buffer entry-heading)) + (if (and p (>= p (point-min)) + (<= p (point-max))) + (progn + (goto-char p) + (org-narrow-to-subtree) + (goto-char (point-min)) + (forward-line 1) + (delete-region (point) (point-max))) + (if (org-goto-first-child) + (org-insert-heading) + (goto-char (point-max)) + (org-insert-subheading t)) + (org-jira-insert entry-heading "\n")) + + ;; Insert 2 spaces of indentation so Jira markup won't cause org-markup + (org-jira-insert + (replace-regexp-in-string + "^" " " + (format "%s" (slot-value Issue heading-entry))))))) + '(description)) + + (when org-jira-download-comments + (org-jira-update-comments-for-issue Issue) + + ;; FIXME: Re-enable when attachments are not erroring. + ;;(org-jira-update-attachments-for-current-issue) + ) + + ;; only sync worklog clocks when the user sets it to be so. + (when org-jira-worklog-sync-p + (org-jira-update-worklogs-for-issue issue-id filename)))))))) + +;; Overload `org-jira-update-worklogs-from-org-clocks'. +(defun my-org-jira-update-worklogs-from-org-clocks () + "Update or add a worklog based on the org clocks." + (interactive) + (let* ((issue-id (org-jira-get-from-org 'issue 'key)) + (filename (org-jira-filename)) + ;; Fetch all workflogs for this issue + (jira-worklogs-ht (org-jira-worklog-to-hashtable issue-id))) + (org-jira-log (format "About to sync worklog for issue: %s in file: %s" + issue-id filename)) + (ensure-on-issue-id-with-filename + issue-id filename + (search-forward (format ":%s:" (or (org-clock-drawer-name) "LOGBOOK")) nil 1 1) + (org-beginning-of-line) + ;; (org-cycle 1) + (while (search-forward "CLOCK: " nil 1 1) + (let ((org-time (buffer-substring-no-properties (point) (point-at-eol)))) + (forward-line) + ;; See where the stuff ends (what point) + (let (next-clock-point) + (save-excursion + (search-forward-regexp "\\(CLOCK\\|:END\\):" nil 1 1) + (setq next-clock-point (point))) + (let ((clock-content + (buffer-substring-no-properties (point) next-clock-point))) + ;; Update via jiralib call + (let* ((worklog (org-jira-org-clock-to-jira-worklog org-time clock-content)) + (comment-text (cdr (assoc 'comment worklog))) + (comment-text (if (string= (org-trim comment-text) "") nil comment-text))) + (unless (cdr (assoc 'worklog-id worklog)) + (jiralib-add-worklog + issue-id + (cdr (assoc 'started worklog)) + (cdr (assoc 'time-spent-seconds worklog)) + comment-text + nil) ; no callback - synchronous + ) + ))))) + (org-jira-log (format "Updating worklog from org-jira-update-worklogs-from-org-clocks call")) + (org-jira-update-worklogs-for-issue issue-id filename) + ))) + +(defun my-org-jira-comment-url (issue-id comment-id) + (format + "%s/browse/%s?focusedCommentId=%s&page=com.atlassian.jira.plugin.system.issuetabpanels%%3Acomment-tabpanel#comment-%s" + jiralib-url issue-id comment-id comment-id)) + +(defun my-org-jira-comment-url-at-point () + (my-org-jira-comment-url + (org-entry-get + (save-excursion + (outline-up-heading 1) + (point)) + "ID") + (org-entry-get (point) "ID"))) + +(defun my-org-jira-kill-comment-url-at-point () + (interactive) + (kill-new (my-org-jira-comment-url-at-point))) + +(provide 'my-org-jira) +;;; my-org-jira.el ends here diff --git a/emacs/.emacs.d/lisp/my/my-ox-jira.el b/emacs/.emacs.d/lisp/my/my-ox-jira.el new file mode 100644 index 0000000..ac581bf --- /dev/null +++ b/emacs/.emacs.d/lisp/my/my-ox-jira.el @@ -0,0 +1,45 @@ +;;; my-ox-jira.el -- Extensions to ox-jira -*- lexical-binding: t -*- + +;; Copyright (C) 2023 Free Software Foundation. + +;; Author: Yuchen Pei <id@ypei.org> +;; Package-Requires: ((emacs "28.2")) + +;; This file is part of dotted. + +;; dotted is free software: you can redistribute it and/or modify it under +;; the terms of the GNU Affero General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; dotted is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General +;; Public License for more details. + +;; You should have received a copy of the GNU Affero General Public +;; License along with dotted. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Extensions to ox-jira. + +;;; Code: + +(require 'ox-jira) +(require 'my-prog) +(defun my-org-backtrace-to-github-jira (beg end) + (interactive "r") + (let ((bt (buffer-substring-no-properties beg end)) + (revision (when current-prefix-arg + (read-string "Rrevision: "))) + ) + (with-temp-buffer + (insert "#+options: ^:nil +") + (goto-char (point-max)) + (insert (my-org-backtrace-to-github bt revision)) + (ox-jira-export-as-jira)))) + +(provide 'my-ox-jira) +;;; my-ox-jira.el ends here diff --git a/emacs/.emacs.d/lisp/my/my-prog.el b/emacs/.emacs.d/lisp/my/my-prog.el index 210d7ef..309df2e 100644 --- a/emacs/.emacs.d/lisp/my/my-prog.el +++ b/emacs/.emacs.d/lisp/my/my-prog.el @@ -86,6 +86,26 @@ "-ansi -pedantic -Wall -g") file))))) +(defun my-c-switch-between-header-and-source () + "Switch between a c/c++ header (.h) and its corresponding source (.c/.cpp/.cc)." + (interactive) + (let ((bse (file-name-sans-extension buffer-file-name)) + (ext (downcase (file-name-extension buffer-file-name))) + (new-file)) + (cond + ;; first condition - the extension is "h" + ((equal ext "h") + (cond ((file-exists-p (setq new-file (concat bse ".c"))) + (find-file new-file)) + ((file-exists-p (setq new-file (concat bse ".cpp"))) + (find-file new-file)) + ((file-exists-p (setq new-file (concat bse ".cc"))) + (find-file new-file)))) + ;; second condition - the extension is "c" or "cpp" + ((member ext '("c" "cpp" "cc")) + (when (file-exists-p (setq new-file (concat bse ".h"))) + (find-file new-file)))))) + ;;; To override `xref-query-replace-in-results'. (defun my-xref-query-replace-in-results (from to) "Perform interactive replacement of FROM with TO in all displayed xrefs. @@ -155,5 +175,264 @@ create a shell buffer using `my-shell-with-directory'" (call-interactively 'my-shell-with-directory) (my-buffer-quick-major-mode 'shell-mode))) +;;; gdb +(require 'gdb-mi) +(require 'gud) +(require 'org) +(defun my-org-backtrace-region (beg end) + "Convert selected backtrace to org links and copy the result to kill ring. + +With a prefix arg, convert from bottom to top." + (let ((bt (buffer-substring-no-properties beg end)) + (case-fold-search nil) + (results) (func-name)) + (with-temp-buffer + (insert bt) + (goto-char (point-min)) + ;; remove paging lines + (flush-lines "^--.*--$") + (goto-char (point-min)) + (while (re-search-forward "^#[0-9]+\\ +\\(?:[0-9a-fx]+ in \\)?\\([^ ]+\\) .*$" end t) + (setq func-name (match-string-no-properties 1)) + (let ((point-from) (file-location-from) + (point-at) (file-location-at) + (file-location)) + (save-excursion + (when (re-search-forward " from \\(/[^ ]+\\)$" end t) + (setq file-location-from (match-string-no-properties 1) + point-from (point)))) + (save-excursion + ;; a weak check of file:lineno + (when (re-search-forward " at \\(/[^ ]+:.*\\)$" end t) + (setq file-location-at (match-string-no-properties 1) + point-at (point)))) + (setq file-location + (cond ((not file-location-from) file-location-at) + ((not file-location-at) file-location-from) + ((< point-at point-from) file-location-at) + (t file-location-from))) + (when (and func-name file-location) + (push (concat "[[" file-location "][" func-name "]]") results)))) + (unless current-prefix-arg (setq results (reverse results))) + (kill-new (string-join results (if current-prefix-arg " < " " > ")))))) + +(defun my-stack-frame-to-org (rev) + "Convert stack frame in gdb frames buffer to org. + +Conversion is in a similar fashion to `my-org-backtrace-region'." + (let ((results)) + (with-current-buffer (gdb-stack-buffer-name) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^[0-9]+\\ +in \\(.*\\) of \\(.*\\)$" nil t) + (setq func-name (match-string-no-properties 1) + file-location (match-string-no-properties 2)) + (push (concat "[[" file-location "][" func-name "]]") results)))) + (unless rev (setq results (reverse results))) + (string-join results (if current-prefix-arg " < " " > ")))) + +(defun my-insert-stack-frame-to-org (rev) + (interactive "P") + (insert (my-stack-frame-to-org rev))) + +(defun my-kill-stack-frame-to-org (rev) + (interactive "P") + (kill-new (my-stack-frame-to-org rev))) + +(defun my-org-backtrace () + (interactive) + (if (region-active-p) + (my-org-backtrace-region (region-beginning) (region-end)) + (my-org-backtrace-region + (point) + (save-excursion (comint-next-prompt 1) (point))))) + +(defun my-gdb (&optional command) + "lock gud command buffer and restore middle and right windows. + +Assuming a three window horizontal split to start with. Assuming +the default configuration of gdb windows is all of them on the +left and the source buffer on the right. +" + (interactive) + ;; save windows + (let* ((old-window (selected-window)) + (right-buffer + (window-buffer + (progn + (while (window-in-direction 'right) + (select-window (window-in-direction 'right))) + (selected-window)))) + (middle-buffer + (window-buffer + (window-in-direction 'left)))) + (select-window old-window) + ;; call gdb + (if (called-interactively-p) + (call-interactively 'gdb) + (gdb command)) + (sleep-for 6) + ;; lock gud-comint-buffer + (my-toggle-lock-window-to-buffer (get-buffer-window gud-comint-buffer)) + ;; restore windows + (select-window (car gdb-source-window-list)) + (switch-to-buffer middle-buffer) + (split-window-horizontally) + (select-window (window-next-sibling)) + (switch-to-buffer right-buffer) + (balance-windows) + (when (window-live-p old-window) (select-window old-window)))) + +(defun my-gdb-restart () + (interactive) + (let ((old-window (selected-window))) + (select-window (get-buffer-window gud-comint-buffer)) + (gdb-delchar-or-quit 0) + (call-interactively 'my-gdb) + (when (window-live-p old-window) (select-window old-window)))) + +(defun my-gdb-kill () + (interactive) + (let ((kill-buffer-query-functions nil)) + (kill-buffer "*gud-replay*"))) + +(defun my-gdb-quit () + (interactive) + (let ((old-window (selected-window))) + (select-window (get-buffer-window gud-comint-buffer)) + (goto-char (point-max)) + (gdb-delchar-or-quit 0) + (my-toggle-lock-current-window-to-buffer) + (when (window-live-p old-window) (select-window old-window)))) + +(defun my-gdb-frames-add-breakpoint () + (interactive) + (gdb-select-frame) + (with-current-buffer (gdb-get-source-buffer) + (call-interactively 'gud-break))) + +(defun my-gdb-frames-remove-breakpoint () + (interactive) + (gdb-select-frame) + (with-current-buffer (gdb-get-source-buffer) + (call-interactively 'gud-remove))) + +(defun my-gdb-frames-select-next (n) + (interactive "p") + (next-line n) + (gdb-select-frame)) +(defun my-gdb-frames-select-previous (n) + (interactive "p") + (next-line (- n)) + (gdb-select-frame)) +(defun my-gdb-switch-to-source-buffer () + (interactive) + (select-window (display-buffer (gdb-get-source-buffer)))) + +(defun my-gud-comint-set-prompt-regexp () + (setq comint-prompt-regexp "\\((rr)|(gdb)\\) ")) + +(defun my-file-loc-to-github (file-loc &optional revision) + "Convert a file location to a github url." + (pcase-let* ((`(,file ,line-no) (split-string file-loc ":")) + (revision (or revision (vc-working-revision file))) + (repo-url (vc-git-repository-url file)) + (repo-root (vc-git-root file)) + (path (file-relative-name file repo-root))) + (format "%s/blob/%s/%s#L%s" repo-url revision path line-no))) + +(defun my-org-backtrace-to-github (bt &optional revision) + (string-join + (mapcar + (lambda (link) + (string-match "\\[\\[\\(.*\\)\\]\\[\\(.*\\)\\]\\]" link) + (let ((target (match-string 1 link)) + (label (match-string 2 link))) + (format "[[%s][%s]]" + (my-file-loc-to-github target revision) + label))) + (split-string bt " > ")) + " > ")) + +(defun my-org-backtrace-to-github-region (beg end) + (interactive "r") + (kill-new + (my-org-backtrace-to-github (buffer-substring-no-properties beg end)))) + +(defun my-org-backtrace-to-github-slack (beg end) + (interactive "r") + (let ((bt (buffer-substring-no-properties beg end)) + (revision (when current-prefix-arg + (read-string "Rrevision: "))) + ) + (with-temp-buffer + (insert "#+options: ^:nil +") + (goto-char (point-max)) + (insert (my-org-backtrace-to-github bt revision)) + (org-md-export-as-markdown)))) + +;;; which-func +(defun my-copy-which-func () + (interactive) + (kill-new (which-function)) + ) + +(defun my-set-header-line-to-which-func () + (setq header-line-format + '((which-func-mode + ("" which-func-format " ") + )))) + +;; override bookmark-make-record for easier default bookmark name. +(defun my-bookmark-make-record () + "Return a new bookmark record (NAME . ALIST) for the current location." + (let ((record (funcall bookmark-make-record-function))) + ;; Set up default name if the function does not provide one. + (unless (stringp (car record)) + (if (car record) (push nil record)) + (setcar record (or bookmark-current-bookmark (bookmark-buffer-name)))) + ;; Set up defaults. + (bookmark-prop-set + record 'defaults + (delq nil (delete-dups (append (bookmark-prop-get record 'defaults) + (list (which-function) + bookmark-current-bookmark + (car record) + (bookmark-buffer-name)))))) + record)) + +;;; bison-mode +(require 'bison-mode) +(defun my-bison-imenu-create-index () + (let ((end)) + (beginning-of-buffer) + (re-search-forward "^%%") + (forward-line 1) + (setq end (save-excursion + (when (re-search-forward "^%%" nil t) (point)))) + (loop while (re-search-forward "^\\([a-z].*?\\)\\s-*\n?\\s-*:" end t) + collect (cons (match-string 1) (point))))) +(defun my-bison-set-imenu-create-index-function () + (setq imenu-create-index-function + 'my-bison-imenu-create-index)) + +;;; json-mode +(require 'json-mode) +(defun my-json-mode-path () + (string-join + (mapcar 'prin1-to-string (plist-get (json-path-to-position (point)) :path)) + "/")) + +(defun my-json-set-header-line-to-path () + (setq header-line-format + '((:eval (my-json-mode-path))))) + +;;; eglot +(defun my-eglot-format-buffer-when-managed () + (when (eglot-managed-p) + (unless (derived-mode-p 'haskell-mode 'c-mode 'c++-mode) + (eglot-format-buffer)))) + (provide 'my-prog) ;;; my-prog.el ends here |