Programmatically add keyboard shortcut to Mac System Preferences - keyboard

If I go to System Preferences, Keyboard, Keyboard Shortcuts, then Application Shortcuts, I can define custom shortcuts to be used on a Mac.
Any way to access this functionality via Applescript?

The shortcuts are stored in NSUserKeyEquivalents dictionaries in ~/Library/Preferences/.GlobalPreferences.plist and the property lists of applications.
defaults write -g NSUserKeyEquivalents -dict-add Duplicate '~#d' Minimize '\0'
defaults write com.apple.finder NSUserKeyEquivalents '{"Show Package Contents"="#\r";}'
The shortcut format is described in the Cocoa Text System article.

System Preferences isn't scriptable with Applescript natively, you have to interact with it by GUI Scripting. GUI Scripting is really a last resort that allows you to interact with controls by explicitly declaring and calling them, and it doesn't take much to throw off a GUI script. It is difficult to implement even for experienced Applescript programmers. You'll find a few introductory tutorials out there in the web, but not much else.

The internals of the Mac OS are quickly becoming a lost art. Run the following in a shell, or run via shell in Applescript:
defaults write com.google.Chrome NSUserKeyEquivalents '{ "Search the Web…" = "#k"; }'

Also good to know: shortcuts for Services are in the pbs.plist, and they're stored using a different property than the NSUserKeyEquivalents.
There's info on how to write a basic script to change/add shortcuts for Services here:
Set Services keyboard shortcut via script OSX
This was the method I found the simplest, and it worked well for me (macOS 10.12.6 Sierra):
You can also use PlistBuddy and defaults:
/usr/libexec/PlistBuddy -c 'Delete NSServicesStatus:"(null) - test2 -
runWorkflowAsService"' ~/Library/Preferences/pbs.plist
2>/dev/null;defaults write pbs NSServicesStatus -dict-add '"(null) -
test2 - runWorkflowAsService"' '{key_equivalent = "^~#2";}'
The PlistBuddy command is not needed if there is not an existing entry
for the service. Replace test2 with the name of the service. Quit and
reopen applications to apply the changes.
^~#2 is control-option-command-2. See
http://osxnotes.net/keybindings.html.
And in case this might help those who are a bit less familiar with writing/executing scripts on macOS, I saved the script as a shell script (.sh extension), and ran it from Terminal using the following commannd:
sh "/path/to/script/scriptfile.sh"

I have written an AppleScript library to programmatically add Global & Application shortcuts. It took a tremendous amount of effort to work around the various quirks in how macOS implements shortcuts.
Version 1.0 is available here:
https://forum.latenightsw.com/t/setting-other-applications-keyboard-shortcuts-using-nsuserdefaults-defaults-not-updating/3537/5
I will be making some minor API additions & changes when I find the time, and will post the source code here in full at that time. Note that as mentioned above, Services shortcuts are stored using a completely different system & are not handled here.

Related

alt-tab like functionality when using terminal?

When working in GUI we do alt-tab (or cmd-tab in mac) to switch between multiple programs, for example I am writing a text file in a text editor and then I do alt-tab to switch to already running browser to google up something then I alt-tab again to come back to keep editing.
How do you perform such "switch between" programs in command line interface - for example working with a ssh command line shell?
EDIT: I forgot to mention it, I am using ssh to connect to my university's server, and they don't have screen & tmux installed, and my account have no right to install any new apps... Is there any built-in functionality to perform this task, or any work around? For exmaple can I "minimize" running proggram and come back to regular shell interface, do some work, then display the "minimized" process again?
Another workaround: use the shell's job control, eg if you're editing a file, CTRL-z pauses the editor and brings you back to the shell, where you can compile, see manpages, browse the web or whatever -- and of course you can background the browser or anything else.
Screen command offers the ability to detach a long running process (or program, or shell-script) from a session and then attach it back at a later time.
As a crude workaround, run multiple terminal windows on your computer, and alt-tab between them.
Incidentally, at the Linux console, you can switch virtual terminals with ctrl+alt+F for at least F1 through F6, commonly F8 or more (depends on how the distro sets them up). Not your case, I know, but in case future visitors should benefit.
If you are comfortable in Emacs, it allows you to run multiple independent ansi-term buffers.
You can also use "GNU screen" to emulate multiple terminals in one terminal.

Editing e-mails in your browser using (g)vim

Long ago, I was using the hack given in http://vim.wikia.com/wiki/VimTip805 . This hack allowed me to edit any active window frame using gvim. For instance, I was able to edit my gmail replies using gvim.
Unfortunately, the hack does not work to me any more. Is there any other way to achieve the same? Or at least to achieve the same using some concrete browser (for example, firefox)?
Google Chrome
you can use GhostText with running server vim-ghost. Its not ideal, but allow to interactively use external editor (text is automatically copied to a web textarea element each return to normal mode).
Vim-ghost is written in tcl so you need install tcl.
In my case I have tcl installed but without standard library tcllib. So I found lacking packages in tcllib (tcllib/module/sha1 and tcllib/module/json) and copy them to a folder listed in tcl path (the first result of echo $tcl_pkgPath). More info: man pkg_mkIndex or here.
Of course vim-ghost server must be run (eg. in autorun script):
~/.ghost-text-server.tcl &
You can also like Vimium to navigate through web using links, tabs, j, gg and many vim-like features.
You should check vimperator( pentadactyl, which is a fork of vimperator). They offer the ability to edit text boxes, but also offers several additional functions that allow you to control firefox in a similar way to Vim.
If you prefer Vim only for edit text boxes you could try the firefox plugin "It's all text", as mentioned by Kent.
I'd recommend It's All Text plugin for Firefox.

