Both command line development tools and IDEs require work to get the most out of them. I used to think command line tools were better because I was more in control, then I realised if I just spent the time learning what IDEs were doing on my behalf I would still have more or less the same amount of control, especially if the IDE is customisable (which the best ones are).
So with command line tools you have the option to customise your workflow from the ground up, but with IDEs you have the option to customise your workflow from the top down. Both have advantages.
Compare that to couple of thousand commands available on the command line that do all sorts of things and that can be combined in useful, creative and often times unexpected ways. All that in addition to having a programmable command interpreter (i.e. the shell itself) that allows you to automated things you do often. Vim is often described as programming your text transformations, well command line is programming your workflow, but it is also more powerful because of the shear number of commands available.
Honestly, it's not a crime to like nice windows, y'know.
(And it's beside the point, but brushed metal has been dead for years by now!)
Bushed metal on the other hand is not something I want or desire.
... which means nobody else needs it, right? :)
Something tells me instead of telling you what you can customise in good IDEs I should show you. With that in mind, tell me something I shouldn't be able to customise in Visual Studio and I'll show you how its done. To start this off, here's how to create custom keyboard shortcuts, as you can see it's very easy to do:
https://visualstudiomagazine.com/blogs/tool-tracker/2012/07/...
I chose BASH for my language of choice, but could have use Python or Ruby or anything that the shell can execute.
In Emacs or Vim, it's a single line of code you add to your initialization file.
I think there may be different definitions of "easy" in play here. I'll concede that Visual Studio makes custom keybindings possible, but so does any text editor worthy of even momentary consideration as a professional tool.
And I'll take your challenge. Here's something I can do in Emacs: I can take a spreadsheet received from a client, full of intended configuration settings for a custom internal application. I can export it as CSV, load it in Emacs as such, and extract the relevant sections of the content into tables in a plaintext Org-mode document. I can then add a function to that document, in whatever language I choose, which will receive the contents of those tables as structured data in the language's own idiom, and generate the collection of complex SQL statements necessary to implement the desired configuration. From there I can decide whether I want this SQL script inserted into the document I'm writing, or written out to a file that I can copy to a remote host and feed to the SQL monitor. Or I can instead have Emacs itself connect to the target RDBMS and apply the configuration directly. Or any combination of those. And once the document's written, I can do all this with a single keystroke. Another single keystroke exports the document to HTML, so I can share it with the client to demonstrate exactly how their intent has been translated to reality, and with colleagues so they can see what's been done.
Perhaps that sounds fantastic to some. For me, it's Thursday before last. It took a little less than an hour.
I'm sure Visual Studio suits your needs quite well. I'm glad of that; everyone should have a tool that does what they need it to. But Visual Studio, from all I've seen of it, does very little to expand the scope of what you can do. Those of us who are fond of Emacs or Vim are so because, by comparison with something like Visual Studio, Emacs and Vim give you superpowers.
Okay, so let's look at this. If I've understood correctly, you want to be able to generate data migration code based on a CSV file, and export that code so that it's ready to be inserted into documentation, is that a fair assessment?
So for Visual Studio, one way to do this would be to write a custom runner for Fluent Migrator:
https://github.com/schambers/fluentmigrator
There's also the documentation task, which has to include the source data and resulting SQL script, as well as the transformation code. I'm not seeing anything here that would simplify that in the slightest; you'd have to either write the HTML document by hand, or write code to generate HTML. In the workflow I described, all that code is already written, and you can invoke it with a single keystroke.
And beyond that, there's the matter of data ingestion. You're starting from CSVs, so you have to read those and parse them just to have the data you need to work with in a form which you can use. Any serious language has a CSV parsing library, of course, so that's not a difficult task in its own right, but it's still more code you have to write, and more effort you have to put in - selecting a CSV parser, adding it to the project, learning its API, et cetera. In the workflow I described, it's a copy-paste operation.
Don't get me wrong - I didn't say, or assume, that anything I described couldn't be done in Visual Studio. But at this point we're talking about, what, a few hours at least? And you're spending a fair chunk of that time on overhead, especially in document generation. You have to find, vet, and install libraries, write or modify a bunch of code, and so forth. By the time you're done, you've probably had to spend the better part of a day on this one task.
In the workflow I described, the only code I needed to write was that in which I expressed the actual transformation from tabular data to SQL statements. Everything else, Emacs and Org-mode took care of for me; all I needed to know was how to invoke capabilities already present. And I had the job done and dusted in less than an hour, with plenty of time left in my day for other work.
That's what I mean when I say Emacs and Vim give you superpowers - not that there's anything you can do in one of those editors that (with enough effort) you can't do in another environment, but that those editors are better than anything else (at least anything else I or anyone I know has ever encountered) at helping you get more done, faster, without having to spend time on ancillaries that distract you from the meat of the task at hand.
The thing is, if that's the case, what you're describing isn't a custom plugin, it's an existing plugin someone else has taken time to write that you're making use of. If that's the argument you're making then you could say Emacs has a better ecosystem of plugins, and that it's easier to tie them together, is that what you're trying to state?
For one thing, Org isn't a plugin; it's part of the Emacs distribution, rather than something you have to explicitly install. All you need to do to use all the functionality I described is install Emacs and start it up.
For another, Emacs doesn't actually have a plugin system, per se. Instead of the usual headache, where a program written in language A exposes a lossy subset of itself to plugins written in language B, Emacs just exposes all of the language in which it itself is written, and you can do what you like. The usual distinction between first-class application code and second-class plugin code doesn't exist. There's just Emacs Lisp code, any of which can freely interact with any other Emacs Lisp code running in the same process space, including effectively all of Emacs itself.
You can add new code by installing packages from a repository, which you can do in a single command if you know the name of the plugin you want. (If you don't, there's a searchable list.) Or you can do it by opening an Emacs Lisp buffer, writing some code, and evaluating it - again, with a single keystroke. If you like it and want to keep it around, save it to a file: boom, it's a "plugin". Add a line to your init file to load it, and it's a "plugin" you're using. Or you can just drop your new code into your init file directly, because your init file is - you guessed it - just Emacs Lisp code, that happens to be in a file Emacs will load and execute when it starts up.
As I said before, the Blub paradox applies: it's easy to recognize something less powerful than what you're familiar with as such, but something more powerful just looks weird. From the sound of it, Emacs looks very weird to you. It did to me, too, before I started using it. Now I won't willingly use anything else. Perhaps I'm just very weird, too.
Nah, it's nothing to do with the blub paradox. I've dabbled with Emacs before, I could see certain benefits to its flexibility, but was put off by other factors such as the clunky keyboard shortcuts (which is why I'm glad for both ergoemacs and spacemacs, as they have better defaults IMO), reliance on Lisp and a couple of other minor issues. Overall I think it's a great tool, and I can see why its popular.
That said, using the blub paradox implies (whether you intended to or not) that you believe it's more powerful than the competition. The way I see it is that any program is only as good as its existing features. Org mode is a good example of a strong feature for Emacs, but I could point out a number of strong feature for VS too. IntelliTest is a good example:
https://msdn.microsoft.com/en-us/library/dn823749.aspx
IntelliTrace is another:
https://visualstudiomagazine.com/articles/2012/02/07/intelli...
If someone has only ever debugged using print statements or breakpoints then they miss the power of such features, so I could just as easily invoke the blub paradox with reference to VS as well.
The point is there is not one single ultimate tool, they all have strengths and weaknesses. Emacs is not a paradigm shift better than VS, and VS is not a paradigm shift better than Emacs, so the blub paradox does not apply.
Emacs integrates well with the same capabilities in almost any language that provides them - even C#.
See the difference?
Org-mode is a best-of-breed outlining application. It's a dead-simple workflow management and time tracking application. Org-mode is a better Markdown than Markdown integrated with a multi-format publication generation capability. Org-mode is a literate programming environment facilitating reproducible research that allows embedding code inside documentation, but unlike some alternatives supports a zillion languages and lets you pass values between them.
I haven't found anything that I like as well as org-mode for any of those individual tasks, much ALL of them. Org-mode somehow does all these things and manages simplicity. It's all plain text that I never have to fret compatibility or corruption.
It can even export to Markdown! (And I'll only author in Markdown under duress anymore.)
It's funny that you chose the phrase "Magic Things". Before I settled on the "superpower" metaphor, I was going to talk about the times when I've done things with Emacs, in and out of Org-mode, that have made my colleagues say things like "wow, that's really cool" or "holy shit how did you even just do that". I opted not to because I figured it would sound like bragging, on the one hand, and on the other because you can do things in Emacs that really do have to be seen to be believed. But "magic" is the word I was going to use.
(It's not always an advantage, either. I've had people show contempt for things like Org-mode tables, on the assumption that because they're rendered in text, they can't possibly be anything other than text, and I must be wasting insane amounts of time making columns line up and the like. I used to work for one of those people. I'm really glad I don't work for him any more.)
I think this is the biggest draw for Emacs. It's a fully featured lisp development environment. If you want to change it, you just write lisp. If your IDE is free software, you can do the same thing, but they aren't always that easy to extend. Emacs, shell script, and the various tools are a set of APIs that you can code against. Most IDEs are geared towards giving you a UI interface to the functionality, not a programming API.
And that's fair, but not really what I'm after most of the time.
You can do that with Visual Studio too with Visual Studio Extensions. You can also manage extensions (including those from other users) with a built-in package manager, just like in Emacs.
Here's a Visual Studio Extensions tutorial if you're interested:
https://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Buildi...
(defconst trc-comment-keywords "\\<\\(FIXME\\|TODO\\|BUG\\|HACK\\|NOTE\\|WARNING\\|ERROR\\)")
;; Install the word coloring
(defun add-comment-keywords ()
(font-lock-add-keywords nil
`((,trc-comment-keywords 1 font-lock-warning-face t))))
(add-hook 'find-file-hooks 'add-comment-keywords t)
(set-face-underline 'font-lock-warning-face "yellow") ; Just make sure we'll see it
This defines a function #'add-comment-keywords and adds it as a hook to the "open file" operation. The function highlights all matches to the regexp in trc-comment-keywords so that they're highlighted in the source code using a modified font-lock-warning-face.This is an example of something you could just type in and evaluate right there, in your buffer. Later, you can save it in your init file to have it always enabled.
A more complicated example of related code I wrote with some help from the Internet and the Emacs documentation:
(defun list-comment-notes ()
"List all TODO/FIXME/HACK, itp. in a new buffer for reference."
(interactive)
(save-excursion
(goto-char (point-min))
(let ((collected-lines '()))
(while (re-search-forward trc-comment-keywords nil t)
;; collect lines
(setq collected-lines (cons
(format "%d: %s" (line-number-at-pos) (grab-current-line))
collected-lines)))
;; generate a new buffer
(let ((notes-buffer (generate-new-buffer (concat (buffer-name) "-comment-notes"))))
(set-buffer notes-buffer)
;; dump collected stuff to here.
(dolist (a-line collected-lines)
(insert a-line)
(insert "\n"))))))
What it does is it scans the current buffer for all occurrences of the keywords and lists them in a new buffer (with "-comment-notes" appended to the name). It's a crude function that could use some improvements, but it works well enough and is now just a M-x list-comment-notes away. Or, with the way M-x works, just M-x l-c-n away. Or I could bind it to a key.The great thing about Emacs is that all you need to extend it is to type the source somewhere. No need for creating projects, build scripts, rebooting your editor, etc. You can evalute and reevaluate the code until it does what you want. Lisp interactivity, which Emacs inherits, is addicting and still unparalleled in other programming languages / environments.
(defun tom/insert-sterling-symbol ()
(interactive)
(insert "£"))
(defun tom/set-buffer-modified ()
(interactive)
(set-buffer-modified-p 't))
(defun tom/unix ()
"Set buffer to unix line endings"
(interactive)
(set-buffer-file-coding-system 'unix))
The last one exists only because I could never remember the right command to select Unix-style line endings. So rather than train myself to learn it, I just wrote a small wrapper with an obvious (to me...) name, because it's so easy to do that.I've written some Visual Studio addins as well... the experience is not really comparable. (Visual Studio VBA macros, when it supported that, were painful too.) emacs makes it a lot easier.
I could've edited the Emmet source code in place, but to do so would've meant losing my customizations next time I upgraded the package. I could have forked it, but that would mean having to manually merge changes into the fork every time a new release comes out.
Instead, after a couple hours of reading the Emmet source and fiddling around in an Emacs Lisp buffer, I ended up with this:
(defcustom emmet-verticalize-html-attributes nil
"Whether to verticalize attributes in HTML tags.
\"Verticalize\" here means to separate each pair of attributes by
newline and enough indentation to line up the first character of
attribute names. For example, the unverticalized production
<div id=\"foo\" class=\"bar\"></div>
when verticalized becomes
<div id=\"foo\"
class=\"bar\"></div>"
:type 'boolean
:group 'emmet)
(defcustom emmet-verticalize-minimum-attributes 3
"The minimum number of attributes required for
verticalization. If a tag has fewer than this many
attributes. they will not be verticalized, even when
verticalization is enabled.
Values less than 2 have no effect, since verticalization only has
an effect on tags with at least two attributes."
:type 'integer
:group 'emmet)
(defun emmet-verticalize-html-tag (orig &rest args)
(let ((html (apply orig args))
(attribute-count 0))
(if (null emmet-verticalize-html-attributes)
html
(save-match-data
(with-temp-buffer
(insert html)
(html-mode)
(goto-char (point-min))
(while (re-search-forward (pcre-to-elisp "^\\<[^\\/]\\S+") nil t)
(while (and (not (= (point) (point-max)))
(not (looking-at (pcre-to-elisp "\\/?>")))
(re-search-forward (pcre-to-elisp "\\w[\\w\\d_-]+\\=\\\".*?\\\"" ) nil t))
(setq attribute-count (1+ attribute-count))
(and (not (looking-at (pcre-to-elisp "\\/?>")))
(newline-and-indent))))
(indent-region (point-min) (point-max))
(if (>= attribute-count emmet-verticalize-minimum-attributes)
(buffer-substring-no-properties (point-min) (point-max))
html))))))
(advice-add 'emmet-make-html-tag :around #'emmet-verticalize-html-tag)
(defcustom emmet-indent-html t
"Whether or not to indent generated HTML according to the same rules
used by `html-mode'.
When non-nil, Emmet-generated HTML will be indented via
`html-mode', with a newline after every closing angle bracket.
When nil, Emmet-generated HTML won't be post-processed in this
way. (The version of Emmet I'm using, 1.0.8, applies no
indentation whatsoever.)"
:type 'boolean
:group 'emmet)
(defun emmet-indent-html-snippet (html)
(if (not emmet-indent-html)
html
(save-match-data
(with-temp-buffer
(insert html)
(goto-char (point-min))
(while (and (re-search-forward (pcre-to-elisp "\\>") nil t)
(not (eobp)))
(newline))
(goto-char (point-min))
(while (search-forward "\n\n" nil t)
(replace-match "\n" nil t))
(html-mode)
(indent-region (point-min) (point-max))
(buffer-substring-no-properties (point-min) (point-max))))))
(advice-add 'emmet-make-html-tag :filter-return #'emmet-indent-html-snippet)
...which not only implements the behavior I desire, and does so without modifying the original source or breaking my ability to upgrade Emmet, but also adds customization options to those provided by stock Emmet, so that I can adjust the way my Emmet extensions behave without having to touch the code. (Not that touching the code is any great hardship, but it's nice to be able to adjust the way these extensions behave in the same interface I use to make other minor adjustments to the way Emmet works.)Shortly after I copied that code into the Emacs buffer I'm using (via Firefox's "It's All Text!" extension) to edit this comment, but before posting, I inadvertently killed Emacs's message buffer, which contains a running log of everything displayed in the editor's echo area. I wasn't prompted for confirmation before killing that buffer, but I felt I should've been. So I opened an Emacs Lisp buffer and wrote this:
(defun defend-message-buffer (kill-fun &rest args)
(let* ((buf (car args))
(buf-name (if (stringp buf)
buf
(substring-no-properties (buffer-name buf)))))
(if (string= buf-name "*Messages*")
(and (yes-or-no-p "Really kill the message buffer? ")
(funcall kill-fun buf))
(funcall kill-fun buf))))
(advice-add 'kill-buffer :around #'defend-message-buffer)
And now I am.I switched to AutoHotKey and now I have a macro system that works everywhere.
There are many thing you can do, but it really, really isn't just like emacs.
"a built-in package manager, just like in Emacs."
They both have built-in package managers for extensions. I don't think this is a controversial statement.
The extension mechanism really isn't like emacs at all. Package management is a bit more similar (although can you easily add new repositories for nuget?)
Yes. Here's a guide showing how to create a local Nuget repository:
http://codurance.com/2015/05/04/creating-a-local-nuget-repos...
In the guide you can see this screenshot:
http://codurance.com/assets/img/custom/blog/2015-05-01-creat...
Which shows you one way to set up the package source.
Also worth mentioning Paket, which is a Nuget replacement. In addition to working with the standard Nuget library, Paket can pull dependencies directly from Git repos.
Take my first foray into vi, at its most basic level. I'm at a shell prompt, where I can use vi to edit multiple files, saving each one when I'm done with it and occasionally switching to another window to run something else, coming back when I need to edit more. But there's nothing storing my list of open files or buffers and where they are on my screen, my position in each file isn't saved; it's like vi expected me to spawn a new instance every five minutes.
When I tried emacs, which allows much more functionality inside the editor -- connecting to servers, databases, or hosting shells or debuggers -- it just made the problem worse. If I started a shell inside emacs before stopping the emacs process entirely, that shell won't be there when I get back and my files won't either. If I want to have a specific file on the right-hand side of my screen, emacs will forget where I put it. If I open a file in a new window, that file will be gone. If I want to have a file stand out by changing its background colour to a subtly-different hue, that will have changed back by the time I need to re-open my editor.
I don't like this idea; I don't want my editing environment to be some ephemeral process that's created when I start and gets destroyed when I'm finished. And while Vim has sessions and Emacs probably has three forms of saved states, they don't quite work: no saved window positions and sizes, no working with files you haven't given a name. I imagine that it's the same feeling you get when you read that something allows Emacs-like functionality: on a checklist, they might both have tick marks on each row, but when you try to use it, it doesn't work how you expect. I think that Emacs and Vim's command-line history have made its users used to this behaviour, spawning all sorts of tools to make configuring your environment easier instead of just trying to save the changes as they happen. I've seen plugins like CtrlP or projectile that enforce the idea that your environment shouldn't last, you can just set it up again each time. And that means you don't bother personalising your environment and putting things where you want them to be, because it's all going to be irretrievably gone if your computer crashes, so don't get attached. Alright, rant over.
Do not close vim.
I keep a main vim instance which has different buffers open. These buffers have their own history, e.g. undo-tree, etc. And keep in mind, that it takes time to get adjusted to vim, otherwise one gets overwhelmed quite quickly. E.g. I suggest to ignore windows and tabs at the beginning and get comfortable with buffers first (e.g. mostly I only use buffers).
However, as someone once said: "The universe tends toward maximum irony. Don't push it." If you don't close vim and keep it open for weeks, then all your environment changes are going to keep on building up, only for you to lose everything the next time you need to restart your system, or upgrade your editor or terminal, or your OS crashes, or there's a power failure, or your computer catches fire.
This is useful for long running work, but more often it is not necessary. If you are just exploring the code base or making small edits here and there you don't really need persistent tmux session for that.
But yeah, that's pretty much my objection -- it's not a big one, and there's room in the world for more than one type of software. I'm aware of tmux, but it just shifts the problem from vim to tmux: once you need to upgrade tmux, or your OS, or your computer, everything you've set up gets lost, and I really don't want that to happen.
I'm also aware of things like teamocil, and I even used itermocil for a while. But it turns out that the kind of environment edits I like to make are ones that I just do, rather than ones I can specify in a config file then restart to set everything up again. For example, when you say:
> If you are just exploring the code base or making small edits here and there you don't really need persistent tmux session for that.
Coincidentally I do have a relevant example for that. Last week, when I was exploring the files that make up the zoneinfo database, I put the files that I needed to keep referring to (of which there were like 5) to the side, knowing full well that they wouldn't go away. Then they just stayed there for a while as I got distracted with other stuff. This week, when I had to return to it, they're still there; and all the files from the other projects I'm working on are all in their positions, too, ready for when I switch back next week, surviving through a system restart and an editor upgrade.
Which editor are you used to using that does, though? I ask because I'd like to experiment with it a little and see what it does and, to the extent possible, how it does so, because that seems like a useful capability for Emacs to have, and one of the nice things about Emacs is that it offers a programming environment flexible enough to support most other editors' "hey, neat" capabilities - the Sublime minimap, for instance.
I there an editor/IDE you use that gives you the persistence?
Most modern IDEs also have a notion of session.