I'm struggling to adapt my emacs conf file for my mac...
What I'm trying to do is being able to scroll up/down by block by using ctrl + arrows.
The problem is that when I try to do it, mac intercepts the command and does something specific to mac os...
Here is my current .emacs file:
(add-to-list 'load-path "~/.emacs.d/")
(setq column-number-mode t)
(setq shift-select-mode t)
(show-paren-mode 1)
(global-linum-mode 1)
(set-face-attribute 'linum nil :background "#000000")
(setq linum-format
(lambda (line)
(propertize (format
(let ((w (length (number-to-string
(count-lines (point-min) (point-max))))))
(concat "%" (number-to-string w) "d "))
line)
'face 'linum)))
(add-to-list 'auto-mode-alist (cons "\\.php[0-9]*$" 'php-mode))
(global-set-key "" 'do_insert_time)
(global-set-key "" 'std-file-header)
(setq header-made-by "Made by "
header-login "Login "
header-login-beg "<"
header-login-mid "#"
header-login-end ">"
header-started "Started on "
header-last "Last update "
header-for " for "
header-in " in "
domaine-name "")
(if (setq user-nickname (getenv "USER_NICKNAME"))
t
(setq user-nickname (user-full-name))
)
(setq write-file-hooks (cons 'update-std-header write-file-hooks))
(setq std-c-alist '( (cs . "/*") (cc . "** ") (ce . "*/") )
std-css-alist '( (cs . "/*") (cc . "** ") (ce . "*/") )
std-cpp-alist '( (cs . "//") (cc . "// ") (ce . "//") )
std-pov-alist '( (cs . "//") (cc . "// ") (ce . "//") )
std-java-alist '( (cs . "//") (cc . "// ") (ce . "//") )
std-latex-alist '( (cs . "%%") (cc . "%% ") (ce . "%%") )
std-lisp-alist '( (cs . ";;") (cc . ";; ") (ce . ";;") )
std-xdefault-alist '( (cs . "!!") (cc . "!! ") (ce . "!!") )
std-pascal-alist '( (cs . "{ ") (cc . " ") (ce . "}" ) )
std-makefile-alist '( (cs . "##") (cc . "## ") (ce . "##") )
std-text-alist '( (cs . "##") (cc . "## ") (ce . "##") )
std-fundamental-alist '( (cs . " ") (cc . " ") (ce . " ") )
std-html-alist '( (cs . "<!--") (cc . " -- ") (ce . "-->"))
std-php-alist '( (cs . "#!/usr/local/bin/php\n<?php") (cc . "// ")(ce . "//"))
std-nroff-alist '( (cs . "\\\"") (cc . "\\\" ") (ce . "\\\""))
std-sscript-alist '( (cs . "#!/bin/sh") (cc . "## ") (ce . "##"))
std-perl-alist '( (cs . "#!/usr/local/bin/perl -w") (cc . "## ")(ce . "##"))
std-cperl-alist '( (cs . "#!/usr/local/bin/perl -w") (cc . "## ")(ce . "##"))
)
(setq std-modes-alist '(("C" . std-c-alist)
("C/l" . std-c-alist)
("CSS" . std-c-alist)
("PoV" . std-pov-alist)
("C++" . std-cpp-alist)
("C++/l" . std-cpp-alist)
("Lisp" . std-lisp-alist)
("Lisp Interaction" . std-lisp-alist)
("Emacs-Lisp" . std-lisp-alist)
("Fundamental" . std-fundamental-alist)
("Shell-script" . std-sscript-alist)
("Makefile" . std-makefile-alist)
("GNUmakefile" . std-makefile-alist)
("BSDmakefile" . std-makefile-alist)
("Perl" . std-cperl-alist)
("CPerl" . std-cperl-alist)
("xdefault" . std-xdefault-alist)
("java" . std-java-alist)
("latex" . std-latex-alist)
("Pascal" . stdp-ascal-alist)
("Text" . std-text-alist)
("HTML" . std-html-alist)
("PHP" . std-php-alist)
("Nroff" . std-nroff-alist)
("TeX" . std-latex-alist)
("LaTeX" . std-latex-alist))
)
(defun std-get (a)
(interactive)
(cdr (assoc a (eval (cdr (assoc mode-name std-modes-alist)))))
)
(defun update-std-header ()
"Updates std header with last modification time & owner.\n(According to mode)"
(interactive)
(save-excursion
(if (buffer-modified-p)
(progn
(goto-char (point-min))
(if (search-forward header-last nil t)
(progn
; (delete-region (point-at-bol) (point-at-eol))
(delete-region
(progn (beginning-of-line) (point))
(progn (end-of-line) (point)))
(insert-string (concat (std-get 'cc)
header-last
(current-time-string)
" "
user-nickname))
(message "Last modification header field updated."))))))
nil)
(defun std-file-header ()
"Puts a standard header at the beginning of the file.\n(According to mode)"
(interactive)
(goto-char (point-min))
(let ((projname "toto")(location "tiuti"))
(setq projname (read-from-minibuffer
(format "Type project name (RETURN to quit) : ")))
(setq location (getenv "PWD"))
(insert-string (std-get 'cs))
(newline)
(insert-string (concat (std-get 'cc)
(buffer-name)
header-for
projname
header-in
location))
(newline)
(insert-string (std-get 'cc))
(newline)
(insert-string (concat (std-get 'cc) header-made-by user-nickname))
(newline)
(insert-string (concat (std-get 'cc)
header-login
header-login-beg
(getenv "USER")
header-login-mid
domaine-name
header-login-end))
(newline)
(insert-string (std-get 'cc))
(newline)
(insert-string (concat (std-get 'cc)
header-started
(current-time-string)
" "
user-nickname))
(newline)
(insert-string (concat (std-get 'cc)
header-last
(current-time-string)
" "
user-nickname))
(newline)
(insert-string (std-get 'ce))
(newline)))
(defun insert-std-vertical-comments ()
"Inserts vertical comments (according to mode)."
(interactive)
(beginning-of-line)
(insert-string (std-get 'cs))
(newline)
(let ((ok t)(comment ""))
(while ok
(setq comment (read-from-minibuffer
(format "Type comment (RETURN to quit) : ")))
(if (= 0 (length comment))
(setq ok nil)
(progn
(insert-string (concat (std-get 'cc) comment))
(newline)))))
(insert-string (std-get 'ce))
(newline))
(defun std-toggle-comment ()
"Toggles line comment on or off (according to mode)."
(interactive)
(save-excursion
(let (beg end)
(beginning-of-line)
(setq beg (point))
(end-of-line)
(setq end (point))
(save-restriction
(if (not (equal beg end))
(progn
(narrow-to-region beg end)
(goto-char beg)
(if (search-forward (std-get 'cs) end t)
(progn
(beginning-of-line)
(replace-string (std-get 'cs) "")
(replace-string (std-get 'ce) ""))
(progn
(beginning-of-line)
(insert-string (std-get 'cs))
(end-of-line)
(insert-string (std-get 'ce)))))))))
;; (indent-according-to-mode)
(indent-for-tab-command)
(next-line 1))
;;; Added by Eole Wednesday May 29 2002, 1:33:55
;;; Extended bindings for this package and for commenting code
(global-set-key "h" 'update-std-header)
(global-set-key "" 'std-file-header)
;;;; Generating local keymaps for exotics modes.
;;; In CPerl mode, C-c C-h is used to do some help.
;;; so it is C-c C-h h
;;; For working, it requires info pages about perl
(add-hook 'cperl-mode-hook
'(lambda ()
(define-key cperl-mode-map ""
'comment-region)
(define-key cperl-mode-map "h"
'std-file-header)))
;; for perl-mode
(add-hook 'perl-mode-hook
'(lambda ()
(define-key perl-mode-map ""
'comment-region)))
;; for all kind of lisp code
(add-hook 'emacs-lisp-mode-hook
'(lambda ()
(define-key emacs-lisp-mode-map ""
'comment-region)))
(add-hook 'lisp-mode-hook
'(lambda ()
(define-key lisp-mode-map ""
'comment-region)))
;; for La(TeX)-mode
(add-hook 'tex-mode-hook
'(lambda ()
(define-key tex-mode-map ""
'comment-region)))
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(inhibit-startup-screen t))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
Thanks very much!
Reassign or disable the "Mission control" and "Application windows" keyboard shortcuts in System Preferences.
The normal way to bind Ctrl-up and -down is via the following lines in your .emacs file:
(global-set-key "C-<up>" 'scroll-down)
(global-set-key "C-<down>" 'scroll-up)
This works when Emacs receives all key strokes directly from the OS. In the case emacs is run inside a terminal it depends additionally on the terminal settings. You test the keys your Emacs instance receives with the Emacs command describe-key (keyboard shortcut Ctrl-h k) plus the key combo you want to use, say, Ctrl-up. If, as I suspect, the help window only mentions <up> instead of <C-up>, the terminal settings drop the Ctrl modifier.
Your best change, I suggest, is to install an emacs build which runs as a Carbon application like emacsformacosx.
Then the above listed bindings should work.
Related
I'm trying to install ripgrep in emacs in order to use it with hledger-mode
I added this lines to my ~/.emacs.d/init.el:
(require 'rg)
(rg-enable-default-bindings)
And running emacs -nw --debug-init shows me this:
Debugger entered--Lisp error: (file-missing "Cannot open load file" "No such file or directory" "rg")
this is my brew info rg
==> ripgrep: stable 13.0.0 (bottled), HEAD
Search tool like grep and The Silver Searcher
https://github.com/BurntSushi/ripgrep
/opt/homebrew/Cellar/ripgrep/13.0.0 (13 files, 5.8MB) *
Poured from bottle on 2023-01-18 at 19:36:26
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/ripgrep.rb
License: Unlicense
==> Dependencies
Build: asciidoctor, pkg-config, rust
Required: pcre2
==> Options
--HEAD
Install HEAD version
==> Caveats
zsh completions have been installed to:
/opt/homebrew/share/zsh/site-functions
==> Analytics
install: 9,411 (30 days), 30,297 (90 days), 122,177 (365 days)
install-on-request: 9,241 (30 days), 29,736 (90 days), 118,865 (365 days)
build-error: 3 (30 days)
and emacs --version
GNU Emacs 28.2
Copyright (C) 2022 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
running C-u M-: (getenv "PATH") inside emacs show me /opt/homebrew/bin in the PATH and ls -l /opt/homebrew/bin/rg shows the following:
lrwxr-xr-x 1 XXXX XXXX 31 Jan 18 19:36 rg -> ../Cellar/ripgrep/13.0.0/bin/rg
I have and iMac M1 2001 with ventura 13.1 and Rosetta installed.
Here is my entire ~/.emacs.d/init.el:
;; Install MELPA
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
;; Comment/uncomment this line to enable MELPA Stable if desired. See `package-archive-priorities`
;; and `package-pinned-packages`. Most users will not need or want to do this.
;;(add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
(add-hook 'after-init-hook 'global-company-mode)
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(package-selected-packages '(hledger-mode)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
;; load mu4e from the installation path.
;; yours might differ check with the Emacs installation
(add-to-list 'load-path "/opt/homebrew/Cellar/mu/1.8.13/share/emacs/site-lisp/mu/mu4e")
(require 'mu4e)
;; the headers to show in the headers list -- a pair of a field
;; and its width, with `nil' meaning 'unlimited'
;; (better only use that for the last field.
;; These are the defaults:
(setq mu4e-headers-fields
'( (:human-date . 25) ;; alternatively, use :human-date
(:flags . 6)
(:maildir . 20)
(:from-or-to . 22)
(:subject . nil))) ;; alternatively, use :thread-subject%:
;;(Use-package mu4e
;; :load-path "/usr/local/share/emacs/site-lisp/mu/mu4e/")
;; :load-path "/opt/homebrew/Cellar/mu/1.8.13/bin")
;; for sending mails
(require 'smtpmail)
;; we installed this with homebrew
(setq mu4e-mu-binary (executable-find "mu"))
;; this is the directory we created before:
(setq mu4e-maildir "~/.maildir")
;; this command is called to sync imap servers:
(setq mu4e-get-mail-command (concat (executable-find "mbsync") " -a"))
;; how often to call it in seconds:
(setq mu4e-update-interval 300)
;; save attachment to desktop by default
;; or another choice of yours:
(setq mu4e-attachment-dir "~/Downloads")
;; rename files when moving - needed for mbsync:
(setq mu4e-change-filenames-when-moving t)
;; list of your email adresses:
(setq mu4e-user-mail-address-list '("justme#gmail.com"))
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize))
;; check your ~/.maildir to see how the subdirectories are called
;; for the generic imap account:
;; e.g `ls ~/.maildir/example'
(setq mu4e-maildir-shortcuts
'(("/gmail/INBOX" . ?g)
(:maildir "/gmail/Archives" :key ?a)
("/gmail/[Gmail]/Enviados" . ?G)))
;;(add-to-list 'mu4e-bookmarks
;; (make-mu4e-bookmark
;; :name "Inbox - Gmail"
;; :query "maildir:/gmail/INBOX"
;; :key ?g))
(setq mu4e-contexts
`(,(make-mu4e-context
:name "gmail"
:enter-func
(lambda () (mu4e-message "Enter justme#gmail.com context"))
:leave-func
(lambda () (mu4e-message "Leave justme#gmail.com context"))
:match-func
(lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "afrancocorrea#gmail.com")))
:vars '((user-mail-address . "justme#gmail.com")
(user-full-name . "Me and myself")
(mu4e-drafts-folder . "/gmail/Borradores")
(mu4e-refile-folder . "/gmail/Archives")
(mu4e-sent-folder . "/gmail/Enviados")
(mu4e-trash-folder . "/gmail/Papelera")))))
;; gpg encryptiom & decryption:
;; this can be left alone
;;(require 'epa-file)
;;(epa-file-enable)
;;(setq epa-pinentry-mode 'loopback)
;;(auth-source-forget-all-cached)
;; don't keep message compose buffers around after sending:
(setq message-kill-buffer-on-exit t)
;; send function:
(setq send-mail-function 'sendmail-send-it
message-send-mail-function 'sendmail-send-it)
;; send program:
;; this is exeranal. remember we installed it before.
(setq sendmail-program (executable-find "msmtp"))
;; select the right sender email from the context.
(setq message-sendmail-envelope-from 'header)
;; chose from account before sending
;; this is a custom function that works for me.
;; well I stole it somewhere long ago.
;; I suggest using it to make matters easy
;; of course adjust the email adresses and account descriptions
(defun timu/set-msmtp-account ()
(if (message-mail-p)
(save-excursion
(let*
((from (save-restriction
(message-narrow-to-headers)
(message-fetch-field "from")))
(account
(cond
((string-match "justme#gmail.com" from) "gmail"))))
(setq message-sendmail-extra-arguments (list '"-a" account))))))
(add-hook 'message-send-mail-hook 'timu/set-msmtp-account)
;; mu4e cc & bcc
;; this is custom as well
(add-hook 'mu4e-compose-mode-hook
(defun timu/add-cc-and-bcc ()
"My Function to automatically add Cc & Bcc: headers.
This is in the mu4e compose mode."
(save-excursion (message-add-header "Cc:\n"))
(save-excursion (message-add-header "Bcc:\n"))))
;; mu4e address completion
(add-hook 'mu4e-compose-mode-hook 'company-mode)
;; store link to message if in header view, not to header query:
(setq org-mu4e-link-query-in-headers-mode nil)
;; don't have to confirm when quitting:
(setq mu4e-confirm-quit nil)
;; number of visible headers in horizontal split view:
(setq mu4e-headers-visible-lines 20)
;; don't show threading by default:
(setq mu4e-headers-show-threads nil)
;; hide annoying "mu4e Retrieving mail..." msg in mini buffer:
(setq mu4e-hide-index-messages t)
;; customize the reply-quote-string:
(setq message-citation-line-format "%N # %Y-%m-%d %H:%M :\n")
;; M-x find-function RET message-citation-line-format for docs:
(setq message-citation-line-function 'message-insert-formatted-citation-line)
;; by default do not show related emails:
(setq mu4e-headers-include-related nil)
;; by default do not show threads:
(setq mu4e-headers-show-threads nil)
(require 'rg)
(rg-enable-default-bindings)
;;; Basic configuration
(require 'hledger-mode)
;; To open files with .journal extension in hledger-mode
(add-to-list 'auto-mode-alist '("\\.journal\\'" . hledger-mode))
;; Personal Accounting
(global-set-key (kbd "C-c e") 'hledger-jentry)
(global-set-key (kbd "C-c j") 'hledger-run-command)
;; Provide the path to you journal file.
;; The default location is too opinionated.
(setq hledger-jfile "~/Documents/hledger/hledger.journal")
When installing ripgrep with brew, you're making it available for your computer on the command line, ie the terminal. It doesn't mean you told Emacs how to use it. For that you have to follow installation instruction from here.
The easiest solution would be to mimic the way it is done in your init.el for mu4e, ie :
1). download rg.el from the GitHub link of the installation instruction above
2). Place the file somewhere in your .emacs.d/ folder
3). Add the path to the rg.el file the same way it is done in your init.el for mu4e and the require 'rg
Doing this should fix your problem, but for a better understanding of Emacs configuration I recommend you look at System crafter's YouTube channel
I am trying following code:
(require-extension srfi-13)
(require-extension regex)
(print (string-substitute* "This is a test" '(("a test" . "NO TESTING ZONE" ) ) ) )
It works, with following output:
This is NO TESTING ZONE
But following does not work:
(print (string-substitute* "This is a test" '(("a test" . (string-append "NO " "TESTING") ) ) ) )
Following is the error:
Error: (string-substitute) bad argument type - not a string: (string-append "NO " "TESTING")
Even though, following shows that the output is indeed a string:
(print (string? (string-append "NO " "TESTING")))
#t
Where is the problem and how can this be solved?
This has nothing to do with string-substitute*.
You're quoting the list, so (string-append "NO " "TESTING") is not evaluated:
> '(("a test" . (string-append "NO " "TESTING")))
'(("a test" string-append "NO " "TESTING"))
Use quasiquote:
`(("a test" . ,(string-append "NO " "TESTING")
or don't quote at all:
(list (cons "a test" (string-append "NO " "TESTING"))
This works fine on the Mac, but when trying to set it up on Windows it didn't work.
I have msysGit Bash already on the windows path and tried setting as per other instructions.
(setq explicit-shell-file-name "bash")
(setq shell-file-name explicit-shell-file-name)
(setenv "SHELL" "bash")
(setq explicit-bash-args '("--noediting" "-i"))
(setq w32-quote-process-args ?\")
(setenv "PATH"
(concat ".:/usr/local/bin:/mingw/bin:/bin:"
(replace-regexp-in-string " " "\\\\ "
(replace-regexp-in-string "\\\\" "/"
(replace-regexp-in-string "\\([A-Za-z]\\):" "/\\1"
(getenv "PATH"))))))
I added
(setq debug-on-error t)
And re-ran the command M-x magit-version to get the output:
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
string-match("cmd\\.exe" nil)
(if (string-match "cmd\\.exe" tramp-encoding-shell) "/c" "-c")
eval((if (string-match "cmd\\.exe" tramp-encoding-shell) "/c" "-c"))
I then set
(setq tramp-encoding-shell explicit-shell-file-name)
And everything starts working properly.
Hey guys I need to see my ruby version and gemset name in emacs mode-line. Do you know how to do it?
Take a look at rvm.el. I provides many features that make the use of RVM from Emacs more enjoyable.
I tried but I can't custom strings to mode-line so I customize all of it.
;; modeline
(defun branch-name ()
(when vc-mode
(concat "\ue0a0 " (substring vc-mode 5))
))
(defun current-ruby ()
(when vc-mode
(replace-regexp-in-string "\n$" "" (shell-command-to-string "~/.rvm/bin/rvm-prompt"))
))
(setq-default mode-line-format
(list
"[" mode-line-modified "]"
" "
"%b"
" | "
'mode-name
" | "
'(:eval (projectile-project-name))
" "
'(:eval (branch-name))
" | "
'(:eval (current-ruby))
" | "
"%p (%l,%c)"
))
In emacs org-mode with iimage-mode enabled, it can show an inline image from a relative file path, like:
[[file:images/foo.jpg]]
What I want is: how can it shows an image locates in an zip archive, like this:
[[file:images.zip/foo.jpg]]
Is there a way to do this?
Rules for this to work:
If you have a zip file zippedimg.zip containing the image myimage.png, you should reference it in the org mode file as [[./zippedimg_zip/myimage.png]]. Note that I have replaced the . in zippedimg.zip to _.
The reason for doing so is that I am creating the same directory as mentioned within the [[ and ]]. But as the zippedimg.zip file exists, emacs does not allow creating a directory with the same name. So for zippedimg.zip file, I am extracting ONLY the image in it while preserving the path inside the zip into a zippedimg_zip directory.
Here is a mininum working org file to test it out:
#+TITLE: Image from archive
#+STARTUP: inlineimages
#+NAME: fig:myimage
#+HEADER: :extractfromarchive t
# The below caption line is optional
#+CAPTION: My image myimage.png inside ./zippedimg.zip
[[./zippedimg_zip/myimage.png]]
Here is the code you need to put somewhere in your emacs init:
;; Execute the `modi/org-include-img-from-archive' function just before saving the file
(add-hook 'before-save-hook #'modi/org-include-img-from-archive)
;; Execute the `modi/org-include-img-from-archive' function before processing the
;; file for export
(add-hook 'org-export-before-processing-hook #'modi/org-include-img-from-archive)
(defun modi/org-include-img-from-archive (&rest ignore)
"Extract image files from the archive files. Only .zip files are supported
as of now.
Only looks at #HEADER: lines that have \":extractfromarchive t\".
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)) ; go to the beginning of the buffer
(while (search-forward-regexp
"^\\s-*#\\+HEADER:.*\\s-:extractfromarchive\\s-+t"
nil :noerror)
(let (;; only .zip supported as of now
(search-expr "\\[\\[\\(.*?\\)_zip/\\(.*?\\)\\([^/]+\\..*\\)\\]\\]")
arc-file
path-in-arc-file
img-file img-file-full-path
dest-dir dest-dir-full-path
cmd)
;; Keep on going on to the next line till it finds a line with
;; `[[./path/to/zip-file/path/inside/zip/to/the/image]]'
(while (progn
(forward-line 1)
(or (not (looking-at search-expr))
(eobp))))
(when (looking-at search-expr)
(setq arc-file (expand-file-name
(concat (match-string-no-properties 1) ".zip")))
(setq path-in-arc-file (match-string-no-properties 2))
(setq img-file (match-string-no-properties 3))
(setq dest-dir (concat "./" (file-name-base arc-file)
"_zip/" path-in-arc-file))
(setq dest-dir-full-path (concat (file-name-sans-extension arc-file)
"_zip/" path-in-arc-file))
(setq img-file-full-path (expand-file-name img-file dest-dir))
;; (message (concat "arc-file: %s\npath-in-arc-file: %s\n"
;; "img-file: %s\nimg-file-full-path: %s\n"
;; "dest-dir: %s\ndest-dir-full-path: %s")
;; arc-file path-in-arc-file
;; img-file img-file-full-path
;; dest-dir dest-dir-full-path)
(when (file-newer-than-file-p arc-file img-file-full-path)
;; This block is executed only if arc-file is newer than
;; img-file-full-path
;; or if img-file does not exist
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Testing-Accessibility.html
(when (file-exists-p dest-dir-full-path)
(delete-directory dest-dir-full-path t t))
(make-directory dest-dir-full-path t)
(setq cmd (format "unzip -j %s %s%s -d ./%s."
arc-file path-in-arc-file img-file
(concat (file-name-base arc-file) "_zip/"
path-in-arc-file)))
(message "%s" cmd)
(shell-command cmd)
(shell-command (concat "touch " img-file-full-path)))))))))
thanks kaushalmodi,
below is what I did, by following the answer in this question how to display pdf images in org mode. As this is the first time I do lisp programming, the code maybe not well designed.
(add-hook 'org-mode-hook #'modi/org-include-img-from-zip)
(defun modi/org-include-img-from-zip (&rest ignore)
"extract images from zip an archive.
This function does nothing if not in org-mode."
(interactive)
(when (derived-mode-p 'org-mode)
(save-excursion
(goto-char (point-min))
(while (search-forward-regexp
"^\\s-*#\\+STARTUP:.*\\s-convertfromzip"
nil 'noerror)
(let* (filenoext imgext imgfile imgfilename zipfile imgpath cmd)
(setq zipfile "arc.zip")
;; Keep on going on to the next line till it finds a line with
;; `[[FILE]]'
(while (progn
(forward-line 1)
(not (looking-at "\\[\\[\\(.*\\)\\.\\(.*\\)\\]\\]"))))
(when (looking-at "\\[\\[file:\\(.*\\)\\.\\(.*\\)\\]\\]")
(setq filenoext (match-string-no-properties 1))
(setq imgext (match-string-no-properties 2))
(setq imgpath (concat filenoext "." imgext))
(setq imgfile (expand-file-name (concat filenoext "." imgext)))
(setq imgfilename (file-name-nondirectory imgfile))
(when (string= (substring imgpath 0 1) "~")
(setq imgpath (concat "%HOME%" (substring imgpath 1 nil)))
(setq imgpath (file-name-directory imgpath))
(setq cmd (concat "7z e " zipfile " -y -o"imgpath " " imgfilename " " imgfilename ))
(with-temp-buffer (shell-command cmd t))
)
))))))