.emacs .txt file visual-line-mode simultaneously with muse-mode - emacs

I indicate my muse-mode files (usually named with .txt suffix) as being muse-mode by starting them with a "#title". To do this, I have
;; muse-mode on *.txt files, if a #title or sect. header is on top 4 lines
(add-hook 'text-mode-hook
(lambda ()
(unless (or (eq major-mode 'muse-mode)
(not (stringp buffer-file-truename)))
(when (equal (file-name-extension buffer-file-truename) "txt")
(save-excursion
(goto-line 5)
(if (re-search-backward "\* [A-Z][a-z]+.*\\|#title " 1 t)
(muse-mode)))))))
If I also have
(add-to-list 'auto-mode-alist '("\\.txt$" . visual-line-mode))
in the .emacs (following the code above), then muse-mode no longer works. Though if I invoke visual-line-mode with Meta-x from within emacs on a muse file, it doesn't mess things up.
Ideally, I would like to have visual-line-mode working on all .txt files, but without messing up muse. Or else, I would like to start all .txt files in visual-line-mode except when they are muse files.

The variable 'auto-mode-alist chooses the major mode.
visual-line-mode is a minor mode, and by adding it to the 'auto-mode-alist you're making it act like a major mode, which replaces the text-mode you were starting with.
Instead, add turn-on-visual-line-mode-in-txt to the text-mode-hook like so:
(add-hook `text-mode-hook 'turn-on-visual-line-mode)
(defun turn-on-visual-line-mode-in-txt ()
(when (and (buffer-file-name)
(string-match ".txt$" (buffer-file-name)))
(turn-on-visual-line-mode)))
For more information on the differences, read the manual for major and minor modes.

I think #treyJackson identified the problem, but here are some extra comments:
BTW, your use of a text-mode-hook to switch to muse-mode will misbehave in various circumstances (because you first switch to text-mode, then halfway through you activate muse-mode, after which the end of the text-mode activation (usually, not much left to do, but there could be more functions on the text-mode-hook to run) will still be performed). A more robust approach might be to do:
(add-to-list 'auto-mode-alist '("\\.txt\\'" . text-or-muse-mode))
(defun text-or-muse-mode ()
(if (save-excursion
(goto-line 5)
(re-search-backward "\\* [A-Z][a-z]+.*\\|#title " 1 t))
(muse-mode)
(text-mode)))
Of course, you could also use a -*- muse -*- on the first line, or rely on magic-mode-alist instead.

Related

How to turn filenames with line numbers into hyperlinks?

I am novice emacs user, and currently i am trying to set up work environment for python. I am using rope, but has come across the following: although rope's "Find occurences" command works fine, its result are put in a modeless buffer, and to access them i must copy file names.
Buffer contents are here
As far as i can tell, closes functionality to what i want (that is, opening a file on a given line after clicking on it or pressing RET) is provided by compilation-mode. However, as things are, enabling compilation-mode only causes highlighting of the filenames.
If i undestand correctly, to process lines i need to provide items into compilation-error-regexp-alist, like it is done in following snippet (from emacs wiki
(require 'compile)
(let ((symbol 'compilation-ledger)
(pattern '("^Error: \"\\([^\"\n]+?\\)\", line \\([0-9]+\\):" 1 2)))
(cond ((eval-when-compile (boundp 'compilation-error-regexp-systems-list))
;; xemacs21
(add-to-list 'compilation-error-regexp-alist-alist
(list symbol pattern))
(compilation-build-compilation-error-regexp-alist))
((eval-when-compile (boundp 'compilation-error-regexp-alist-alist))
;; emacs22 up
(add-to-list 'compilation-error-regexp-alist symbol)
(add-to-list 'compilation-error-regexp-alist-alist
(cons symbol pattern)))
(t
;; emacs21
(add-to-list 'compilation-error-regexp-alist pattern))))
How should i modify it to make it work with my buffer?
Are there better/quicker alternatives?
Generally, the quickest way to open a file when its name is displayed in a buffer is
M-x ffap
(short for M-x find-file-at-point)
If you want to open the file automatically, you could define your own function:
(defun open-file-at-point ()
(interactive)
(let ((file (ffap-file-at-point)))
(if file
(find-file file)
(error "No file at point"))))
and maybe bind it to a key with
(global-set-key (kbd "C-<return>") 'open-file-at-point)
If you want to use compilation-mode, you will have to add a matching regexp to compilation-error-regexp-alist(-alist). For your example, the following seems to work:
(add-to-list
'compilation-error-regexp-alist
'python-file-name)
(add-to-list
'compilation-error-regexp-alist-alist
(list
'python-file-name
(concat "\\(?1:.*?\\)" ;; file name
" : " ;; seperator
"\\(?2:[[:digit:]]+\\)") ;; line number
1 2)) ;; subexpr 1 is the file name, subexp 2 is the line number

How do I display ANSI color codes in emacs for any mode?

I have a log file that uses ANSI escape color codes to format the text. The mode is fundamental. There are other answered questions that address this issue but I'm not sure how to apply it to this mode or any other mode. I know the solution has something to do with configuring ansi-color in some way.
ANSI codes in shell mode
ANSI codes in gdb mode
You could use code below
(require 'ansi-color)
(defun display-ansi-colors ()
(interactive)
(ansi-color-apply-on-region (point-min) (point-max)))
Then you can execute display-ansi-colors via M-x, via a key-binding of your choosing, or via some programmatic condition (maybe your log files have a extension or name that matches some regexp)
If you want to do this with read-only buffers (log files, grep results), you may use inhibit-read-only, so the function will be:
(defun display-ansi-colors ()
(interactive)
(let ((inhibit-read-only t))
(ansi-color-apply-on-region (point-min) (point-max))))
User defined function:
(defun my-ansi-color (&optional beg end)
"Interpret ANSI color esacape sequence by colorifying cotent.
Operate on selected region on whole buffer."
(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(list (point-min) (point-max))))
(ansi-color-apply-on-region beg end))
For buffers that uses comint/compilation use filter:
(ignore-errors
(require 'ansi-color)
(defun my-colorize-compilation-buffer ()
(when (eq major-mode 'compilation-mode)
(ansi-color-apply-on-region compilation-filter-start (point-max))))
(add-hook 'compilation-filter-hook 'my-colorize-compilation-buffer))
Gavenkoa's and Juanleon's solutions worked for me, but were not satisfying as they were modifying the contents of the file I was reading.
To colorize without modifying the contents of the file, download tty-format.el and add the following to your .emacs:
(add-to-list 'load-path "path/to/your/tty-format.el/")
(require 'tty-format)
;; M-x display-ansi-colors to explicitly decode ANSI color escape sequences
(defun display-ansi-colors ()
(interactive)
(format-decode-buffer 'ansi-colors))
;; decode ANSI color escape sequences for *.txt or README files
(add-hook 'find-file-hooks 'tty-format-guess)
;; decode ANSI color escape sequences for .log files
(add-to-list 'auto-mode-alist '("\\.log\\'" . display-ansi-colors))
tty-format is based on ansi-color.el which is only shipped natively with recent versions of emacs.
On large files, performance of ansi-color-apply-on-region is slow. Here's a solution that colors the current region and works with read-only buffers.
(require 'ansi-color)
(defun ansi-color-region ()
"Color the ANSI escape sequences in the acitve region.
Sequences start with an escape \033 (typically shown as \"^[\")
and end with \"m\", e.g. this is two sequences
^[[46;1mTEXT^[[0m
where the first sequence says to diplay TEXT as bold with
a cyan background and the second sequence turns it off.
This strips the ANSI escape sequences and if the buffer is saved,
the sequences will be lost."
(interactive)
(if (not (region-active-p))
(message "ansi-color-region: region is not active"))
(if buffer-read-only
;; read-only buffers may be pointing a read-only file system, so don't mark the buffer as
;; modified. If the buffer where to become modified, a warning will be generated when emacs
;; tries to autosave.
(let ((inhibit-read-only t)
(modified (buffer-modified-p)))
(ansi-color-apply-on-region (region-beginning) (region-end))
(set-buffer-modified-p modified))
(ansi-color-apply-on-region (region-beginning) (region-end))))
The one downside is that ansi-color-apply-on-region removes the ANSI escape sequence characters from the buffer, so when you save, they are lost. I wonder if there's a way to hide the characters instead of stripping them?

Emacs: Best-practice for lazy loading modes in .emacs?

Is there a best practice around lazily loading modes when encountering a relevant file extension?
At this point I have roughly 25 different Emacs modes installed, and startup has become slow. For example, although it's great to have clojure-mode at the ready, I rarely use it, and I want to avoid loading it at all unless I open a file with extension .clj. Such a "lazy require" functionality seems like the right way do mode configuration in general..
I found nothing online, so I've taken a crack at it myself.
Instead of:
(require 'clojure-mode)
(require 'tpl-mode)
I have this:
(defun lazy-require (ext mode)
(add-hook
'find-file-hook
`(lambda ()
(when (and (stringp buffer-file-name)
(string-match (concat "\\." ,ext "\\'") buffer-file-name))
(require (quote ,mode))
(,mode)))))
(lazy-require "soy" 'soy-mode)
(lazy-require "tpl" 'tpl-mode)
This seems to work (I'm an elisp newbie so comments are welcome!), but I'm unnerved about finding nothing written about this topic online. Is this a reasonable approach?
The facility you want is called autoloading. The clojure-mode source file, clojure-mode.el, includes a comment for how to arrange this:
;; Add these lines to your .emacs:
;; (autoload 'clojure-mode "clojure-mode" "A major mode for Clojure" t)
;; (add-to-list 'auto-mode-alist '("\\.clj$" . clojure-mode))
This is one way,
(provide 'my-slime)
(eval-after-load "slime"
'(progn
(setq slime-lisp-implementations
'((sbcl ("/usr/bin/sbcl"))
(clisp ("/usr/bin/clisp")))
common-lisp-hyperspec-root "/home/sujoy/documents/hyperspec/")
(slime-setup '(slime-asdf
slime-autodoc
slime-editing-commands
slime-fancy-inspector
slime-fontifying-fu
slime-fuzzy
slime-indentation
slime-mdot-fu
slime-package-fu
slime-references
slime-repl
slime-sbcl-exts
slime-scratch
slime-xref-browser))
(slime-autodoc-mode)
(setq slime-complete-symbol*-fancy t)
(setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol)
(add-hook 'lisp-mode-hook (lambda () (slime-mode t)))))
(require 'slime)
along with,
;; slime mode
(autoload 'slime "my-slime" "Slime mode." t)
(autoload 'slime-connect "my-slime" "Slime mode." t)

How to run hook depending on file location

I am involved in python project where tabs are used, however i am not using them in every other code i write, it is vital to use them in that particular project. Projects are located in one directory under specific directories. I.E:
\main_folder
\project1
\project2
\project3
...etc
I have couple functions/hooks on file open and save that untabify and tabify whole buffer i work on.
;; My Functions
(defun untabify-buffer ()
"Untabify current buffer"
(interactive)
(untabify (point-min) (point-max)))
(defun tabify-buffer ()
"Tabify current buffer"
(interactive)
(tabify (point-min) (point-max)))
;; HOOKS
; untabify buffer on open
(add-hook 'find-file-hook 'untabify-buffer)
; tabify on save
(add-hook 'before-save-hook 'tabify-buffer)
If i put it in .emacs file it is run on every .py file i open which is not what i want. What i`d like to have is to have these hooks used only in one particular folder with respective subfolders. Tried .dir_locals but it works only for properties not hooks. I can not use hooks in specific modes (i.e. python-mode) as almost all projects are written in python. To be honest i tried writing elisp conditional save but failed.
A very easy solution is to just add a configuration variable that can be used to disable the hooks. For example:
(defvar tweak-tabs t)
(add-hook 'find-file-hook
(lambda () (when tweak-tabs (untabify (point-min) (point-max)))))
(add-hook 'before-save-hook
(lambda () (when tweak-tabs (tabify (point-min) (point-max)))))
Now you can add a .dir-locals.el file in the relevant directories, setting tweak-tabs to nil, disabling this feature there.
(But another problem is that this is a pretty bad way to deal with tabs. For example, after you save a file you do see the tabs in it.)
Just for the record, to answer the literal question in the title (as I reached this question via a web search): one way to add a hook that depends on file location is to make it a function that checks for buffer-file-name. (Idea from this answer.)
For example, for the exact same problem (turn on tabs only in a particular directory, and leave tabs turned off elsewhere), I'm currently doing something like (after having installed the package smart-tabs-mode with M-x package-install):
(smart-tabs-insinuate 'python) ; This screws up all Python files (inserts tabs)
(add-hook 'python-mode-hook ; So we need to un-screw most of them
(lambda ()
(unless (and (stringp buffer-file-name)
(string-match "specialproject" buffer-file-name))
(setq smart-tabs-mode nil)))
t) ; Add this hook to end of the list
(This is a bit inverted, as smart-tabs-insinuate itself modifies python-mode-hook and then we're modifying it back, but it should do as an example.)

Emacs: Tab completion of file name appends an extra i:\cygwin

I am facing some strange behavior with file-name completion in emacs. C-x C-f to find file opens up the minibuffer with i:/cygwin/home/rrajagop/StockScreener/working_copy/master_repo/stock_screener/. Hitting a TAB makes it i:/cygwini:/cygwin/home/rrajagop/StockScreener/working_copy/master_repo/stock_screener/. A couple of interesting things I've noticed:
When the minibuffer opens up, i:/cygwin is greyed out and the path seems to start from /home. A C-a (go to begining of line) takes me to /home and not to i:/cygwin. So it looks like something in emacs is parsing the path to start from /home and not from i:/cygwin.
I checked that TAB runs minibuffer-complete from minibuffer.el (by doing a describe-key for TAB), so it looks like minibuffer-complete is doing some translation for cygwin and appending the extra i:/cygwin.
How would I go about figuring this out/fixing it?
EDIT: Extra Information
I tried opening up emacs with -Q and this problem doesn't happen. So this is something I'm loading in my .emacs. This is what I have in my .emacs
(require 'cl)
; Needed to see how fast Emacs loads. Loading time is printed at the
; and of the execution of .emacs file.
(defvar *emacs-load-start* (current-time))
; I really like this font. I also tried Monaco which you can
; see on lot of Railscasts but I couldn't find the one which
; supports Serbian Cyrillic and Latin letters.
(set-default-font "-outline-Courier New-normal-r-normal-normal-19-142-96-96-c-*-iso8859-1")
;; Don't show that splash screen
(setq inhibit-startup-message t)
; This should allegedly speed up Emacs starting by preventing
; some requests from the window manager back to the Emacs. Frankly
; speaking I didn't notice some speed up but I still keep it:(
(modify-frame-parameters nil '((wait-for-wm . nil)))
;Allows syntax highlighting to work, among other things
(global-font-lock-mode 1)
; Sets initial window position
(set-frame-position (selected-frame) 0 0)
; Sets initial window size to 85 columns and 47 rows
(set-frame-size (selected-frame) 88 32)
; Makes last line ends in carriage return
(setq requre-final-newline t)
; Sets Ctrl-x / key combination for easy commenting
; out of selected lines.
(global-set-key "\C-x/" 'comment-or-uncomment-region)
; Allow resizing of the mini-buffer when necessary
(setq resize-minibuffer-mode t)
; Auto magically read compressed files
(auto-compression-mode 1)
; Set standard indent to 2 rather then 4
(setq standard-indent 2)
; This tells Emacs to create backup files.
(setq make-backup-files t)
; And this will enable versioning with default values.
(setq version-control t)
; Remove annoying message about deleting excess backup of .recentf
; which is list of recent files used
(setq delete-old-versions t)
; Finally do not spread backups all over the disk.
; Just save all backup files in this directory.
(setq backup-directory-alist (quote ((".*" . "~/.emacs_backups/"))))
;; Directory to put various el files.
(add-to-list 'load-path "~/.emacs.d/includes")
(require 'ascii-table)
;; Loading collection of generic modes for different languages
(require 'generic-x)
;; Recent files
(require 'recentf)
(recentf-mode 1)
;; Loads ruby mode when a ruby file is opened.
(autoload 'ruby-mode "ruby-mode" "Major mode for editing ruby scripts." t)
(setq auto-mode-alist (cons '(".rb$" . ruby-mode) auto-mode-alist))
(setq auto-mode-alist (cons '(".rhtml$" . html-mode) auto-mode-alist))
(setq auto-mode-alist (cons '(".html.erb$" . html-mode) auto-mode-alist))
;; Turn on ruby electric (auto completion of parenthesis, etc.)
(add-hook 'ruby-mode-hook
(lambda()
(add-hook 'local-write-file-hooks
'(lambda()
(save-excursion
(untabify (point-min) (point-max))
(delete-trailing-whitespace) )))
(set (make-local-variable 'indent-tabs-mode) 'nil)
(set (make-local-variable 'tab-width) 2)
(imenu-add-to-menubar "IMENU")
(define-key ruby-mode-map "\C-m" 'newline-and-indent)
(require 'ruby-electric)
(ruby-electric-mode t) ))
;; Ruby debugging.
(add-to-list 'load-path "~/.emacs.d/plugins/rdebug")
(autoload 'rdebug "rdebug" "Ruby debugging support." t)
(global-set-key [f9] 'gud-step)
(global-set-key [f10] 'gud-next)
(global-set-key [f11] 'gud-cont)
(global-set-key "\C-c\C-d" 'rdebug)
;; set compile command based on current major mode
(autoload 'mode-compile "mode-compile"
"Command to compile current buffer file based on the major mode" t)
(global-set-key "\C-cc" 'mode-compile)
(autoload 'mode-compile-kill "mode-compile"
"Command to kill a compilation launched by `mode-compile'" t)
(global-set-key "\C-ck" 'mode-compile-kill)
;; yasnippet - adding code snippet insertion
(add-to-list 'load-path "~/.emacs.d/plugins/yasnippet")
(require 'yasnippet) ;; not yasnippet-bundle
(yas/initialize)
(yas/load-directory "~/.emacs.d/plugins/yasnippet/snippets")
;; Use CYGWIN bash
(require 'setup-cygwin)
;; Subversion integration via psvn - not gonna use svn anymore
;; (require 'psvn)
;; add some elisp tutorials to the info directory
(let ((info-root (concat usb-drive-letter "cygwin/usr/local/bin/emacs/info/")))
(setq Info-directory-list (list info-root
(concat info-root "elisp-tutorial-2.04/")
(concat info-root "emacs-lisp-intro-2.14")) )
)
;; Load time for .emacs - this should be the last line in .emacs for accurate load time
(message "ido and org-install took: %ds"
(destructuring-bind (hi lo ms) (current-time)
(- (+ hi lo) (+ (first *emacs-load-start*) (second *emacs-load-start*)) )))
I think my answer to your previous question on finding the package loading tramp will help you out here.
you can control tramp by changing the variable tramp-mode.
Side note, you would probably find it useful to use customize to customize emacs.
I did a customize-apropos with tramp and it found the tramp group. Clicking there showed all the ways to configure tramp, including turning it off.
File-name-shadow-mode greys out the c: in the file name..... so when cygwin-mount-substitute-longest-mount-name runs it does no see the c: and adds another
M-x find-file
c:/home/
> a
c:/home/a ; but the c: is greyed
> TAB
c:c:/home/anything