XMonad shift multiple workspaces over - xmonad

I am a proud and satisfied user of XMonad, but I don't really know how to write configs for it. I was wondering whether it was possible to customize my xmonad.hs config to achieve the following functionality:
When focused on an empty workspace, enter a certain modifier (e.g. alt-shift-left) to move all following (i.e. higher index) workspaces to the left by one. So, if I have a terminal in workspace 1, a browser in workspace 3, and email in workspace 4, I can switch to workspace 2 and use this keystroke to move the browser to workspace 2 and the mail client to workspace 3.
When focused on any workspace, enter a certain modifier (e.g. alt-shift-right) to move all the windows in that workspace to the next workspace to the right, shifting all the following indices over by one as well, Hilbert Hotel style. That way, if I want to open a window in the second workspace, I can empty it by moving its current contents to the third, the contents of the third to the fourth, and so on. Essentially, this is the inverse of the above operation.
XMonad seems powerful and customizable enough that I doubt that this is impossible. Does anyone have an implementation?

Using XMonad.Actions.DynamicWorkspace you can add and delete Workspaces, and XMonad.Actions.WorkspaceNames provides functionality for renaming them.
This way you can
delete the current workspace and rename the ones to the right by -1 and
add a workspace and rename the ones to the right by +1.
This way there is no need to shift the applications.

Related

Can I filter sidebar directories by name (in sublime text 3) to quickly find node module, for example?

