DCOP scripting the Kate application

This article was imported form wiki.kate-editor.org. Note that kscript is no longer available in Kate since v. 2.4. If you absolutely have to, it is still possible to run dcop scripts using the External Tools feature.

Incorporation of a script into Kate

Kate works with all scripts which are defined by desktop files in $KDEDIR/share/apps/kate/scripts/ directory where $KDEDIR stands for the director where KDE looks for its files, for example /usr/kde, or for your own directory in ~/.kde/. In the first case the scripts are available for all users, in the latter only for yourself. This desktop file has the following structure:

[Desktop Entry]
Encoding=UTF-8
Name=English name of the script
Name[nl]=name in the Dutch
Type=ShellScript/bash
X-KDE-ScriptName=scriptname.sh

As an example we will write a script that counts the number of lines, words and characters in the current document. Our desktop file looks like this:

[Desktop Entry]
Encoding=UTF-8
Name=Word Count
Name[nl]=Woorden count
Type=ShellScript/bash
X-KDE-ScriptName=wordcount.sh

Save this file in ~/.kde/share/apps/kate/scripts/ under the
name wordcount.desktop. (It is possible that you have to create the directory if it does not exist.)

The script itself

Now we will write the script itself. It is named wordcount.sh, and it must be in the same directory as the corresponding desktop file. In this case it is just a normal shell-script, and so we have to start with shebang line:

#!/bin/bash

We use the DCOP technology (technical information) which allows our script to communicate with Kate. When the script is called from Kate it gets its DCOP name as first argument (this is usually just kate). The rest must dig out our script itself.

In the DCOP-browser dcop or kdcop we can find what Kate offers. We want find to out what is the number of the document currently shown in Kate's window. We can do this by running the following command, try it a terminal window (while Kate is running):

dcop kate KateDocumentManager activeDocumentNumber

This returns a value which stands up for the number of the currently active document in Kate. Instead of kate in the above example we may have to use something like kate-10665. Actual number of kate's process could be found with the command dcop ' kate * ' .

But for our script we have already got the correct DCOP name of the current kate: $1! Therefore the active document number can be find in our script by:

#!/bin/bash
doc=`dcop $1 KateDocumentManager activeDocumentNumber`

(Notice reversed quotations mark/backticks!) Then we can read (and also use!) this document through the EditInterface of that document:

edit="editinterface#$doc text=`dcop $1 #text`

The complete text of our active document appears now in the variable edit. But we wanted to count words, and for that we can use Unix-tool wc (word count). This tool examines document on its standard input so we can just pipe the output of the DCOP command right into wc, and output of wc can then be used in a KDE dialog for pretty display. The output wc consists from 3 numbers, the number of lines, words and characters.

Therefore, we can do this:

#!/bin/bash
doc=`dcop $1 KateDocumentManager activeDocumentNumber`
dcop $1 editinterface#$doc text | wc | {
    read lines words chars
    kdialog -- msgbox lines
}

Save this under the name wordcount.sh, in the same directory as desktop file referring this script. Now restart Kate, and you can find new command word count in the menu Tools > KDE-Scripts.

Improving the Script

Our script is possibly still too fragile. We can check whether kate runs:

#!/bin/bash
case "$1" in
kate*) ;;
*) echo "Please call me from Kate" > &2
exit 1;;
esac
#...

and we can embellish the output of KDialog with HTML. For that we place the complete message between <qt>- and </qt>-tags:

kdialog --title "words count" \
--msgbox "<qt><table >
<tr><td>Number of lines:</td><td align=right><b>$lines</b></td></tr>
<tr><td>Number of words:</td><td align=right><b>$words</b></td></tr>
<tr><td>Number of characters:</td><td align=right><b>$chars</b></td></tr>
</table></qt>"

so the resulting script now looks like this:

#!/bin/bash
case "$1" in kate*) ;;
*) echo "Please call me from Kate" > &2 exit 1;;
esac
doc=`dcop $1 KateDocumentManager activeDocumentNumber`
dcop $1 editinterface#$doc text | wc | { \
   read lines words chars kdialog -- title "words count" \
           --msgbox "<qt><table> <tr><td>Aantal regels:</td>
           <td align=right><b>$lines</b></td></tr>
           <tr><td>Aantal woorden:</td><td align=right><b>$words</b></td></tr>
           <tr><td>Aantal tekens:</td><td align=right><b>$chars</b></td></tr>
           </table></qt>"
   }

A screenshot of the dialog is available at:

<img src="kate1.png_small.jpg" alt="kate1.png" width="400" height="325"/>
(click for real size)

Words Count in Selected Text

This we leave to the reader as nice exercise! Tip: use the DCOP function SelectionInterface#<number> hasSelection to get whether there is a selection in the current document and the command SelectionInterface#<number> selection to get the content fo the selection. Take care as well to show in the dialog with results that the results are for the selection not for whole document.

For more information on shell scripting you may consult the following documents:

Comments

Fixes to this script

There was nothing wrong with the original version of the script except that it got munged a bit when it pasted into the blog editor. Here are the problems:

  1. In the case statement, ” > &2 exit 1;;” should read ” >& 2 exit 1;;” (Note the space before the 2)
  2. There needs to be a semicolon after “read lines words chars”since it is a separate command
  3. Remove the extra space right before the “title” option. It should be “—title” not “— title”. An unconnected “—” terminates the kdialog command string, hence nothing comes out.

Once I did these changes, it worked fine on KUbuntu 8.10

-Jonathan

get kate process dcop

get kate process dcop name

katedoc=dcop 'kate*'

Get the active document number

doc=dcop $katedoc KateDocumentManager activeDocumentNumber

but it only works when there is a single instance of kate running…

could not find a better solution. Could you perhaps fix this?

Alternative

I got this from the bug entry, it works:

Step by step howto for Kate Application: - Settings > Configure Kate… - ‘External Tools’ page - Create new external tool Label: Word Count Script: copy&paste 3 lines:

url=echo "%URL"|sed -r 's,^\w+\:/+,/,' count=wc -lwm "$url" kdialog —msgbox “Word count for\n%URL:\n$(echo $count|sed -r ‘s,\s(\w+)\s+(\w+)\s+(\w+).,Linebreaks: \1\nWords: \2\nCharacters: \3,’)”

Executable: wc Mime Types: leave blank Save: Current Document Command Line Name: leave blank or type ‘word-count’ - Save & Apply

Use: Tools > External Tools > Word Count

problem with this script

There is a problem with this script, as well as with the HTML-tidy script for Kate distributed with KDE.

dcop ' kate * '

returns not simply “kate”, but kate-1204 or even a few kate processes in case a few windows are open. In that case the command

dcop kate KateDocumentManager activeDocumentNumber

returns “call failed”. This did work on some KDE live cd’s (perhaps where a single instance of kate was forced) but it did not on my KDE 3.5.2 (kubuntu 5.10).

I did a workaround by setting kate kate process dcop name like this:

# get kate process dcop name
katedoc=`dcop 'kate*'`
# Get the active document number
doc=`dcop $katedoc KateDocumentManager activeDocumentNumber`

but it only works when there is a single instance of kate running…

could not find a better solution. Could you perhaps fix this?

One more question: I do not see the Tools > KDE scripts menu, is that on purpose, or is it a bug?

problem getting kate process number

I got a problem getting the kate process number.

 dcop kate KateDocumentManager activeDocumentNumber

returned an error: call failed

Therefore, I first had to get the kate process number and assign it to the variable $1

 dcop 'kate *' > $1

Then it worked! (I am using Kubuntu 5.10 and KDE 3.5.2)