What window manager should I use as example?

I want to implement a simple specialized window manager for presentations (not user-controllable) that supports only the following operations:
Moving and resizing of windows
Switching desktops
Starting applications not on current desktop (in background) without disrupting current image.
I don't need any user input, button/titles, ...
What existing window manager should I use as example? There are many little "hello world" window managers, but they usually does not support desktop switching.
You don't need to reimplement the wheel.
openbox will do everything you mention and more besides.
Simply edit the rc.xml to disable the root menu, and re-launch.
Openbox also allows per app setting so that certain applications can open on a particular desktop by default, or with a particular size, or open hidden.
It also supports wildcards in the window selection, so that settings can apply to all windows.
devilspie2 is a window matching utility that can perform actions whenever a window opens.
It is highly hackable and the code is available on github. It will match windows by name/class/etc when they open, and perform actions on them. (including matching all windows and moving them to a different desktop. It will work with most window managers.
Based on the original devilspie which does not have Lua scripting, but is configured using s-exprs instead.
xdotool will also allow you to perform complex actions on windows without hacking any code. It will even fake user input (mouse/kbd) if you need it.
There are a few window managers written in Python that could be good starting points. Qtile and whimsy both describe themselves as hackable.

Looking for a "scriptable GUI markup language" for linux(like HTA in windows)

OK, the title is a bit(lot) cryptic, but that's the best one-line-summary I could come up with.
When developing, I prefer to develop CLI utilities, since they are much easier to write and test, and most of the programs I write don't really require a full blown interface.
Using the program is another story. My users don't like to use the shell, and they prefer a GUI with buttons, file pickers, text boxes, radio buttons and checkboxes.
Now, when I worked on windows, my solution was to write the program as a shell utility, and then use HTA to write a GUI. HTA was perfect for this, because creating a nice, simple interface with HTML is very easy, and using vbscript to run a shell command that calls the utility with the right arguments is also very easy.
Now, there is no HTA in linux, and I can't use regular html files because they can't use shell scripts(that would be a security issue). Is there any linux\cross-platform solution for writing quick GUI wrappers like the ones I described?
There's zenity. From the package info: "Zenity lets you display Gtk+ dialog boxes from the command line and through shell scripts. It is similar to gdialog, but is intended to be saner. It comes from the same family as dialog, Xdialog, and cdialog."
Update: If zenity is too simplistic then there is also Gtkdialog.
Update II: There appear to be some youtube videos on GUI interfacing with bash.
Tk comes to mind for GUIs, hosted in Tcl, Perl, or some other scripting language.

Are there any ide's out there with good support for vim/vi bindings?

Finding vim plugin maintenance and configuring is too laborious and relies on external configurations (such as ruby) tricky. What I want is an IDE like Eclipse, Visual Studio, that I can use vim in. I still want to be able to use different modes (command, visual, insert), but I don't want these inbuilt commands to conflict with the IDE's commands.
I've heard PIDA is good for this but looks like a bit of a mission to configure on Mac.
Eclipse has a VIM plugin. Eclipse runs on OS X
http://www.vimplugin.org/
Also, I think the Komodo IDEs and editors have VIM bindings, but I have little experience with them. Apparently, they also run on OS X.
http://docs.activestate.com/komodo/4.4/vikeybind.html
I use Komodo Edit on OS X, Ubuntu and Windows. It's open source, supports a ton of languages and has good Vi/Vim key binding support without getting in the way of itself. It's also easy to add in support for additional key bindings. It's built on the Mozilla code base and can be extended with Add-ons (Remote Drive Tree/Source Tree/MoreKomodo are great examples). I also personally love being able to write macros for myself in either JS or Python to add extra functionality.
The full fledged IDE is worth looking at if you can use the extra features. For most of the things that I work on, I can't use a full fledged remote debugger so Komodo Edit suits my needs.
It also has built in SSH support all in a package that is very responsive on my 5 year old work machine with several 1000 line files open in tabs.
Emacs has a vi emulation mode called Viper ;-)
Besides the vim plugin for Eclipse there is also ViEmu for (amongst others) Visual Studio, if you are not afraid of shelling out some $. Haven't used it though, as vim is my IDE :)
This AutoHotKey script isn't quite what you asked for, but I mention it in case it's helpful.
As you say, PIDA has real Vim, nothing can come close to that. Keybinding emulation only goes so far. It's not that bad to get running on a Mac, Windows is a mission though.
QT creator has Vi bindings.

Resources