Here is my example, where I could have some input to filter directory subfolders.
The direct answer to the question is that this is not possible; the list of files and folders in the side bar is controlled by what folders you add and the settings that you include/exclude files and folders from within those folders. In theory you could try to modify the settings to change what appears in the side bar, but every time those settings change the file catalog needs to be rebuilt, which is something that can take some time (particularly in something with a large node_modules folder). It also causes all of the folders in the side bar to fold up.
The expected workflow is more designed around working with files than with working with groups of folders and that workflow centers around the Goto Anything panel. Choosing Goto > Goto Anything in the menu will open a panel showing you a list of every file that is currently contained in the side bar (except binary files).
The panel can filter text via fuzzy matching using as many search terms as you want (in any order you want) and will move the most likely matches closer to the top of the list. It also learns over time what files you pick when you use certain filters.
For your use case here you can open the panel and use a filter like node_modules or nmod/ to filter to files in the node_modules/ directory, acorn/ to see only files that exist in folders that match acorn, or a combination. You can also include fragments of filenames like lodash/ indjs to bring the index.js of the `lodash/ package to the top of the list.
The best way to get a feel for how this works is to play with it a little bit. Note also that the context menu in open files has a Reveal in side bar command that will focus the side bar on that file, which can be a handy way to see the other siblings of files you have open.

Sublime Text 3: import projects list from folder/files to OpenRecent list

I save several projects in a same folder by manual click Project -> Save Project As...
and I used to use cmd + ctrl + p to open Switch Projectlist to switch between projects
and everything's works fine.
but today, I accidentally remove my Switch Project list in by click Project -> Open Recent -> Clear Items, so my Switch Project list is empty now...
I know I could add them back through reopen ALL my projects. due to the number of projects is pretty a lot, that will be kind of annoying to add them back one by one.
I wanna know if there's a smarter way to do that for me.
maybe import all my *.sublime-project files from folder or something.
thanks
Short of manually opening every project, I don't think there is any way to do something like this directly. There isn't a command or plugin endpoint that I'm aware of that lets you open a project by name or filename, so it's not possible to create a plugin to do the work, and Sublime doesn't have the ability to pre-load the list of packages directly either.
That said, it is possible to manually update the list of recent projects, but whether or not that is more or less work than opening all of the projects is something to consider.
If you use Preferences > Browse Packages from the menu or the command palette, a file browser will open on your Packages folder. From there go up one directory level and go inside of the Local folder, where you will find a Session.sublime_session file.
Sublime saves it's state into this file when you quit it, and uses it to restore state when you start it again. Here you will find all of the saved information, such as the windows and files that were open and so on.
Changing this file will change the data that Sublime loads, so you can modify the session file to set up the data that you want. You need to make sure that you modify the file while Sublime is not running or your changes will be ignored and clobbered away. Also it's a good idea to make a backup of the file before you start in case things go pear shaped.
Down near the bottom of the file you will find a top level key named workspaces, and inside of it a recent_workspaces key:
"workspaces":
{
"recent_workspaces":
[
"/home/tmartin/local/src/OverrideAudit/OverrideAudit.sublime-workspace",
]
}
This is where the list of recent projects is stored for use in the menu and the quick switch project command. Particular things to notice are that the entries are naming sublime-workspace files, and that the paths are absolute.
NOTE: On windows, the filenames stored in the session file are in a format like /C/Users/tmartin and not c:\users\tmartin; on that platform you need to make sure that you adjust the paths accordingly. As long as there is already at least one entry in the list when you look at the session file, you can easily see how to construct the paths that you need.
Despite the name of the commands and menu items, what you're actually switching between is different workspaces. Every sublime-project is associated with a sublime-workspace file, which acts as a dedicated sublime_session file for that particular project. This mapping is one-to-many in that you can have multiple workspaces for the same project file, allowing you to reference the same paths in multiple windows but have different window layouts.
While Sublime is not running you can edit this file to add in the full paths to all of your workspace files; when you start Sublime up the list will be populated (every sublime-workspace file knows what sublime-project it is associated with).
What remains is whether or not it's quick to come up with the list of files in a way that you can easily paste them into the session file.

Is it possible to share SublimeText preferences *and* override one specific pref?

I share Sublime prefs between two machines (home, work) using Git.
My monitor at work has a higher DPI than my monitor at home, so in one of the two machines I'd like to override font_size.
I was hoping for:
The possibility to override using a command-line flag (to do something like subl --override-pref font_size=15), like kitty --override does.
Another level of prefs cascading below User.
, but I don't think any of this exists in Sublime. Language-specific config is not what I'm looking for, I want something global, but only in one of the two machines.
Ideas? Workarounds? Thanks.
The general mechanism at play for settings files is that when Sublime loads a sublime-settings file by name, it pulls all of the similarly named files across all of the known packages and combines them together (the same also happens for many other resource files) with content from later files overriding anything that appears in an earlier file.
The order that's imposed here is lexically by package, with Default always being first and User always being last. That's why the default settings are in the Default package and your custom settings are in the User package. Additionally syntax specific settings also apply (as do settings specific to projects).
Apart from this mechanism there's no direct way to override settings without some sort of manual intervention on your part. Potential solutions for this sort of problem include the following examples:
Don't sync the Preferences.sublime-settings file
If the file isn't synced across multiple machines, then this problem becomes moot because each machine can easily have it's own unique settings. The downside to that is that each machine then has it's own unique settings, which is a pain in the butt if you often move from machine to machine and things don't quite work the same way.
Use separate git branches
An alternative here if you're using git such as you are is to try and keep separate branches per host or per host type (like hi_dpi and reg_dpi or some such). Then on each machine check out the appropriate branch.
The obvious downsides here are having to try and cross-sync desired settings changes (for both User as well as any packages you might install) between branches, which is less than ideal unless you really love git.
Use extra Preferences.sublime-settings files
Here the idea is that you don't include the font_size setting in your User/Preferences.sublime-settings file at all. Instead, you use Browse Packages from the command palette to open the Packages folder, then create a new folder there with some arbitrary name. Inside of that folder include a Preferences.sublime-settings file that contains only the font_size setting.
Doing this on multiple machines, you can sync the settings in your User folder across machines without also syncing the preference that contains the font_size. As a note, if you create the file while Sublime is already running, you may need to quit and restart to get it to notice that the settings file exists; this only applies the one time, though.
Use a plugin
Looking at the link provided above, the ultimate trump card for any setting is a setting that's been applied directly to a view. Given that, you can use a plugin that selectively always applies a specific font size to any newly created or opened file:
import sublime
import sublime_plugin
import socket
class CustomFontListener(sublime_plugin.EventListener):
hostname = socket.gethostname()
def on_new(self, view):
if self.hostname in ("host1", "host1.example.com", "host2"):
view.settings().set("font_size", 20)
on_load = on_new
Now any time you open a file or create a new buffer, if the current hostname is in the list you've configured the view will immediately get an appropriate font_size applied; otherwise the one from the preferences would be used instead.
You could also extend this to be configurable via it's own settings file, apply a different font size depending on the host name, etc.
Settings in views are persisted in the sublime-session file and also in the workspace files associated with sublime-project files, so these settings will remain in place even across restarts.
Something to keep in mind is that the internal commands for changing the font size (via Preferences > Font or via the mouse wheel keyboard shortcuts) work by writing a new font_size to your user preferences.
If you're using separate preference files, then doing this will add font_size to your User settings and you will need to manually remove it and modify the other settings file.
If you're using the plugin, then these shortcuts won't seem to do anything because it applies a font_size that overrides the User preference, but in fact as outlined above your preferences file end up being changed and you may not notice right away.
So whichever way you go, if you tend to use those you may need to make manual adjustments to settings files in the aftermath. It's also possible to create smarter versions of those commands as well, if this is the sort of thing that happens often.

Can you prevent P4Merge from jumping back to the top of the file when editing the workspace file?

I have a long standing issue with P4Merge. When I diff a workspace file with the version in the depot and then proceed to edit the workspace file, within P4Merge, after every edit and save the cursor jumps back to the top of the file. This force me to navigate back to the last diff I was at.
So the steps are something like:
Diff workspace file with depot version
Edit workspace file by pressing Edit File (in right pane) button
Edit the workspace file
Save the file (ctrl+s)
The result after step 4 is that you are automatically scrolled back to the first change in the file and have to track back the change you were previously focused on.
Is there any way to prevent this from happening? I.e. I just want to stay at the current line and be able to proceed to go to the next or previous change from there.
No, there is not a way to prevent this -- sounds like a bug more than anything.
As a workaround you can configure other merge tools to use with Perforce. Since you're on Windows my personal recommendation would be P4WinMerge (the merge tool that used to be bundled with P4Win -- I always found it a lot less "jittery" than the newer one so I never bothered to switch over), which you can still download thanks to the Wayback Machine:
http://web.archive.org/web/20160703111618/http://filehost.perforce.com/perforce/r07.2/bin.ntx86/p4winst.exe

"Show In - Explorer" with multiple files?

Here's a frequent situation: You have about thirty files checked out into a specific pending change-list. After working on those files, and before submitting them, you needed to move them to a folder (external to deposits, so a simple "Integrate" wouldn't be suitable).
Using the "Show In - Explorer" option, you'll get a lot of window popped-up. And that's just painful (and sometimes, the system just cannot open all of them).
So, question is, is there a simple way to copy-paste multiple files from a change-list without doing it individually?
You can do this with a custom tool.
In P4V, open the custom tools manager via the Tools->Manage Custom Tools... menu item
Click New->Tool... to open the Add Custom Tool dialog and enter these parameters (xcopy isn't the ideal app for this, but I'll talk about that later1)
alt text http://img202.imageshack.us/img202/6678/p4editcustomtool.png
Now you will be able to select all the files in your change list, right click on them, and a new item will be available in the context menu Copy selected files to another location..."
alt text http://img97.imageshack.us/img97/4003/p4vcustomtoolincontextm.png
An input box will appear, asking you where you wish to copy the files.
alt text http://img132.imageshack.us/img132/7612/p4locationprompt.png
Click OK and the files will be copied to the location you entered in the input dialog. Maybe...
1There are some problems with xcopy:
the target directory must already exist
it doesn't seem to work if the path contains spaces
if the process fails, you're process list will fill up with a bunch of instances of xcopy.exe that are stuck trying to do who knows what
the custom tool will no longer work if the previous condition occurs
I tried robocopy also, which would be perfect if there was a way to pass it the source directory, but P4V custom tool editor doesn't provide the parent directory as a parameter. Ideally, you should write your own file copy utility, if this is really important to you. It wouldn't require that much effort.
Lastly, the P4V custom tool editor offers a file browser, but not a folder browser, and the latter is what you really need for a tool such as this.
So, play around with the custom tool thing. You might be able to come up with an answer to your problem.
I know you want to do these things outside of Perforce, but the best I can think of is if you create another workspace specifically for exporting files. You can sync your Perforce workspace to contain only the files in a particular changelist.
In this workspace, try giving the files in your changelist, after it is submitted, a particular label. If you sync your workspace to this label, it will delete every file that does not have this label based on this Perforce page. (do Find for label in that page)
p4 sync #label_name
This involves Perforce, but it does provide a way to get only the files you want.
I believe you can also accomplish this only using changelist numbers, but it may be more complicated. I'm not 100% sure this works
p4 sync #none
p4 sync #changelist,#changelist
I think this will sync files only in this changelist.

Resources