Emacs Rocks
emacsrocks.com
emacsrocks.com
One note, if you do clone the repo, make sure to use the --recursive option (as the readme instructs) since there are a bunch of other git repositories imported in the repo.
https://github.com/bbatsov/prelude
That is, even if you didn't want to use it outright for your config, prelude's init.el and modules are a good resource for learning how to wire things together with Emacs Lisp.
Doing this, you can tell that this guy really doesn't care for the Emacs package-repositories :)
http://webcache.googleusercontent.com/search?q=cache:http://...
NOTE: The Emacs tutorial has lots of weird terms: "Meta key", "frame", "buffer". This is because Emacs started a LONG time ago. Don't worry, you'll get the hang of it with practice.
I have no idea why we make people jump through the hoops of learning archaic terminology, rather than evolving the software to use the terms people actually use today.
The Meta key is called the "Meta key" because that's the label that was on the keyboards of the Lisp machines in the MIT AI lab when Emacs was first developed. It's been thirty-plus years since that key was found on anything close to a significant fraction of keyboards in use in the world. There's no evidence that it's ever going to make a roaring comeback, either.
In other words, the Meta key, as a key, is dead and gone. It is literally as dead as disco! And yet the name persists, even though the way people have interacted with the "Meta key" for decades has been to press a key labeled something other than "Meta."
So: why hang on to a dead word? It serves no practical purpose, and does active harm by confusing people new to the editor.
But no, rather than update our terminology so it bears some resemblance to the world we actually live in, we hang on to it and tell newcomers that to learn Emacs they're just going to have to get used to pretending they're working on a space-cadet keyboard, because that's The Way It Has Always Been Done. Sigh.
And the window/frame term swap is only one of many such examples. So basically, you could make your own Emacs that uses modern terminology and is completely incompatible with all existing 3rd-party elisp code, and then you could try to convince people to switch to it. But would having two equivalent but fundamentally incompatible Emacs/elisp variants be beneficial to Emacs as a whole? I doubt it.
Emacs has a lot of hurdles in front of it: niche extension language, huge volume of customization before it becomes usable for your average Notepad++/Sublime user, etc., why add confusing documentation and naming on top of it?
The cost is huge, but IMO it is worth paying. It is a one time cost (refactoring, updating the documentation and many/most extensions) which could open Emacs to a much larger audience.
I left text editors for a few years (buried in Eclipse) but came back recently for Haskell and Go, and the community is ON FIRE. So much good stuff now: Melpa, flycheck, magit.
PS: "Meta" is fine. There's no standard "Alt" key anyway. On Mac, meta is often the "option" key but not always. It helps that Emacs has it's own term when switching between Windows, Mac, VNC of either, terminal, etc.
Multiple-cursors looks amazing.
Because it doesn't refer to a key. It's more of a identifier. It would be considerably more confusing to substitute whatever key you think it should be. Cmd? Alt? Opt? Esc?
When I see "M-" in the literature, I know what that means and translate it to the relevant keystrokes. For instance, M-x for me is actually "C-[ x". I've customized it that way. However, we have a lingua franca for communicating commands despite the personalizations.
Similarly: there is no particularly good reason to use the term "lambda" for anonymous function constructs --- its use traces back to a typesetting quirk of Alonzo Church's. But here we are today, typing "lambda" like a bunch of chumps. :)
You have your cause and effect backwards. TL;DR: The Lispm's bucky keyboard simply extended existing practice.
Emacs predates the Lisp machines (CADRs in this case), and was originally written in TECO. Originally escape escape would open and close a minibuffer in which you could simply enter raw TECO. The Knight TV system had a custom keyboard used by us at MIT AI (and at Stanford AI for their own, slightly different TV system) had a Meta key which was used to invoke the minubuffer with a single keystroke (meta-altmode, mapped to escape when using ASCII) which later turned into direct "long" commands (M-X commands) and a wider keyspace.
In those days most programs on the PDP-6 & PDP-10 used six or seven bit bytes (though byte pointers could stride by 1-18 bit bytes) but the KTV was built on a PDP-11 which had 8 bit bytes, so meta was trivially available. FWIW the PDP-11 was memory mapped into the 36-bit PDP-6 through an arcane process I have thankfully forgotten.
Disco lives on as house music, which has influenced current pop music so much it's scary. Disco didn't die, it just went underground. Like every other cultural phenomenon, it has its subcultures and offshoots. I could play you music released in the last year that you would probably think was released in the late sixties.
I've been meaning to dig deeper, and things like this site are a great way to whet my appetite.
I'm not a C++ programmer, but I turned up the following guide with a Google search, which might you might find interesting:
C/C++ Development Environment for Emacs
On the bad side, you'll have to spend time tweaking packages and so on to get IDE-similar goodies like autocomplete. I can't remember if there's a similar thing as a background compilation that highlight errors as you type. But the thing with emacs is that if you wonder about a plugin, there'a good chance it exists already.
Check out Flycheck: http://flycheck.readthedocs.org/en/latest/
I use unobtrusive dabbrev-style completion --- I don't want popup menus with completion possibilities drawn from documentation, because Dash.app does a better job of that and is shared by all applications.
I think Emacs does an at least adequate job at all the core functions of Xcode, but does some things Xcode can't do at all.
(It's been a few years since I've written more than a couple thousands lines in Xcode, though.)
Have I just never configured ctags correctly?
Which is a shame, because Xcode's text editor is awful (or did I mention that already??), and Visual Studio's is crashingly average. I'd much rather use emacs.
(I use company-mode, with the clang backend, and it's OK. For code navigation, currently nothing, but rtags (https://github.com/Andersbakken/rtags) is on my todo list. The README is worth a skim - it has a cute way of grabbing the list of files you're using.)
Emacs allows you to jump to anything instantly, even with source tree like Clang or Linux.
- Powerful automatic indentation: https://raw.githubusercontent.com/Bruce-Connor/aggressive-in.... It does not only indent the current line, but the whole Semantic context around your cursor.
- Live grep: http://tuhdo.github.io/static/live_grep.gif
- Access to a list of project with a few key strokes: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Quickly access any file in your project, as large as Linux kernel, instantly, regardless of where you are in the project, and within a few keystrokes: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Jump to any file depends on context, even if the file path is in a plain ASCII text file: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Copy files from anywhere to anywhere: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Delete files anywhere; files are always at your finger tip to do whatever with them: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Switch between other files with same names but different extensions: http://tuhdo.github.io/static/helm-projectile/helm-projectil.... Work not only for C/C++ but other languages, and is customizable. You don't have to configure anything, like adding include paths for the command to search. Everything is automatic. Just use it as it is.
- Jump to tag definition, from Emacs's own parser or external parser like GNU Global: http://tuhdo.github.io/static/c-ide/helm-gtags-jump-dwim.gif
- Jump to any definition from a list of definitions in source tree, even for Linux kernel: http://tuhdo.github.io/static/c-ide/helm-gtags-select.gif
- Jump up to parent: http://tuhdo.github.io/static/c-ide/senator-go-to-up-referen....
- Do you like outline tree?: http://tuhdo.github.io/static/c-ide/sr-speedbar.gif
- Interactive outline tree: http://tuhdo.github.io/static/c-ide/helm-semantic-or-imenu-w....
- Easily move back and forth using the interactive outline tree: http://tuhdo.github.io/static/part3/helm-semantic-or-imenu-2....
- References retrieved from its Emacs internal parser: http://tuhdo.github.io/static/c-ide/semantic-symref.gif.
- Beautiful compile output: http://tuhdo.github.io/static/c-ide/compilation-compile.gif
- Frontend support for GDB: http://tuhdo.github.io/static/c-ide/gdb-many-windows.gif
- Code completion: http://tuhdo.github.io/static/c-ide/semantic-boost-demo.gif.
- Open man page for symbol at cursor: http://tuhdo.github.io/static/part3/helm-man-woman.gif.
- Emacs open 39MB C file: http://tuhdo.github.io/static/performance.gif
- Emac opens multi-gigabtye file: http://www.emacswiki.org/VLF
- Emacs is a bit torrent client: https://bitbucket.org/ukaszg/aria2-mode/
You can see more demos in:
+ Emacs Mini Manual: http://tuhdo.github.io/emacs-tutor.html + C/C++ Development Environment for Emacs: http://tuhdo.github.io/c-ide.html + A Package in a league of its own: Helm: http://tuhdo.github.io/helm-intro.html + Exploring large projects with Projectile and Helm Projectile: http://tuhdo.github.io/helm-projectile.html
Note that in the demos you may see me type in the commands. You can think of it like the start menu in Windows, but actually those commands can be executed quickly with a shortcut. I type in the commands for demonstration purpose to Emacs users.
Those demos are just tip of the iceberg.
If you write C++, did you check my C/C++ guide: http://tuhdo.github.io/c-ide.html. Aside from refactoring, you have mostly everything like:
- code navigation: jump to anywhere instantly. DEMO: http://tuhdo.github.io/static/c-ide/helm-gtags-jump-dwim.gif.
- code completion: context-sensitve completion. DEMO: http://tuhdo.github.io/static/c-ide/semantic-boost-demo.gif.
- code compilation: you can click on the error and it gets you to where you want; work with any build system, while other IDE only supports a specific build system, i.e. for Makefile project, you only get plain text error message. DEMO: http://tuhdo.github.io/static/c-ide/compilation-mode.gif.
- code debugging: provides a frontend for GDB; DEMO: http://tuhdo.github.io/static/c-ide/gdb-many-windows.gif.
- Powerful automatic indentation: https://github.com/Bruce-Connor/aggressive-indent-mode. It does not only indent the current line, but the whole Semantic context around your cursor. Demos inside the homepage.
- Live grep: http://tuhdo.github.io/static/live_grep.gif.
- Access to a list of project with a few key strokes: http://tuhdo.github.io/static/helm-projectile/helm-projectil...
- Quickly access any file in your project, as large as Linux kernel, instantly, regardless of where you are in the project, and within a few keystrokes: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Jump to any file depends on context, even if the file path is in a plain ASCII text file: http://tuhdo.github.io/static/helm-projectile/helm-projectil...
- Copy files from anywhere to anywhere: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Delete files anywhere; files are always at your finger tip to do whatever with them: http://tuhdo.github.io/static/helm-projectile/helm-projectil....
- Switch between other files with same names but different extensions: http://tuhdo.github.io/static/helm-projectile/helm-projectil.... Work not only for C/C++ but other languages, and is customizable. You don't have to configure anything, like adding include paths. Everything is automatically done for you.
- Jump to tag definition, from its own parser or external parser like GNu Global: http://tuhdo.github.io/static/c-ide/helm-gtags-jump-dwim.gif
- Jump up to parent: http://tuhdo.github.io/static/c-ide/senator-go-to-up-referen....
- Do you like outline tree?: http://tuhdo.github.io/static/c-ide/sr-speedbar.gif
- Interactive outline tree: http://tuhdo.github.io/static/c-ide/helm-semantic-or-imenu-w...
- Easily move back and forth using the interactive outline tree: http://tuhdo.github.io/static/part3/helm-semantic-or-imenu-2...
- References retrieved from its Emacs internal parser: http://tuhdo.github.io/static/c-ide/semantic-symref.gif.
- Beautiful compile output: http://tuhdo.github.io/static/c-ide/compilation-compile.gif
- Frontend support for GDB: http://tuhdo.github.io/static/c-ide/gdb-many-windows.gif
- Open man page for symbol at cursor: http://tuhdo.github.io/static/part3/helm-man-woman.gif.
- Emacs open 39MB C file: http://tuhdo.github.io/static/performance.gif
- Emac opens multi-gigabtye file: http://www.emacswiki.org/VLF
;)
- Prelude (for those who want to learn Emacs): https://github.com/bbatsov/prelude
- Spacemacs (for long time Vim users): https://github.com/syl20bnr/spacemacs
Warning (initialization): An error occurred while loading `c:/Users/swah/.emacs':
Wrong type argument: listp, 769
To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file. Start Emacs with
the `--debug-init' option to view a complete error backtrace.
That .emacs file contains only has two lines: (defvar emacs-root (expand-file-name "~/Dropbox/dotfiles/emacs/"))
(load-file "~/Dropbox/dotfiles/emacs/init.el")
So I did M-x toggle-debug-on-error and reloaded init.el manually.. Then I took a look at the Messages buffer: Debugger entered--Lisp error: (wrong-type-argument listp 769)
memq(&rest 769)
(if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))
(let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist))))
(if (subrp function) (let ((max (cdr (subr-arity function)))) (if (eq (quote many) max) most-positive-fixnum max)) (if (eq (quote macro) (car-safe function)) (setq function (cdr function))) (let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))))
magit-max-args-internal(delete-directory)
(>= (magit-max-args-internal (quote delete-directory)) 2)
(if (>= (magit-max-args-internal (quote delete-directory)) 2) (defalias (quote magit-delete-directory) (quote delete-directory)) (defun magit-delete-directory (directory &optional recursive) "Deletes a directory named DIRECTORY. If RECURSIVE is non-nil,\nrecursively delete all of DIRECTORY's contents as well.\n\nDoes not follow symlinks." (if (or (file-symlink-p directory) (not (file-directory-p directory))) (delete-file directory) (if recursive (dolist (file (directory-files directory (quote full) "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) (magit-delete-directory file recursive))) (delete-directory directory))))
(progn (defun magit-max-args-internal (function) "Returns the maximum number of arguments accepted by FUNCTION." (if (symbolp function) (setq function (symbol-function function))) (if (subrp function) (let ((max (cdr (subr-arity function)))) (if (eq (quote many) max) most-positive-fixnum max)) (if (eq (quote macro) (car-safe function)) (setq function (cdr function))) (let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))))) (if (functionp (quote start-file-process)) (defalias (quote magit-start-process) (quote start-file-process)) (defalias (quote magit-start-process) (quote start-process))) (unless (fboundp (quote string-match-p)) (defun string-match-p (regexp string &optional start) "Same as `string-match' except this function does not\nchange the match data." (let ((inhibit-changing-match-data t)) (string-match regexp string start)))) (if (fboundp (quote with-silent-modifications)) (defalias (quote magit-with-silent-modifications) (quote with-silent-modifications)) (defmacro magit-with-silent-modifications (&rest body) "Execute body without changing `buffer-modified-p'. Also, do not\nrecord undo information." (\` (set-buffer-modified-p (prog1 (buffer-modified-p) (let (... before-change-functions after-change-functions) (\,@ body))))))) (if (>= (magit-max-args-internal (quote delete-directory)) 2) (defalias (quote magit-delete-directory) (quote delete-directory)) (defun magit-delete-directory (directory &optional recursive) "Deletes a directory named DIRECTORY. If RECURSIVE is non-nil,\nrecursively delete all of DIRECTORY's contents as well.\n\nDoes not follow symlinks." (if (or (file-symlink-p directory) (not (file-directory-p directory))) (delete-file directory) (if recursive (dolist (file (directory-files directory ... "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) (magit-delete-directory file recursive))) (delete-directory directory)))))
eval((progn (defun magit-max-args-internal (function) "Returns the maximum number of arguments accepted by FUNCTION." (if (symbolp function) (setq function (symbol-function function))) (if (subrp function) (let ((max (cdr (subr-arity function)))) (if (eq (quote many) max) most-positive-fixnum max)) (if (eq (quote macro) (car-safe function)) (setq function (cdr function))) (let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))))) (if (functionp (quote start-file-process)) (defalias (quote magit-start-process) (quote start-file-process)) (defalias (quote magit-start-process) (quote start-process))) (unless (fboundp (quote string-match-p)) (defun string-match-p (regexp string &optional start) "Same as `string-match' except this function does not\nchange the match data." (let ((inhibit-changing-match-data t)) (string-match regexp string start)))) (if (fboundp (quote with-silent-modifications)) (defalias (quote magit-with-silent-modifications) (quote with-silent-modifications)) (defmacro magit-with-silent-modifications (&rest body) "Execute body without changing `buffer-modified-p'. Also, do not\nrecord undo information." (\` (set-buffer-modified-p (prog1 (buffer-modified-p) (let (... before-change-functions after-change-functions) (\,@ body))))))) (if (>= (magit-max-args-internal (quote delete-directory)) 2) (defalias (quote magit-delete-directory) (quote delete-directory)) (defun magit-delete-directory (directory &optional recursive) "Deletes a directory named DIRECTORY. If RECURSIVE is non-nil,\nrecursively delete all of DIRECTORY's contents as well.\n\nDoes not follow symlinks." (if (or (file-symlink-p directory) (not (file-directory-p directory))) (delete-file directory) (if recursive (dolist (file (directory-files directory ... "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) (magit-delete-directory file recursive))) (delete-directory directory))))) nil)
#[128 "\301\302\303B\"D\207" [lexical-binding quote eval progn] 5 1631664]((defun magit-max-args-internal (function) "Returns the maximum number of arguments accepted by FUNCTION." (if (symbolp function) (setq function (symbol-function function))) (if (subrp function) (let ((max (cdr (subr-arity function)))) (if (eq (quote many) max) most-positive-fixnum max)) (if (eq (quote macro) (car-safe function)) (setq function (cdr function))) (let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))))) (if (functionp (quote start-file-process)) (defalias (quote magit-start-process) (quote start-file-process)) (defalias (quote magit-start-process) (quote start-process))) (unless (fboundp (quote string-match-p)) (defun string-match-p (regexp string &optional start) "Same as `string-match' except this function does not\nchange the match data." (let ((inhibit-changing-match-data t)) (string-match regexp string start)))) (if (fboundp (quote with-silent-modifications)) (defalias (quote magit-with-silent-modifications) (quote with-silent-modifications)) (defmacro magit-with-silent-modifications (&rest body) "Execute body without changing `buffer-modified-p'. Also, do not\nrecord undo information." (\` (set-buffer-modified-p (prog1 (buffer-modified-p) (let ((buffer-undo-list t) before-change-functions after-change-functions) (\,@ body))))))) (if (>= (magit-max-args-internal (quote delete-directory)) 2) (defalias (quote magit-delete-directory) (quote delete-directory)) (defun magit-delete-directory (directory &optional recursive) "Deletes a directory named DIRECTORY. If RECURSIVE is non-nil,\nrecursively delete all of DIRECTORY's contents as well.\n\nDoes not follow symlinks." (if (or (file-symlink-p directory) (not (file-directory-p directory))) (delete-file directory) (if recursive (dolist (file (directory-files directory (quote full) "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) (magit-delete-directory file recursive))) (delete-directory directory)))))
(eval-and-compile (defun magit-max-args-internal (function) "Returns the maximum number of arguments accepted by FUNCTION." (if (symbolp function) (setq function (symbol-function function))) (if (subrp function) (let ((max (cdr (subr-arity function)))) (if (eq (quote many) max) most-positive-fixnum max)) (if (eq (quote macro) (car-safe function)) (setq function (cdr function))) (let ((arglist (if (byte-code-function-p function) (aref function 0) (second function)))) (if (memq (quote &rest) arglist) most-positive-fixnum (length (remq (quote &optional) arglist)))))) (if (functionp (quote start-file-process)) (defalias (quote magit-start-process) (quote start-file-process)) (defalias (quote magit-start-process) (quote start-process))) (unless (fboundp (quote string-match-p)) (defun string-match-p (regexp string &optional start) "Same as `string-match' except this function does not\nchange the match data." (let ((inhibit-changing-match-data t)) (string-match regexp string start)))) (if (fboundp (quote with-silent-modifications)) (defalias (quote magit-with-silent-modifications) (quote with-silent-modifications)) (defmacro magit-with-silent-modifications (&rest body) "Execute body without changing `buffer-modified-p'. Also, do not\nrecord undo information." (\` (set-buffer-modified-p (prog1 (buffer-modified-p) (let (... before-change-functions after-change-functions) (\,@ body))))))) (if (>= (magit-max-args-internal (quote delete-directory)) 2) (defalias (quote magit-delete-directory) (quote delete-directory)) (defun magit-delete-directory (directory &optional recursive) "Deletes a directory named DIRECTORY. If RECURSIVE is non-nil,\nrecursively delete all of DIRECTORY's contents as well.\n\nDoes not follow symlinks." (if (or (file-symlink-p directory) (not (file-directory-p directory))) (delete-file directory) (if recursive (dolist (file (directory-files directory ... "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")) (magit-delete-directory file recursive))) (delete-directory directory)))))
eval-buffer(#<buffer *load*> nil "c:/Users/swah/Dropbox/dotfiles/emacs_new/packages/magit/magit.el" nil t) ; Reading at buffer position 28726
load-with-code-conversion("c:/Users/swah/Dropbox/dotfiles/emacs_new/packages/magit/magit.el" "c:/Users/swah/Dropbox/dotfiles/emacs_new/packages/magit/magit.el" nil t)
require(magit)
eval-buffer() ; Reading at buffer position 3564
#<subr call-interactively>(eval-buffer record nil)
funcall(#<subr call-interactively> eval-buffer record nil)
(with-no-warnings (funcall ad--addoit-function function record-flag keys))
(setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys)))
(let ((ido-ubiquitous-next-override (ido-ubiquitous-get-command-override function))) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys))))
(ido-ubiquitous-with-override (ido-ubiquitous-get-command-override function) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys))))
(let (ad-return-value) (ido-ubiquitous-with-override (ido-ubiquitous-get-command-override function) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys)))) ad-return-value)
ad-Advice-call-interactively(#<subr call-interactively> eval-buffer record nil)
apply(ad-Advice-call-interactively #<subr call-interactively> (eval-buffer record nil))
call-interactively(eval-buffer record nil)
command-execute(eval-buffer record)
execute-extended-command(nil "eval-buffer")
#<subr call-interactively>(execute-extended-command nil nil)
funcall(#<subr call-interactively> execute-extended-command nil nil)
(with-no-warnings (funcall ad--addoit-function function record-flag keys))
(setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys)))
(let ((ido-ubiquitous-next-override (ido-ubiquitous-get-command-override function))) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys))))
(ido-ubiquitous-with-override (ido-ubiquitous-get-command-override function) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys))))
(let (ad-return-value) (ido-ubiquitous-with-override (ido-ubiquitous-get-command-override function) (setq ad-return-value (with-no-warnings (funcall ad--addoit-function function record-flag keys)))) ad-return-value)
ad-Advice-call-interactively(#<subr call-interactively> execute-extended-command nil nil)
apply(ad-Advice-call-interactively #<subr call-interactively> (execute-extended-command nil nil))
call-interactively(execute-extended-command nil nil)
command-execute(execute-extended-command)
I decide to try updating magit. After a bit of googling, I find out how to update packages installed with package.el: http://stackoverflow.com/questions/14836958/updating-package....15 packages are updated. I close Emacs and open again, and it still seems to break on the same place - something related to Magit. Fault of my customizations? Maybe. I don't know. Consider going back to Sublime? Yep.
So... no, tracking the source of errors ain't that trivial. What options do I have now? Throw away my customizations and start over?
I wrote a guide on how to use package.el to install your package and how to customize and extend your Emacs here: http://tuhdo.github.io/emacs-tutor3.html, if you want control of your configuration from scratch.
Probably if you do not have proper Elisp learning, you should use Prelude: https://github.com/bbatsov/prelude. Everything is configured for you and packages are downloaded automatically. This is the easy way. Put your personal configuration code in ~/.emacs.d/personal/. You can also enable additional modules based on your need in ~/.emacs.d/sample/prelude-modules.el by toggling off comments: https://github.com/bbatsov/prelude/blob/master/sample/prelud....
I haven't tried loading from a different location, but you should try in your ~/.emacs.d first. Are you sure your packages are installed in Dropbox folder? I think it is installed in ~/.emacs.d. You should use a VCS like Git to store your configuration in the same .emacs.d directory.
Finally, to make sure it is because Magit, you should uninstall it to see if your Emacs loads properly. In my Windows machine, it loads perfectly fine with more than 130 packages.
I still think we need more text editors.
BTW I say this as an emacs fan and the author of http://david.rothlis.net/emacs/howtolearn.html and https://github.com/drothlis/clang-ctags/
Where emacs shines (for me, at least) is when you spend a lot of time in different languages. Maybe you spend 50% of the time in C++, but the other 50% in shell, makefiles, python, etc. -- and the benefit of better C++ code navigation begins to seem like a micro-optimisation that isn't worth the tradeoff compared to Emacs's support for navigation, version control, compilation, linting, grepping, etc etc, all of which are consistent across all languages. Not to mention Emacs's great support for text manipulation in general.
Also Emacs seems to me the best bet for the "one true editor" you'll still be using in 20 years (by which time hopefully few of us will still be using C++).
I'll also point out that on OS X, Emacs has a lower learning curve than any other OS, at least as far as the basic keystrokes: OS X's Command key still works for the usual shortcuts (cut, copy, paste, save, open, quit, undo) while the quirky emacs bindings are on the Control and Option keys. This doesn't make it any easier to set up a C++ navigation solution, of course.
You are right that supports for C++ is not as rich, since it is such a complicated language. But for small C++ projects and large C projects, it is pretty much usable, especially just for code navigation. At least it's better than using Grep and better than nothing at all. The currently available tools are perfectly usable for those who only write C.
For code completion, there's no pretty solution, but at least simple solution like company-clang which uses clang to get completion candidates from system include paths is pretty usable.
I've just recently learned the basics of lisp, this will be the perfect time to find out more about emacs. It is fantastic, and every time I discover some new feature it blows my mind how great and useful it is.
It's like turning your trusty old emacs into a monster hacker tool. Watching the screencasts is much more entertaining than reading boring documentation.
I think it might very well be worth paying that to someone just learning vim. I'm skeptical enough of that population understand that, though.
I tried to get used to it, but my foot pedal is just collecting dust under the desk now.
If I had the money, I'd try out the Maltron 3D keyboard. I haven't heard about such problems with it. It also comes with a numpad in the middle, which I kinda miss in the Kinesis. It would be great for nethack, and something else.
(I've been using OS X's sticky-keys setting with Emacs for years, BTW.)
One user's transition from vim to emacs+evil was recently discussed here.[3][4]
[1] - http://www.emacswiki.org/emacs/Evil
[2] - https://gitorious.org/evil/pages/Home
[3] - http://juanjoalvarez.net.nyud.net/es/detail/2014/sep/19/vim-...
Re-mapping caps lock to ctrl is also immensely helpful.
M-l - lowercase current string starting at point
M-c - capitalize from current point to next word delimiter
`emacs -nw -Q` or `emacsclient -nw`
when you want to open an instance in a terminal?
?
I mean, Emacs is an OS, right? They've certainly crammed enough things into it to make it an OS.
There's no scheduler inside Emacs. In contrast, there is something very much like a scheduler inside Firefox and inside Google Chrome so that more than one browser tab can make computational progress "simultaneously".
What Emacs does have (at least when it is running on a Unix-like OS rather than on Windows) is a way to use the underlying OS to create and manage child processes. I.e., a way to add processes to the OS's scheduler. But a terminal-emulation app that lets the user create and manage multiple terminal-emulation windows or tabs has the same capability, and no one calls it an OS with an OS.
Moreover, the programs `screen` and `tmux` also have that capability, and no one call them OSes within OSes.
People who like Emacs sometimes treat it like a generalized interface to information. But the combination of a Unix shell and a terminal-emulation app ("the Unix commandline") is often treated the same way, and no one calls it an OS within an OS. Ditto a simple web browser like Lynx.
EDIT: replaced "OS" with "OS within an OS" to try to make my argument less vulnerable to jacquesm's reply.
Meh. If you have to call it an OS, it isn't one.
Really? I thought I had an original thought there for a second. So, someone, somewhere, agrees with me out there.
I'm not sure which one is better either.
For example, if I want to do a regexp search/replace in Vim, I can do this from Normal Mode (which will replace throughout the whole file):
:%s/regxp/replacement/g<enter>
Emacs (by default) has `replace-regexp`: M-x replace-regexp<enter>regexp<enter>replacement<enter>
My only problem? This only replaces from the cursor to the end of the file/buffer, so to replace over the whole file I would need to do: M-< M-x replace-regexp<enter>regexp<enter>replacement<enter>
It just seems that much more complicated, and now I've lost my place, so I'm at the top of the buffer rather than wherever I was in the file.On the other hand, I find Emacs Lisp to be much easier to deal with then VimScript/VimL even as someone that has written my own Vim plugins, and created plugins to patch issues with files in the standard Vim dist (too lazy to submit a patch and wait for the next Vim release).
https://www.gnu.org/software/emacs/manual/html_node/emacs/Ma...
I switched from Vim to Emacs and in the beginning there were some things I really missed. One that I remember was "*", which in Vim/my config highlights current word in whole buffer and let's you n/N between matches. In Emacs, doing the same with M-left C-s C-w felt just wrong.
Fixing this was a matter of 2-3 lines of very straightforward elisp. I since started relying more on Occur mode and IEdit mode for this, but the experience of lacking a feature and adding it absolutely painlessly remained with me.
Writing simple elisp and simple editing-related features is a joy under Emacs. It's much easier than in Vim, for a number of different reasons. This makes me think that "the Emacs way" is about scripting and programming it to do whatever you need it to do.
(defun replace-regexp-g ()
(interactive)
(save-excursion
(goto-char 0)
(call-interactively 'replace-regexp)))Be aware, however, of iedit-mode. Select a region of text and enable iedit-mode, and any change to the selected region will be propagated to every other instance of the region's text throughout the document.
Using iedit-mode in combination with rgrep (recursive grep) and wgrep (editable grep buffer that propagates changes to the underlying documents) is a decent way of doing project-wide refactorings.
And of course, neither iedit nor wgrep are part of the base emacs install. Using the package manager is essential.
If you are just replacing plain text (no regexps) then take a look at iedit. Then C-; will edit all occurrences of the word at cursor.
spacemacs also has extensive documentation, so you can learn key bindings easily and be productive with Emacs immediately without any extra configuration.
When you use certain major or minor modes in emacs, you get to use a whole new set of keystrokes, by which you're effectively doing modal editing.
One well-known example is magit.[1] When you activate magit, you can type all sorts of new one- or two-key commands. This is comparable to modes in vim.
So it is actaully Vim that takes 2x the time to do anything because you have multiple modes to track and switch from.
If you look at how stenographers type, they don't use modes, they use cords. They also minimize moving the hands away from the homerow (or equivalent of), and by "minimize" I think that movement might be 0 actually.
But I think it comes down to preference of whether you want the universality of commands, or conceptual separation of modes.