scite-session 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: efd809ac386914ed6ce5c31d292b843f9bbb0d9e
4
+ data.tar.gz: 5b19a590c94d8863047538eb4a825b7499072160
5
+ SHA512:
6
+ metadata.gz: 4dc744eb71c3bb741348587574a068b7e704bfbd401b1ff568f27e434ba49d9550eef10207abe65fbd023c173f9c5324bd20c0f55a6b36231193e3f495098081
7
+ data.tar.gz: c3d6c856128c6f88798272b93f583fa68f6c9f7ada83621fdba081d460f46fbccf0fe254e681b94df52ed5d2a062a4ce3e273475bc500fa6df636faa1ea59327
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in scite-session.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Sergey Baev, https://github.com/tinbka
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ # SciTE::Session
2
+
3
+ This gem is used to ease a process of starting to work on a new project.
4
+ It handles SciTE sessions using a yaml file with a list of windows needed to pop up on demand. With a command it restores and arranges on a display a project-specific set of SciTE windows setting them custom meta-titles.
5
+ It works only within KDE using `kwin`, `xwininfo` and `wmctrl`.
6
+
7
+ SciTE is a non-popular text editor which I use for several reasons:
8
+ 1. My eyes favor non-monospace fonts.
9
+ 2. Several years ago I made cute lexers with beautiful color scheme for Ruby, CofeeScript, HAML, and Slim.
10
+ 3. It allows to arrange its instances so that I have configs in the first corner, models in the second, controllers in the third and so on. One day it has become mnemonical.
11
+
12
+ I use one Dolphin instance to manage files which allows text editor windows to contain only code not wasting display space.
13
+
14
+ For more info on title template read comment at top of `./bin/kwintag.fish`
15
+
16
+ ## Installation
17
+
18
+ Inside new project dir, so that it would be installed into an according gemset, run
19
+
20
+ $ gem install scite-session
21
+
22
+ ## Usage
23
+
24
+ Suggest there is two windows for project "my-app": one with models and another with controllers.
25
+ Save sessions to `~/scite/my-app/models` and `~/scite/my-app/controllers` accordingly.
26
+ In a console:
27
+
28
+ ```ruby
29
+ require 'scite/session'
30
+ windows = SciTE::Window.find_all
31
+ windows[0].title = 'Models: :title:'
32
+ windows[1].title = 'Controllers: :title:'
33
+ windows[0].session = 'my-app/models'
34
+ windows[1].session = 'my-app/controllers'
35
+ SciTE::Session.save windows, layout: 'my-app'
36
+ ```
37
+
38
+ Now when you run
39
+
40
+ ```ruby
41
+ SciTE::Session.restore layout: 'my-app'
42
+ ```
43
+ or
44
+ ```
45
+ $ scite-session my-app
46
+ ```
47
+
48
+ Those windows will be back on positions.
49
+ You can manually adjust a layout at ~/scite/layouts/my-app.yml
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "scite/session"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env fish
2
+
3
+ # This is a modified version of what can be found at https://unix.stackexchange.com/questions/22561/override-the-window-title-for-an-arbitrary-window-in-kde-and-set-a-custom-window
4
+ # This version implements "meta-title", that is it keeps a custom template for a window, and when a program changes a title for the window, it extracts the title, inserts it into the template and sets a result as an actual title.
5
+ #
6
+ # Usage:
7
+ # $ kwintag
8
+ # then quickly make a window active and in the opened window type a title you want
9
+ # There is a keyword ":title:", it will be substituted with the title a program itself want to set. E.g.
10
+ # suggest you set "Specs: :title:" on an editor window,
11
+ # then an editor tries to reset it to "message_spec.rb * SciTE",
12
+ # then a window title actually becomes "Specs: message_spec.rb *"
13
+ # It handles asterisk as well as regular KDE dashes and long dashes.
14
+
15
+ # this block is so you can use it from the command line with -t and -w
16
+ if test "$argv" != "" -a (math (count $argv)%2 == 0)
17
+ for i in (seq 1 (count $argv))
18
+ if test $argv[$i] = '-t'
19
+ set title_i_want $argv[(math 1 + $i)]
20
+ else if test $argv[$i] = '-w'
21
+ set window_id $argv[(math 1 + $i)]
22
+ end
23
+ end
24
+ if not test $window_id
25
+ echo "YOU DIDN'T ENTER A `window_id` WITH `-w`,
26
+ SO MAKE SURE THE WINDOW YOU WANT HAS FOCUS
27
+ TWO SECONDS FROM NOW!"
28
+ sleep 2
29
+ end
30
+ end
31
+
32
+ # get the id of the currently focused window
33
+ if not test $window_id
34
+ set window_id (xprop -root _NET_ACTIVE_WINDOW | grep -P -o "0x\w+")
35
+ end
36
+
37
+ echo window_id = $window_id
38
+
39
+ # get the title to force on that window
40
+
41
+ if not test $title_i_want
42
+ set title_i_want (kdialog --title "entitled" --inputbox "Type the title you want and hit enter.
43
+ To stop renaming, just enter nothing and hit esc.")
44
+ end
45
+
46
+ # this bit is needed for a kludge that allows window renaming
47
+ set has_renamed_before "FALSE"
48
+ set interrupt_message "WAIT WAIT I WANT A TURN BLOO BLOO BLEE BLUH BLOO" # hopefully i never want to actually use that as a title xD
49
+ xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME $interrupt_message -id $window_id
50
+
51
+ set auto_title ""
52
+ set custom_title ""
53
+ # take the output of xprop
54
+ # pipe it into a while loop
55
+ # everytime it outputs a new line
56
+ # stuff it into a variable named "current_title"
57
+ xprop -spy _NET_WM_NAME -id $window_id | while read current_title
58
+
59
+ # cut off extraneous not-the-title bits of that string
60
+ set current_title (echo $current_title | grep -P -o '(?<=_NET_WM_NAME\(UTF8_STRING\) = ").*(?="\z)')
61
+
62
+ # if the current title is the interrupt message
63
+ # AND
64
+ # this script has renamed the window at least once before
65
+ # then we wanna let the new name take over
66
+ if test $current_title = $interrupt_message -a $has_renamed_before = "TRUE"
67
+ exit
68
+ # if title_i_want is an empty string, exit
69
+ else if test $title_i_want = ""
70
+ xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "WIDNOW WILL START RENAMING ITSELF AS NORMAL" -id $window_id
71
+ exit
72
+ # otherwise just change the title to what i want
73
+ else if test $current_title != $custom_title
74
+ set auto_title (echo $current_title | sed -re 's| \* ([—\-] )?| * - |')
75
+ echo auto title: $auto_title
76
+ set auto_title_short (echo $auto_title | grep -P -o '.*?(?= [—\-] )')
77
+ echo auto title short: $auto_title_short
78
+ echo title i want: $title_i_want
79
+ set custom_title (echo $title_i_want | sed -e "s|:title:|$auto_title_short|")
80
+ echo custom title: $custom_title
81
+ echo $current_title != $custom_title
82
+ xprop -f _NET_WM_NAME 8u -set _NET_WM_NAME "$custom_title" -id $window_id
83
+ set has_renamed_before "TRUE"
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'scite/session'
3
+ SciTE::Session.restore layout: ARGV[0]
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,44 @@
1
+ # Basic implementation of an animation. Could be used anywhere.
2
+ # Optimized to not do anything when it is too late to display a frame.
3
+ module Animation
4
+ class << self
5
+
6
+ def swing_easing(part)
7
+ 0.5 - Math.cos(part * Math::PI)/2
8
+ end
9
+
10
+ def perform(initial_values, target_values, frames: 40, duration: 400.0, &interpolation)
11
+ keys = initial_values.merge(target_values).keys
12
+ values_diff = keys.map_hash {|k| [k, target_values[k].to_f - initial_values[k].to_f]}
13
+
14
+ initial_time = Time.now.to_f
15
+ duration_ms = duration.to_f / 1000
16
+ frame_count = frames
17
+ wait_count = frames - 1
18
+
19
+ 1.upto(frame_count) {|frame_i|
20
+ if frame_i != frame_count
21
+ now = Time.now.to_f
22
+ this_must_be_run_at = initial_time + duration_ms/wait_count * (frame_i - 1)
23
+ next_must_be_run_at = initial_time + duration_ms/wait_count * frame_i
24
+ next if now > this_must_be_run_at + 0.001
25
+ end
26
+
27
+ frame_values = keys.map_hash {|k|
28
+ time_part = frame_i.to_f / frame_count
29
+ [k, initial_values[k] + values_diff[k] * swing_easing(time_part)]
30
+ }
31
+ #$log << frame_values
32
+ yield frame_values
33
+
34
+ if frame_i != frame_count
35
+ now = Time.now.to_f
36
+ if now < next_must_be_run_at
37
+ sleep next_must_be_run_at - now
38
+ end
39
+ end
40
+ }
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,58 @@
1
+ require "scite/session/version"
2
+ require "rmtools"
3
+ require "scite/animation"
4
+ require "scite/window"
5
+
6
+ module SciTE
7
+
8
+ class << self
9
+
10
+ def run(params={})
11
+ sh_pid = Process.spawn "scite #{params.map {|k, v| "-#{k}:\"#{v}\""}*' '} 1>/dev/null 2>/dev/null", pgroup: 0
12
+ pid = `pgrep -P #{sh_pid}`.chomp
13
+ #$log << pid
14
+ pid
15
+ end
16
+
17
+ def set_title(wid, title)
18
+ Process.spawn "#{File.dirname(__FILE__)}/../../bin/kwintag.fish -t '#{title}' -w #{wid} 1>/dev/null 2>/dev/null", pgroup: 0
19
+ end
20
+
21
+ end
22
+
23
+ # Save and restore a SciTE sessions layout.
24
+ module Session
25
+ mattr_accessor :home, :layouts_home
26
+ self.home = "#{ENV['HOME']}/scite"
27
+ self.layouts_home = "#{home}/layouts"
28
+
29
+ class << self
30
+
31
+ def save(windows, layout:)
32
+ File.write "#{layouts_home}/#{layout}.yml", windows.map {|win|
33
+ {session: win.session, title: win.title, move_to: win.position}
34
+ }.to_yaml
35
+ end
36
+
37
+ def restore(windows: nil, layout: nil)
38
+ if layout
39
+ windows ||= YAML.load read "#{layouts_home}/#{layout}.yml"
40
+ end
41
+
42
+ windows.map! {|params|
43
+ if params.is Window
44
+ params
45
+ else
46
+ Window.new params
47
+ end
48
+ }
49
+ windows.each {|w|
50
+ w.create
51
+ sleep 0.1
52
+ }
53
+ windows.each &:wait
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ module SciTE
2
+ module Session
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,109 @@
1
+ module KDE
2
+
3
+ # Basic operations over windows in KDE.
4
+ class Window
5
+ class_attribute :header_height, :border_width
6
+ self.header_height = 23
7
+ self.border_width = 2
8
+
9
+ attr_reader :title, :position, :pid
10
+ attr_writer :title
11
+
12
+ def self.find(title: nil)
13
+ if title
14
+ if info = `wmctrl -l -p`[/^(0x\w+) +-?\d+ (\d+) .+ #{title}$/]
15
+ new title: title, pid: $2.to_i, wid: $1
16
+ end
17
+ end
18
+ end
19
+
20
+ def initialize(title: nil, pid: nil, wid: nil)
21
+ @title, @pid, @wid = title, pid, wid
22
+ @threads = []
23
+ end
24
+
25
+ def wait
26
+ @threads.joins
27
+ @threads = []
28
+ self
29
+ end
30
+
31
+ def wid
32
+ @wid ||= `wmctrl -l -p | grep " #@pid "`[/0x\w+/]
33
+ end
34
+
35
+ def position
36
+ @position ||= begin
37
+ shape = `xwininfo -id #{wid} -shape`.lines
38
+ dimms = shape.grep(/-geometry/)[0].match(/(?<w>\d+)x(?<h>\d+)/)
39
+ corner = shape.grep(/Corner/)[0].match(/\+(?<x>-?\d+)\+(?<y>-?\d+)/)
40
+ {w: dimms[:w].to_i, h: dimms[:h].to_i,
41
+ x: corner[:x].to_i - border_width, y: corner[:y].to_i - header_height}
42
+ end
43
+ end
44
+
45
+ def position=(coords)
46
+ coords = coords.map_hash {|k, v| [k, v.to_i]}
47
+ if @position != coords
48
+ @position = coords
49
+ `wmctrl -i -r #{wid} -e 0,#{coords[:x]},#{coords[:y]},#{coords[:w]},#{coords[:h]}`
50
+ end
51
+ end
52
+
53
+ def move(frames: 20, duration: 400.0, **coords)
54
+ coords.reverse_merge! position
55
+ #$log << [position, coords, {frames: frames, duration: duration}]
56
+ Animation.perform(position, coords, frames: frames, duration: duration) {|coords|
57
+ self.position = coords
58
+ }
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ module SciTE
66
+
67
+ # SciTE-specific operations over windows in KDE.
68
+ class Window < KDE::Window
69
+ attr_reader :session, :move_to
70
+ attr_writer :session
71
+
72
+ def self.find_all
73
+ `wmctrl -l -p`.split("\n").map {|line|
74
+ if line[/^(0x\w+) +-?\d+ (\d+) +\S+ +(.+ [-*] SciTE)$/]
75
+ new(title: $3, pid: $2.to_i, wid: $1)
76
+ end
77
+ }.compact
78
+ end
79
+
80
+ def initialize(title: nil, pid: nil, wid: nil, session: nil, move_to: nil)
81
+ @session, @move_to = session, move_to
82
+ super title: title, pid: pid, wid: wid
83
+ end
84
+
85
+ def create(&oncreate)
86
+ @pid ||= SciTE.run loadsession: "#{SciTE::Session.home}/#@session"
87
+ @threads << Thread.new {
88
+ sleep 0.2
89
+ self.position = {w: 50, h: 20, x: 2550, y: -40}
90
+ sleep 3 # даём вкладкам прогрузиться
91
+ move if @move_to
92
+ set_title if @title
93
+ yield self if block_given?
94
+ }
95
+ self
96
+ end
97
+
98
+ def move(frames: 20, duration: 400.0, **coords)
99
+ coords.reverse_merge! @move_to if @move_to
100
+ super
101
+ end
102
+
103
+ def set_title
104
+ SciTE.set_title wid, @title
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'scite/session/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "scite-session"
8
+ spec.version = SciTE::Session::VERSION
9
+ spec.authors = ["Sergey Baev"]
10
+
11
+ spec.summary = "Restores and arranges multiple SciTE sessions within KDE"
12
+ spec.homepage = "https://github.com/tinbka/" + spec.name
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
+ spec.require_paths = ["lib"]
16
+ spec.bindir = "bin"
17
+ spec.executables = ["scite-session"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.10"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+
22
+ spec.add_dependency "rmtools", "~> 2.5.0"
23
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scite-session
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sergey Baev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rmtools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.5.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.5.0
55
+ description:
56
+ email:
57
+ executables:
58
+ - scite-session
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/kwintag.fish
70
+ - bin/scite-session
71
+ - bin/setup
72
+ - lib/scite/animation.rb
73
+ - lib/scite/session.rb
74
+ - lib/scite/session/version.rb
75
+ - lib/scite/window.rb
76
+ - scite-session.gemspec
77
+ homepage: https://github.com/tinbka/scite-session
78
+ licenses: []
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.4.8
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Restores and arranges multiple SciTE sessions within KDE
100
+ test_files: []